diff options
author | Teresa Johnson <tejohnson@google.com> | 2015-11-10 21:09:06 +0000 |
---|---|---|
committer | Teresa Johnson <tejohnson@google.com> | 2015-11-10 21:09:06 +0000 |
commit | 2d5fb8cac4ec7b6f763c6f91b52f6a954ad99942 (patch) | |
tree | 0def0e94c9a600926ff70b62935510dd70b15395 /llvm/lib/Linker/LinkModules.cpp | |
parent | 6db4640b801f1d749495e20d77f9129196ac8686 (diff) | |
download | bcm5719-llvm-2d5fb8cac4ec7b6f763c6f91b52f6a954ad99942.tar.gz bcm5719-llvm-2d5fb8cac4ec7b6f763c6f91b52f6a954ad99942.zip |
Ensure ModuleLinker materializes complete comdat groups
Summary:
The module linker lazy links some "discardable if unused" global
values (e.g. linkonce), materializing and linking them only
if they are referenced in the module. If a comdat group contains a
linkonce member that is not referenced, however, it would not be
materialized and linked, leading to an incomplete comdat group.
If there are other object files not part of the same LTO link that also
define and use that comdat group, the linker may select the incomplete
group leading to link time unsats.
To solve this, whenever a global value body is linked, make sure we
materialize any other members of the same comdat group that are not yet
materialized. This ensures they are in the lazy link list and get linked
as well.
Added new test and adjusted old test to remove parts that didn't
make sense with fix.
Reviewers: rafael
Subscribers: dexonsmith, davidxl, llvm-commits
Differential Revision: http://reviews.llvm.org/D14516
llvm-svn: 252647
Diffstat (limited to 'llvm/lib/Linker/LinkModules.cpp')
-rw-r--r-- | llvm/lib/Linker/LinkModules.cpp | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/llvm/lib/Linker/LinkModules.cpp b/llvm/lib/Linker/LinkModules.cpp index 8968377663e..71af9d0d61e 100644 --- a/llvm/lib/Linker/LinkModules.cpp +++ b/llvm/lib/Linker/LinkModules.cpp @@ -509,6 +509,8 @@ private: ComdatsChosen; bool getComdatResult(const Comdat *SrcC, Comdat::SelectionKind &SK, bool &LinkFromSrc); + // Keep track of the global value members of each comdat in source. + DenseMap<const Comdat *, std::vector<GlobalValue *>> ComdatMembers; /// Given a global in the source module, return the global in the /// destination module that is being linked to, if any. @@ -1386,6 +1388,7 @@ bool ModuleLinker::linkGlobalValueProto(GlobalValue *SGV) { std::tie(SK, LinkFromSrc) = ComdatsChosen[SC]; C = DstM->getOrInsertComdat(SC->getName()); C->setSelectionKind(SK); + ComdatMembers[SC].push_back(SGV); } else if (DGV) { if (shouldLinkFromSource(LinkFromSrc, *DGV, *SGV)) return true; @@ -1589,6 +1592,19 @@ void ModuleLinker::linkAliasBody(GlobalAlias &Dst, GlobalAlias &Src) { bool ModuleLinker::linkGlobalValueBody(GlobalValue &Src) { Value *Dst = ValueMap[&Src]; assert(Dst); + if (const Comdat *SC = Src.getComdat()) { + // To ensure that we don't generate an incomplete comdat group, + // we must materialize and map in any other members that are not + // yet materialized in Dst, which also ensures their definitions + // are linked in. Otherwise, linkonce and other lazy linked GVs will + // not be materialized if they aren't referenced. + for (auto *SGV : ComdatMembers[SC]) { + if (ValueMap[SGV]) + continue; + Value *NewV = ValMaterializer.materializeValueFor(SGV); + ValueMap[SGV] = NewV; + } + } if (shouldInternalizeLinkedSymbols()) if (auto *DGV = dyn_cast<GlobalValue>(Dst)) DGV->setLinkage(GlobalValue::InternalLinkage); |