diff options
Diffstat (limited to 'llvm/lib/Linker/LinkModules.cpp')
-rw-r--r-- | llvm/lib/Linker/LinkModules.cpp | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/llvm/lib/Linker/LinkModules.cpp b/llvm/lib/Linker/LinkModules.cpp index e884f452f03..d1000dc9a9f 100644 --- a/llvm/lib/Linker/LinkModules.cpp +++ b/llvm/lib/Linker/LinkModules.cpp @@ -1250,10 +1250,9 @@ void ModuleLinker::linkNamedMDNodes() { /// Drop DISubprograms that have been superseded. /// -/// FIXME: this creates an asymmetric result: we strip functions from losing -/// subprograms in DstM, but leave losing subprograms in SrcM. -/// TODO: Remove this logic once the backend can correctly determine canonical -/// subprograms. +/// FIXME: this creates an asymmetric result: we strip losing subprograms from +/// DstM, but leave losing subprograms in SrcM. Instead we should also strip +/// losers from SrcM, but this requires extra plumbing in MapMetadata. void ModuleLinker::stripReplacedSubprograms() { // Avoid quadratic runtime by returning early when there's nothing to do. if (OverridingFunctions.empty()) @@ -1263,8 +1262,8 @@ void ModuleLinker::stripReplacedSubprograms() { auto Functions = std::move(OverridingFunctions); OverridingFunctions.clear(); - // Drop functions from subprograms if they've been overridden by the new - // compile unit. + // Drop subprograms whose functions have been overridden by the new compile + // unit. NamedMDNode *CompileUnits = DstM->getNamedMetadata("llvm.dbg.cu"); if (!CompileUnits) return; @@ -1275,15 +1274,19 @@ void ModuleLinker::stripReplacedSubprograms() { DITypedArray<DISubprogram> SPs(CU.getSubprograms()); assert(SPs && "Expected valid subprogram array"); + SmallVector<Metadata *, 16> NewSPs; + NewSPs.reserve(SPs.getNumElements()); for (unsigned S = 0, SE = SPs.getNumElements(); S != SE; ++S) { DISubprogram SP = SPs.getElement(S); - if (!SP || !SP.getFunction() || !Functions.count(SP.getFunction())) + if (SP && SP.getFunction() && Functions.count(SP.getFunction())) continue; - // Prevent DebugInfoFinder from tagging this as the canonical subprogram, - // since the canonical one is in the incoming module. - SP->replaceFunction(nullptr); + NewSPs.push_back(SP); } + + // Redirect operand to the overriding subprogram. + if (NewSPs.size() != SPs.getNumElements()) + CU.replaceSubprograms(DIArray(MDNode::get(DstM->getContext(), NewSPs))); } } |