You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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:
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 ThinLTO.
The text was updated successfully, but these errors were encountered:
It looks like my analysis was premature. The BitcodeReader actually does get destroyed after parsing a module. What causes this symptom is that when materializing the debug info for the linkonce_odr function in the second module, we make a call to DIBuilder::buildODRType, which uses the LLVMContext to look up whether we already built a unique type with the same UID and this returns the type from the first module (which pulls in the DICompileUnit from the first module as well).
There is still a performance improvement to be made by not materializing linkonce_odr functions more than once, but at least we are deserializing them from the correct module now.
Extended Description
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
void handleAllErrors(HandlerTs Handlers) {}
inline void consumeError(Error Err) {
handleAllErrors( {});
}
void ArchiveMemberHeader()
{
consumeError(Error());
}
$ cat b.cpp
class Error {};
template
void handleAllErrors( HandlerTs Handlers) {}
inline void consumeError(Error Err) {
handleAllErrors( {});
}
int main(int argc, char **argv) {
consumeError(Error());
}
$ 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 ThinLTO.
The text was updated successfully, but these errors were encountered: