X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FLinker%2FLinkModules.cpp;h=504073887c33ca378ec7ea24517218dcd2e644fe;hb=95f8931c553485203bc0496972756ae25dfdb32a;hp=c9563e6c272bb333d2b0affb8e167317a732c26a;hpb=72478e59c7dfb01870a8f6b5ae6c7e1fb18719c3;p=oota-llvm.git diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index c9563e6c272..504073887c3 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -36,61 +36,57 @@ using namespace llvm; //===----------------------------------------------------------------------===// namespace { - typedef SmallPtrSet TypeSet; +typedef SmallPtrSet TypeSet; class TypeMapTy : public ValueMapTypeRemapper { - /// MappedTypes - This is a mapping from a source type to a destination type - /// to use. + /// This is a mapping from a source type to a destination type to use. DenseMap MappedTypes; - /// SpeculativeTypes - When checking to see if two subgraphs are isomorphic, - /// we speculatively add types to MappedTypes, but keep track of them here in - /// case we need to roll back. + /// When checking to see if two subgraphs are isomorphic, we speculatively + /// add types to MappedTypes, but keep track of them here in case we need to + /// roll back. SmallVector SpeculativeTypes; - /// SrcDefinitionsToResolve - This is a list of non-opaque structs in the - /// source module that are mapped to an opaque struct in the destination - /// module. + /// This is a list of non-opaque structs in the source module that are mapped + /// to an opaque struct in the destination module. SmallVector SrcDefinitionsToResolve; - /// DstResolvedOpaqueTypes - This is the set of opaque types in the - /// destination modules who are getting a body from the source module. + /// This is the set of opaque types in the destination modules who are + /// getting a body from the source module. SmallPtrSet DstResolvedOpaqueTypes; public: TypeMapTy(TypeSet &Set) : DstStructTypesSet(Set) {} TypeSet &DstStructTypesSet; - /// addTypeMapping - Indicate that the specified type in the destination - /// module is conceptually equivalent to the specified type in the source - /// module. + /// Indicate that the specified type in the destination module is conceptually + /// equivalent to the specified type in the source module. void addTypeMapping(Type *DstTy, Type *SrcTy); - /// linkDefinedTypeBodies - Produce a body for an opaque type in the dest - /// module from a type definition in the source module. + /// Produce a body for an opaque type in the dest module from a type + /// definition in the source module. void linkDefinedTypeBodies(); - /// get - Return the mapped type to use for the specified input type from the + /// Return the mapped type to use for the specified input type from the /// source module. Type *get(Type *SrcTy); FunctionType *get(FunctionType *T) {return cast(get((Type*)T));} - /// dump - Dump out the type map for debugging purposes. + /// Dump out the type map for debugging purposes. void dump() const { - for (DenseMap::const_iterator - I = MappedTypes.begin(), E = MappedTypes.end(); I != E; ++I) { + for (auto &Pair : MappedTypes) { dbgs() << "TypeMap: "; - I->first->print(dbgs()); + Pair.first->print(dbgs()); dbgs() << " => "; - I->second->print(dbgs()); + Pair.second->print(dbgs()); dbgs() << '\n'; } } private: Type *getImpl(Type *T); - /// remapType - Implement the ValueMapTypeRemapper interface. + /// Implement the ValueMapTypeRemapper interface. Type *remapType(Type *SrcTy) override { return get(SrcTy); } @@ -110,17 +106,28 @@ void TypeMapTy::addTypeMapping(Type *DstTy, Type *SrcTy) { // Check to see if these types are recursively isomorphic and establish a // mapping between them if so. - if (!areTypesIsomorphic(DstTy, SrcTy)) { - // Oops, they aren't isomorphic. Just discard this request by rolling out - // any speculative mappings we've established. - for (unsigned i = 0, e = SpeculativeTypes.size(); i != e; ++i) - MappedTypes.erase(SpeculativeTypes[i]); + if (areTypesIsomorphic(DstTy, SrcTy)) { + SpeculativeTypes.clear(); + return; + } + + // Oops, they aren't isomorphic. Just discard this request by rolling out + // any speculative mappings we've established. + unsigned Removed = 0; + for (unsigned I = 0, E = SpeculativeTypes.size(); I != E; ++I) { + Type *SrcTy = SpeculativeTypes[I]; + auto Iter = MappedTypes.find(SrcTy); + auto *DstTy = dyn_cast(Iter->second); + if (DstTy && DstResolvedOpaqueTypes.erase(DstTy)) + Removed++; + MappedTypes.erase(Iter); } + SrcDefinitionsToResolve.resize(SrcDefinitionsToResolve.size() - Removed); SpeculativeTypes.clear(); } -/// areTypesIsomorphic - Recursively walk this pair of types, returning true -/// if they are isomorphic, false if they are not. +/// Recursively walk this pair of types, returning true if they are isomorphic, +/// false if they are not. bool TypeMapTy::areTypesIsomorphic(Type *DstTy, Type *SrcTy) { // Two types with differing kinds are clearly not isomorphic. if (DstTy->getTypeID() != SrcTy->getTypeID()) return false; @@ -150,14 +157,14 @@ bool TypeMapTy::areTypesIsomorphic(Type *DstTy, Type *SrcTy) { // Mapping a non-opaque source type to an opaque dest. If this is the first // type that we're mapping onto this destination type then we succeed. Keep - // the dest, but fill it in later. This doesn't need to be speculative. If - // this is the second (different) type that we're trying to map onto the - // same opaque type then we fail. + // the dest, but fill it in later. If this is the second (different) type + // that we're trying to map onto the same opaque type then we fail. if (cast(DstTy)->isOpaque()) { // We can only map one source type onto the opaque destination type. - if (!DstResolvedOpaqueTypes.insert(cast(DstTy))) + if (!DstResolvedOpaqueTypes.insert(cast(DstTy)).second) return false; SrcDefinitionsToResolve.push_back(SSTy); + SpeculativeTypes.push_back(SrcTy); Entry = DstTy; return true; } @@ -204,8 +211,6 @@ bool TypeMapTy::areTypesIsomorphic(Type *DstTy, Type *SrcTy) { return true; } -/// linkDefinedTypeBodies - Produce a body for an opaque type in the dest -/// module from a type definition in the source module. void TypeMapTy::linkDefinedTypeBodies() { SmallVector Elements; SmallString<16> TmpName; @@ -245,8 +250,6 @@ void TypeMapTy::linkDefinedTypeBodies() { DstResolvedOpaqueTypes.clear(); } -/// get - Return the mapped type to use for the specified input type from the -/// source module. Type *TypeMapTy::get(Type *Ty) { Type *Result = getImpl(Ty); @@ -256,7 +259,7 @@ Type *TypeMapTy::get(Type *Ty) { return Result; } -/// getImpl - This is the recursive version of get(). +/// This is the recursive version of get(). Type *TypeMapTy::getImpl(Type *Ty) { // If we already have an entry for this type, return it. Type **Entry = &MappedTypes[Ty]; @@ -360,152 +363,153 @@ Type *TypeMapTy::getImpl(Type *Ty) { //===----------------------------------------------------------------------===// namespace { - class ModuleLinker; - - /// ValueMaterializerTy - Creates prototypes for functions that are lazily - /// linked on the fly. This speeds up linking for modules with many - /// lazily linked functions of which few get used. - class ValueMaterializerTy : public ValueMaterializer { - TypeMapTy &TypeMap; - Module *DstM; - std::vector &LazilyLinkFunctions; - public: - ValueMaterializerTy(TypeMapTy &TypeMap, Module *DstM, - std::vector &LazilyLinkFunctions) : - ValueMaterializer(), TypeMap(TypeMap), DstM(DstM), - LazilyLinkFunctions(LazilyLinkFunctions) { - } +class ModuleLinker; - Value *materializeValueFor(Value *V) override; - }; +/// Creates prototypes for functions that are lazily linked on the fly. This +/// speeds up linking for modules with many/ lazily linked functions of which +/// few get used. +class ValueMaterializerTy : public ValueMaterializer { + TypeMapTy &TypeMap; + Module *DstM; + std::vector &LazilyLinkFunctions; - namespace { - class LinkDiagnosticInfo : public DiagnosticInfo { - const Twine &Msg; +public: + ValueMaterializerTy(TypeMapTy &TypeMap, Module *DstM, + std::vector &LazilyLinkFunctions) + : ValueMaterializer(), TypeMap(TypeMap), DstM(DstM), + LazilyLinkFunctions(LazilyLinkFunctions) {} - public: - LinkDiagnosticInfo(DiagnosticSeverity Severity, const Twine &Msg); - void print(DiagnosticPrinter &DP) const override; - }; - LinkDiagnosticInfo::LinkDiagnosticInfo(DiagnosticSeverity Severity, - const Twine &Msg) - : DiagnosticInfo(DK_Linker, Severity), Msg(Msg) {} - void LinkDiagnosticInfo::print(DiagnosticPrinter &DP) const { DP << Msg; } - } + Value *materializeValueFor(Value *V) override; +}; - /// ModuleLinker - This is an implementation class for the LinkModules - /// function, which is the entrypoint for this file. - class ModuleLinker { - Module *DstM, *SrcM; +class LinkDiagnosticInfo : public DiagnosticInfo { + const Twine &Msg; - TypeMapTy TypeMap; - ValueMaterializerTy ValMaterializer; +public: + LinkDiagnosticInfo(DiagnosticSeverity Severity, const Twine &Msg); + void print(DiagnosticPrinter &DP) const override; +}; +LinkDiagnosticInfo::LinkDiagnosticInfo(DiagnosticSeverity Severity, + const Twine &Msg) + : DiagnosticInfo(DK_Linker, Severity), Msg(Msg) {} +void LinkDiagnosticInfo::print(DiagnosticPrinter &DP) const { DP << Msg; } + +/// This is an implementation class for the LinkModules function, which is the +/// entrypoint for this file. +class ModuleLinker { + Module *DstM, *SrcM; + + TypeMapTy TypeMap; + ValueMaterializerTy ValMaterializer; + + /// 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, + /// but this allows us to reuse the ValueMapper code. + ValueToValueMapTy ValueMap; + + struct AppendingVarInfo { + GlobalVariable *NewGV; // New aggregate global in dest module. + const Constant *DstInit; // Old initializer from dest module. + const Constant *SrcInit; // Old initializer from src module. + }; - /// ValueMap - 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, but this allows us to reuse the ValueMapper code. - ValueToValueMapTy ValueMap; + std::vector AppendingVars; - struct AppendingVarInfo { - GlobalVariable *NewGV; // New aggregate global in dest module. - Constant *DstInit; // Old initializer from dest module. - Constant *SrcInit; // Old initializer from src module. - }; + // Set of items not to link in from source. + SmallPtrSet DoNotLinkFromSource; - std::vector AppendingVars; + // Vector of functions to lazily link in. + std::vector LazilyLinkFunctions; - unsigned Mode; // Mode to treat source module. + Linker::DiagnosticHandlerFunction DiagnosticHandler; - // Set of items not to link in from source. - SmallPtrSet DoNotLinkFromSource; +public: + ModuleLinker(Module *dstM, TypeSet &Set, Module *srcM, + Linker::DiagnosticHandlerFunction DiagnosticHandler) + : DstM(dstM), SrcM(srcM), TypeMap(Set), + ValMaterializer(TypeMap, DstM, LazilyLinkFunctions), + DiagnosticHandler(DiagnosticHandler) {} - // Vector of functions to lazily link in. - std::vector LazilyLinkFunctions; + bool run(); - public: - ModuleLinker(Module *dstM, TypeSet &Set, Module *srcM, unsigned mode) - : DstM(dstM), SrcM(srcM), TypeMap(Set), - ValMaterializer(TypeMap, DstM, LazilyLinkFunctions), Mode(mode) {} +private: + bool shouldLinkFromSource(bool &LinkFromSrc, const GlobalValue &Dest, + const GlobalValue &Src); - bool run(); + /// Helper method for setting a message and returning an error code. + bool emitError(const Twine &Message) { + DiagnosticHandler(LinkDiagnosticInfo(DS_Error, Message)); + return true; + } - private: - bool shouldLinkFromSource(bool &LinkFromSrc, const GlobalValue &Dest, - const GlobalValue &Src); + void emitWarning(const Twine &Message) { + DiagnosticHandler(LinkDiagnosticInfo(DS_Warning, Message)); + } - /// Helper method for setting a message and returning an error code. - bool emitError(const Twine &Message) { - DstM->getContext().diagnose(LinkDiagnosticInfo(DS_Error, Message)); - return true; - } + bool getComdatLeader(Module *M, StringRef ComdatName, + const GlobalVariable *&GVar); + bool computeResultingSelectionKind(StringRef ComdatName, + Comdat::SelectionKind Src, + Comdat::SelectionKind Dst, + Comdat::SelectionKind &Result, + bool &LinkFromSrc); + std::map> + ComdatsChosen; + bool getComdatResult(const Comdat *SrcC, Comdat::SelectionKind &SK, + bool &LinkFromSrc); + + /// Given a global in the source module, return the global in the + /// destination module that is being linked to, if any. + GlobalValue *getLinkedToGlobal(const GlobalValue *SrcGV) { + // If the source has no name it can't link. If it has local linkage, + // there is no name match-up going on. + if (!SrcGV->hasName() || SrcGV->hasLocalLinkage()) + return nullptr; + + // Otherwise see if we have a match in the destination module's symtab. + GlobalValue *DGV = DstM->getNamedValue(SrcGV->getName()); + if (!DGV) + return nullptr; + + // If we found a global with the same name in the dest module, but it has + // internal linkage, we are really not doing any linkage here. + if (DGV->hasLocalLinkage()) + return nullptr; + + // Otherwise, we do in fact link to the destination global. + return DGV; + } - void emitWarning(const Twine &Message) { - DstM->getContext().diagnose(LinkDiagnosticInfo(DS_Warning, Message)); - } + void computeTypeMapping(); - bool getComdatLeader(Module *M, StringRef ComdatName, - const GlobalVariable *&GVar); - bool computeResultingSelectionKind(StringRef ComdatName, - Comdat::SelectionKind Src, - Comdat::SelectionKind Dst, - Comdat::SelectionKind &Result, - bool &LinkFromSrc); - std::map> - ComdatsChosen; - bool getComdatResult(const Comdat *SrcC, Comdat::SelectionKind &SK, - bool &LinkFromSrc); - - /// getLinkageResult - This analyzes the two global values and determines - /// what the result will look like in the destination module. - bool getLinkageResult(GlobalValue *Dest, const GlobalValue *Src, - GlobalValue::LinkageTypes <, - GlobalValue::VisibilityTypes &Vis, - bool &LinkFromSrc); - - /// getLinkedToGlobal - Given a global in the source module, return the - /// global in the destination module that is being linked to, if any. - GlobalValue *getLinkedToGlobal(GlobalValue *SrcGV) { - // If the source has no name it can't link. If it has local linkage, - // there is no name match-up going on. - if (!SrcGV->hasName() || SrcGV->hasLocalLinkage()) - return nullptr; - - // Otherwise see if we have a match in the destination module's symtab. - GlobalValue *DGV = DstM->getNamedValue(SrcGV->getName()); - if (!DGV) return nullptr; - - // If we found a global with the same name in the dest module, but it has - // internal linkage, we are really not doing any linkage here. - if (DGV->hasLocalLinkage()) - return nullptr; - - // Otherwise, we do in fact link to the destination global. - return DGV; - } + void upgradeMismatchedGlobalArray(StringRef Name); + void upgradeMismatchedGlobals(); - void computeTypeMapping(); + bool linkAppendingVarProto(GlobalVariable *DstGV, + const GlobalVariable *SrcGV); - void upgradeMismatchedGlobalArray(StringRef Name); - void upgradeMismatchedGlobals(); + bool linkGlobalValueProto(GlobalValue *GV); + GlobalValue *linkGlobalVariableProto(const GlobalVariable *SGVar, + GlobalValue *DGV, bool LinkFromSrc); + GlobalValue *linkFunctionProto(const Function *SF, GlobalValue *DGV, + bool LinkFromSrc); + GlobalValue *linkGlobalAliasProto(const GlobalAlias *SGA, GlobalValue *DGV, + bool LinkFromSrc); - bool linkAppendingVarProto(GlobalVariable *DstGV, GlobalVariable *SrcGV); - bool linkGlobalProto(GlobalVariable *SrcGV); - bool linkFunctionProto(Function *SrcF); - bool linkAliasProto(GlobalAlias *SrcA); - bool linkModuleFlagsMetadata(); + bool linkModuleFlagsMetadata(); - void linkAppendingVarInit(const AppendingVarInfo &AVI); - void linkGlobalInits(); - void linkFunctionBody(Function *Dst, Function *Src); - void linkAliasBodies(); - void linkNamedMDNodes(); - }; + void linkAppendingVarInit(const AppendingVarInfo &AVI); + void linkGlobalInits(); + void linkFunctionBody(Function *Dst, Function *Src); + void linkAliasBodies(); + void linkNamedMDNodes(); +}; } -/// forceRenaming - The LLVM SymbolTable class autorenames globals that conflict -/// in the symbol table. This is good for all clients except for us. Go -/// through the trouble to force this back. +/// The LLVM SymbolTable class autorenames globals that conflict in the symbol +/// table. This is good for all clients except for us. Go through the trouble +/// to force this back. static void forceRenaming(GlobalValue *GV, StringRef Name) { // If the global doesn't force its name or if it already has the right name, // there is nothing for us to do. @@ -524,8 +528,8 @@ static void forceRenaming(GlobalValue *GV, StringRef Name) { } } -/// copyGVAttributes - copy additional attributes (those not needed to construct -/// a GlobalValue) from the SrcGV to the DestGV. +/// copy additional attributes (those not needed to construct a GlobalValue) +/// from the SrcGV to the DestGV. static void copyGVAttributes(GlobalValue *DestGV, const GlobalValue *SrcGV) { // Use the maximum alignment, rather than just copying the alignment of SrcGV. auto *DestGO = dyn_cast(DestGV); @@ -690,12 +694,15 @@ bool ModuleLinker::getComdatResult(const Comdat *SrcC, bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc, const GlobalValue &Dest, const GlobalValue &Src) { + // We always have to add Src if it has appending linkage. + if (Src.hasAppendingLinkage()) { + LinkFromSrc = true; + return false; + } + bool SrcIsDeclaration = Src.isDeclarationForLinker(); bool DestIsDeclaration = Dest.isDeclarationForLinker(); - // FIXME: Make datalayout mandatory and just use getDataLayout(). - DataLayout DL(Dest.getParent()); - if (SrcIsDeclaration) { // If Src is external or if both Src & Dest are external.. Just link the // external globals, we aren't adding anything. @@ -726,6 +733,9 @@ bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc, return false; } + // FIXME: Make datalayout mandatory and just use getDataLayout(). + DataLayout DL(Dest.getParent()); + uint64_t DestSize = DL.getTypeAllocSize(Dest.getType()->getElementType()); uint64_t SrcSize = DL.getTypeAllocSize(Src.getType()->getElementType()); LinkFromSrc = SrcSize > DestSize; @@ -759,62 +769,35 @@ bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc, "': symbol multiply defined!"); } -/// This analyzes the two global values and determines what the result will look -/// like in the destination module. In particular, it computes the resultant -/// linkage type and visibility, computes whether the global in the source -/// should be copied over to the destination (replacing the existing one), and -/// computes whether this linkage is an error or not. -bool ModuleLinker::getLinkageResult(GlobalValue *Dest, const GlobalValue *Src, - GlobalValue::LinkageTypes <, - GlobalValue::VisibilityTypes &Vis, - bool &LinkFromSrc) { - assert(Dest && "Must have two globals being queried"); - assert(!Src->hasLocalLinkage() && - "If Src has internal linkage, Dest shouldn't be set!"); - - if (shouldLinkFromSource(LinkFromSrc, *Dest, *Src)) - return true; - - if (LinkFromSrc) - LT = Src->getLinkage(); - else - LT = Dest->getLinkage(); - - // Compute the visibility. We follow the rules in the System V Application - // Binary Interface. - assert(!GlobalValue::isLocalLinkage(LT) && - "Symbols with local linkage should not be merged"); - Vis = isLessConstraining(Src->getVisibility(), Dest->getVisibility()) ? - Dest->getVisibility() : Src->getVisibility(); - return false; -} - -/// computeTypeMapping - Loop over all of the linked values to compute type -/// mappings. For example, if we link "extern Foo *x" and "Foo *x = NULL", then -/// we have two struct types 'Foo' but one got renamed when the module was -/// loaded into the same LLVMContext. +/// Loop over all of the linked values to compute type mappings. For example, +/// if we link "extern Foo *x" and "Foo *x = NULL", then we have two struct +/// types 'Foo' but one got renamed when the module was loaded into the same +/// LLVMContext. void ModuleLinker::computeTypeMapping() { - // Incorporate globals. - for (Module::global_iterator I = SrcM->global_begin(), - E = SrcM->global_end(); I != E; ++I) { - GlobalValue *DGV = getLinkedToGlobal(I); - if (!DGV) continue; + for (GlobalValue &SGV : SrcM->globals()) { + GlobalValue *DGV = getLinkedToGlobal(&SGV); + if (!DGV) + continue; - if (!DGV->hasAppendingLinkage() || !I->hasAppendingLinkage()) { - TypeMap.addTypeMapping(DGV->getType(), I->getType()); + if (!DGV->hasAppendingLinkage() || !SGV.hasAppendingLinkage()) { + TypeMap.addTypeMapping(DGV->getType(), SGV.getType()); continue; } // Unify the element type of appending arrays. ArrayType *DAT = cast(DGV->getType()->getElementType()); - ArrayType *SAT = cast(I->getType()->getElementType()); + ArrayType *SAT = cast(SGV.getType()->getElementType()); TypeMap.addTypeMapping(DAT->getElementType(), SAT->getElementType()); } - // Incorporate functions. - for (Module::iterator I = SrcM->begin(), E = SrcM->end(); I != E; ++I) { - if (GlobalValue *DGV = getLinkedToGlobal(I)) - TypeMap.addTypeMapping(DGV->getType(), I->getType()); + for (GlobalValue &SGV : *SrcM) { + if (GlobalValue *DGV = getLinkedToGlobal(&SGV)) + TypeMap.addTypeMapping(DGV->getType(), SGV.getType()); + } + + for (GlobalValue &SGV : SrcM->aliases()) { + if (GlobalValue *DGV = getLinkedToGlobal(&SGV)) + TypeMap.addTypeMapping(DGV->getType(), SGV.getType()); } // Incorporate types by name, scanning all the types in the source module. @@ -860,8 +843,6 @@ void ModuleLinker::computeTypeMapping() { TypeMap.addTypeMapping(DST, ST); } - // Don't bother incorporating aliases, they aren't generally typed well. - // Now that we have discovered all of the type equivalences, get a body for // any 'opaque' types in the dest module that are now resolved. TypeMap.linkDefinedTypeBodies(); @@ -944,10 +925,10 @@ void ModuleLinker::upgradeMismatchedGlobals() { upgradeMismatchedGlobalArray("llvm.global_dtors"); } -/// linkAppendingVarProto - If there were any appending global variables, link -/// them together now. Return true on error. +/// If there were any appending global variables, link them together now. +/// Return true on error. bool ModuleLinker::linkAppendingVarProto(GlobalVariable *DstGV, - GlobalVariable *SrcGV) { + const GlobalVariable *SrcGV) { if (!SrcGV->hasAppendingLinkage() || !DstGV->hasAppendingLinkage()) return emitError("Linking globals named '" + SrcGV->getName() + @@ -1012,261 +993,167 @@ bool ModuleLinker::linkAppendingVarProto(GlobalVariable *DstGV, return false; } -/// linkGlobalProto - Loop through the global variables in the src module and -/// merge them into the dest module. -bool ModuleLinker::linkGlobalProto(GlobalVariable *SGV) { +bool ModuleLinker::linkGlobalValueProto(GlobalValue *SGV) { GlobalValue *DGV = getLinkedToGlobal(SGV); - llvm::Optional NewVisibility; + + // Handle the ultra special appending linkage case first. + if (DGV && DGV->hasAppendingLinkage()) + return linkAppendingVarProto(cast(DGV), + cast(SGV)); + + bool LinkFromSrc = true; + Comdat *C = nullptr; + GlobalValue::VisibilityTypes Visibility = SGV->getVisibility(); bool HasUnnamedAddr = SGV->hasUnnamedAddr(); - unsigned Alignment = SGV->getAlignment(); - bool LinkFromSrc = false; - Comdat *DC = nullptr; if (const Comdat *SC = SGV->getComdat()) { Comdat::SelectionKind SK; std::tie(SK, LinkFromSrc) = ComdatsChosen[SC]; - DC = DstM->getOrInsertComdat(SC->getName()); - DC->setSelectionKind(SK); + C = DstM->getOrInsertComdat(SC->getName()); + C->setSelectionKind(SK); + } else if (DGV) { + if (shouldLinkFromSource(LinkFromSrc, *DGV, *SGV)) + return true; } - if (DGV) { - if (!DC) { - // Concatenation of appending linkage variables is magic and handled later. - if (DGV->hasAppendingLinkage() || SGV->hasAppendingLinkage()) - return linkAppendingVarProto(cast(DGV), SGV); - - // Determine whether linkage of these two globals follows the source - // module's definition or the destination module's definition. - GlobalValue::LinkageTypes NewLinkage = GlobalValue::InternalLinkage; - GlobalValue::VisibilityTypes NV; - if (getLinkageResult(DGV, SGV, NewLinkage, NV, LinkFromSrc)) - return true; - NewVisibility = NV; - HasUnnamedAddr = HasUnnamedAddr && DGV->hasUnnamedAddr(); - if (DGV->hasCommonLinkage() && SGV->hasCommonLinkage()) - Alignment = std::max(Alignment, DGV->getAlignment()); - else if (!LinkFromSrc) - Alignment = DGV->getAlignment(); - - // If we're not linking from the source, then keep the definition that we - // have. - if (!LinkFromSrc) { - // Special case for const propagation. - if (GlobalVariable *DGVar = dyn_cast(DGV)) { - DGVar->setAlignment(Alignment); - - if (DGVar->isDeclaration() && SGV->isConstant() && - !DGVar->isConstant()) - DGVar->setConstant(true); - } - - // Set calculated linkage, visibility and unnamed_addr. - DGV->setLinkage(NewLinkage); - DGV->setVisibility(*NewVisibility); - DGV->setUnnamedAddr(HasUnnamedAddr); - } - } + if (!LinkFromSrc) { + // Track the source global so that we don't attempt to copy it over when + // processing global initializers. + DoNotLinkFromSource.insert(SGV); - if (!LinkFromSrc) { + if (DGV) // Make sure to remember this mapping. - ValueMap[SGV] = ConstantExpr::getBitCast(DGV,TypeMap.get(SGV->getType())); - - // Track the source global so that we don't attempt to copy it over when - // processing global initializers. - DoNotLinkFromSource.insert(SGV); + ValueMap[SGV] = + ConstantExpr::getBitCast(DGV, TypeMap.get(SGV->getType())); + } - return false; - } + if (DGV) { + Visibility = isLessConstraining(Visibility, DGV->getVisibility()) + ? DGV->getVisibility() + : Visibility; + HasUnnamedAddr = HasUnnamedAddr && DGV->hasUnnamedAddr(); } - // If the Comdat this variable was inside of wasn't selected, skip it. - if (DC && !DGV && !LinkFromSrc) { - DoNotLinkFromSource.insert(SGV); + if (!LinkFromSrc && !DGV) return false; + + GlobalValue *NewGV; + if (auto *SGVar = dyn_cast(SGV)) { + NewGV = linkGlobalVariableProto(SGVar, DGV, LinkFromSrc); + if (!NewGV) + return true; + } else if (auto *SF = dyn_cast(SGV)) { + NewGV = linkFunctionProto(SF, DGV, LinkFromSrc); + } else { + NewGV = linkGlobalAliasProto(cast(SGV), DGV, LinkFromSrc); } - // No linking to be performed or linking from the source: simply create an - // 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(SGV->getType()->getElementType()), - SGV->isConstant(), SGV->getLinkage(), /*init*/nullptr, - SGV->getName(), /*insertbefore*/nullptr, - SGV->getThreadLocalMode(), - SGV->getType()->getAddressSpace()); - // Propagate alignment, visibility and section info. - copyGVAttributes(NewDGV, SGV); - NewDGV->setAlignment(Alignment); - if (NewVisibility) - NewDGV->setVisibility(*NewVisibility); - NewDGV->setUnnamedAddr(HasUnnamedAddr); + if (NewGV) { + if (NewGV != DGV) + copyGVAttributes(NewGV, SGV); - if (DC) - NewDGV->setComdat(DC); + NewGV->setUnnamedAddr(HasUnnamedAddr); + NewGV->setVisibility(Visibility); - if (DGV) { - DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewDGV, DGV->getType())); - DGV->eraseFromParent(); + if (auto *NewGO = dyn_cast(NewGV)) { + if (C) + NewGO->setComdat(C); + } + + // Make sure to remember this mapping. + if (NewGV != DGV) { + if (DGV) { + DGV->replaceAllUsesWith( + ConstantExpr::getBitCast(NewGV, DGV->getType())); + DGV->eraseFromParent(); + } + ValueMap[SGV] = NewGV; + } } - // Make sure to remember this mapping. - ValueMap[SGV] = NewDGV; return false; } -/// linkFunctionProto - Link the function in the source module into the -/// destination module if needed, setting up mapping information. -bool ModuleLinker::linkFunctionProto(Function *SF) { - GlobalValue *DGV = getLinkedToGlobal(SF); - llvm::Optional NewVisibility; - bool HasUnnamedAddr = SF->hasUnnamedAddr(); +/// Loop through the global variables in the src module and merge them into the +/// dest module. +GlobalValue *ModuleLinker::linkGlobalVariableProto(const GlobalVariable *SGVar, + GlobalValue *DGV, + bool LinkFromSrc) { + unsigned Alignment = 0; + bool ClearConstant = false; - bool LinkFromSrc = false; - Comdat *DC = nullptr; - if (const Comdat *SC = SF->getComdat()) { - Comdat::SelectionKind SK; - std::tie(SK, LinkFromSrc) = ComdatsChosen[SC]; - DC = DstM->getOrInsertComdat(SC->getName()); - DC->setSelectionKind(SK); + if (DGV) { + if (DGV->hasCommonLinkage() && SGVar->hasCommonLinkage()) + Alignment = std::max(SGVar->getAlignment(), DGV->getAlignment()); + + auto *DGVar = dyn_cast(DGV); + if (!SGVar->isConstant() || (DGVar && !DGVar->isConstant())) + ClearConstant = true; } - if (DGV) { - if (!DC) { - GlobalValue::LinkageTypes NewLinkage = GlobalValue::InternalLinkage; - GlobalValue::VisibilityTypes NV; - if (getLinkageResult(DGV, SF, NewLinkage, NV, LinkFromSrc)) - return true; - NewVisibility = NV; - HasUnnamedAddr = HasUnnamedAddr && DGV->hasUnnamedAddr(); - - if (!LinkFromSrc) { - // Set calculated linkage - DGV->setLinkage(NewLinkage); - DGV->setVisibility(*NewVisibility); - DGV->setUnnamedAddr(HasUnnamedAddr); - } + if (!LinkFromSrc) { + if (auto *NewGVar = dyn_cast(DGV)) { + if (Alignment) + NewGVar->setAlignment(Alignment); + if (NewGVar->isDeclaration() && ClearConstant) + NewGVar->setConstant(false); } + return DGV; + } - if (!LinkFromSrc) { - // Make sure to remember this mapping. - ValueMap[SF] = ConstantExpr::getBitCast(DGV, TypeMap.get(SF->getType())); + // No linking to be performed or linking from the source: simply create an + // 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()), + SGVar->isConstant(), SGVar->getLinkage(), /*init*/ nullptr, + SGVar->getName(), /*insertbefore*/ nullptr, SGVar->getThreadLocalMode(), + SGVar->getType()->getAddressSpace()); - // Track the function from the source module so we don't attempt to remap - // it. - DoNotLinkFromSource.insert(SF); + if (Alignment) + NewDGV->setAlignment(Alignment); - return false; - } - } + return NewDGV; +} + +/// Link the function in the source module into the destination module if +/// needed, setting up mapping information. +GlobalValue *ModuleLinker::linkFunctionProto(const Function *SF, + GlobalValue *DGV, + bool LinkFromSrc) { + if (!LinkFromSrc) + return DGV; // If the function is to be lazily linked, don't create it just yet. // The ValueMaterializerTy will deal with creating it if it's used. if (!DGV && (SF->hasLocalLinkage() || SF->hasLinkOnceLinkage() || SF->hasAvailableExternallyLinkage())) { DoNotLinkFromSource.insert(SF); - return false; - } - - // If the Comdat this function was inside of wasn't selected, skip it. - if (DC && !DGV && !LinkFromSrc) { - DoNotLinkFromSource.insert(SF); - return false; + return nullptr; } // If there is no linkage to be performed or we are linking from the source, // bring SF over. - Function *NewDF = Function::Create(TypeMap.get(SF->getFunctionType()), - SF->getLinkage(), SF->getName(), DstM); - copyGVAttributes(NewDF, SF); - if (NewVisibility) - NewDF->setVisibility(*NewVisibility); - NewDF->setUnnamedAddr(HasUnnamedAddr); - - if (DC) - NewDF->setComdat(DC); - - if (DGV) { - // Any uses of DF need to change to NewDF, with cast. - DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewDF, DGV->getType())); - DGV->eraseFromParent(); - } - - ValueMap[SF] = NewDF; - return false; + return Function::Create(TypeMap.get(SF->getFunctionType()), SF->getLinkage(), + SF->getName(), DstM); } -/// LinkAliasProto - Set up prototypes for any aliases that come over from the -/// source module. -bool ModuleLinker::linkAliasProto(GlobalAlias *SGA) { - GlobalValue *DGV = getLinkedToGlobal(SGA); - llvm::Optional NewVisibility; - bool HasUnnamedAddr = SGA->hasUnnamedAddr(); - - bool LinkFromSrc = false; - Comdat *DC = nullptr; - if (const Comdat *SC = SGA->getComdat()) { - Comdat::SelectionKind SK; - std::tie(SK, LinkFromSrc) = ComdatsChosen[SC]; - DC = DstM->getOrInsertComdat(SC->getName()); - DC->setSelectionKind(SK); - } - - if (DGV) { - if (!DC) { - GlobalValue::LinkageTypes NewLinkage = GlobalValue::InternalLinkage; - GlobalValue::VisibilityTypes NV; - if (getLinkageResult(DGV, SGA, NewLinkage, NV, LinkFromSrc)) - return true; - NewVisibility = NV; - HasUnnamedAddr = HasUnnamedAddr && DGV->hasUnnamedAddr(); - - if (!LinkFromSrc) { - // Set calculated linkage. - DGV->setLinkage(NewLinkage); - DGV->setVisibility(*NewVisibility); - DGV->setUnnamedAddr(HasUnnamedAddr); - } - } - - if (!LinkFromSrc) { - // Make sure to remember this mapping. - ValueMap[SGA] = ConstantExpr::getBitCast(DGV,TypeMap.get(SGA->getType())); - - // Track the alias from the source module so we don't attempt to remap it. - DoNotLinkFromSource.insert(SGA); - - return false; - } - } - - // If the Comdat this alias was inside of wasn't selected, skip it. - if (DC && !DGV && !LinkFromSrc) { - DoNotLinkFromSource.insert(SGA); - return false; - } +/// Set up prototypes for any aliases that come over from the source module. +GlobalValue *ModuleLinker::linkGlobalAliasProto(const GlobalAlias *SGA, + GlobalValue *DGV, + bool LinkFromSrc) { + if (!LinkFromSrc) + return DGV; // If there is no linkage to be performed or we're linking from the source, // bring over SGA. auto *PTy = cast(TypeMap.get(SGA->getType())); - auto *NewDA = - GlobalAlias::create(PTy->getElementType(), PTy->getAddressSpace(), - SGA->getLinkage(), SGA->getName(), DstM); - copyGVAttributes(NewDA, SGA); - if (NewVisibility) - NewDA->setVisibility(*NewVisibility); - NewDA->setUnnamedAddr(HasUnnamedAddr); - - if (DGV) { - // Any uses of DGV need to change to NewDA, with cast. - DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewDA, DGV->getType())); - DGV->eraseFromParent(); - } - - ValueMap[SGA] = NewDA; - return false; + return GlobalAlias::create(PTy->getElementType(), PTy->getAddressSpace(), + SGA->getLinkage(), SGA->getName(), DstM); } -static void getArrayElements(Constant *C, SmallVectorImpl &Dest) { +static void getArrayElements(const Constant *C, + SmallVectorImpl &Dest) { unsigned NumElements = cast(C->getType())->getNumElements(); for (unsigned i = 0; i != NumElements; ++i) @@ -1305,8 +1192,8 @@ void ModuleLinker::linkAppendingVarInit(const AppendingVarInfo &AVI) { AVI.NewGV->setInitializer(ConstantArray::get(NewType, DstElements)); } -/// linkGlobalInits - Update the initializers in the Dest module now that all -/// globals that may be referenced are in Dest. +/// Update the initializers in the Dest module now that all globals that may be +/// referenced are in Dest. void ModuleLinker::linkGlobalInits() { // Loop over all of the globals in the src module, mapping them over as we go for (Module::const_global_iterator I = SrcM->global_begin(), @@ -1323,9 +1210,9 @@ void ModuleLinker::linkGlobalInits() { } } -/// linkFunctionBody - 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. +/// 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. void ModuleLinker::linkFunctionBody(Function *Dst, Function *Src) { assert(Src && Dst && Dst->isDeclaration() && !Src->isDeclaration()); @@ -1339,25 +1226,17 @@ void ModuleLinker::linkFunctionBody(Function *Dst, Function *Src) { ValueMap[I] = DI; } - if (Mode == Linker::DestroySource) { - // Splice the body of the source function into the dest function. - 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 (Function::iterator BB = Dst->begin(), BE = Dst->end(); BB != BE; ++BB) - for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) - RemapInstruction(I, ValueMap, RF_IgnoreMissingEntries, - &TypeMap, &ValMaterializer); + // Splice the body of the source function into the dest function. + Dst->getBasicBlockList().splice(Dst->end(), Src->getBasicBlockList()); - } else { - // Clone the body of the function into the dest function. - SmallVector Returns; // Ignore returns. - CloneFunctionInto(Dst, Src, ValueMap, false, Returns, "", nullptr, - &TypeMap, &ValMaterializer); - } + // 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 (Function::iterator BB = Dst->begin(), BE = Dst->end(); BB != BE; ++BB) + for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) + RemapInstruction(I, ValueMap, RF_IgnoreMissingEntries, &TypeMap, + &ValMaterializer); // There is no need to map the arguments anymore. for (Function::arg_iterator I = Src->arg_begin(), E = Src->arg_end(); @@ -1366,7 +1245,7 @@ void ModuleLinker::linkFunctionBody(Function *Dst, Function *Src) { } -/// linkAliasBodies - Insert all of the aliases in Src into the Dest module. +/// Insert all of the aliases in Src into the Dest module. void ModuleLinker::linkAliasBodies() { for (Module::alias_iterator I = SrcM->alias_begin(), E = SrcM->alias_end(); I != E; ++I) { @@ -1381,8 +1260,7 @@ void ModuleLinker::linkAliasBodies() { } } -/// linkNamedMDNodes - Insert all of the named MDNodes in Src into the Dest -/// module. +/// Insert all of the named MDNodes in Src into the Dest module. void ModuleLinker::linkNamedMDNodes() { const NamedMDNode *SrcModFlags = SrcM->getModuleFlagsMetadata(); for (Module::const_named_metadata_iterator I = SrcM->named_metadata_begin(), @@ -1397,8 +1275,7 @@ void ModuleLinker::linkNamedMDNodes() { } } -/// linkModuleFlagsMetadata - Merge the linker flags in Src into the Dest -/// module. +/// Merge the linker flags in Src into the Dest module. bool ModuleLinker::linkModuleFlagsMetadata() { // If the source module has no module flags, we are done. const NamedMDNode *SrcModFlags = SrcM->getModuleFlagsMetadata(); @@ -1594,7 +1471,7 @@ bool ModuleLinker::run() { computeTypeMapping(); ComdatsChosen.clear(); - for (const StringMapEntry &SMEC : SrcM->getComdatSymbolTable()) { + for (const auto &SMEC : SrcM->getComdatSymbolTable()) { const Comdat &C = SMEC.getValue(); if (ComdatsChosen.count(&C)) continue; @@ -1612,7 +1489,7 @@ bool ModuleLinker::run() { // initializers (which could refer to functions not yet mapped over). for (Module::global_iterator I = SrcM->global_begin(), E = SrcM->global_end(); I != E; ++I) - if (linkGlobalProto(I)) + if (linkGlobalValueProto(I)) return true; // Link the functions together between the two modules, without doing function @@ -1621,13 +1498,13 @@ bool ModuleLinker::run() { // all of the global values that may be referenced are available in our // ValueMap. for (Module::iterator I = SrcM->begin(), E = SrcM->end(); I != E; ++I) - if (linkFunctionProto(I)) + if (linkGlobalValueProto(I)) return true; // If there were any aliases, link them now. for (Module::alias_iterator I = SrcM->alias_begin(), E = SrcM->alias_end(); I != E; ++I) - if (linkAliasProto(I)) + if (linkGlobalValueProto(I)) return true; for (unsigned i = 0, e = AppendingVars.size(); i != e; ++i) @@ -1647,10 +1524,8 @@ bool ModuleLinker::run() { } // Materialize if needed. - if (SF->isMaterializable()) { - if (std::error_code EC = SF->materialize()) - return emitError(EC.message()); - } + if (std::error_code EC = SF->materialize()) + return emitError(EC.message()); // Skip if no body (function is external). if (SF->isDeclaration()) @@ -1698,10 +1573,8 @@ bool ModuleLinker::run() { } // Materialize if needed. - if (SF->isMaterializable()) { - if (std::error_code EC = SF->materialize()) - return emitError(EC.message()); - } + if (std::error_code EC = SF->materialize()) + return emitError(EC.message()); // Skip if no body (function is external). if (SF->isDeclaration()) @@ -1729,12 +1602,25 @@ bool ModuleLinker::run() { return false; } -Linker::Linker(Module *M) : Composite(M) { +void Linker::init(Module *M, DiagnosticHandlerFunction DiagnosticHandler) { + this->Composite = M; + this->DiagnosticHandler = DiagnosticHandler; + TypeFinder StructTypes; StructTypes.run(*M, true); IdentifiedStructTypes.insert(StructTypes.begin(), StructTypes.end()); } +Linker::Linker(Module *M, DiagnosticHandlerFunction DiagnosticHandler) { + init(M, DiagnosticHandler); +} + +Linker::Linker(Module *M) { + init(M, [this](const DiagnosticInfo &DI) { + Composite->getContext().diagnose(DI); + }); +} + Linker::~Linker() { } @@ -1743,8 +1629,9 @@ void Linker::deleteModule() { Composite = nullptr; } -bool Linker::linkInModule(Module *Src, unsigned Mode) { - ModuleLinker TheLinker(Composite, IdentifiedStructTypes, Src, Mode); +bool Linker::linkInModule(Module *Src) { + ModuleLinker TheLinker(Composite, IdentifiedStructTypes, Src, + DiagnosticHandler); return TheLinker.run(); } @@ -1752,14 +1639,20 @@ bool Linker::linkInModule(Module *Src, unsigned Mode) { // LinkModules entrypoint. //===----------------------------------------------------------------------===// -/// LinkModules - This function links two modules together, with the resulting -/// Dest module modified to be the composite of the two input modules. If an -/// error occurs, true is returned and ErrorMsg (if not null) is set to indicate -/// the problem. Upon failure, the Dest module could be in a modified state, -/// and shouldn't be relied on to be consistent. -bool Linker::LinkModules(Module *Dest, Module *Src, unsigned Mode) { +/// This function links two modules together, with the resulting Dest module +/// modified to be the composite of the two input modules. If an error occurs, +/// true is returned and ErrorMsg (if not null) is set to indicate the problem. +/// Upon failure, the Dest module could be in a modified state, and shouldn't be +/// relied on to be consistent. +bool Linker::LinkModules(Module *Dest, Module *Src, + DiagnosticHandlerFunction DiagnosticHandler) { + Linker L(Dest, DiagnosticHandler); + return L.linkInModule(Src); +} + +bool Linker::LinkModules(Module *Dest, Module *Src) { Linker L(Dest); - return L.linkInModule(Src, Mode); + return L.linkInModule(Src); } //===----------------------------------------------------------------------===// @@ -1768,6 +1661,15 @@ bool Linker::LinkModules(Module *Dest, Module *Src, unsigned Mode) { LLVMBool LLVMLinkModules(LLVMModuleRef Dest, LLVMModuleRef Src, LLVMLinkerMode Mode, char **OutMessages) { - LLVMBool Result = Linker::LinkModules(unwrap(Dest), unwrap(Src), Mode); + Module *D = unwrap(Dest); + std::string Message; + raw_string_ostream Stream(Message); + DiagnosticPrinterRawOStream DP(Stream); + + LLVMBool Result = Linker::LinkModules( + D, unwrap(Src), [&](const DiagnosticInfo &DI) { DI.print(DP); }); + + if (OutMessages && Result) + *OutMessages = strdup(Message.c_str()); return Result; }