<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - LTO: linkonce_odr functions are deserialized multiple times from the same source"
href="https://bugs.llvm.org/show_bug.cgi?id=34944">34944</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>LTO: linkonce_odr functions are deserialized multiple times from the same source
</td>
</tr>
<tr>
<th>Product</th>
<td>libraries
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>All
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>enhancement
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>Bitcode Reader
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>aprantl@apple.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>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()
{
consumeError(Error());
}
$ cat b.cpp
class Error {};
template <typename HandlerTs>
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.</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>