diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2015-12-02 22:59:04 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2015-12-02 22:59:04 +0000 |
commit | 4b5ec2637384579ac64e3b6a8671282e6bedd028 (patch) | |
tree | 23b222c64e584dd6b05ee77018a48c7edee912b7 /llvm/lib | |
parent | 71552ce64b161cc94c0bdbc69d6e2f72c54cf90e (diff) | |
download | bcm5719-llvm-4b5ec2637384579ac64e3b6a8671282e6bedd028.tar.gz bcm5719-llvm-4b5ec2637384579ac64e3b6a8671282e6bedd028.zip |
Switch the linker to having a whitelist of GVs.
This replaces DoNotLinkFromSource with ValuesToLink. It also moves the
computation of ValuesToLink earlier.
It is a bit simpler and an important step in slitting the linker into an
ir mover and a linker proper.
The test change is because we now avoid creating dead declarations.
llvm-svn: 254559
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Linker/LinkModules.cpp | 118 |
1 files changed, 67 insertions, 51 deletions
diff --git a/llvm/lib/Linker/LinkModules.cpp b/llvm/lib/Linker/LinkModules.cpp index 1a01b78cd0b..21df66863e5 100644 --- a/llvm/lib/Linker/LinkModules.cpp +++ b/llvm/lib/Linker/LinkModules.cpp @@ -392,8 +392,7 @@ class ModuleLinker { /// but this allows us to reuse the ValueMapper code. ValueToValueMapTy ValueMap; - // Set of items not to link in from source. - SmallPtrSet<const GlobalValue *, 16> DoNotLinkFromSource; + SetVector<GlobalValue *> ValuesToLink; DiagnosticHandlerFunction DiagnosticHandler; @@ -862,18 +861,8 @@ Value *ModuleLinker::materializeDeclFor(Value *V) { if (!SGV) return nullptr; - // If we are done linking global value bodies (i.e. we are performing - // metadata linking), don't link in the global value due to this - // reference, simply map it to null. - if (DoneLinkingBodies) - return nullptr; - linkGlobalValueProto(SGV); - if (HasError) - return nullptr; - Value *Ret = ValueMap[SGV]; - assert(Ret); - return Ret; + return ValueMap[SGV]; } void ValueMaterializerTy::materializeInitFor(GlobalValue *New, @@ -881,6 +870,11 @@ void ValueMaterializerTy::materializeInitFor(GlobalValue *New, return ModLinker->materializeInitFor(New, Old); } +static bool shouldLazyLink(const GlobalValue &GV) { + return GV.hasLocalLinkage() || GV.hasLinkOnceLinkage() || + GV.hasAvailableExternallyLinkage(); +} + void ModuleLinker::materializeInitFor(GlobalValue *New, GlobalValue *Old) { if (auto *F = dyn_cast<Function>(New)) { if (!F->isDeclaration()) @@ -900,7 +894,7 @@ void ModuleLinker::materializeInitFor(GlobalValue *New, GlobalValue *Old) { if (isPerformingImport() && !doImportAsDefinition(Old)) return; - if (!New->hasLocalLinkage() && DoNotLinkFromSource.count(Old)) + if (!ValuesToLink.count(Old) && !shouldLazyLink(*Old)) return; linkGlobalValueBody(*New, *Old); @@ -1342,7 +1336,8 @@ bool ModuleLinker::linkAppendingVarProto(GlobalVariable *DstGV, [this](Constant *E) { auto *Key = dyn_cast<GlobalValue>( E->getAggregateElement(2)->stripPointerCasts()); - return DoNotLinkFromSource.count(Key); + return Key && !ValuesToLink.count(Key) && + !shouldLazyLink(*Key); }), SrcElements.end()); uint64_t NewSize = DstElements.size() + SrcElements.size(); @@ -1381,14 +1376,6 @@ bool ModuleLinker::linkGlobalValueProto(GlobalValue *SGV) { // Handle the ultra special appending linkage case first. assert(!DGV || SGV->hasAppendingLinkage() == DGV->hasAppendingLinkage()); - if (SGV->hasAppendingLinkage() && isPerformingImport()) { - // Don't want to append to global_ctors list, for example, when we - // are importing for ThinLTO, otherwise the global ctors and dtors - // get executed multiple times for local variables (the latter causing - // double frees). - DoNotLinkFromSource.insert(SGV); - return false; - } if (SGV->hasAppendingLinkage()) return linkAppendingVarProto(cast_or_null<GlobalVariable>(DGV), cast<GlobalVariable>(SGV)); @@ -1411,15 +1398,9 @@ bool ModuleLinker::linkGlobalValueProto(GlobalValue *SGV) { return true; } - if (!LinkFromSrc) { - // Track the source global so that we don't attempt to copy it over when - // processing global initializers. - DoNotLinkFromSource.insert(SGV); - - if (DGV) - // Make sure to remember this mapping. - ValueMap[SGV] = - ConstantExpr::getBitCast(DGV, TypeMap.get(SGV->getType())); + if (!LinkFromSrc && DGV) { + // Make sure to remember this mapping. + ValueMap[SGV] = ConstantExpr::getBitCast(DGV, TypeMap.get(SGV->getType())); } if (DGV) @@ -1431,6 +1412,12 @@ bool ModuleLinker::linkGlobalValueProto(GlobalValue *SGV) { // When linking from source we setVisibility from copyGlobalValueProto. setVisibility(NewGV, SGV, DGV); } else { + // If we are done linking global value bodies (i.e. we are performing + // metadata linking), don't link in the global value due to this + // reference, simply map it to null. + if (DoneLinkingBodies) + return false; + NewGV = copyGlobalValueProto(TypeMap, SGV, DGV, LinkFromSrc); } @@ -1774,30 +1761,62 @@ bool ModuleLinker::linkIfNeeded(GlobalValue &GV) { if (shouldLinkOnlyNeeded() && !(DGV && DGV->isDeclaration())) return false; - if (DGV && !GV.hasLocalLinkage()) { + if (DGV && !GV.hasLocalLinkage() && !GV.hasAppendingLinkage()) { + auto *DGVar = dyn_cast<GlobalVariable>(DGV); + auto *SGVar = dyn_cast<GlobalVariable>(&GV); + if (DGVar && SGVar) { + if (DGVar->isDeclaration() && SGVar->isDeclaration() && + (!DGVar->isConstant() || !SGVar->isConstant())) { + DGVar->setConstant(false); + SGVar->setConstant(false); + } + if (DGVar->hasCommonLinkage() && SGVar->hasCommonLinkage()) { + unsigned Align = std::max(DGVar->getAlignment(), SGVar->getAlignment()); + SGVar->setAlignment(Align); + DGVar->setAlignment(Align); + } + } + GlobalValue::VisibilityTypes Visibility = getMinVisibility(DGV->getVisibility(), GV.getVisibility()); DGV->setVisibility(Visibility); GV.setVisibility(Visibility); + + bool HasUnnamedAddr = GV.hasUnnamedAddr() && DGV->hasUnnamedAddr(); + DGV->setUnnamedAddr(HasUnnamedAddr); + GV.setUnnamedAddr(HasUnnamedAddr); } + // Don't want to append to global_ctors list, for example, when we + // are importing for ThinLTO, otherwise the global ctors and dtors + // get executed multiple times for local variables (the latter causing + // double frees). + if (GV.hasAppendingLinkage() && isPerformingImport()) + return false; + + if (isPerformingImport() && !doImportAsDefinition(&GV)) + return false; + + if (!DGV && !shouldOverrideFromSrc() && + (GV.hasLocalLinkage() || GV.hasLinkOnceLinkage() || + GV.hasAvailableExternallyLinkage())) + return false; + if (const Comdat *SC = GV.getComdat()) { bool LinkFromSrc; Comdat::SelectionKind SK; std::tie(SK, LinkFromSrc) = ComdatsChosen[SC]; - if (!LinkFromSrc) { - DoNotLinkFromSource.insert(&GV); - return false; - } - } - - if (!DGV && !shouldOverrideFromSrc() && - (GV.hasLocalLinkage() || GV.hasLinkOnceLinkage() || - GV.hasAvailableExternallyLinkage())) { + if (LinkFromSrc) + ValuesToLink.insert(&GV); return false; } - MapValue(&GV, ValueMap, RF_MoveDistinctMDs, &TypeMap, &ValMaterializer); - return HasError; + + bool LinkFromSrc = true; + if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, GV)) + return true; + if (LinkFromSrc) + ValuesToLink.insert(&GV); + return false; } bool ModuleLinker::run() { @@ -1881,13 +1900,10 @@ bool ModuleLinker::run() { if (linkIfNeeded(GA)) return true; - for (const auto &Entry : DstM.getComdatSymbolTable()) { - const Comdat &C = Entry.getValue(); - if (C.getSelectionKind() == Comdat::Any) - continue; - const GlobalValue *GV = SrcM.getNamedValue(C.getName()); - if (GV) - MapValue(GV, ValueMap, RF_MoveDistinctMDs, &TypeMap, &ValMaterializer); + for (GlobalValue *GV : ValuesToLink) { + MapValue(GV, ValueMap, RF_MoveDistinctMDs, &TypeMap, &ValMaterializer); + if (HasError) + return true; } // Note that we are done linking global value bodies. This prevents |