diff options
Diffstat (limited to 'contrib/llvm/lib/Linker/LinkModules.cpp')
-rw-r--r-- | contrib/llvm/lib/Linker/LinkModules.cpp | 607 |
1 files changed, 166 insertions, 441 deletions
diff --git a/contrib/llvm/lib/Linker/LinkModules.cpp b/contrib/llvm/lib/Linker/LinkModules.cpp index 6ffa71e..fae9c95 100644 --- a/contrib/llvm/lib/Linker/LinkModules.cpp +++ b/contrib/llvm/lib/Linker/LinkModules.cpp @@ -11,13 +11,15 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Linker/Linker.h" #include "LinkDiagnosticInfo.h" #include "llvm-c/Linker.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/StringSet.h" #include "llvm/IR/DiagnosticPrinter.h" #include "llvm/IR/LLVMContext.h" +#include "llvm/Linker/Linker.h" +#include "llvm/Support/Error.h" +#include "llvm/Transforms/Utils/FunctionImportUtils.h" using namespace llvm; namespace { @@ -26,7 +28,7 @@ namespace { /// entrypoint for this file. class ModuleLinker { IRMover &Mover; - Module &SrcM; + std::unique_ptr<Module> SrcM; SetVector<GlobalValue *> ValuesToLink; StringSet<> Internalize; @@ -34,31 +36,19 @@ class ModuleLinker { /// For symbol clashes, prefer those from Src. unsigned Flags; - /// Function index passed into ModuleLinker for using in function - /// importing/exporting handling. - const FunctionInfoIndex *ImportIndex; - /// Functions to import from source module, all other functions are /// imported as declarations instead of definitions. - DenseSet<const GlobalValue *> *FunctionsToImport; - - /// Set to true if the given FunctionInfoIndex contains any functions - /// from this source module, in which case we must conservatively assume - /// that any of its functions may be imported into another module - /// as part of a different backend compilation process. - bool HasExportedFunctions = false; - - /// Association between metadata value id and temporary metadata that - /// remains unmapped after function importing. Saved during function - /// importing and consumed during the metadata linking postpass. - DenseMap<unsigned, MDNode *> *ValIDToTempMDMap; + DenseSet<const GlobalValue *> *GlobalsToImport; /// Used as the callback for lazy linking. /// The mover has just hit GV and we have to decide if it, and other members /// of the same comdat, should be linked. Every member to be linked is passed /// to Add. - void addLazyFor(GlobalValue &GV, IRMover::ValueAdder Add); + void addLazyFor(GlobalValue &GV, const IRMover::ValueAdder &Add); + bool shouldLinkReferencedLinkOnce() { + return !(Flags & Linker::DontForceLinkLinkonceODR); + } bool shouldOverrideFromSrc() { return Flags & Linker::OverrideFromSrc; } bool shouldLinkOnlyNeeded() { return Flags & Linker::LinkOnlyNeeded; } bool shouldInternalizeLinkedSymbols() { @@ -70,7 +60,7 @@ class ModuleLinker { /// Should we have mover and linker error diag info? bool emitError(const Twine &Message) { - SrcM.getContext().diagnose(LinkDiagnosticInfo(DS_Error, Message)); + SrcM->getContext().diagnose(LinkDiagnosticInfo(DS_Error, Message)); return true; } @@ -85,8 +75,8 @@ class ModuleLinker { 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; + // Keep track of the lazy linked global members of each comdat in source. + DenseMap<const Comdat *, std::vector<GlobalValue *>> LazyComdatMembers; /// Given a global in the source module, return the global in the /// destination module that is being linked to, if any. @@ -111,289 +101,36 @@ class ModuleLinker { return DGV; } + /// Drop GV if it is a member of a comdat that we are dropping. + /// This can happen with COFF's largest selection kind. + void dropReplacedComdat(GlobalValue &GV, + const DenseSet<const Comdat *> &ReplacedDstComdats); + bool linkIfNeeded(GlobalValue &GV); /// Helper method to check if we are importing from the current source /// module. - bool isPerformingImport() const { return FunctionsToImport != nullptr; } + bool isPerformingImport() const { return GlobalsToImport != nullptr; } /// If we are importing from the source module, checks if we should /// import SGV as a definition, otherwise import as a declaration. bool doImportAsDefinition(const GlobalValue *SGV); public: - ModuleLinker(IRMover &Mover, Module &SrcM, unsigned Flags, - const FunctionInfoIndex *Index = nullptr, - DenseSet<const GlobalValue *> *FunctionsToImport = nullptr, - DenseMap<unsigned, MDNode *> *ValIDToTempMDMap = nullptr) - : Mover(Mover), SrcM(SrcM), Flags(Flags), ImportIndex(Index), - FunctionsToImport(FunctionsToImport), - ValIDToTempMDMap(ValIDToTempMDMap) { - assert((ImportIndex || !FunctionsToImport) && - "Expect a FunctionInfoIndex when importing"); - // If we have a FunctionInfoIndex but no function to import, - // then this is the primary module being compiled in a ThinLTO - // backend compilation, and we need to see if it has functions that - // may be exported to another backend compilation. - if (ImportIndex && !FunctionsToImport) - HasExportedFunctions = ImportIndex->hasExportedFunctions(SrcM); - assert((ValIDToTempMDMap || !FunctionsToImport) && - "Function importing must provide a ValIDToTempMDMap"); - } + ModuleLinker(IRMover &Mover, std::unique_ptr<Module> SrcM, unsigned Flags, + DenseSet<const GlobalValue *> *GlobalsToImport = nullptr) + : Mover(Mover), SrcM(std::move(SrcM)), Flags(Flags), + GlobalsToImport(GlobalsToImport) {} bool run(); }; - -/// Class to handle necessary GlobalValue changes required by ThinLTO including -/// linkage changes and any necessary renaming. -class ThinLTOGlobalProcessing { - /// The Module which we are exporting or importing functions from. - Module &M; - - /// Function index passed in for function importing/exporting handling. - const FunctionInfoIndex *ImportIndex; - - /// Functions to import from this module, all other functions will be - /// imported as declarations instead of definitions. - DenseSet<const GlobalValue *> *FunctionsToImport; - - /// Set to true if the given FunctionInfoIndex contains any functions - /// from this source module, in which case we must conservatively assume - /// that any of its functions may be imported into another module - /// as part of a different backend compilation process. - bool HasExportedFunctions = false; - - /// Populated during ThinLTO global processing with locals promoted - /// to global scope in an exporting module, which now need to be linked - /// in if calling from the ModuleLinker. - SetVector<GlobalValue *> NewExportedValues; - - /// Check if we should promote the given local value to global scope. - bool doPromoteLocalToGlobal(const GlobalValue *SGV); - - /// Helper methods to check if we are importing from or potentially - /// exporting from the current source module. - bool isPerformingImport() const { return FunctionsToImport != nullptr; } - bool isModuleExporting() const { return HasExportedFunctions; } - - /// If we are importing from the source module, checks if we should - /// import SGV as a definition, otherwise import as a declaration. - bool doImportAsDefinition(const GlobalValue *SGV); - - /// Get the name for SGV that should be used in the linked destination - /// module. Specifically, this handles the case where we need to rename - /// a local that is being promoted to global scope. - std::string getName(const GlobalValue *SGV); - - /// Process globals so that they can be used in ThinLTO. This includes - /// promoting local variables so that they can be reference externally by - /// thin lto imported globals and converting strong external globals to - /// available_externally. - void processGlobalsForThinLTO(); - void processGlobalForThinLTO(GlobalValue &GV); - - /// Get the new linkage for SGV that should be used in the linked destination - /// module. Specifically, for ThinLTO importing or exporting it may need - /// to be adjusted. - GlobalValue::LinkageTypes getLinkage(const GlobalValue *SGV); - -public: - ThinLTOGlobalProcessing( - Module &M, const FunctionInfoIndex *Index, - DenseSet<const GlobalValue *> *FunctionsToImport = nullptr) - : M(M), ImportIndex(Index), FunctionsToImport(FunctionsToImport) { - // If we have a FunctionInfoIndex but no function to import, - // then this is the primary module being compiled in a ThinLTO - // backend compilation, and we need to see if it has functions that - // may be exported to another backend compilation. - if (!FunctionsToImport) - HasExportedFunctions = ImportIndex->hasExportedFunctions(M); - } - - bool run(); - - /// Access the promoted globals that are now exported and need to be linked. - SetVector<GlobalValue *> &getNewExportedValues() { return NewExportedValues; } -}; -} - -/// Checks if we should import SGV as a definition, otherwise import as a -/// declaration. -static bool -doImportAsDefinitionImpl(const GlobalValue *SGV, - DenseSet<const GlobalValue *> *FunctionsToImport) { - auto *GA = dyn_cast<GlobalAlias>(SGV); - if (GA) { - if (GA->hasWeakAnyLinkage()) - return false; - const GlobalObject *GO = GA->getBaseObject(); - if (!GO->hasLinkOnceODRLinkage()) - return false; - return doImportAsDefinitionImpl(GO, FunctionsToImport); - } - // Always import GlobalVariable definitions, except for the special - // case of WeakAny which are imported as ExternalWeak declarations - // (see comments in ModuleLinker::getLinkage). The linkage changes - // described in ModuleLinker::getLinkage ensure the correct behavior (e.g. - // global variables with external linkage are transformed to - // available_externally definitions, which are ultimately turned into - // declarations after the EliminateAvailableExternally pass). - if (isa<GlobalVariable>(SGV) && !SGV->isDeclaration() && - !SGV->hasWeakAnyLinkage()) - return true; - // Only import the function requested for importing. - auto *SF = dyn_cast<Function>(SGV); - if (SF && FunctionsToImport->count(SF)) - return true; - // Otherwise no. - return false; -} - -bool ThinLTOGlobalProcessing::doImportAsDefinition(const GlobalValue *SGV) { - if (!isPerformingImport()) - return false; - return doImportAsDefinitionImpl(SGV, FunctionsToImport); } bool ModuleLinker::doImportAsDefinition(const GlobalValue *SGV) { if (!isPerformingImport()) return false; - return doImportAsDefinitionImpl(SGV, FunctionsToImport); -} - -bool ThinLTOGlobalProcessing::doPromoteLocalToGlobal(const GlobalValue *SGV) { - assert(SGV->hasLocalLinkage()); - // Both the imported references and the original local variable must - // be promoted. - if (!isPerformingImport() && !isModuleExporting()) - return false; - - // Local const variables never need to be promoted unless they are address - // taken. The imported uses can simply use the clone created in this module. - // For now we are conservative in determining which variables are not - // address taken by checking the unnamed addr flag. To be more aggressive, - // the address taken information must be checked earlier during parsing - // of the module and recorded in the function index for use when importing - // from that module. - auto *GVar = dyn_cast<GlobalVariable>(SGV); - if (GVar && GVar->isConstant() && GVar->hasUnnamedAddr()) - return false; - - // Eventually we only need to promote functions in the exporting module that - // are referenced by a potentially exported function (i.e. one that is in the - // function index). - return true; -} - -std::string ThinLTOGlobalProcessing::getName(const GlobalValue *SGV) { - // For locals that must be promoted to global scope, ensure that - // the promoted name uniquely identifies the copy in the original module, - // using the ID assigned during combined index creation. When importing, - // we rename all locals (not just those that are promoted) in order to - // avoid naming conflicts between locals imported from different modules. - if (SGV->hasLocalLinkage() && - (doPromoteLocalToGlobal(SGV) || isPerformingImport())) - return FunctionInfoIndex::getGlobalNameForLocal( - SGV->getName(), - ImportIndex->getModuleId(SGV->getParent()->getModuleIdentifier())); - return SGV->getName(); -} - -GlobalValue::LinkageTypes -ThinLTOGlobalProcessing::getLinkage(const GlobalValue *SGV) { - // Any local variable that is referenced by an exported function needs - // to be promoted to global scope. Since we don't currently know which - // functions reference which local variables/functions, we must treat - // all as potentially exported if this module is exporting anything. - if (isModuleExporting()) { - if (SGV->hasLocalLinkage() && doPromoteLocalToGlobal(SGV)) - return GlobalValue::ExternalLinkage; - return SGV->getLinkage(); - } - - // Otherwise, if we aren't importing, no linkage change is needed. - if (!isPerformingImport()) - return SGV->getLinkage(); - - switch (SGV->getLinkage()) { - case GlobalValue::ExternalLinkage: - // External defnitions are converted to available_externally - // definitions upon import, so that they are available for inlining - // and/or optimization, but are turned into declarations later - // during the EliminateAvailableExternally pass. - if (doImportAsDefinition(SGV) && !dyn_cast<GlobalAlias>(SGV)) - return GlobalValue::AvailableExternallyLinkage; - // An imported external declaration stays external. - return SGV->getLinkage(); - - case GlobalValue::AvailableExternallyLinkage: - // An imported available_externally definition converts - // to external if imported as a declaration. - if (!doImportAsDefinition(SGV)) - return GlobalValue::ExternalLinkage; - // An imported available_externally declaration stays that way. - return SGV->getLinkage(); - - case GlobalValue::LinkOnceAnyLinkage: - case GlobalValue::LinkOnceODRLinkage: - // These both stay the same when importing the definition. - // The ThinLTO pass will eventually force-import their definitions. - return SGV->getLinkage(); - - case GlobalValue::WeakAnyLinkage: - // Can't import weak_any definitions correctly, or we might change the - // program semantics, since the linker will pick the first weak_any - // definition and importing would change the order they are seen by the - // linker. The module linking caller needs to enforce this. - assert(!doImportAsDefinition(SGV)); - // If imported as a declaration, it becomes external_weak. - return GlobalValue::ExternalWeakLinkage; - - case GlobalValue::WeakODRLinkage: - // For weak_odr linkage, there is a guarantee that all copies will be - // equivalent, so the issue described above for weak_any does not exist, - // and the definition can be imported. It can be treated similarly - // to an imported externally visible global value. - if (doImportAsDefinition(SGV) && !dyn_cast<GlobalAlias>(SGV)) - return GlobalValue::AvailableExternallyLinkage; - else - return GlobalValue::ExternalLinkage; - - case GlobalValue::AppendingLinkage: - // It would be incorrect to import an appending linkage variable, - // since it would cause global constructors/destructors to be - // executed multiple times. This should have already been handled - // by linkIfNeeded, and we will assert in shouldLinkFromSource - // if we try to import, so we simply return AppendingLinkage. - return GlobalValue::AppendingLinkage; - - case GlobalValue::InternalLinkage: - case GlobalValue::PrivateLinkage: - // If we are promoting the local to global scope, it is handled - // similarly to a normal externally visible global. - if (doPromoteLocalToGlobal(SGV)) { - if (doImportAsDefinition(SGV) && !dyn_cast<GlobalAlias>(SGV)) - return GlobalValue::AvailableExternallyLinkage; - else - return GlobalValue::ExternalLinkage; - } - // A non-promoted imported local definition stays local. - // The ThinLTO pass will eventually force-import their definitions. - return SGV->getLinkage(); - - case GlobalValue::ExternalWeakLinkage: - // External weak doesn't apply to definitions, must be a declaration. - assert(!doImportAsDefinition(SGV)); - // Linkage stays external_weak. - return SGV->getLinkage(); - - case GlobalValue::CommonLinkage: - // Linkage stays common on definitions. - // The ThinLTO pass will eventually force-import their definitions. - return SGV->getLinkage(); - } - - llvm_unreachable("unknown linkage type"); + return FunctionImportGlobalProcessing::doImportAsDefinition(SGV, + GlobalsToImport); } static GlobalValue::VisibilityTypes @@ -466,15 +203,13 @@ bool ModuleLinker::computeResultingSelectionKind(StringRef ComdatName, const GlobalVariable *DstGV; const GlobalVariable *SrcGV; if (getComdatLeader(DstM, ComdatName, DstGV) || - getComdatLeader(SrcM, ComdatName, SrcGV)) + getComdatLeader(*SrcM, ComdatName, SrcGV)) return true; const DataLayout &DstDL = DstM.getDataLayout(); - const DataLayout &SrcDL = SrcM.getDataLayout(); - uint64_t DstSize = - DstDL.getTypeAllocSize(DstGV->getType()->getPointerElementType()); - uint64_t SrcSize = - SrcDL.getTypeAllocSize(SrcGV->getType()->getPointerElementType()); + const DataLayout &SrcDL = SrcM->getDataLayout(); + uint64_t DstSize = DstDL.getTypeAllocSize(DstGV->getValueType()); + uint64_t SrcSize = SrcDL.getTypeAllocSize(SrcGV->getValueType()); if (Result == Comdat::SelectionKind::ExactMatch) { if (SrcGV->getInitializer() != DstGV->getInitializer()) return emitError("Linking COMDATs named '" + ComdatName + @@ -537,31 +272,15 @@ bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc, return false; } - bool SrcIsDeclaration = Src.isDeclarationForLinker(); - bool DestIsDeclaration = Dest.isDeclarationForLinker(); - if (isPerformingImport()) { - if (isa<Function>(&Src)) { - // For functions, LinkFromSrc iff this is a function requested - // for importing. For variables, decide below normally. - LinkFromSrc = FunctionsToImport->count(&Src); - return false; - } - - // Check if this is an alias with an already existing definition - // in Dest, which must have come from a prior importing pass from - // the same Src module. Unlike imported function and variable - // definitions, which are imported as available_externally and are - // not definitions for the linker, that is not a valid linkage for - // imported aliases which must be definitions. Simply use the existing - // Dest copy. - if (isa<GlobalAlias>(&Src) && !DestIsDeclaration) { - assert(isa<GlobalAlias>(&Dest)); - LinkFromSrc = false; - return false; - } + // LinkFromSrc iff this is a global requested for importing. + LinkFromSrc = GlobalsToImport->count(&Src); + return false; } + bool SrcIsDeclaration = Src.isDeclarationForLinker(); + bool DestIsDeclaration = Dest.isDeclarationForLinker(); + if (SrcIsDeclaration) { // If Src is external or if both Src & Dest are external.. Just link the // external globals, we aren't adding anything. @@ -598,8 +317,8 @@ bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc, } const DataLayout &DL = Dest.getParent()->getDataLayout(); - uint64_t DestSize = DL.getTypeAllocSize(Dest.getType()->getElementType()); - uint64_t SrcSize = DL.getTypeAllocSize(Src.getType()->getElementType()); + uint64_t DestSize = DL.getTypeAllocSize(Dest.getValueType()); + uint64_t SrcSize = DL.getTypeAllocSize(Src.getValueType()); LinkFromSrc = SrcSize > DestSize; return false; } @@ -658,9 +377,10 @@ bool ModuleLinker::linkIfNeeded(GlobalValue &GV) { DGV->setVisibility(Visibility); GV.setVisibility(Visibility); - bool HasUnnamedAddr = GV.hasUnnamedAddr() && DGV->hasUnnamedAddr(); - DGV->setUnnamedAddr(HasUnnamedAddr); - GV.setUnnamedAddr(HasUnnamedAddr); + GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::getMinUnnamedAddr( + DGV->getUnnamedAddr(), GV.getUnnamedAddr()); + DGV->setUnnamedAddr(UnnamedAddr); + GV.setUnnamedAddr(UnnamedAddr); } // Don't want to append to global_ctors list, for example, when we @@ -670,12 +390,12 @@ bool ModuleLinker::linkIfNeeded(GlobalValue &GV) { if (GV.hasAppendingLinkage() && isPerformingImport()) return false; - if (isPerformingImport() && !doImportAsDefinition(&GV)) - return false; - - if (!DGV && !shouldOverrideFromSrc() && - (GV.hasLocalLinkage() || GV.hasLinkOnceLinkage() || - GV.hasAvailableExternallyLinkage())) + if (isPerformingImport()) { + if (!doImportAsDefinition(&GV)) + return false; + } else if (!DGV && !shouldOverrideFromSrc() && + (GV.hasLocalLinkage() || GV.hasLinkOnceLinkage() || + GV.hasAvailableExternallyLinkage())) return false; if (GV.isDeclaration()) @@ -685,9 +405,8 @@ bool ModuleLinker::linkIfNeeded(GlobalValue &GV) { bool LinkFromSrc; Comdat::SelectionKind SK; std::tie(SK, LinkFromSrc) = ComdatsChosen[SC]; - if (LinkFromSrc) - ValuesToLink.insert(&GV); - return false; + if (!LinkFromSrc) + return false; } bool LinkFromSrc = true; @@ -698,9 +417,15 @@ bool ModuleLinker::linkIfNeeded(GlobalValue &GV) { return false; } -void ModuleLinker::addLazyFor(GlobalValue &GV, IRMover::ValueAdder Add) { +void ModuleLinker::addLazyFor(GlobalValue &GV, const IRMover::ValueAdder &Add) { + if (!shouldLinkReferencedLinkOnce()) + // For ThinLTO we don't import more than what was required. + // The client has to guarantee that the linkonce will be availabe at link + // time (by promoting it to weak for instance). + return; + // Add these to the internalize list - if (!GV.hasLinkOnceLinkage()) + if (!GV.hasLinkOnceLinkage() && !shouldLinkOnlyNeeded()) return; if (shouldInternalizeLinkedSymbols()) @@ -710,43 +435,59 @@ void ModuleLinker::addLazyFor(GlobalValue &GV, IRMover::ValueAdder Add) { const Comdat *SC = GV.getComdat(); if (!SC) return; - for (GlobalValue *GV2 : ComdatMembers[SC]) { - if (!GV2->hasLocalLinkage() && shouldInternalizeLinkedSymbols()) + for (GlobalValue *GV2 : LazyComdatMembers[SC]) { + GlobalValue *DGV = getLinkedToGlobal(GV2); + bool LinkFromSrc = true; + if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, *GV2)) + return; + if (!LinkFromSrc) + continue; + if (shouldInternalizeLinkedSymbols()) Internalize.insert(GV2->getName()); Add(*GV2); } } -void ThinLTOGlobalProcessing::processGlobalForThinLTO(GlobalValue &GV) { - if (GV.hasLocalLinkage() && - (doPromoteLocalToGlobal(&GV) || isPerformingImport())) { - GV.setName(getName(&GV)); - GV.setLinkage(getLinkage(&GV)); - if (!GV.hasLocalLinkage()) - GV.setVisibility(GlobalValue::HiddenVisibility); - if (isModuleExporting()) - NewExportedValues.insert(&GV); +void ModuleLinker::dropReplacedComdat( + GlobalValue &GV, const DenseSet<const Comdat *> &ReplacedDstComdats) { + Comdat *C = GV.getComdat(); + if (!C) + return; + if (!ReplacedDstComdats.count(C)) + return; + if (GV.use_empty()) { + GV.eraseFromParent(); return; } - GV.setLinkage(getLinkage(&GV)); -} - -void ThinLTOGlobalProcessing::processGlobalsForThinLTO() { - for (GlobalVariable &GV : M.globals()) - processGlobalForThinLTO(GV); - for (Function &SF : M) - processGlobalForThinLTO(SF); - for (GlobalAlias &GA : M.aliases()) - processGlobalForThinLTO(GA); -} -bool ThinLTOGlobalProcessing::run() { - processGlobalsForThinLTO(); - return false; + if (auto *F = dyn_cast<Function>(&GV)) { + F->deleteBody(); + } else if (auto *Var = dyn_cast<GlobalVariable>(&GV)) { + Var->setInitializer(nullptr); + } else { + auto &Alias = cast<GlobalAlias>(GV); + Module &M = *Alias.getParent(); + PointerType &Ty = *cast<PointerType>(Alias.getType()); + GlobalValue *Declaration; + if (auto *FTy = dyn_cast<FunctionType>(Alias.getValueType())) { + Declaration = Function::Create(FTy, GlobalValue::ExternalLinkage, "", &M); + } else { + Declaration = + new GlobalVariable(M, Ty.getElementType(), /*isConstant*/ false, + GlobalValue::ExternalLinkage, + /*Initializer*/ nullptr); + } + Declaration->takeName(&Alias); + Alias.replaceAllUsesWith(Declaration); + Alias.eraseFromParent(); + } } bool ModuleLinker::run() { - for (const auto &SMEC : SrcM.getComdatSymbolTable()) { + Module &DstM = Mover.getModule(); + DenseSet<const Comdat *> ReplacedDstComdats; + + for (const auto &SMEC : SrcM->getComdatSymbolTable()) { const Comdat &C = SMEC.getValue(); if (ComdatsChosen.count(&C)) continue; @@ -755,50 +496,79 @@ bool ModuleLinker::run() { if (getComdatResult(&C, SK, LinkFromSrc)) return true; ComdatsChosen[&C] = std::make_pair(SK, LinkFromSrc); + + if (!LinkFromSrc) + continue; + + Module::ComdatSymTabType &ComdatSymTab = DstM.getComdatSymbolTable(); + Module::ComdatSymTabType::iterator DstCI = ComdatSymTab.find(C.getName()); + if (DstCI == ComdatSymTab.end()) + continue; + + // The source comdat is replacing the dest one. + const Comdat *DstC = &DstCI->second; + ReplacedDstComdats.insert(DstC); } - for (GlobalVariable &GV : SrcM.globals()) - if (const Comdat *SC = GV.getComdat()) - ComdatMembers[SC].push_back(&GV); + // Alias have to go first, since we are not able to find their comdats + // otherwise. + for (auto I = DstM.alias_begin(), E = DstM.alias_end(); I != E;) { + GlobalAlias &GV = *I++; + dropReplacedComdat(GV, ReplacedDstComdats); + } + + for (auto I = DstM.global_begin(), E = DstM.global_end(); I != E;) { + GlobalVariable &GV = *I++; + dropReplacedComdat(GV, ReplacedDstComdats); + } + + for (auto I = DstM.begin(), E = DstM.end(); I != E;) { + Function &GV = *I++; + dropReplacedComdat(GV, ReplacedDstComdats); + } + + for (GlobalVariable &GV : SrcM->globals()) + if (GV.hasLinkOnceLinkage()) + if (const Comdat *SC = GV.getComdat()) + LazyComdatMembers[SC].push_back(&GV); - for (Function &SF : SrcM) - if (const Comdat *SC = SF.getComdat()) - ComdatMembers[SC].push_back(&SF); + for (Function &SF : *SrcM) + if (SF.hasLinkOnceLinkage()) + if (const Comdat *SC = SF.getComdat()) + LazyComdatMembers[SC].push_back(&SF); - for (GlobalAlias &GA : SrcM.aliases()) - if (const Comdat *SC = GA.getComdat()) - ComdatMembers[SC].push_back(&GA); + for (GlobalAlias &GA : SrcM->aliases()) + if (GA.hasLinkOnceLinkage()) + if (const Comdat *SC = GA.getComdat()) + LazyComdatMembers[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()) + for (GlobalVariable &GV : SrcM->globals()) if (linkIfNeeded(GV)) return true; - for (Function &SF : SrcM) + for (Function &SF : *SrcM) if (linkIfNeeded(SF)) return true; - for (GlobalAlias &GA : SrcM.aliases()) + for (GlobalAlias &GA : SrcM->aliases()) if (linkIfNeeded(GA)) return true; - if (ImportIndex) { - ThinLTOGlobalProcessing ThinLTOProcessing(SrcM, ImportIndex, - FunctionsToImport); - if (ThinLTOProcessing.run()) - return true; - for (auto *GV : ThinLTOProcessing.getNewExportedValues()) - ValuesToLink.insert(GV); - } - for (unsigned I = 0; I < ValuesToLink.size(); ++I) { GlobalValue *GV = ValuesToLink[I]; const Comdat *SC = GV->getComdat(); if (!SC) continue; - for (GlobalValue *GV2 : ComdatMembers[SC]) - ValuesToLink.insert(GV2); + for (GlobalValue *GV2 : LazyComdatMembers[SC]) { + GlobalValue *DGV = getLinkedToGlobal(GV2); + bool LinkFromSrc = true; + if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, *GV2)) + return true; + if (LinkFromSrc) + ValuesToLink.insert(GV2); + } } if (shouldInternalizeLinkedSymbols()) { @@ -806,13 +576,21 @@ bool ModuleLinker::run() { Internalize.insert(GV->getName()); } - if (Mover.move(SrcM, ValuesToLink.getArrayRef(), - [this](GlobalValue &GV, IRMover::ValueAdder Add) { - addLazyFor(GV, Add); - }, - ValIDToTempMDMap, false)) + // FIXME: Propagate Errors through to the caller instead of emitting + // diagnostics. + bool HasErrors = false; + if (Error E = Mover.move(std::move(SrcM), ValuesToLink.getArrayRef(), + [this](GlobalValue &GV, IRMover::ValueAdder Add) { + addLazyFor(GV, Add); + })) { + handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) { + DstM.getContext().diagnose(LinkDiagnosticInfo(DS_Error, EIB.message())); + HasErrors = true; + }); + } + if (HasErrors) return true; - Module &DstM = Mover.getModule(); + for (auto &P : Internalize) { GlobalValue *GV = DstM.getNamedValue(P.first()); GV->setLinkage(GlobalValue::InternalLinkage); @@ -824,30 +602,11 @@ bool ModuleLinker::run() { Linker::Linker(Module &M) : Mover(M) {} bool Linker::linkInModule(std::unique_ptr<Module> Src, unsigned Flags, - const FunctionInfoIndex *Index, - DenseSet<const GlobalValue *> *FunctionsToImport, - DenseMap<unsigned, MDNode *> *ValIDToTempMDMap) { - ModuleLinker ModLinker(Mover, *Src, Flags, Index, FunctionsToImport, - ValIDToTempMDMap); - return ModLinker.run(); -} - -bool Linker::linkInModuleForCAPI(Module &Src) { - ModuleLinker ModLinker(Mover, Src, 0, nullptr, nullptr); + DenseSet<const GlobalValue *> *GlobalsToImport) { + ModuleLinker ModLinker(Mover, std::move(Src), Flags, GlobalsToImport); return ModLinker.run(); } -bool Linker::linkInMetadata(Module &Src, - DenseMap<unsigned, MDNode *> *ValIDToTempMDMap) { - SetVector<GlobalValue *> ValuesToLink; - if (Mover.move( - Src, ValuesToLink.getArrayRef(), - [this](GlobalValue &GV, IRMover::ValueAdder Add) { assert(false); }, - ValIDToTempMDMap, true)) - return true; - return false; -} - //===----------------------------------------------------------------------===// // LinkModules entrypoint. //===----------------------------------------------------------------------===// @@ -863,44 +622,10 @@ bool Linker::linkModules(Module &Dest, std::unique_ptr<Module> Src, return L.linkInModule(std::move(Src), Flags); } -bool llvm::renameModuleForThinLTO(Module &M, const FunctionInfoIndex *Index) { - ThinLTOGlobalProcessing ThinLTOProcessing(M, Index); - return ThinLTOProcessing.run(); -} - //===----------------------------------------------------------------------===// // C API. //===----------------------------------------------------------------------===// -static void diagnosticHandler(const DiagnosticInfo &DI, void *C) { - auto *Message = reinterpret_cast<std::string *>(C); - raw_string_ostream Stream(*Message); - DiagnosticPrinterRawOStream DP(Stream); - DI.print(DP); -} - -LLVMBool LLVMLinkModules(LLVMModuleRef Dest, LLVMModuleRef Src, - LLVMLinkerMode Unused, char **OutMessages) { - Module *D = unwrap(Dest); - LLVMContext &Ctx = D->getContext(); - - LLVMContext::DiagnosticHandlerTy OldDiagnosticHandler = - Ctx.getDiagnosticHandler(); - void *OldDiagnosticContext = Ctx.getDiagnosticContext(); - std::string Message; - Ctx.setDiagnosticHandler(diagnosticHandler, &Message, true); - - Linker L(*D); - Module *M = unwrap(Src); - LLVMBool Result = L.linkInModuleForCAPI(*M); - - Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext, true); - - if (OutMessages && Result) - *OutMessages = strdup(Message.c_str()); - return Result; -} - LLVMBool LLVMLinkModules2(LLVMModuleRef Dest, LLVMModuleRef Src) { Module *D = unwrap(Dest); std::unique_ptr<Module> M(unwrap(Src)); |