summaryrefslogtreecommitdiff
path: root/lib/LTO/LTO.cpp
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2017-02-02 05:22:42 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2017-02-02 05:22:42 +0000
commitd69c1efa3844be71ad9b2359f716ceed629304ee (patch)
treeb435660b1f35e601ba983252edd25a3e5d26e9c3 /lib/LTO/LTO.cpp
parente482a05c0695b6276d178e93497a100090b38567 (diff)
LTO: Link non-prevailing weak_odr or linkonce_odr globals into the combined module with available_externally linkage.
These linkages mean that the ultimately prevailing symbol will have the same semantics as any non-prevailing copy of the symbol, so we are free to ignore the linker's resolution. Differential Revision: https://reviews.llvm.org/D29367 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@293865 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/LTO/LTO.cpp')
-rw-r--r--lib/LTO/LTO.cpp21
1 files changed, 17 insertions, 4 deletions
diff --git a/lib/LTO/LTO.cpp b/lib/LTO/LTO.cpp
index 4d0c039891e..df19ded398d 100644
--- a/lib/LTO/LTO.cpp
+++ b/lib/LTO/LTO.cpp
@@ -446,6 +446,11 @@ Error LTO::addRegularLTO(BitcodeModule BM, const SymbolResolution *&ResI,
if (GV.hasAppendingLinkage())
Keep.push_back(&GV);
+ DenseSet<GlobalObject *> AliasedGlobals;
+ for (auto &GA : M.aliases())
+ if (GlobalObject *GO = GA.getBaseObject())
+ AliasedGlobals.insert(GO);
+
for (const InputFile::Symbol &Sym :
make_range(InputFile::symbol_iterator(SymTab.symbols().begin(), SymTab,
nullptr),
@@ -471,13 +476,21 @@ Error LTO::addRegularLTO(BitcodeModule BM, const SymbolResolution *&ResI,
GV->setLinkage(GlobalValue::WeakODRLinkage);
break;
}
- } else if (GV->hasAvailableExternallyLinkage()) {
- // We can link available_externally symbols even if they are
- // non-prevailing.
+ } else if (isa<GlobalObject>(GV) &&
+ (GV->hasLinkOnceODRLinkage() || GV->hasWeakODRLinkage() ||
+ GV->hasAvailableExternallyLinkage()) &&
+ !AliasedGlobals.count(cast<GlobalObject>(GV))) {
+ // Either of the above three types of linkage indicates that the
+ // chosen prevailing symbol will have the same semantics as this copy of
+ // the symbol, so we can link it with available_externally linkage. We
+ // only need to do this if the symbol is undefined.
GlobalValue *CombinedGV =
RegularLTO.CombinedModule->getNamedValue(GV->getName());
- if (!CombinedGV || CombinedGV->isDeclaration())
+ if (!CombinedGV || CombinedGV->isDeclaration()) {
Keep.push_back(GV);
+ GV->setLinkage(GlobalValue::AvailableExternallyLinkage);
+ cast<GlobalObject>(GV)->setComdat(nullptr);
+ }
}
}
// Common resolution: collect the maximum size/alignment over all commons.