[llvm-bugs] [Bug 34944] New: LTO: linkonce_odr functions are deserialized multiple times from the same source

via llvm-bugs llvm-bugs at lists.llvm.org
Fri Oct 13 16:38:32 PDT 2017


            Bug ID: 34944
           Summary: LTO: linkonce_odr functions are deserialized multiple
                    times from the same source
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: Bitcode Reader
          Assignee: unassignedbugs at nondot.org
          Reporter: aprantl at apple.com
                CC: llvm-bugs at lists.llvm.org

After r314699 (which runs the Verifier as part of the UpgradeDebugInfo) we
noticed that during a (full)LTO debug build of clang we were getting lots of
"DICompileUnit not listed in llvm.dbg.cu" warnings.

The following example has been reduced from llvm-ar:

$ cat a.cpp
class Error {};
template <typename HandlerTs>
void handleAllErrors(HandlerTs Handlers) {}
inline void consumeError(Error Err) {
  handleAllErrors( []() {});
void ArchiveMemberHeader() 

$ cat b.cpp
class Error {};
template <typename HandlerTs>
void handleAllErrors( HandlerTs  Handlers) {}
inline void consumeError(Error Err) {
  handleAllErrors( []() {});
int main(int argc, char **argv) {

$ clang++ -x c++ -std=c++14 -fPIC  -flto -g -fno-exceptions -fno-rtti -c -o a.o
-c a.cpp
$ $R/clang++ -x c++ -std=c++14 -fPIC  -flto -g -fno-exceptions -fno-rtti -c -o
b.o -c b.cpp
$ $R/llvm-lto a.o b.o
DICompileUnit not listed in llvm.dbg.cu
!35 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !25,
producer: "clang version 6.0.0 (trunk 315470) (llvm/trunk 315472)",
isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
llvm-lto: warning loading file 'b.o': ignoring invalid debug info in b.o

Curious! After loading this into the debugger, I noticed that the linkonce_odr
function _Z12consumeError5Error, which is present in both files, is
deserialized in a most peculiar way: The BitcodeReader has a
DeferredFunctionInfo map. The BitcodeReader stays alive between reading module
A and module B. Module A is deserialized as usual. When module b is
deserialized, the BitcodeReader object is reused and when it comes to
materializing _Z12consumeError5Error it is found in the DeferredFunctionInfo,
which points to the other module, A. The BitcodeReader then deserializes the
function from module A(!) into module B(!), together with all the debug info
metadata hanging off it, including the DICompileUnit that we are already
familiar with from the warning.

This behavior seems really silly: The BitcodeReader is smart enough to know
that it already found this function in another module and deserializes it from
there only to later delete the function when it gets uniqued at module merge
time. I'm guessing the the BitcodeReader's behavior is more a side-effect of
the implementation than an intentional behavior, but I wonder if we could just
not make it materialize linkonce_odr functions that were already visited, if we
know that we are doing LTO. I guess this optimization would also benefit

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/20171013/a6939246/attachment-0001.html>

More information about the llvm-bugs mailing list