diff options
Diffstat (limited to 'lib/Linker')
-rw-r--r-- | lib/Linker/IRMover.cpp | 828 | ||||
-rw-r--r-- | lib/Linker/LinkModules.cpp | 607 | ||||
-rw-r--r-- | lib/Linker/Makefile | 15 |
3 files changed, 409 insertions, 1041 deletions
diff --git a/lib/Linker/IRMover.cpp b/lib/Linker/IRMover.cpp index 8dd59f9e0e3e2..4935868c00f47 100644 --- a/lib/Linker/IRMover.cpp +++ b/lib/Linker/IRMover.cpp @@ -16,8 +16,11 @@ #include "llvm/IR/DebugInfo.h" #include "llvm/IR/DiagnosticPrinter.h" #include "llvm/IR/GVMaterializer.h" +#include "llvm/IR/Intrinsics.h" #include "llvm/IR/TypeFinder.h" +#include "llvm/Support/Error.h" #include "llvm/Transforms/Utils/Cloning.h" +#include <utility> using namespace llvm; //===----------------------------------------------------------------------===// @@ -345,43 +348,40 @@ class IRLinker; /// speeds up linking for modules with many/ lazily linked functions of which /// few get used. class GlobalValueMaterializer final : public ValueMaterializer { - IRLinker *TheIRLinker; + IRLinker &TheIRLinker; public: - GlobalValueMaterializer(IRLinker *TheIRLinker) : TheIRLinker(TheIRLinker) {} - Value *materializeDeclFor(Value *V) override; - void materializeInitFor(GlobalValue *New, GlobalValue *Old) override; - Metadata *mapTemporaryMetadata(Metadata *MD) override; - void replaceTemporaryMetadata(const Metadata *OrigMD, - Metadata *NewMD) override; - bool isMetadataNeeded(Metadata *MD) override; + GlobalValueMaterializer(IRLinker &TheIRLinker) : TheIRLinker(TheIRLinker) {} + Value *materialize(Value *V) override; }; class LocalValueMaterializer final : public ValueMaterializer { - IRLinker *TheIRLinker; + IRLinker &TheIRLinker; public: - LocalValueMaterializer(IRLinker *TheIRLinker) : TheIRLinker(TheIRLinker) {} - Value *materializeDeclFor(Value *V) override; - void materializeInitFor(GlobalValue *New, GlobalValue *Old) override; - Metadata *mapTemporaryMetadata(Metadata *MD) override; - void replaceTemporaryMetadata(const Metadata *OrigMD, - Metadata *NewMD) override; - bool isMetadataNeeded(Metadata *MD) override; + LocalValueMaterializer(IRLinker &TheIRLinker) : TheIRLinker(TheIRLinker) {} + Value *materialize(Value *V) override; }; +/// Type of the Metadata map in \a ValueToValueMapTy. +typedef DenseMap<const Metadata *, TrackingMDRef> MDMapT; + /// This is responsible for keeping track of the state used for moving data /// from SrcM to DstM. class IRLinker { Module &DstM; - Module &SrcM; + std::unique_ptr<Module> SrcM; + /// See IRMover::move(). std::function<void(GlobalValue &, IRMover::ValueAdder)> AddLazyFor; TypeMapTy TypeMap; GlobalValueMaterializer GValMaterializer; LocalValueMaterializer LValMaterializer; + /// A metadata map that's shared between IRLinker instances. + MDMapT &SharedMDs; + /// Mapping of values from what they used to be in Src, to what they are now /// in DstM. ValueToValueMapTy is a ValueMap, which involves some overhead /// due to the use of Value handles which the Linker doesn't actually need, @@ -402,52 +402,30 @@ class IRLinker { /// references. bool DoneLinkingBodies = false; - bool HasError = false; - - /// Flag indicating that we are just linking metadata (after function - /// importing). - bool IsMetadataLinkingPostpass; - - /// Flags to pass to value mapper invocations. - RemapFlags ValueMapperFlags = RF_MoveDistinctMDs; - - /// Association between metadata values created during bitcode parsing and - /// the value id. Used to correlate temporary metadata created during - /// function importing with the final metadata parsed during the subsequent - /// metadata linking postpass. - DenseMap<const Metadata *, unsigned> MetadataToIDs; + /// The Error encountered during materialization. We use an Optional here to + /// avoid needing to manage an unconsumed success value. + Optional<Error> FoundError; + void setError(Error E) { + if (E) + FoundError = std::move(E); + } - /// 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; + /// Most of the errors produced by this module are inconvertible StringErrors. + /// This convenience function lets us return one of those more easily. + Error stringErr(const Twine &T) { + return make_error<StringError>(T, inconvertibleErrorCode()); + } - /// Set of subprogram metadata that does not need to be linked into the - /// destination module, because the functions were not imported directly - /// or via an inlined body in an imported function. - SmallPtrSet<const Metadata *, 16> UnneededSubprograms; + /// Entry point for mapping values and alternate context for mapping aliases. + ValueMapper Mapper; + unsigned AliasMCID; /// Handles cloning of a global values from the source module into /// the destination module, including setting the attributes and visibility. GlobalValue *copyGlobalValueProto(const GlobalValue *SGV, bool ForDefinition); - /// Helper method for setting a message and returning an error code. - bool emitError(const Twine &Message) { - SrcM.getContext().diagnose(LinkDiagnosticInfo(DS_Error, Message)); - HasError = true; - return true; - } - void emitWarning(const Twine &Message) { - SrcM.getContext().diagnose(LinkDiagnosticInfo(DS_Warning, Message)); - } - - /// Check whether we should be linking metadata from the source module. - bool shouldLinkMetadata() { - // ValIDToTempMDMap will be non-null when we are importing or otherwise want - // to link metadata lazily, and then when linking the metadata. - // We only want to return true for the former case. - return ValIDToTempMDMap == nullptr || IsMetadataLinkingPostpass; + SrcM->getContext().diagnose(LinkDiagnosticInfo(DS_Warning, Message)); } /// Given a global in the source module, return the global in the @@ -474,18 +452,23 @@ class IRLinker { void computeTypeMapping(); - Constant *linkAppendingVarProto(GlobalVariable *DstGV, - const GlobalVariable *SrcGV); + Expected<Constant *> linkAppendingVarProto(GlobalVariable *DstGV, + const GlobalVariable *SrcGV); + /// Given the GlobaValue \p SGV in the source module, and the matching + /// GlobalValue \p DGV (if any), return true if the linker will pull \p SGV + /// into the destination module. + /// + /// Note this code may call the client-provided \p AddLazyFor. bool shouldLink(GlobalValue *DGV, GlobalValue &SGV); - Constant *linkGlobalValueProto(GlobalValue *GV, bool ForAlias); + Expected<Constant *> linkGlobalValueProto(GlobalValue *GV, bool ForAlias); - bool linkModuleFlagsMetadata(); + Error linkModuleFlagsMetadata(); void linkGlobalInit(GlobalVariable &Dst, GlobalVariable &Src); - bool linkFunctionBody(Function &Dst, Function &Src); + Error linkFunctionBody(Function &Dst, Function &Src); void linkAliasBody(GlobalAlias &Dst, GlobalAlias &Src); - bool linkGlobalValueBody(GlobalValue &Dst, GlobalValue &Src); + Error linkGlobalValueBody(GlobalValue &Dst, GlobalValue &Src); /// Functions that take care of cloning a specific global value type /// into the destination module. @@ -495,70 +478,26 @@ class IRLinker { void linkNamedMDNodes(); - /// Populate the UnneededSubprograms set with the DISubprogram metadata - /// from the source module that we don't need to link into the dest module, - /// because the functions were not imported directly or via an inlined body - /// in an imported function. - void findNeededSubprograms(ValueToValueMapTy &ValueMap); - - /// The value mapper leaves nulls in the list of subprograms for any - /// in the UnneededSubprograms map. Strip those out after metadata linking. - void stripNullSubprograms(); - public: - IRLinker(Module &DstM, IRMover::IdentifiedStructTypeSet &Set, Module &SrcM, + IRLinker(Module &DstM, MDMapT &SharedMDs, + IRMover::IdentifiedStructTypeSet &Set, std::unique_ptr<Module> SrcM, ArrayRef<GlobalValue *> ValuesToLink, - std::function<void(GlobalValue &, IRMover::ValueAdder)> AddLazyFor, - DenseMap<unsigned, MDNode *> *ValIDToTempMDMap = nullptr, - bool IsMetadataLinkingPostpass = false) - : DstM(DstM), SrcM(SrcM), AddLazyFor(AddLazyFor), TypeMap(Set), - GValMaterializer(this), LValMaterializer(this), - IsMetadataLinkingPostpass(IsMetadataLinkingPostpass), - ValIDToTempMDMap(ValIDToTempMDMap) { + std::function<void(GlobalValue &, IRMover::ValueAdder)> AddLazyFor) + : DstM(DstM), SrcM(std::move(SrcM)), AddLazyFor(std::move(AddLazyFor)), + TypeMap(Set), GValMaterializer(*this), LValMaterializer(*this), + SharedMDs(SharedMDs), + Mapper(ValueMap, RF_MoveDistinctMDs | RF_IgnoreMissingLocals, &TypeMap, + &GValMaterializer), + AliasMCID(Mapper.registerAlternateMappingContext(AliasValueMap, + &LValMaterializer)) { + ValueMap.getMDMap() = std::move(SharedMDs); for (GlobalValue *GV : ValuesToLink) maybeAdd(GV); - - // If appropriate, tell the value mapper that it can expect to see - // temporary metadata. - if (!shouldLinkMetadata()) - ValueMapperFlags = ValueMapperFlags | RF_HaveUnmaterializedMetadata; - } - - ~IRLinker() { - // In the case where we are not linking metadata, we unset the CanReplace - // flag on all temporary metadata in the MetadataToIDs map to ensure - // none was replaced while being a map key. Now that we are destructing - // the map, set the flag back to true, so that it is replaceable during - // metadata linking. - if (!shouldLinkMetadata()) { - for (auto MDI : MetadataToIDs) { - Metadata *MD = const_cast<Metadata *>(MDI.first); - MDNode *Node = dyn_cast<MDNode>(MD); - assert((Node && Node->isTemporary()) && - "Found non-temp metadata in map when not linking metadata"); - Node->setCanReplace(true); - } - } } + ~IRLinker() { SharedMDs = std::move(*ValueMap.getMDMap()); } - bool run(); - Value *materializeDeclFor(Value *V, bool ForAlias); - void materializeInitFor(GlobalValue *New, GlobalValue *Old, bool ForAlias); - - /// Save the mapping between the given temporary metadata and its metadata - /// value id. Used to support metadata linking as a postpass for function - /// importing. - Metadata *mapTemporaryMetadata(Metadata *MD); - - /// Replace any temporary metadata saved for the source metadata's id with - /// the new non-temporary metadata. Used when metadata linking as a postpass - /// for function importing. - void replaceTemporaryMetadata(const Metadata *OrigMD, Metadata *NewMD); - - /// Indicates whether we need to map the given metadata into the destination - /// module. Used to prevent linking of metadata only needed by functions not - /// linked into the dest module. - bool isMetadataNeeded(Metadata *MD); + Error run(); + Value *materialize(Value *V, bool ForAlias); }; } @@ -583,133 +522,59 @@ static void forceRenaming(GlobalValue *GV, StringRef Name) { } } -Value *GlobalValueMaterializer::materializeDeclFor(Value *V) { - return TheIRLinker->materializeDeclFor(V, false); -} - -void GlobalValueMaterializer::materializeInitFor(GlobalValue *New, - GlobalValue *Old) { - TheIRLinker->materializeInitFor(New, Old, false); -} - -Metadata *GlobalValueMaterializer::mapTemporaryMetadata(Metadata *MD) { - return TheIRLinker->mapTemporaryMetadata(MD); -} - -void GlobalValueMaterializer::replaceTemporaryMetadata(const Metadata *OrigMD, - Metadata *NewMD) { - TheIRLinker->replaceTemporaryMetadata(OrigMD, NewMD); +Value *GlobalValueMaterializer::materialize(Value *SGV) { + return TheIRLinker.materialize(SGV, false); } -bool GlobalValueMaterializer::isMetadataNeeded(Metadata *MD) { - return TheIRLinker->isMetadataNeeded(MD); +Value *LocalValueMaterializer::materialize(Value *SGV) { + return TheIRLinker.materialize(SGV, true); } -Value *LocalValueMaterializer::materializeDeclFor(Value *V) { - return TheIRLinker->materializeDeclFor(V, true); -} - -void LocalValueMaterializer::materializeInitFor(GlobalValue *New, - GlobalValue *Old) { - TheIRLinker->materializeInitFor(New, Old, true); -} - -Metadata *LocalValueMaterializer::mapTemporaryMetadata(Metadata *MD) { - return TheIRLinker->mapTemporaryMetadata(MD); -} - -void LocalValueMaterializer::replaceTemporaryMetadata(const Metadata *OrigMD, - Metadata *NewMD) { - TheIRLinker->replaceTemporaryMetadata(OrigMD, NewMD); -} - -bool LocalValueMaterializer::isMetadataNeeded(Metadata *MD) { - return TheIRLinker->isMetadataNeeded(MD); -} - -Value *IRLinker::materializeDeclFor(Value *V, bool ForAlias) { +Value *IRLinker::materialize(Value *V, bool ForAlias) { auto *SGV = dyn_cast<GlobalValue>(V); if (!SGV) return nullptr; - return linkGlobalValueProto(SGV, ForAlias); -} + Expected<Constant *> NewProto = linkGlobalValueProto(SGV, ForAlias); + if (!NewProto) { + setError(NewProto.takeError()); + return nullptr; + } + if (!*NewProto) + return nullptr; + + GlobalValue *New = dyn_cast<GlobalValue>(*NewProto); + if (!New) + return *NewProto; -void IRLinker::materializeInitFor(GlobalValue *New, GlobalValue *Old, - bool ForAlias) { // If we already created the body, just return. if (auto *F = dyn_cast<Function>(New)) { if (!F->isDeclaration()) - return; + return New; } else if (auto *V = dyn_cast<GlobalVariable>(New)) { - if (V->hasInitializer()) - return; + if (V->hasInitializer() || V->hasAppendingLinkage()) + return New; } else { auto *A = cast<GlobalAlias>(New); if (A->getAliasee()) - return; + return New; } - if (ForAlias || shouldLink(New, *Old)) - linkGlobalValueBody(*New, *Old); -} - -Metadata *IRLinker::mapTemporaryMetadata(Metadata *MD) { - if (!ValIDToTempMDMap) - return nullptr; - // If this temporary metadata has a value id recorded during function - // parsing, record that in the ValIDToTempMDMap if one was provided. - if (MetadataToIDs.count(MD)) { - unsigned Idx = MetadataToIDs[MD]; - // Check if we created a temp MD when importing a different function from - // this module. If so, reuse it the same temporary metadata, otherwise - // add this temporary metadata to the map. - if (!ValIDToTempMDMap->count(Idx)) { - MDNode *Node = cast<MDNode>(MD); - assert(Node->isTemporary()); - (*ValIDToTempMDMap)[Idx] = Node; - } - return (*ValIDToTempMDMap)[Idx]; - } - return nullptr; -} - -void IRLinker::replaceTemporaryMetadata(const Metadata *OrigMD, - Metadata *NewMD) { - if (!ValIDToTempMDMap) - return; -#ifndef NDEBUG - auto *N = dyn_cast_or_null<MDNode>(NewMD); - assert(!N || !N->isTemporary()); -#endif - // If a mapping between metadata value ids and temporary metadata - // created during function importing was provided, and the source - // metadata has a value id recorded during metadata parsing, replace - // the temporary metadata with the final mapped metadata now. - if (MetadataToIDs.count(OrigMD)) { - unsigned Idx = MetadataToIDs[OrigMD]; - // Nothing to do if we didn't need to create a temporary metadata during - // function importing. - if (!ValIDToTempMDMap->count(Idx)) - return; - MDNode *TempMD = (*ValIDToTempMDMap)[Idx]; - TempMD->replaceAllUsesWith(NewMD); - MDNode::deleteTemporary(TempMD); - ValIDToTempMDMap->erase(Idx); - } -} - -bool IRLinker::isMetadataNeeded(Metadata *MD) { - // Currently only DISubprogram metadata is marked as being unneeded. - if (UnneededSubprograms.empty()) - return true; - MDNode *Node = dyn_cast<MDNode>(MD); - if (!Node) - return true; - DISubprogram *SP = getDISubprogram(Node); - if (!SP) - return true; - return !UnneededSubprograms.count(SP); + // When linking a global for an alias, it will always be linked. However we + // need to check if it was not already scheduled to satify a reference from a + // regular global value initializer. We know if it has been schedule if the + // "New" GlobalValue that is mapped here for the alias is the same as the one + // already mapped. If there is an entry in the ValueMap but the value is + // different, it means that the value already had a definition in the + // destination module (linkonce for instance), but we need a new definition + // for the alias ("New" will be different. + if (ForAlias && ValueMap.lookup(SGV) == New) + return New; + + if (ForAlias || shouldLink(New, *SGV)) + setError(linkGlobalValueBody(*New, *SGV)); + + return New; } /// Loop through the global variables in the src module and merge them into the @@ -719,7 +584,7 @@ GlobalVariable *IRLinker::copyGlobalVariableProto(const GlobalVariable *SGVar) { // identical version of the symbol over in the dest module... the // initializer will be filled in later by LinkGlobalInits. GlobalVariable *NewDGV = - new GlobalVariable(DstM, TypeMap.get(SGVar->getType()->getElementType()), + new GlobalVariable(DstM, TypeMap.get(SGVar->getValueType()), SGVar->isConstant(), GlobalValue::ExternalLinkage, /*init*/ nullptr, SGVar->getName(), /*insertbefore*/ nullptr, SGVar->getThreadLocalMode(), @@ -759,7 +624,7 @@ GlobalValue *IRLinker::copyGlobalValueProto(const GlobalValue *SGV, NewGV = copyGlobalAliasProto(cast<GlobalAlias>(SGV)); else NewGV = new GlobalVariable( - DstM, TypeMap.get(SGV->getType()->getElementType()), + DstM, TypeMap.get(SGV->getValueType()), /*isConstant*/ false, GlobalValue::ExternalLinkage, /*init*/ nullptr, SGV->getName(), /*insertbefore*/ nullptr, SGV->getThreadLocalMode(), @@ -768,12 +633,17 @@ GlobalValue *IRLinker::copyGlobalValueProto(const GlobalValue *SGV, if (ForDefinition) NewGV->setLinkage(SGV->getLinkage()); - else if (SGV->hasExternalWeakLinkage() || SGV->hasWeakLinkage() || - SGV->hasLinkOnceLinkage()) + else if (SGV->hasExternalWeakLinkage()) NewGV->setLinkage(GlobalValue::ExternalWeakLinkage); NewGV->copyAttributesFrom(SGV); + if (auto *NewGO = dyn_cast<GlobalObject>(NewGV)) { + // Metadata for global variables and function declarations is copied eagerly. + if (isa<GlobalVariable>(SGV) || SGV->isDeclaration()) + NewGO->copyMetadata(cast<GlobalObject>(SGV), 0); + } + // Remove these copied constants in case this stays a declaration, since // they point to the source module. If the def is linked the values will // be mapped in during linkFunctionBody. @@ -791,7 +661,7 @@ GlobalValue *IRLinker::copyGlobalValueProto(const GlobalValue *SGV, /// types 'Foo' but one got renamed when the module was loaded into the same /// LLVMContext. void IRLinker::computeTypeMapping() { - for (GlobalValue &SGV : SrcM.globals()) { + for (GlobalValue &SGV : SrcM->globals()) { GlobalValue *DGV = getLinkedToGlobal(&SGV); if (!DGV) continue; @@ -802,16 +672,16 @@ void IRLinker::computeTypeMapping() { } // Unify the element type of appending arrays. - ArrayType *DAT = cast<ArrayType>(DGV->getType()->getElementType()); - ArrayType *SAT = cast<ArrayType>(SGV.getType()->getElementType()); + ArrayType *DAT = cast<ArrayType>(DGV->getValueType()); + ArrayType *SAT = cast<ArrayType>(SGV.getValueType()); TypeMap.addTypeMapping(DAT->getElementType(), SAT->getElementType()); } - for (GlobalValue &SGV : SrcM) + for (GlobalValue &SGV : *SrcM) if (GlobalValue *DGV = getLinkedToGlobal(&SGV)) TypeMap.addTypeMapping(DGV->getType(), SGV.getType()); - for (GlobalValue &SGV : SrcM.aliases()) + for (GlobalValue &SGV : SrcM->aliases()) if (GlobalValue *DGV = getLinkedToGlobal(&SGV)) TypeMap.addTypeMapping(DGV->getType(), SGV.getType()); @@ -819,7 +689,7 @@ void IRLinker::computeTypeMapping() { // At this point, the destination module may have a type "%foo = { i32 }" for // example. When the source module got loaded into the same LLVMContext, if // it had the same type, it would have been renamed to "%foo.42 = { i32 }". - std::vector<StructType *> Types = SrcM.getIdentifiedStructTypes(); + std::vector<StructType *> Types = SrcM->getIdentifiedStructTypes(); for (StructType *ST : Types) { if (!ST->hasName()) continue; @@ -871,12 +741,16 @@ static void getArrayElements(const Constant *C, } /// If there were any appending global variables, link them together now. -/// Return true on error. -Constant *IRLinker::linkAppendingVarProto(GlobalVariable *DstGV, - const GlobalVariable *SrcGV) { - Type *EltTy = cast<ArrayType>(TypeMap.get(SrcGV->getType()->getElementType())) +Expected<Constant *> +IRLinker::linkAppendingVarProto(GlobalVariable *DstGV, + const GlobalVariable *SrcGV) { + Type *EltTy = cast<ArrayType>(TypeMap.get(SrcGV->getValueType())) ->getElementType(); + // FIXME: This upgrade is done during linking to support the C API. Once the + // old form is deprecated, we should move this upgrade to + // llvm::UpgradeGlobalVariable() and simplify the logic here and in + // Mapper::mapAppendingVariable() in ValueMapper.cpp. StringRef Name = SrcGV->getName(); bool IsNewStructor = false; bool IsOldStructor = false; @@ -894,55 +768,40 @@ Constant *IRLinker::linkAppendingVarProto(GlobalVariable *DstGV, EltTy = StructType::get(SrcGV->getContext(), Tys, false); } + uint64_t DstNumElements = 0; if (DstGV) { - ArrayType *DstTy = cast<ArrayType>(DstGV->getType()->getElementType()); + ArrayType *DstTy = cast<ArrayType>(DstGV->getValueType()); + DstNumElements = DstTy->getNumElements(); - if (!SrcGV->hasAppendingLinkage() || !DstGV->hasAppendingLinkage()) { - emitError( + if (!SrcGV->hasAppendingLinkage() || !DstGV->hasAppendingLinkage()) + return stringErr( "Linking globals named '" + SrcGV->getName() + - "': can only link appending global with another appending global!"); - return nullptr; - } + "': can only link appending global with another appending " + "global!"); // Check to see that they two arrays agree on type. - if (EltTy != DstTy->getElementType()) { - emitError("Appending variables with different element types!"); - return nullptr; - } - if (DstGV->isConstant() != SrcGV->isConstant()) { - emitError("Appending variables linked with different const'ness!"); - return nullptr; - } + if (EltTy != DstTy->getElementType()) + return stringErr("Appending variables with different element types!"); + if (DstGV->isConstant() != SrcGV->isConstant()) + return stringErr("Appending variables linked with different const'ness!"); - if (DstGV->getAlignment() != SrcGV->getAlignment()) { - emitError( + if (DstGV->getAlignment() != SrcGV->getAlignment()) + return stringErr( "Appending variables with different alignment need to be linked!"); - return nullptr; - } - if (DstGV->getVisibility() != SrcGV->getVisibility()) { - emitError( + if (DstGV->getVisibility() != SrcGV->getVisibility()) + return stringErr( "Appending variables with different visibility need to be linked!"); - return nullptr; - } - if (DstGV->hasUnnamedAddr() != SrcGV->hasUnnamedAddr()) { - emitError( + if (DstGV->hasGlobalUnnamedAddr() != SrcGV->hasGlobalUnnamedAddr()) + return stringErr( "Appending variables with different unnamed_addr need to be linked!"); - return nullptr; - } - if (StringRef(DstGV->getSection()) != SrcGV->getSection()) { - emitError( + if (DstGV->getSection() != SrcGV->getSection()) + return stringErr( "Appending variables with different section name need to be linked!"); - return nullptr; - } } - SmallVector<Constant *, 16> DstElements; - if (DstGV) - getArrayElements(DstGV->getInitializer(), DstElements); - SmallVector<Constant *, 16> SrcElements; getArrayElements(SrcGV->getInitializer(), SrcElements); @@ -958,7 +817,7 @@ Constant *IRLinker::linkAppendingVarProto(GlobalVariable *DstGV, return !shouldLink(DGV, *Key); }), SrcElements.end()); - uint64_t NewSize = DstElements.size() + SrcElements.size(); + uint64_t NewSize = DstNumElements + SrcElements.size(); ArrayType *NewType = ArrayType::get(EltTy, NewSize); // Create the new global variable. @@ -972,28 +831,9 @@ Constant *IRLinker::linkAppendingVarProto(GlobalVariable *DstGV, Constant *Ret = ConstantExpr::getBitCast(NG, TypeMap.get(SrcGV->getType())); - // Stop recursion. - ValueMap[SrcGV] = Ret; - - for (auto *V : SrcElements) { - Constant *NewV; - if (IsOldStructor) { - auto *S = cast<ConstantStruct>(V); - auto *E1 = MapValue(S->getOperand(0), ValueMap, ValueMapperFlags, - &TypeMap, &GValMaterializer); - auto *E2 = MapValue(S->getOperand(1), ValueMap, ValueMapperFlags, - &TypeMap, &GValMaterializer); - Value *Null = Constant::getNullValue(VoidPtrTy); - NewV = - ConstantStruct::get(cast<StructType>(EltTy), E1, E2, Null, nullptr); - } else { - NewV = - MapValue(V, ValueMap, ValueMapperFlags, &TypeMap, &GValMaterializer); - } - DstElements.push_back(NewV); - } - - NG->setInitializer(ConstantArray::get(NewType, DstElements)); + Mapper.scheduleMapAppendingVariable(*NG, + DstGV ? DstGV->getInitializer() : nullptr, + IsOldStructor, SrcElements); // Replace any uses of the two global variables with uses of the new // global. @@ -1005,52 +845,31 @@ Constant *IRLinker::linkAppendingVarProto(GlobalVariable *DstGV, return Ret; } -static bool useExistingDest(GlobalValue &SGV, GlobalValue *DGV, - bool ShouldLink) { - if (!DGV) - return false; - - if (SGV.isDeclaration()) - return true; - - if (DGV->isDeclarationForLinker() && !SGV.isDeclarationForLinker()) - return false; - - if (ShouldLink) - return false; - - return true; -} - bool IRLinker::shouldLink(GlobalValue *DGV, GlobalValue &SGV) { - // Already imported all the values. Just map to the Dest value - // in case it is referenced in the metadata. - if (IsMetadataLinkingPostpass) { - assert(!ValuesToLink.count(&SGV) && - "Source value unexpectedly requested for link during metadata link"); - return false; - } - - if (ValuesToLink.count(&SGV)) - return true; - - if (SGV.hasLocalLinkage()) + if (ValuesToLink.count(&SGV) || SGV.hasLocalLinkage()) return true; - if (DGV && !DGV->isDeclaration()) + if (DGV && !DGV->isDeclarationForLinker()) return false; if (SGV.hasAvailableExternallyLinkage()) return true; - if (DoneLinkingBodies) + if (SGV.isDeclaration() || DoneLinkingBodies) return false; - AddLazyFor(SGV, [this](GlobalValue &GV) { maybeAdd(&GV); }); - return ValuesToLink.count(&SGV); + // Callback to the client to give a chance to lazily add the Global to the + // list of value to link. + bool LazilyAdded = false; + AddLazyFor(SGV, [this, &LazilyAdded](GlobalValue &GV) { + maybeAdd(&GV); + LazilyAdded = true; + }); + return LazilyAdded; } -Constant *IRLinker::linkGlobalValueProto(GlobalValue *SGV, bool ForAlias) { +Expected<Constant *> IRLinker::linkGlobalValueProto(GlobalValue *SGV, + bool ForAlias) { GlobalValue *DGV = getLinkedToGlobal(SGV); bool ShouldLink = shouldLink(DGV, *SGV); @@ -1066,9 +885,8 @@ Constant *IRLinker::linkGlobalValueProto(GlobalValue *SGV, bool ForAlias) { return cast<Constant>(I->second); } - DGV = nullptr; - if (ShouldLink || !ForAlias) - DGV = getLinkedToGlobal(SGV); + if (!ShouldLink && ForAlias) + DGV = nullptr; // Handle the ultra special appending linkage case first. assert(!DGV || SGV->hasAppendingLinkage() == DGV->hasAppendingLinkage()); @@ -1077,7 +895,7 @@ Constant *IRLinker::linkGlobalValueProto(GlobalValue *SGV, bool ForAlias) { cast<GlobalVariable>(SGV)); GlobalValue *NewGV; - if (useExistingDest(*SGV, DGV, ShouldLink)) { + if (DGV && !ShouldLink) { NewGV = DGV; } else { // If we are done linking global value bodies (i.e. we are performing @@ -1087,9 +905,17 @@ Constant *IRLinker::linkGlobalValueProto(GlobalValue *SGV, bool ForAlias) { return nullptr; NewGV = copyGlobalValueProto(SGV, ShouldLink); - if (!ForAlias) + if (ShouldLink || !ForAlias) forceRenaming(NewGV, SGV->getName()); } + + // Overloaded intrinsics have overloaded types names as part of their + // names. If we renamed overloaded types we should rename the intrinsic + // as well. + if (Function *F = dyn_cast<Function>(NewGV)) + if (auto Remangled = Intrinsic::remangleIntrinsicFunction(F)) + NewGV = Remangled.getValue(); + if (ShouldLink || ForAlias) { if (const Comdat *SC = SGV->getComdat()) { if (auto *GO = dyn_cast<GlobalObject>(NewGV)) { @@ -1119,196 +945,74 @@ Constant *IRLinker::linkGlobalValueProto(GlobalValue *SGV, bool ForAlias) { /// referenced are in Dest. void IRLinker::linkGlobalInit(GlobalVariable &Dst, GlobalVariable &Src) { // Figure out what the initializer looks like in the dest module. - Dst.setInitializer(MapValue(Src.getInitializer(), ValueMap, ValueMapperFlags, - &TypeMap, &GValMaterializer)); + Mapper.scheduleMapGlobalInitializer(Dst, *Src.getInitializer()); } /// Copy the source function over into the dest function and fix up references /// to values. At this point we know that Dest is an external function, and /// that Src is not. -bool IRLinker::linkFunctionBody(Function &Dst, Function &Src) { +Error IRLinker::linkFunctionBody(Function &Dst, Function &Src) { assert(Dst.isDeclaration() && !Src.isDeclaration()); // Materialize if needed. if (std::error_code EC = Src.materialize()) - return emitError(EC.message()); - - if (!shouldLinkMetadata()) - // This is only supported for lazy links. Do after materialization of - // a function and before remapping metadata on instructions below - // in RemapInstruction, as the saved mapping is used to handle - // the temporary metadata hanging off instructions. - SrcM.getMaterializer()->saveMetadataList(MetadataToIDs, - /* OnlyTempMD = */ true); + return errorCodeToError(EC); - // Link in the prefix data. + // Link in the operands without remapping. if (Src.hasPrefixData()) - Dst.setPrefixData(MapValue(Src.getPrefixData(), ValueMap, ValueMapperFlags, - &TypeMap, &GValMaterializer)); - - // Link in the prologue data. + Dst.setPrefixData(Src.getPrefixData()); if (Src.hasPrologueData()) - Dst.setPrologueData(MapValue(Src.getPrologueData(), ValueMap, - ValueMapperFlags, &TypeMap, - &GValMaterializer)); - - // Link in the personality function. + Dst.setPrologueData(Src.getPrologueData()); if (Src.hasPersonalityFn()) - Dst.setPersonalityFn(MapValue(Src.getPersonalityFn(), ValueMap, - ValueMapperFlags, &TypeMap, - &GValMaterializer)); - - // Go through and convert function arguments over, remembering the mapping. - Function::arg_iterator DI = Dst.arg_begin(); - for (Argument &Arg : Src.args()) { - DI->setName(Arg.getName()); // Copy the name over. - - // Add a mapping to our mapping. - ValueMap[&Arg] = &*DI; - ++DI; - } + Dst.setPersonalityFn(Src.getPersonalityFn()); - // Copy over the metadata attachments. - SmallVector<std::pair<unsigned, MDNode *>, 8> MDs; - Src.getAllMetadata(MDs); - for (const auto &I : MDs) - Dst.setMetadata(I.first, MapMetadata(I.second, ValueMap, ValueMapperFlags, - &TypeMap, &GValMaterializer)); + // Copy over the metadata attachments without remapping. + Dst.copyMetadata(&Src, 0); - // Splice the body of the source function into the dest function. + // Steal arguments and splice the body of Src into Dst. + Dst.stealArgumentListFrom(Src); Dst.getBasicBlockList().splice(Dst.end(), Src.getBasicBlockList()); - // At this point, all of the instructions and values of the function are now - // copied over. The only problem is that they are still referencing values in - // the Source function as operands. Loop through all of the operands of the - // functions and patch them up to point to the local versions. - for (BasicBlock &BB : Dst) - for (Instruction &I : BB) - RemapInstruction(&I, ValueMap, RF_IgnoreMissingEntries | ValueMapperFlags, - &TypeMap, &GValMaterializer); - - // There is no need to map the arguments anymore. - for (Argument &Arg : Src.args()) - ValueMap.erase(&Arg); - - return false; + // Everything has been moved over. Remap it. + Mapper.scheduleRemapFunction(Dst); + return Error::success(); } void IRLinker::linkAliasBody(GlobalAlias &Dst, GlobalAlias &Src) { - Constant *Aliasee = Src.getAliasee(); - Constant *Val = MapValue(Aliasee, AliasValueMap, ValueMapperFlags, &TypeMap, - &LValMaterializer); - Dst.setAliasee(Val); + Mapper.scheduleMapGlobalAliasee(Dst, *Src.getAliasee(), AliasMCID); } -bool IRLinker::linkGlobalValueBody(GlobalValue &Dst, GlobalValue &Src) { +Error IRLinker::linkGlobalValueBody(GlobalValue &Dst, GlobalValue &Src) { if (auto *F = dyn_cast<Function>(&Src)) return linkFunctionBody(cast<Function>(Dst), *F); if (auto *GVar = dyn_cast<GlobalVariable>(&Src)) { linkGlobalInit(cast<GlobalVariable>(Dst), *GVar); - return false; + return Error::success(); } linkAliasBody(cast<GlobalAlias>(Dst), cast<GlobalAlias>(Src)); - return false; -} - -void IRLinker::findNeededSubprograms(ValueToValueMapTy &ValueMap) { - // Track unneeded nodes to make it simpler to handle the case - // where we are checking if an already-mapped SP is needed. - NamedMDNode *CompileUnits = SrcM.getNamedMetadata("llvm.dbg.cu"); - if (!CompileUnits) - return; - for (unsigned I = 0, E = CompileUnits->getNumOperands(); I != E; ++I) { - auto *CU = cast<DICompileUnit>(CompileUnits->getOperand(I)); - assert(CU && "Expected valid compile unit"); - // Ensure that we don't remove subprograms referenced by DIImportedEntity. - // It is not legal to have a DIImportedEntity with a null entity or scope. - // FIXME: The DISubprogram for functions not linked in but kept due to - // being referenced by a DIImportedEntity should also get their - // IsDefinition flag is unset. - SmallPtrSet<DISubprogram *, 8> ImportedEntitySPs; - for (auto *IE : CU->getImportedEntities()) { - if (auto *SP = dyn_cast<DISubprogram>(IE->getEntity())) - ImportedEntitySPs.insert(SP); - if (auto *SP = dyn_cast<DISubprogram>(IE->getScope())) - ImportedEntitySPs.insert(SP); - } - for (auto *Op : CU->getSubprograms()) { - // Unless we were doing function importing and deferred metadata linking, - // any needed SPs should have been mapped as they would be reached - // from the function linked in (either on the function itself for linked - // function bodies, or from DILocation on inlined instructions). - assert(!(ValueMap.MD()[Op] && IsMetadataLinkingPostpass) && - "DISubprogram shouldn't be mapped yet"); - if (!ValueMap.MD()[Op] && !ImportedEntitySPs.count(Op)) - UnneededSubprograms.insert(Op); - } - } - if (!IsMetadataLinkingPostpass) - return; - // In the case of metadata linking as a postpass (e.g. for function - // importing), see which DISubprogram MD from the source has an associated - // temporary metadata node, which means the SP was needed by an imported - // function. - for (auto MDI : MetadataToIDs) { - const MDNode *Node = dyn_cast<MDNode>(MDI.first); - if (!Node) - continue; - DISubprogram *SP = getDISubprogram(Node); - if (!SP || !ValIDToTempMDMap->count(MDI.second)) - continue; - UnneededSubprograms.erase(SP); - } -} - -// Squash null subprograms from compile unit subprogram lists. -void IRLinker::stripNullSubprograms() { - NamedMDNode *CompileUnits = DstM.getNamedMetadata("llvm.dbg.cu"); - if (!CompileUnits) - return; - for (unsigned I = 0, E = CompileUnits->getNumOperands(); I != E; ++I) { - auto *CU = cast<DICompileUnit>(CompileUnits->getOperand(I)); - assert(CU && "Expected valid compile unit"); - - SmallVector<Metadata *, 16> NewSPs; - NewSPs.reserve(CU->getSubprograms().size()); - bool FoundNull = false; - for (DISubprogram *SP : CU->getSubprograms()) { - if (!SP) { - FoundNull = true; - continue; - } - NewSPs.push_back(SP); - } - if (FoundNull) - CU->replaceSubprograms(MDTuple::get(CU->getContext(), NewSPs)); - } + return Error::success(); } /// Insert all of the named MDNodes in Src into the Dest module. void IRLinker::linkNamedMDNodes() { - findNeededSubprograms(ValueMap); - const NamedMDNode *SrcModFlags = SrcM.getModuleFlagsMetadata(); - for (const NamedMDNode &NMD : SrcM.named_metadata()) { + const NamedMDNode *SrcModFlags = SrcM->getModuleFlagsMetadata(); + for (const NamedMDNode &NMD : SrcM->named_metadata()) { // Don't link module flags here. Do them separately. if (&NMD == SrcModFlags) continue; NamedMDNode *DestNMD = DstM.getOrInsertNamedMetadata(NMD.getName()); // Add Src elements into Dest node. - for (const MDNode *op : NMD.operands()) - DestNMD->addOperand(MapMetadata( - op, ValueMap, ValueMapperFlags | RF_NullMapMissingGlobalValues, - &TypeMap, &GValMaterializer)); + for (const MDNode *Op : NMD.operands()) + DestNMD->addOperand(Mapper.mapMDNode(*Op)); } - stripNullSubprograms(); } /// Merge the linker flags in Src into the Dest module. -bool IRLinker::linkModuleFlagsMetadata() { +Error IRLinker::linkModuleFlagsMetadata() { // If the source module has no module flags, we are done. - const NamedMDNode *SrcModFlags = SrcM.getModuleFlagsMetadata(); + const NamedMDNode *SrcModFlags = SrcM->getModuleFlagsMetadata(); if (!SrcModFlags) - return false; + return Error::success(); // If the destination module doesn't have module flags yet, then just copy // over the source module's flags. @@ -1317,7 +1021,7 @@ bool IRLinker::linkModuleFlagsMetadata() { for (unsigned I = 0, E = SrcModFlags->getNumOperands(); I != E; ++I) DstModFlags->addOperand(SrcModFlags->getOperand(I)); - return false; + return Error::success(); } // First build a map of the existing module flags and requirements. @@ -1373,10 +1077,9 @@ bool IRLinker::linkModuleFlagsMetadata() { if (DstBehaviorValue == Module::Override) { // Diagnose inconsistent flags which both have override behavior. if (SrcBehaviorValue == Module::Override && - SrcOp->getOperand(2) != DstOp->getOperand(2)) { - emitError("linking module flags '" + ID->getString() + - "': IDs have conflicting override values"); - } + SrcOp->getOperand(2) != DstOp->getOperand(2)) + return stringErr("linking module flags '" + ID->getString() + + "': IDs have conflicting override values"); continue; } else if (SrcBehaviorValue == Module::Override) { // Update the destination flag to that of the source. @@ -1386,11 +1089,9 @@ bool IRLinker::linkModuleFlagsMetadata() { } // Diagnose inconsistent merge behavior types. - if (SrcBehaviorValue != DstBehaviorValue) { - emitError("linking module flags '" + ID->getString() + - "': IDs have conflicting behaviors"); - continue; - } + if (SrcBehaviorValue != DstBehaviorValue) + return stringErr("linking module flags '" + ID->getString() + + "': IDs have conflicting behaviors"); auto replaceDstValue = [&](MDNode *New) { Metadata *FlagOps[] = {DstOp->getOperand(0), ID, New}; @@ -1406,10 +1107,9 @@ bool IRLinker::linkModuleFlagsMetadata() { llvm_unreachable("not possible"); case Module::Error: { // Emit an error if the values differ. - if (SrcOp->getOperand(2) != DstOp->getOperand(2)) { - emitError("linking module flags '" + ID->getString() + - "': IDs have conflicting values"); - } + if (SrcOp->getOperand(2) != DstOp->getOperand(2)) + return stringErr("linking module flags '" + ID->getString() + + "': IDs have conflicting values"); continue; } case Module::Warning: { @@ -1452,14 +1152,11 @@ bool IRLinker::linkModuleFlagsMetadata() { Metadata *ReqValue = Requirement->getOperand(1); MDNode *Op = Flags[Flag].first; - if (!Op || Op->getOperand(2) != ReqValue) { - emitError("linking module flags '" + Flag->getString() + - "': does not have the required value"); - continue; - } + if (!Op || Op->getOperand(2) != ReqValue) + return stringErr("linking module flags '" + Flag->getString() + + "': does not have the required value"); } - - return HasError; + return Error::success(); } // This function returns true if the triples match. @@ -1483,41 +1180,47 @@ static std::string mergeTriples(const Triple &SrcTriple, return DstTriple.str(); } -bool IRLinker::run() { +Error IRLinker::run() { + // Ensure metadata materialized before value mapping. + if (SrcM->getMaterializer()) + if (std::error_code EC = SrcM->getMaterializer()->materializeMetadata()) + return errorCodeToError(EC); + // Inherit the target data from the source module if the destination module // doesn't have one already. if (DstM.getDataLayout().isDefault()) - DstM.setDataLayout(SrcM.getDataLayout()); + DstM.setDataLayout(SrcM->getDataLayout()); - if (SrcM.getDataLayout() != DstM.getDataLayout()) { + if (SrcM->getDataLayout() != DstM.getDataLayout()) { emitWarning("Linking two modules of different data layouts: '" + - SrcM.getModuleIdentifier() + "' is '" + - SrcM.getDataLayoutStr() + "' whereas '" + + SrcM->getModuleIdentifier() + "' is '" + + SrcM->getDataLayoutStr() + "' whereas '" + DstM.getModuleIdentifier() + "' is '" + DstM.getDataLayoutStr() + "'\n"); } // Copy the target triple from the source to dest if the dest's is empty. - if (DstM.getTargetTriple().empty() && !SrcM.getTargetTriple().empty()) - DstM.setTargetTriple(SrcM.getTargetTriple()); + if (DstM.getTargetTriple().empty() && !SrcM->getTargetTriple().empty()) + DstM.setTargetTriple(SrcM->getTargetTriple()); - Triple SrcTriple(SrcM.getTargetTriple()), DstTriple(DstM.getTargetTriple()); + Triple SrcTriple(SrcM->getTargetTriple()), DstTriple(DstM.getTargetTriple()); - if (!SrcM.getTargetTriple().empty() && !triplesMatch(SrcTriple, DstTriple)) + if (!SrcM->getTargetTriple().empty() && !triplesMatch(SrcTriple, DstTriple)) emitWarning("Linking two modules of different target triples: " + - SrcM.getModuleIdentifier() + "' is '" + SrcM.getTargetTriple() + - "' whereas '" + DstM.getModuleIdentifier() + "' is '" + - DstM.getTargetTriple() + "'\n"); + SrcM->getModuleIdentifier() + "' is '" + + SrcM->getTargetTriple() + "' whereas '" + + DstM.getModuleIdentifier() + "' is '" + DstM.getTargetTriple() + + "'\n"); DstM.setTargetTriple(mergeTriples(SrcTriple, DstTriple)); // Append the module inline asm string. - if (!SrcM.getModuleInlineAsm().empty()) { + if (!SrcM->getModuleInlineAsm().empty()) { if (DstM.getModuleInlineAsm().empty()) - DstM.setModuleInlineAsm(SrcM.getModuleInlineAsm()); + DstM.setModuleInlineAsm(SrcM->getModuleInlineAsm()); else DstM.setModuleInlineAsm(DstM.getModuleInlineAsm() + "\n" + - SrcM.getModuleInlineAsm()); + SrcM->getModuleInlineAsm()); } // Loop over all of the linked values to compute type mappings. @@ -1534,54 +1237,23 @@ bool IRLinker::run() { continue; assert(!GV->isDeclaration()); - MapValue(GV, ValueMap, ValueMapperFlags, &TypeMap, &GValMaterializer); - if (HasError) - return true; + Mapper.mapValue(*GV); + if (FoundError) + return std::move(*FoundError); } // Note that we are done linking global value bodies. This prevents // metadata linking from creating new references. DoneLinkingBodies = true; + Mapper.addFlags(RF_NullMapMissingGlobalValues); // Remap all of the named MDNodes in Src into the DstM module. We do this // after linking GlobalValues so that MDNodes that reference GlobalValues // are properly remapped. - if (shouldLinkMetadata()) { - // Even if just linking metadata we should link decls above in case - // any are referenced by metadata. IRLinker::shouldLink ensures that - // we don't actually link anything from source. - if (IsMetadataLinkingPostpass) { - // Ensure metadata materialized - if (SrcM.getMaterializer()->materializeMetadata()) - return true; - SrcM.getMaterializer()->saveMetadataList(MetadataToIDs, - /* OnlyTempMD = */ false); - } - - linkNamedMDNodes(); - - if (IsMetadataLinkingPostpass) { - // Handle anything left in the ValIDToTempMDMap, such as metadata nodes - // not reached by the dbg.cu NamedMD (i.e. only reached from - // instructions). - // Walk the MetadataToIDs once to find the set of new (imported) MD - // that still has corresponding temporary metadata, and invoke metadata - // mapping on each one. - for (auto MDI : MetadataToIDs) { - if (!ValIDToTempMDMap->count(MDI.second)) - continue; - MapMetadata(MDI.first, ValueMap, ValueMapperFlags, &TypeMap, - &GValMaterializer); - } - assert(ValIDToTempMDMap->empty()); - } - - // Merge the module flags into the DstM module. - if (linkModuleFlagsMetadata()) - return true; - } + linkNamedMDNodes(); - return false; + // Merge the module flags into the DstM module. + return linkModuleFlagsMetadata(); } IRMover::StructTypeKeyInfo::KeyTy::KeyTy(ArrayRef<Type *> E, bool P) @@ -1591,11 +1263,7 @@ IRMover::StructTypeKeyInfo::KeyTy::KeyTy(const StructType *ST) : ETypes(ST->elements()), IsPacked(ST->isPacked()) {} bool IRMover::StructTypeKeyInfo::KeyTy::operator==(const KeyTy &That) const { - if (IsPacked != That.IsPacked) - return false; - if (ETypes != That.ETypes) - return false; - return true; + return IsPacked == That.IsPacked && ETypes == That.ETypes; } bool IRMover::StructTypeKeyInfo::KeyTy::operator!=(const KeyTy &That) const { @@ -1628,12 +1296,8 @@ bool IRMover::StructTypeKeyInfo::isEqual(const KeyTy &LHS, bool IRMover::StructTypeKeyInfo::isEqual(const StructType *LHS, const StructType *RHS) { - if (RHS == getEmptyKey()) - return LHS == getEmptyKey(); - - if (RHS == getTombstoneKey()) - return LHS == getTombstoneKey(); - + if (RHS == getEmptyKey() || RHS == getTombstoneKey()) + return LHS == RHS; return KeyTy(LHS) == KeyTy(RHS); } @@ -1660,18 +1324,14 @@ IRMover::IdentifiedStructTypeSet::findNonOpaque(ArrayRef<Type *> ETypes, bool IsPacked) { IRMover::StructTypeKeyInfo::KeyTy Key(ETypes, IsPacked); auto I = NonOpaqueStructTypes.find_as(Key); - if (I == NonOpaqueStructTypes.end()) - return nullptr; - return *I; + return I == NonOpaqueStructTypes.end() ? nullptr : *I; } bool IRMover::IdentifiedStructTypeSet::hasType(StructType *Ty) { if (Ty->isOpaque()) return OpaqueStructTypes.count(Ty); auto I = NonOpaqueStructTypes.find(Ty); - if (I == NonOpaqueStructTypes.end()) - return false; - return *I == Ty; + return I == NonOpaqueStructTypes.end() ? false : *I == Ty; } IRMover::IRMover(Module &M) : Composite(M) { @@ -1685,14 +1345,12 @@ IRMover::IRMover(Module &M) : Composite(M) { } } -bool IRMover::move( - Module &Src, ArrayRef<GlobalValue *> ValuesToLink, - std::function<void(GlobalValue &, ValueAdder Add)> AddLazyFor, - DenseMap<unsigned, MDNode *> *ValIDToTempMDMap, - bool IsMetadataLinkingPostpass) { - IRLinker TheIRLinker(Composite, IdentifiedStructTypes, Src, ValuesToLink, - AddLazyFor, ValIDToTempMDMap, IsMetadataLinkingPostpass); - bool RetCode = TheIRLinker.run(); +Error IRMover::move( + std::unique_ptr<Module> Src, ArrayRef<GlobalValue *> ValuesToLink, + std::function<void(GlobalValue &, ValueAdder Add)> AddLazyFor) { + IRLinker TheIRLinker(Composite, SharedMDs, IdentifiedStructTypes, + std::move(Src), ValuesToLink, std::move(AddLazyFor)); + Error E = TheIRLinker.run(); Composite.dropTriviallyDeadConstantArrays(); - return RetCode; + return E; } diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index 6ffa71e147790..fae9c95ebe8fb 100644 --- a/lib/Linker/LinkModules.cpp +++ b/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)); diff --git a/lib/Linker/Makefile b/lib/Linker/Makefile deleted file mode 100644 index 19e646b748302..0000000000000 --- a/lib/Linker/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -##===- lib/Linker/Makefile ---------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../.. -LIBRARYNAME = LLVMLinker -BUILD_ARCHIVE := 1 - -include $(LEVEL)/Makefile.common - |