[llvm-bugs] [Bug 32441] New: [LTO] Private symbol order reversed during IR linking with resolution-based API

via llvm-bugs llvm-bugs at lists.llvm.org
Mon Mar 27 14:21:58 PDT 2017


            Bug ID: 32441
           Summary: [LTO] Private symbol order reversed during IR linking
                    with resolution-based API
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: Object
          Assignee: unassignedbugs at nondot.org
          Reporter: tobias at codeaurora.org
                CC: llvm-bugs at lists.llvm.org

Created attachment 18183
  --> https://bugs.llvm.org/attachment.cgi?id=18183&action=edit
Test case

I'm seeing an issue with customer code that relies on the order of private
symbols (strings), used as initializers for global variables, being preserved
during LTO. The old LTO API does this, the resolution-based API reverses them.
I'm not sure what the C standard says about this, but it just seems arbitrary
to do this.

I've tracked down the root of the issue to ModuleSymbolTable::addModule, so
Peter I'd appreciate your comments on this.

In the following, I'm referring to the trivial test case attached to this bug.
It defines two globals, bar1 and bar2, which are initialized with strings (.str
and .str.1). There is a function foo which uses them in the order bar1 and then
bar2 (this is important).

Let's first run this through the old API:
llvm-lto privateorder.bc -exported-symbol=bar1 -exported-symbol=bar2
-exported-symbol=foo -save-merged-module -o privateorder.o

In ModuleLinker::run(), the 'kept' globals are added in the order
variables-functions-aliases (here: bar1, bar2, foo). The IRMover materializes
them in this order from its worklist, and all is good. The merged module
(privateorder.o.merged.bc) has @.str and @.str1 in the correct order. 

Now if I run this through the new API things are different in
llvm-lto2 privateorder.bc -r privateorder.bc,bar1,px -r privateorder.bc,bar2,px
-r privateorder.bc,foo,px -r privateorder.bc,puts, -o privateorder.o

ModuleSymbolTable::addModule() builds the list of symbols in the module by
iterating over them in the order of functions-variables-aliases, which in this
case leads to the Keep list being [foo,bar1,bar2] in LTO::addModule. The
IRMover now materializes foo first, which triggers its dependences bar1 and
bar2 to be scheduled for materialization by the Mapper, which in turn triggers
the strings (which will be processed in reverse by the Mapper). When the
IRMover reaches bar1 and bar2 in its worklist, they and their initializers are
already materialized.

Now, the easy fix appears to be to change the order in
ModuleSymbolTable::addModule() from functions-variables-aliases to
variables-functions-aliases. I then see the exact same materialization order as
with the old API.

My question for you all is:
Would this be safe/correct? Was there a particular reason why a different
iteration order was chosen for the ModuleSymbolTable? I feel that the
convention across LLVM tends to be variables then functions, rather than the
other way around.


You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20170327/28383acb/attachment.html>

More information about the llvm-bugs mailing list