From 7c4c88cf5f63239ee60f335af4d66ed363c92310 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Mon, 30 Nov 2015 23:54:19 +0000 Subject: [PATCH] This reverts commit r254336 and r254344. They broke a bot and I am debugging why. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@254347 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Linker/LinkModules.cpp | 153 ++++++++++++++------------- lib/Transforms/Utils/ValueMapper.cpp | 6 +- test/Linker/Inputs/comdat11.ll | 9 -- test/Linker/comdat11.ll | 13 --- test/Linker/comdat12.ll | 8 -- test/Linker/comdat9.ll | 3 - 6 files changed, 80 insertions(+), 112 deletions(-) delete mode 100644 test/Linker/Inputs/comdat11.ll delete mode 100644 test/Linker/comdat11.ll delete mode 100644 test/Linker/comdat12.ll diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index edee55a1f9f..cdf1decc813 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -436,8 +436,6 @@ class ModuleLinker { /// references. bool DoneLinkingBodies; - bool HasError = false; - public: ModuleLinker(Module *dstM, Linker::IdentifiedStructTypeSet &Set, Module *srcM, DiagnosticHandlerFunction DiagnosticHandler, unsigned Flags, @@ -485,7 +483,6 @@ private: /// Helper method for setting a message and returning an error code. bool emitError(const Twine &Message) { DiagnosticHandler(LinkDiagnosticInfo(DS_Error, Message)); - HasError = true; return true; } @@ -534,7 +531,6 @@ private: void upgradeMismatchedGlobalArray(StringRef Name); void upgradeMismatchedGlobals(); - bool linkIfNeeded(GlobalValue &GV); bool linkAppendingVarProto(GlobalVariable *DstGV, const GlobalVariable *SrcGV); @@ -908,12 +904,16 @@ Value *ModuleLinker::materializeDeclFor(Value *V) { if (doneLinkingBodies()) return nullptr; - linkGlobalValueProto(SGV); - if (HasError) - return nullptr; - Value *Ret = ValueMap[SGV]; - assert(Ret); - return Ret; + GlobalValue *DGV = copyGlobalValueProto(TypeMap, SGV); + + if (Comdat *SC = SGV->getComdat()) { + if (auto *DGO = dyn_cast(DGV)) { + Comdat *DC = DstM->getOrInsertComdat(SC->getName()); + DGO->setComdat(DC); + } + } + + return DGV; } void ValueMaterializerTy::materializeInitFor(GlobalValue *New, @@ -922,27 +922,15 @@ void ValueMaterializerTy::materializeInitFor(GlobalValue *New, } void ModuleLinker::materializeInitFor(GlobalValue *New, GlobalValue *Old) { - if (auto *F = dyn_cast(New)) { - if (!F->isDeclaration()) - return; - } else if (auto *V = dyn_cast(New)) { - if (V->hasInitializer()) - return; - } else { - auto *A = cast(New); - if (A->getAliasee()) - return; - } - - if (Old->isDeclaration()) - return; - if (isPerformingImport() && !doImportAsDefinition(Old)) return; - if (DoNotLinkFromSource.count(Old)) + // Skip declarations that ValueMaterializer may have created in + // case we link in only some of SrcM. + if (shouldLinkOnlyNeeded() && Old->isDeclaration()) return; + assert(!Old->isDeclaration() && "users should not pass down decls"); linkGlobalValueBody(*Old); } @@ -1417,6 +1405,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; @@ -1436,12 +1425,31 @@ bool ModuleLinker::linkGlobalValueProto(GlobalValue *SGV) { if (DGV) HasUnnamedAddr = HasUnnamedAddr && DGV->hasUnnamedAddr(); + if (!LinkFromSrc && !DGV) + return false; + GlobalValue *NewGV; - if (!LinkFromSrc && DGV) { + if (!LinkFromSrc) { NewGV = DGV; // When linking from source we setVisibility from copyGlobalValueProto. setVisibility(NewGV, SGV, DGV); } else { + // If the GV is to be lazily linked, don't create it just yet. + // The ValueMaterializerTy will deal with creating it if it's used. + if (!DGV && !shouldOverrideFromSrc() && SGV != ImportFunction && + (SGV->hasLocalLinkage() || SGV->hasLinkOnceLinkage() || + SGV->hasAvailableExternallyLinkage())) { + DoNotLinkFromSource.insert(SGV); + return false; + } + + // When we only want to link in unresolved dependencies, blacklist + // the symbol unless unless DestM has a matching declaration (DGV). + if (shouldLinkOnlyNeeded() && !(DGV && DGV->isDeclaration())) { + DoNotLinkFromSource.insert(SGV); + return false; + } + NewGV = copyGlobalValueProto(TypeMap, SGV, DGV); if (isPerformingImport() && !doImportAsDefinition(SGV)) @@ -1451,7 +1459,7 @@ bool ModuleLinker::linkGlobalValueProto(GlobalValue *SGV) { NewGV->setUnnamedAddr(HasUnnamedAddr); if (auto *NewGO = dyn_cast(NewGV)) { - if (C && LinkFromSrc) + if (C) NewGO->setComdat(C); if (DGV && DGV->hasCommonLinkage() && SGV->hasCommonLinkage()) @@ -1834,38 +1842,6 @@ static std::string mergeTriples(const Triple &SrcTriple, const Triple &DstTriple return DstTriple.str(); } -bool ModuleLinker::linkIfNeeded(GlobalValue &GV) { - GlobalValue *DGV = getLinkedToGlobal(&GV); - - if (shouldLinkOnlyNeeded() && !(DGV && DGV->isDeclaration())) - return false; - - if (DGV && !GV.hasLocalLinkage()) { - GlobalValue::VisibilityTypes Visibility = - getMinVisibility(DGV->getVisibility(), GV.getVisibility()); - DGV->setVisibility(Visibility); - GV.setVisibility(Visibility); - } - - 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())) { - return false; - } - MapValue(&GV, ValueMap, RF_MoveDistinctMDs, &TypeMap, &ValMaterializer); - return HasError; -} - bool ModuleLinker::run() { assert(DstM && "Null destination module"); assert(SrcM && "Null source module"); @@ -1925,30 +1901,24 @@ bool ModuleLinker::run() { // Upgrade mismatched global arrays. upgradeMismatchedGlobals(); - for (GlobalVariable &GV : SrcM->globals()) - if (const Comdat *SC = GV.getComdat()) - ComdatMembers[SC].push_back(&GV); - - for (Function &SF : *SrcM) - if (const Comdat *SC = SF.getComdat()) - ComdatMembers[SC].push_back(&SF); - - for (GlobalAlias &GA : SrcM->aliases()) - if (const Comdat *SC = GA.getComdat()) - ComdatMembers[SC].push_back(&GA); - // Insert all of the globals in src into the DstM module... without linking // initializers (which could refer to functions not yet mapped over). for (GlobalVariable &GV : SrcM->globals()) - if (linkIfNeeded(GV)) + if (linkGlobalValueProto(&GV)) return true; - for (Function &SF : *SrcM) - if (linkIfNeeded(SF)) + // Link the functions together between the two modules, without doing function + // bodies... this just adds external function prototypes to the DstM + // function... We do this so that when we begin processing function bodies, + // all of the global values that may be referenced are available in our + // ValueMap. + for (Function &F :*SrcM) + if (linkGlobalValueProto(&F)) return true; + // If there were any aliases, link them now. for (GlobalAlias &GA : SrcM->aliases()) - if (linkIfNeeded(GA)) + if (linkGlobalValueProto(&GA)) return true; for (AppendingVarInfo &AppendingVar : AppendingVars) @@ -1963,6 +1933,37 @@ bool ModuleLinker::run() { MapValue(GV, ValueMap, RF_MoveDistinctMDs, &TypeMap, &ValMaterializer); } + // Link in the function bodies that are defined in the source module into + // DstM. + for (Function &SF : *SrcM) { + // Skip if no body (function is external). + if (SF.isDeclaration()) + continue; + + // Skip if not linking from source. + if (DoNotLinkFromSource.count(&SF)) + continue; + + if (linkGlobalValueBody(SF)) + return true; + } + + // Resolve all uses of aliases with aliasees. + for (GlobalAlias &Src : SrcM->aliases()) { + if (DoNotLinkFromSource.count(&Src)) + continue; + linkGlobalValueBody(Src); + } + + // Update the initializers in the DstM module now that all globals that may + // be referenced are in DstM. + for (GlobalVariable &Src : SrcM->globals()) { + // Only process initialized GV's or ones not already in dest. + if (!Src.hasInitializer() || DoNotLinkFromSource.count(&Src)) + continue; + linkGlobalValueBody(Src); + } + // Note that we are done linking global value bodies. This prevents // metadata linking from creating new references. DoneLinkingBodies = true; diff --git a/lib/Transforms/Utils/ValueMapper.cpp b/lib/Transforms/Utils/ValueMapper.cpp index 00a8984845d..0a63c1d5153 100644 --- a/lib/Transforms/Utils/ValueMapper.cpp +++ b/lib/Transforms/Utils/ValueMapper.cpp @@ -41,9 +41,9 @@ Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM, RemapFlags Flags, if (Value *NewV = Materializer->materializeDeclFor(const_cast(V))) { VM[V] = NewV; - if (auto *NewGV = dyn_cast(NewV)) - Materializer->materializeInitFor( - NewGV, const_cast(cast(V))); + if (auto *GV = dyn_cast(V)) + Materializer->materializeInitFor(cast(NewV), + const_cast(GV)); return NewV; } } diff --git a/test/Linker/Inputs/comdat11.ll b/test/Linker/Inputs/comdat11.ll deleted file mode 100644 index 5b7f74cf0b2..00000000000 --- a/test/Linker/Inputs/comdat11.ll +++ /dev/null @@ -1,9 +0,0 @@ -$foo = comdat any -@foo = global i8 1, comdat -define void @zed() { - call void @bar() - ret void -} -define void @bar() comdat($foo) { - ret void -} diff --git a/test/Linker/comdat11.ll b/test/Linker/comdat11.ll deleted file mode 100644 index dbade4104fe..00000000000 --- a/test/Linker/comdat11.ll +++ /dev/null @@ -1,13 +0,0 @@ -; RUN: llvm-link -S %s %p/Inputs/comdat11.ll -o - | FileCheck %s - -$foo = comdat any -@foo = global i8 0, comdat - -; CHECK: @foo = global i8 0, comdat - -; CHECK: define void @zed() { -; CHECK: call void @bar() -; CHECK: ret void -; CHECK: } - -; CHECK: declare void @bar() diff --git a/test/Linker/comdat12.ll b/test/Linker/comdat12.ll deleted file mode 100644 index d06e222b63a..00000000000 --- a/test/Linker/comdat12.ll +++ /dev/null @@ -1,8 +0,0 @@ -; RUN: llvm-link %s -S -o - | FileCheck %s - -$foo = comdat largest -define internal void @foo() comdat($foo) { - ret void -} - -; CHECK-NOT: foo diff --git a/test/Linker/comdat9.ll b/test/Linker/comdat9.ll index 4f6f2cfb845..274957401aa 100644 --- a/test/Linker/comdat9.ll +++ b/test/Linker/comdat9.ll @@ -14,9 +14,6 @@ $f2 = comdat largest define internal void @f2() comdat($f2) { ret void } -define void @f3() comdat($f2) { - ret void -} ; CHECK-DAG: $f2 = comdat largest ; CHECK-DAG: define internal void @f2() comdat { -- 2.34.1