Index: include/llvm/Linker/IRMover.h =================================================================== --- /dev/null +++ include/llvm/Linker/IRMover.h @@ -0,0 +1,78 @@ +//===- IRMover.h ------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LINKER_IRMOVER_H +#define LLVM_LINKER_IRMOVER_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/IR/DiagnosticInfo.h" + +namespace llvm { +class GlobalValue; +class Module; +class StructType; +class Type; + +class IRMover { + struct StructTypeKeyInfo { + struct KeyTy { + ArrayRef ETypes; + bool IsPacked; + KeyTy(ArrayRef E, bool P); + KeyTy(const StructType *ST); + bool operator==(const KeyTy &that) const; + bool operator!=(const KeyTy &that) const; + }; + static StructType *getEmptyKey(); + static StructType *getTombstoneKey(); + static unsigned getHashValue(const KeyTy &Key); + static unsigned getHashValue(const StructType *ST); + static bool isEqual(const KeyTy &LHS, const StructType *RHS); + static bool isEqual(const StructType *LHS, const StructType *RHS); + }; + +public: + class IdentifiedStructTypeSet { + // The set of opaque types is the composite module. + DenseSet OpaqueStructTypes; + + // The set of identified but non opaque structures in the composite module. + DenseSet NonOpaqueStructTypes; + + public: + void addNonOpaque(StructType *Ty); + void switchToNonOpaque(StructType *Ty); + void addOpaque(StructType *Ty); + StructType *findNonOpaque(ArrayRef ETypes, bool IsPacked); + bool hasType(StructType *Ty); + }; + + IRMover(Module &M, DiagnosticHandlerFunction DiagnosticHandler); + + typedef std::function ValueAdder; + /// Move in the provide values. The source is destroyed. + /// Returns true on error. + bool move(Module &Src, ArrayRef ValuesToLink, + std::function AddLazyFor); + Module &getModule() { return Composite; } + + DiagnosticHandlerFunction getDiagnosticHandler() const { + return DiagnosticHandler; + } + +private: + Module &Composite; + IdentifiedStructTypeSet IdentifiedStructTypes; + DiagnosticHandlerFunction DiagnosticHandler; +}; + +} // End llvm namespace + +#endif Index: include/llvm/Linker/Linker.h =================================================================== --- include/llvm/Linker/Linker.h +++ include/llvm/Linker/Linker.h @@ -10,11 +10,9 @@ #ifndef LLVM_LINKER_LINKER_H #define LLVM_LINKER_LINKER_H -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/DenseSet.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/FunctionInfo.h" +#include "llvm/Linker/IRMover.h" namespace llvm { class Module; @@ -26,41 +24,9 @@ /// module since it is assumed that the user of this class will want to do /// something with it after the linking. class Linker { -public: - struct StructTypeKeyInfo { - struct KeyTy { - ArrayRef ETypes; - bool IsPacked; - KeyTy(ArrayRef E, bool P); - KeyTy(const StructType *ST); - bool operator==(const KeyTy &that) const; - bool operator!=(const KeyTy &that) const; - }; - static StructType *getEmptyKey(); - static StructType *getTombstoneKey(); - static unsigned getHashValue(const KeyTy &Key); - static unsigned getHashValue(const StructType *ST); - static bool isEqual(const KeyTy &LHS, const StructType *RHS); - static bool isEqual(const StructType *LHS, const StructType *RHS); - }; - - typedef DenseSet NonOpaqueStructTypeSet; - typedef DenseSet OpaqueStructTypeSet; - - struct IdentifiedStructTypeSet { - // The set of opaque types is the composite module. - OpaqueStructTypeSet OpaqueStructTypes; - - // The set of identified but non opaque structures in the composite module. - NonOpaqueStructTypeSet NonOpaqueStructTypes; - - void addNonOpaque(StructType *Ty); - void switchToNonOpaque(StructType *Ty); - void addOpaque(StructType *Ty); - StructType *findNonOpaque(ArrayRef ETypes, bool IsPacked); - bool hasType(StructType *Ty); - }; + IRMover Mover; +public: enum Flags { None = 0, OverrideFromSrc = (1 << 0), @@ -88,15 +54,8 @@ unsigned Flags = Flags::None); DiagnosticHandlerFunction getDiagnosticHandler() const { - return DiagnosticHandler; + return Mover.getDiagnosticHandler(); } - -private: - Module &Composite; - - IdentifiedStructTypeSet IdentifiedStructTypes; - - DiagnosticHandlerFunction DiagnosticHandler; }; /// Create a new module with exported local functions renamed and promoted Index: lib/Linker/CMakeLists.txt =================================================================== --- lib/Linker/CMakeLists.txt +++ lib/Linker/CMakeLists.txt @@ -1,4 +1,5 @@ add_llvm_library(LLVMLinker + IRMover.cpp LinkModules.cpp ADDITIONAL_HEADER_DIRS Index: lib/Linker/IRMover.cpp =================================================================== --- /dev/null +++ lib/Linker/IRMover.cpp @@ -0,0 +1,1400 @@ +//===- lib/Linker/IRMover.cpp ---------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Linker/IRMover.h" +#include "LinkDiagnosticInfo.h" +#include "llvm/ADT/SetVector.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/Triple.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DiagnosticPrinter.h" +#include "llvm/IR/TypeFinder.h" +#include "llvm/Transforms/Utils/Cloning.h" +using namespace llvm; + +//===----------------------------------------------------------------------===// +// TypeMap implementation. +//===----------------------------------------------------------------------===// + +namespace { +class TypeMapTy : public ValueMapTypeRemapper { + /// This is a mapping from a source type to a destination type to use. + DenseMap MappedTypes; + + /// 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; + + SmallVector SpeculativeDstOpaqueTypes; + + /// 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; + + /// This is the set of opaque types in the destination modules who are + /// getting a body from the source module. + SmallPtrSet DstResolvedOpaqueTypes; + +public: + TypeMapTy(IRMover::IdentifiedStructTypeSet &DstStructTypesSet) + : DstStructTypesSet(DstStructTypesSet) {} + + IRMover::IdentifiedStructTypeSet &DstStructTypesSet; + /// 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); + + /// Produce a body for an opaque type in the dest module from a type + /// definition in the source module. + void linkDefinedTypeBodies(); + + /// Return the mapped type to use for the specified input type from the + /// source module. + Type *get(Type *SrcTy); + Type *get(Type *SrcTy, SmallPtrSet &Visited); + + void finishType(StructType *DTy, StructType *STy, ArrayRef ETypes); + + FunctionType *get(FunctionType *T) { + return cast(get((Type *)T)); + } + +private: + Type *remapType(Type *SrcTy) override { return get(SrcTy); } + + bool areTypesIsomorphic(Type *DstTy, Type *SrcTy); +}; +} + +void TypeMapTy::addTypeMapping(Type *DstTy, Type *SrcTy) { + assert(SpeculativeTypes.empty()); + assert(SpeculativeDstOpaqueTypes.empty()); + + // 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 (Type *Ty : SpeculativeTypes) + MappedTypes.erase(Ty); + + SrcDefinitionsToResolve.resize(SrcDefinitionsToResolve.size() - + SpeculativeDstOpaqueTypes.size()); + for (StructType *Ty : SpeculativeDstOpaqueTypes) + DstResolvedOpaqueTypes.erase(Ty); + } else { + for (Type *Ty : SpeculativeTypes) + if (auto *STy = dyn_cast(Ty)) + if (STy->hasName()) + STy->setName(""); + } + SpeculativeTypes.clear(); + SpeculativeDstOpaqueTypes.clear(); +} + +/// 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; + + // If we have an entry in the MappedTypes table, then we have our answer. + Type *&Entry = MappedTypes[SrcTy]; + if (Entry) + return Entry == DstTy; + + // Two identical types are clearly isomorphic. Remember this + // non-speculatively. + if (DstTy == SrcTy) { + Entry = DstTy; + return true; + } + + // Okay, we have two types with identical kinds that we haven't seen before. + + // If this is an opaque struct type, special case it. + if (StructType *SSTy = dyn_cast(SrcTy)) { + // Mapping an opaque type to any struct, just keep the dest struct. + if (SSTy->isOpaque()) { + Entry = DstTy; + SpeculativeTypes.push_back(SrcTy); + return true; + } + + // 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. 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)).second) + return false; + SrcDefinitionsToResolve.push_back(SSTy); + SpeculativeTypes.push_back(SrcTy); + SpeculativeDstOpaqueTypes.push_back(cast(DstTy)); + Entry = DstTy; + return true; + } + } + + // If the number of subtypes disagree between the two types, then we fail. + if (SrcTy->getNumContainedTypes() != DstTy->getNumContainedTypes()) + return false; + + // Fail if any of the extra properties (e.g. array size) of the type disagree. + if (isa(DstTy)) + return false; // bitwidth disagrees. + if (PointerType *PT = dyn_cast(DstTy)) { + if (PT->getAddressSpace() != cast(SrcTy)->getAddressSpace()) + return false; + + } else if (FunctionType *FT = dyn_cast(DstTy)) { + if (FT->isVarArg() != cast(SrcTy)->isVarArg()) + return false; + } else if (StructType *DSTy = dyn_cast(DstTy)) { + StructType *SSTy = cast(SrcTy); + if (DSTy->isLiteral() != SSTy->isLiteral() || + DSTy->isPacked() != SSTy->isPacked()) + return false; + } else if (ArrayType *DATy = dyn_cast(DstTy)) { + if (DATy->getNumElements() != cast(SrcTy)->getNumElements()) + return false; + } else if (VectorType *DVTy = dyn_cast(DstTy)) { + if (DVTy->getNumElements() != cast(SrcTy)->getNumElements()) + return false; + } + + // Otherwise, we speculate that these two types will line up and recursively + // check the subelements. + Entry = DstTy; + SpeculativeTypes.push_back(SrcTy); + + for (unsigned I = 0, E = SrcTy->getNumContainedTypes(); I != E; ++I) + if (!areTypesIsomorphic(DstTy->getContainedType(I), + SrcTy->getContainedType(I))) + return false; + + // If everything seems to have lined up, then everything is great. + return true; +} + +void TypeMapTy::linkDefinedTypeBodies() { + SmallVector Elements; + for (StructType *SrcSTy : SrcDefinitionsToResolve) { + StructType *DstSTy = cast(MappedTypes[SrcSTy]); + assert(DstSTy->isOpaque()); + + // Map the body of the source type over to a new body for the dest type. + Elements.resize(SrcSTy->getNumElements()); + for (unsigned I = 0, E = Elements.size(); I != E; ++I) + Elements[I] = get(SrcSTy->getElementType(I)); + + DstSTy->setBody(Elements, SrcSTy->isPacked()); + DstStructTypesSet.switchToNonOpaque(DstSTy); + } + SrcDefinitionsToResolve.clear(); + DstResolvedOpaqueTypes.clear(); +} + +void TypeMapTy::finishType(StructType *DTy, StructType *STy, + ArrayRef ETypes) { + DTy->setBody(ETypes, STy->isPacked()); + + // Steal STy's name. + if (STy->hasName()) { + SmallString<16> TmpName = STy->getName(); + STy->setName(""); + DTy->setName(TmpName); + } + + DstStructTypesSet.addNonOpaque(DTy); +} + +Type *TypeMapTy::get(Type *Ty) { + SmallPtrSet Visited; + return get(Ty, Visited); +} + +Type *TypeMapTy::get(Type *Ty, SmallPtrSet &Visited) { + // If we already have an entry for this type, return it. + Type **Entry = &MappedTypes[Ty]; + if (*Entry) + return *Entry; + + // These are types that LLVM itself will unique. + bool IsUniqued = !isa(Ty) || cast(Ty)->isLiteral(); + +#ifndef NDEBUG + if (!IsUniqued) { + for (auto &Pair : MappedTypes) { + assert(!(Pair.first != Ty && Pair.second == Ty) && + "mapping to a source type"); + } + } +#endif + + if (!IsUniqued && !Visited.insert(cast(Ty)).second) { + StructType *DTy = StructType::create(Ty->getContext()); + return *Entry = DTy; + } + + // If this is not a recursive type, then just map all of the elements and + // then rebuild the type from inside out. + SmallVector ElementTypes; + + // If there are no element types to map, then the type is itself. This is + // true for the anonymous {} struct, things like 'float', integers, etc. + if (Ty->getNumContainedTypes() == 0 && IsUniqued) + return *Entry = Ty; + + // Remap all of the elements, keeping track of whether any of them change. + bool AnyChange = false; + ElementTypes.resize(Ty->getNumContainedTypes()); + for (unsigned I = 0, E = Ty->getNumContainedTypes(); I != E; ++I) { + ElementTypes[I] = get(Ty->getContainedType(I), Visited); + AnyChange |= ElementTypes[I] != Ty->getContainedType(I); + } + + // If we found our type while recursively processing stuff, just use it. + Entry = &MappedTypes[Ty]; + if (*Entry) { + if (auto *DTy = dyn_cast(*Entry)) { + if (DTy->isOpaque()) { + auto *STy = cast(Ty); + finishType(DTy, STy, ElementTypes); + } + } + return *Entry; + } + + // If all of the element types mapped directly over and the type is not + // a nomed struct, then the type is usable as-is. + if (!AnyChange && IsUniqued) + return *Entry = Ty; + + // Otherwise, rebuild a modified type. + switch (Ty->getTypeID()) { + default: + llvm_unreachable("unknown derived type to remap"); + case Type::ArrayTyID: + return *Entry = ArrayType::get(ElementTypes[0], + cast(Ty)->getNumElements()); + case Type::VectorTyID: + return *Entry = VectorType::get(ElementTypes[0], + cast(Ty)->getNumElements()); + case Type::PointerTyID: + return *Entry = PointerType::get(ElementTypes[0], + cast(Ty)->getAddressSpace()); + case Type::FunctionTyID: + return *Entry = FunctionType::get(ElementTypes[0], + makeArrayRef(ElementTypes).slice(1), + cast(Ty)->isVarArg()); + case Type::StructTyID: { + auto *STy = cast(Ty); + bool IsPacked = STy->isPacked(); + if (IsUniqued) + return *Entry = StructType::get(Ty->getContext(), ElementTypes, IsPacked); + + // If the type is opaque, we can just use it directly. + if (STy->isOpaque()) { + DstStructTypesSet.addOpaque(STy); + return *Entry = Ty; + } + + if (StructType *OldT = + DstStructTypesSet.findNonOpaque(ElementTypes, IsPacked)) { + STy->setName(""); + return *Entry = OldT; + } + + if (!AnyChange) { + DstStructTypesSet.addNonOpaque(STy); + return *Entry = Ty; + } + + StructType *DTy = StructType::create(Ty->getContext()); + finishType(DTy, STy, ElementTypes); + return *Entry = DTy; + } + } +} + +LinkDiagnosticInfo::LinkDiagnosticInfo(DiagnosticSeverity Severity, + const Twine &Msg) + : DiagnosticInfo(DK_Linker, Severity), Msg(Msg) {} +void LinkDiagnosticInfo::print(DiagnosticPrinter &DP) const { DP << Msg; } + +//===----------------------------------------------------------------------===// +// ModuleLinker implementation. +//===----------------------------------------------------------------------===// + +namespace { +class ModuleLinker; + +/// 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 GlobalValueMaterializer final : public ValueMaterializer { + ModuleLinker *ModLinker; + +public: + GlobalValueMaterializer(ModuleLinker *ModLinker) : ModLinker(ModLinker) {} + Value *materializeDeclFor(Value *V) override; + void materializeInitFor(GlobalValue *New, GlobalValue *Old) override; +}; + +class LocalValueMaterializer final : public ValueMaterializer { + ModuleLinker *ModLinker; + +public: + LocalValueMaterializer(ModuleLinker *ModLinker) : ModLinker(ModLinker) {} + Value *materializeDeclFor(Value *V) override; + void materializeInitFor(GlobalValue *New, GlobalValue *Old) override; +}; + +/// This is an implementation class for the LinkModules function, which is the +/// entrypoint for this file. +class ModuleLinker { + Module &DstM; + Module &SrcM; + + std::function AddLazyFor; + + TypeMapTy TypeMap; + GlobalValueMaterializer GValMaterializer; + LocalValueMaterializer LValMaterializer; + + /// 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; + ValueToValueMapTy AliasValueMap; + + DenseSet ValuesToLink; + std::vector Worklist; + + void maybeAdd(GlobalValue *GV) { + if (ValuesToLink.insert(GV).second) + Worklist.push_back(GV); + } + + DiagnosticHandlerFunction DiagnosticHandler; + + /// Set to true when all global value body linking is complete (including + /// lazy linking). Used to prevent metadata linking from creating new + /// references. + bool DoneLinkingBodies = false; + + bool HasError = false; + + /// 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) { + DiagnosticHandler(LinkDiagnosticInfo(DS_Error, Message)); + HasError = true; + return true; + } + + void emitWarning(const Twine &Message) { + DiagnosticHandler(LinkDiagnosticInfo(DS_Warning, Message)); + } + + /// 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 computeTypeMapping(); + + Constant *linkAppendingVarProto(GlobalVariable *DstGV, + const GlobalVariable *SrcGV); + + bool shouldLink(GlobalValue *DGV, GlobalValue &SGV); + Constant *linkGlobalValueProto(GlobalValue *GV, bool ForAlias); + + bool linkModuleFlagsMetadata(); + + void linkGlobalInit(GlobalVariable &Dst, GlobalVariable &Src); + bool linkFunctionBody(Function &Dst, Function &Src); + void linkAliasBody(GlobalAlias &Dst, GlobalAlias &Src); + bool linkGlobalValueBody(GlobalValue &Dst, GlobalValue &Src); + + /// Functions that take care of cloning a specific global value type + /// into the destination module. + GlobalVariable *copyGlobalVariableProto(const GlobalVariable *SGVar); + Function *copyFunctionProto(const Function *SF); + GlobalValue *copyGlobalAliasProto(const GlobalAlias *SGA); + + void linkNamedMDNodes(); + +public: + ModuleLinker( + Module &DstM, IRMover::IdentifiedStructTypeSet &Set, Module &SrcM, + DiagnosticHandlerFunction DiagnosticHandler, + ArrayRef ValuesToLink, + std::function AddLazyFor) + : DstM(DstM), SrcM(SrcM), AddLazyFor(AddLazyFor), TypeMap(Set), + GValMaterializer(this), LValMaterializer(this), + DiagnosticHandler(DiagnosticHandler) { + for (GlobalValue *GV : ValuesToLink) + maybeAdd(GV); + } + + bool run(); + Value *materializeDeclFor(Value *V, bool ForAlias); + void materializeInitFor(GlobalValue *New, GlobalValue *Old, bool ForAlias); +}; +} + +/// 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. + if (GV->hasLocalLinkage() || GV->getName() == Name) + return; + + Module *M = GV->getParent(); + + // If there is a conflict, rename the conflict. + if (GlobalValue *ConflictGV = M->getNamedValue(Name)) { + GV->takeName(ConflictGV); + ConflictGV->setName(Name); // This will cause ConflictGV to get renamed + assert(ConflictGV->getName() != Name && "forceRenaming didn't work"); + } else { + GV->setName(Name); // Force the name back + } +} + +Value *GlobalValueMaterializer::materializeDeclFor(Value *V) { + return ModLinker->materializeDeclFor(V, false); +} + +void GlobalValueMaterializer::materializeInitFor(GlobalValue *New, + GlobalValue *Old) { + ModLinker->materializeInitFor(New, Old, false); +} + +Value *LocalValueMaterializer::materializeDeclFor(Value *V) { + return ModLinker->materializeDeclFor(V, true); +} + +void LocalValueMaterializer::materializeInitFor(GlobalValue *New, + GlobalValue *Old) { + ModLinker->materializeInitFor(New, Old, true); +} + +Value *ModuleLinker::materializeDeclFor(Value *V, bool ForAlias) { + auto *SGV = dyn_cast(V); + if (!SGV) + return nullptr; + + return linkGlobalValueProto(SGV, ForAlias); +} + +void ModuleLinker::materializeInitFor(GlobalValue *New, GlobalValue *Old, + bool ForAlias) { + // If we already created the body, just return. + if (auto *F = dyn_cast(New)) { + if (!F->isDeclaration()) + return; + } else if (auto *V = dyn_cast(New)) { + if (V->hasInitializer()) + return; + } else { + auto *A = cast(New); + if (A->getAliasee()) + return; + } + + if (ForAlias || shouldLink(New, *Old)) + linkGlobalValueBody(*New, *Old); +} + +/// Loop through the global variables in the src module and merge them into the +/// dest module. +GlobalVariable * +ModuleLinker::copyGlobalVariableProto(const GlobalVariable *SGVar) { + // 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(), GlobalValue::ExternalLinkage, + /*init*/ nullptr, SGVar->getName(), + /*insertbefore*/ nullptr, SGVar->getThreadLocalMode(), + SGVar->getType()->getAddressSpace()); + NewDGV->setAlignment(SGVar->getAlignment()); + return NewDGV; +} + +/// Link the function in the source module into the destination module if +/// needed, setting up mapping information. +Function *ModuleLinker::copyFunctionProto(const Function *SF) { + // If there is no linkage to be performed or we are linking from the source, + // bring SF over. + return Function::Create(TypeMap.get(SF->getFunctionType()), + GlobalValue::ExternalLinkage, SF->getName(), &DstM); +} + +/// Set up prototypes for any aliases that come over from the source module. +GlobalValue *ModuleLinker::copyGlobalAliasProto(const GlobalAlias *SGA) { + // If there is no linkage to be performed or we're linking from the source, + // bring over SGA. + auto *Ty = TypeMap.get(SGA->getValueType()); + return GlobalAlias::create(Ty, SGA->getType()->getPointerAddressSpace(), + GlobalValue::ExternalLinkage, SGA->getName(), + &DstM); +} + +GlobalValue *ModuleLinker::copyGlobalValueProto(const GlobalValue *SGV, + bool ForDefinition) { + GlobalValue *NewGV; + if (auto *SGVar = dyn_cast(SGV)) { + NewGV = copyGlobalVariableProto(SGVar); + } else if (auto *SF = dyn_cast(SGV)) { + NewGV = copyFunctionProto(SF); + } else { + if (ForDefinition) + NewGV = copyGlobalAliasProto(cast(SGV)); + else + NewGV = new GlobalVariable( + DstM, TypeMap.get(SGV->getType()->getElementType()), + /*isConstant*/ false, GlobalValue::ExternalLinkage, + /*init*/ nullptr, SGV->getName(), + /*insertbefore*/ nullptr, SGV->getThreadLocalMode(), + SGV->getType()->getAddressSpace()); + } + + if (ForDefinition) + NewGV->setLinkage(SGV->getLinkage()); + else if (SGV->hasExternalWeakLinkage() || SGV->hasWeakLinkage() || + SGV->hasLinkOnceLinkage()) + NewGV->setLinkage(GlobalValue::ExternalWeakLinkage); + + NewGV->copyAttributesFrom(SGV); + return NewGV; +} + +/// 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() { + for (GlobalValue &SGV : SrcM.globals()) { + GlobalValue *DGV = getLinkedToGlobal(&SGV); + if (!DGV) + continue; + + 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(SGV.getType()->getElementType()); + TypeMap.addTypeMapping(DAT->getElementType(), SAT->getElementType()); + } + + 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. + // 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 Types = SrcM.getIdentifiedStructTypes(); + for (StructType *ST : Types) { + if (!ST->hasName()) + continue; + + // Check to see if there is a dot in the name followed by a digit. + size_t DotPos = ST->getName().rfind('.'); + if (DotPos == 0 || DotPos == StringRef::npos || + ST->getName().back() == '.' || + !isdigit(static_cast(ST->getName()[DotPos + 1]))) + continue; + + // Check to see if the destination module has a struct with the prefix name. + StructType *DST = DstM.getTypeByName(ST->getName().substr(0, DotPos)); + if (!DST) + continue; + + // Don't use it if this actually came from the source module. They're in + // the same LLVMContext after all. Also don't use it unless the type is + // actually used in the destination module. This can happen in situations + // like this: + // + // Module A Module B + // -------- -------- + // %Z = type { %A } %B = type { %C.1 } + // %A = type { %B.1, [7 x i8] } %C.1 = type { i8* } + // %B.1 = type { %C } %A.2 = type { %B.3, [5 x i8] } + // %C = type { i8* } %B.3 = type { %C.1 } + // + // When we link Module B with Module A, the '%B' in Module B is + // used. However, that would then use '%C.1'. But when we process '%C.1', + // we prefer to take the '%C' version. So we are then left with both + // '%C.1' and '%C' being used for the same types. This leads to some + // variables using one type and some using the other. + if (TypeMap.DstStructTypesSet.hasType(DST)) + TypeMap.addTypeMapping(DST, ST); + } + + // 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(); +} + +static void getArrayElements(const Constant *C, + SmallVectorImpl &Dest) { + unsigned NumElements = cast(C->getType())->getNumElements(); + + for (unsigned i = 0; i != NumElements; ++i) + Dest.push_back(C->getAggregateElement(i)); +} + +/// If there were any appending global variables, link them together now. +/// Return true on error. +Constant *ModuleLinker::linkAppendingVarProto(GlobalVariable *DstGV, + const GlobalVariable *SrcGV) { + Type *EltTy = cast(TypeMap.get(SrcGV->getType()->getElementType())) + ->getElementType(); + + StringRef Name = SrcGV->getName(); + bool IsNewStructor = false; + bool IsOldStructor = false; + if (Name == "llvm.global_ctors" || Name == "llvm.global_dtors") { + if (cast(EltTy)->getNumElements() == 3) + IsNewStructor = true; + else + IsOldStructor = true; + } + + PointerType *VoidPtrTy = Type::getInt8Ty(SrcGV->getContext())->getPointerTo(); + if (IsOldStructor) { + auto &ST = *cast(EltTy); + Type *Tys[3] = {ST.getElementType(0), ST.getElementType(1), VoidPtrTy}; + EltTy = StructType::get(SrcGV->getContext(), Tys, false); + } + + if (DstGV) { + ArrayType *DstTy = cast(DstGV->getType()->getElementType()); + + if (!SrcGV->hasAppendingLinkage() || !DstGV->hasAppendingLinkage()) { + emitError( + "Linking globals named '" + SrcGV->getName() + + "': can only link appending global with another appending global!"); + return nullptr; + } + + // 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 (DstGV->getAlignment() != SrcGV->getAlignment()) { + emitError( + "Appending variables with different alignment need to be linked!"); + return nullptr; + } + + if (DstGV->getVisibility() != SrcGV->getVisibility()) { + emitError( + "Appending variables with different visibility need to be linked!"); + return nullptr; + } + + if (DstGV->hasUnnamedAddr() != SrcGV->hasUnnamedAddr()) { + emitError( + "Appending variables with different unnamed_addr need to be linked!"); + return nullptr; + } + + if (StringRef(DstGV->getSection()) != SrcGV->getSection()) { + emitError( + "Appending variables with different section name need to be linked!"); + return nullptr; + } + } + + SmallVector DstElements; + if (DstGV) + getArrayElements(DstGV->getInitializer(), DstElements); + + SmallVector SrcElements; + getArrayElements(SrcGV->getInitializer(), SrcElements); + + if (IsNewStructor) + SrcElements.erase( + std::remove_if(SrcElements.begin(), SrcElements.end(), + [this](Constant *E) { + auto *Key = dyn_cast( + E->getAggregateElement(2)->stripPointerCasts()); + if (!Key) + return false; + GlobalValue *DGV = getLinkedToGlobal(Key); + return !shouldLink(DGV, *Key); + }), + SrcElements.end()); + uint64_t NewSize = DstElements.size() + SrcElements.size(); + ArrayType *NewType = ArrayType::get(EltTy, NewSize); + + // Create the new global variable. + GlobalVariable *NG = new GlobalVariable( + DstM, NewType, SrcGV->isConstant(), SrcGV->getLinkage(), + /*init*/ nullptr, /*name*/ "", DstGV, SrcGV->getThreadLocalMode(), + SrcGV->getType()->getAddressSpace()); + + NG->copyAttributesFrom(SrcGV); + forceRenaming(NG, SrcGV->getName()); + + 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(V); + auto *E1 = MapValue(S->getOperand(0), ValueMap, RF_MoveDistinctMDs, + &TypeMap, &GValMaterializer); + auto *E2 = MapValue(S->getOperand(1), ValueMap, RF_MoveDistinctMDs, + &TypeMap, &GValMaterializer); + Value *Null = Constant::getNullValue(VoidPtrTy); + NewV = + ConstantStruct::get(cast(EltTy), E1, E2, Null, nullptr); + } else { + NewV = MapValue(V, ValueMap, RF_MoveDistinctMDs, &TypeMap, + &GValMaterializer); + } + DstElements.push_back(NewV); + } + + NG->setInitializer(ConstantArray::get(NewType, DstElements)); + + // Replace any uses of the two global variables with uses of the new + // global. + if (DstGV) { + DstGV->replaceAllUsesWith(ConstantExpr::getBitCast(NG, DstGV->getType())); + DstGV->eraseFromParent(); + } + + return Ret; +} + +static bool useExistingDest(GlobalValue &SGV, GlobalValue *DGV, + bool ShouldLink) { + if (!DGV) + return false; + + if (SGV.isDeclaration()) + return true; + + if (DGV->isDeclarationForLinker()) + return false; + + if (ShouldLink) + return false; + + return true; +} + +bool ModuleLinker::shouldLink(GlobalValue *DGV, GlobalValue &SGV) { + if (ValuesToLink.count(&SGV)) + return true; + + if (SGV.hasLocalLinkage()) + return true; + + if (DGV && !DGV->isDeclaration()) + return false; + + if (SGV.hasAvailableExternallyLinkage()) + return true; + + if (DoneLinkingBodies) + return false; + + AddLazyFor(SGV, [this](GlobalValue &GV) { maybeAdd(&GV); }); + return ValuesToLink.count(&SGV); +} + +Constant *ModuleLinker::linkGlobalValueProto(GlobalValue *SGV, bool ForAlias) { + GlobalValue *DGV = getLinkedToGlobal(SGV); + + bool ShouldLink = shouldLink(DGV, *SGV); + + // just missing from map + if (ShouldLink) { + auto I = ValueMap.find(SGV); + if (I != ValueMap.end()) + return cast(I->second); + + I = AliasValueMap.find(SGV); + if (I != AliasValueMap.end()) + return cast(I->second); + } + + DGV = nullptr; + if (ShouldLink || !ForAlias) + DGV = getLinkedToGlobal(SGV); + + // Handle the ultra special appending linkage case first. + assert(!DGV || SGV->hasAppendingLinkage() == DGV->hasAppendingLinkage()); + if (SGV->hasAppendingLinkage()) + return linkAppendingVarProto(cast_or_null(DGV), + cast(SGV)); + + GlobalValue *NewGV; + if (useExistingDest(*SGV, DGV, ShouldLink)) { + NewGV = DGV; + } else { + // If we are done linking global value bodies (i.e. we are performing + // metadata linking), don't link in the global value due to this + // reference, simply map it to null. + if (DoneLinkingBodies) + return nullptr; + + NewGV = copyGlobalValueProto(SGV, ShouldLink); + if (!ForAlias) + forceRenaming(NewGV, SGV->getName()); + } + if (ShouldLink || ForAlias) { + if (const Comdat *SC = SGV->getComdat()) { + if (auto *GO = dyn_cast(NewGV)) { + Comdat *DC = DstM.getOrInsertComdat(SC->getName()); + DC->setSelectionKind(SC->getSelectionKind()); + GO->setComdat(DC); + } + } + } + + if (!ShouldLink && ForAlias) + NewGV->setLinkage(GlobalValue::InternalLinkage); + + Constant *C = NewGV; + if (DGV) + C = ConstantExpr::getBitCast(NewGV, TypeMap.get(SGV->getType())); + + if (DGV && NewGV != DGV) { + DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewGV, DGV->getType())); + DGV->eraseFromParent(); + } + + return C; +} + +/// Update the initializers in the Dest module now that all globals that may be +/// referenced are in Dest. +void ModuleLinker::linkGlobalInit(GlobalVariable &Dst, GlobalVariable &Src) { + // Figure out what the initializer looks like in the dest module. + Dst.setInitializer(MapValue(Src.getInitializer(), ValueMap, + RF_MoveDistinctMDs, &TypeMap, &GValMaterializer)); +} + +/// 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 ModuleLinker::linkFunctionBody(Function &Dst, Function &Src) { + assert(Dst.isDeclaration() && !Src.isDeclaration()); + + // Materialize if needed. + if (std::error_code EC = Src.materialize()) + return emitError(EC.message()); + + // Link in the prefix data. + if (Src.hasPrefixData()) + Dst.setPrefixData(MapValue(Src.getPrefixData(), ValueMap, + RF_MoveDistinctMDs, &TypeMap, + &GValMaterializer)); + + // Link in the prologue data. + if (Src.hasPrologueData()) + Dst.setPrologueData(MapValue(Src.getPrologueData(), ValueMap, + RF_MoveDistinctMDs, &TypeMap, + &GValMaterializer)); + + // Link in the personality function. + if (Src.hasPersonalityFn()) + Dst.setPersonalityFn(MapValue(Src.getPersonalityFn(), ValueMap, + RF_MoveDistinctMDs, &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; + } + + // Copy over the metadata attachments. + SmallVector, 8> MDs; + Src.getAllMetadata(MDs); + for (const auto &I : MDs) + Dst.setMetadata(I.first, MapMetadata(I.second, ValueMap, RF_MoveDistinctMDs, + &TypeMap, &GValMaterializer)); + + // 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 (BasicBlock &BB : Dst) + for (Instruction &I : BB) + RemapInstruction(&I, ValueMap, + RF_IgnoreMissingEntries | RF_MoveDistinctMDs, &TypeMap, + &GValMaterializer); + + // There is no need to map the arguments anymore. + for (Argument &Arg : Src.args()) + ValueMap.erase(&Arg); + + Src.dematerialize(); + return false; +} + +void ModuleLinker::linkAliasBody(GlobalAlias &Dst, GlobalAlias &Src) { + Constant *Aliasee = Src.getAliasee(); + Constant *Val = MapValue(Aliasee, AliasValueMap, RF_MoveDistinctMDs, &TypeMap, + &LValMaterializer); + Dst.setAliasee(Val); +} + +bool ModuleLinker::linkGlobalValueBody(GlobalValue &Dst, GlobalValue &Src) { + if (auto *F = dyn_cast(&Src)) + return linkFunctionBody(cast(Dst), *F); + if (auto *GVar = dyn_cast(&Src)) { + linkGlobalInit(cast(Dst), *GVar); + return false; + } + linkAliasBody(cast(Dst), cast(Src)); + return false; +} + +/// Insert all of the named MDNodes in Src into the Dest module. +void ModuleLinker::linkNamedMDNodes() { + 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, RF_MoveDistinctMDs | RF_NullMapMissingGlobalValues, + &TypeMap, &GValMaterializer)); + } +} + +/// 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(); + if (!SrcModFlags) + return false; + + // If the destination module doesn't have module flags yet, then just copy + // over the source module's flags. + NamedMDNode *DstModFlags = DstM.getOrInsertModuleFlagsMetadata(); + if (DstModFlags->getNumOperands() == 0) { + for (unsigned I = 0, E = SrcModFlags->getNumOperands(); I != E; ++I) + DstModFlags->addOperand(SrcModFlags->getOperand(I)); + + return false; + } + + // First build a map of the existing module flags and requirements. + DenseMap> Flags; + SmallSetVector Requirements; + for (unsigned I = 0, E = DstModFlags->getNumOperands(); I != E; ++I) { + MDNode *Op = DstModFlags->getOperand(I); + ConstantInt *Behavior = mdconst::extract(Op->getOperand(0)); + MDString *ID = cast(Op->getOperand(1)); + + if (Behavior->getZExtValue() == Module::Require) { + Requirements.insert(cast(Op->getOperand(2))); + } else { + Flags[ID] = std::make_pair(Op, I); + } + } + + // Merge in the flags from the source module, and also collect its set of + // requirements. + for (unsigned I = 0, E = SrcModFlags->getNumOperands(); I != E; ++I) { + MDNode *SrcOp = SrcModFlags->getOperand(I); + ConstantInt *SrcBehavior = + mdconst::extract(SrcOp->getOperand(0)); + MDString *ID = cast(SrcOp->getOperand(1)); + MDNode *DstOp; + unsigned DstIndex; + std::tie(DstOp, DstIndex) = Flags.lookup(ID); + unsigned SrcBehaviorValue = SrcBehavior->getZExtValue(); + + // If this is a requirement, add it and continue. + if (SrcBehaviorValue == Module::Require) { + // If the destination module does not already have this requirement, add + // it. + if (Requirements.insert(cast(SrcOp->getOperand(2)))) { + DstModFlags->addOperand(SrcOp); + } + continue; + } + + // If there is no existing flag with this ID, just add it. + if (!DstOp) { + Flags[ID] = std::make_pair(SrcOp, DstModFlags->getNumOperands()); + DstModFlags->addOperand(SrcOp); + continue; + } + + // Otherwise, perform a merge. + ConstantInt *DstBehavior = + mdconst::extract(DstOp->getOperand(0)); + unsigned DstBehaviorValue = DstBehavior->getZExtValue(); + + // If either flag has override behavior, handle it first. + 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"); + } + continue; + } else if (SrcBehaviorValue == Module::Override) { + // Update the destination flag to that of the source. + DstModFlags->setOperand(DstIndex, SrcOp); + Flags[ID].first = SrcOp; + continue; + } + + // Diagnose inconsistent merge behavior types. + if (SrcBehaviorValue != DstBehaviorValue) { + emitError("linking module flags '" + ID->getString() + + "': IDs have conflicting behaviors"); + continue; + } + + auto replaceDstValue = [&](MDNode *New) { + Metadata *FlagOps[] = {DstOp->getOperand(0), ID, New}; + MDNode *Flag = MDNode::get(DstM.getContext(), FlagOps); + DstModFlags->setOperand(DstIndex, Flag); + Flags[ID].first = Flag; + }; + + // Perform the merge for standard behavior types. + switch (SrcBehaviorValue) { + case Module::Require: + case Module::Override: + 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"); + } + continue; + } + case Module::Warning: { + // Emit a warning if the values differ. + if (SrcOp->getOperand(2) != DstOp->getOperand(2)) { + emitWarning("linking module flags '" + ID->getString() + + "': IDs have conflicting values"); + } + continue; + } + case Module::Append: { + MDNode *DstValue = cast(DstOp->getOperand(2)); + MDNode *SrcValue = cast(SrcOp->getOperand(2)); + SmallVector MDs; + MDs.reserve(DstValue->getNumOperands() + SrcValue->getNumOperands()); + MDs.append(DstValue->op_begin(), DstValue->op_end()); + MDs.append(SrcValue->op_begin(), SrcValue->op_end()); + + replaceDstValue(MDNode::get(DstM.getContext(), MDs)); + break; + } + case Module::AppendUnique: { + SmallSetVector Elts; + MDNode *DstValue = cast(DstOp->getOperand(2)); + MDNode *SrcValue = cast(SrcOp->getOperand(2)); + Elts.insert(DstValue->op_begin(), DstValue->op_end()); + Elts.insert(SrcValue->op_begin(), SrcValue->op_end()); + + replaceDstValue(MDNode::get(DstM.getContext(), + makeArrayRef(Elts.begin(), Elts.end()))); + break; + } + } + } + + // Check all of the requirements. + for (unsigned I = 0, E = Requirements.size(); I != E; ++I) { + MDNode *Requirement = Requirements[I]; + MDString *Flag = cast(Requirement->getOperand(0)); + 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; + } + } + + return HasError; +} + +// This function returns true if the triples match. +static bool triplesMatch(const Triple &T0, const Triple &T1) { + // If vendor is apple, ignore the version number. + if (T0.getVendor() == Triple::Apple) + return T0.getArch() == T1.getArch() && T0.getSubArch() == T1.getSubArch() && + T0.getVendor() == T1.getVendor() && T0.getOS() == T1.getOS(); + + return T0 == T1; +} + +// This function returns the merged triple. +static std::string mergeTriples(const Triple &SrcTriple, + const Triple &DstTriple) { + // If vendor is apple, pick the triple with the larger version number. + if (SrcTriple.getVendor() == Triple::Apple) + if (DstTriple.isOSVersionLT(SrcTriple)) + return SrcTriple.str(); + + return DstTriple.str(); +} + +bool ModuleLinker::run() { + // 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()); + + if (SrcM.getDataLayout() != DstM.getDataLayout()) { + emitWarning("Linking two modules of different data layouts: '" + + 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()); + + Triple SrcTriple(SrcM.getTargetTriple()), DstTriple(DstM.getTargetTriple()); + + 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"); + + DstM.setTargetTriple(mergeTriples(SrcTriple, DstTriple)); + + // Append the module inline asm string. + if (!SrcM.getModuleInlineAsm().empty()) { + if (DstM.getModuleInlineAsm().empty()) + DstM.setModuleInlineAsm(SrcM.getModuleInlineAsm()); + else + DstM.setModuleInlineAsm(DstM.getModuleInlineAsm() + "\n" + + SrcM.getModuleInlineAsm()); + } + + // Loop over all of the linked values to compute type mappings. + computeTypeMapping(); + + std::reverse(Worklist.begin(), Worklist.end()); + while (!Worklist.empty()) { + GlobalValue *GV = Worklist.back(); + Worklist.pop_back(); + + // Already mapped. + if (ValueMap.find(GV) != ValueMap.end() || + AliasValueMap.find(GV) != AliasValueMap.end()) + continue; + + assert(!GV->isDeclaration()); + MapValue(GV, ValueMap, RF_MoveDistinctMDs, &TypeMap, &GValMaterializer); + if (HasError) + return true; + } + + // Note that we are done linking global value bodies. This prevents + // metadata linking from creating new references. + DoneLinkingBodies = true; + + // 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. + linkNamedMDNodes(); + + // Merge the module flags into the DstM module. + if (linkModuleFlagsMetadata()) + return true; + + return false; +} + +IRMover::StructTypeKeyInfo::KeyTy::KeyTy(ArrayRef E, bool P) + : ETypes(E), IsPacked(P) {} + +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; +} + +bool IRMover::StructTypeKeyInfo::KeyTy::operator!=(const KeyTy &That) const { + return !this->operator==(That); +} + +StructType *IRMover::StructTypeKeyInfo::getEmptyKey() { + return DenseMapInfo::getEmptyKey(); +} + +StructType *IRMover::StructTypeKeyInfo::getTombstoneKey() { + return DenseMapInfo::getTombstoneKey(); +} + +unsigned IRMover::StructTypeKeyInfo::getHashValue(const KeyTy &Key) { + return hash_combine(hash_combine_range(Key.ETypes.begin(), Key.ETypes.end()), + Key.IsPacked); +} + +unsigned IRMover::StructTypeKeyInfo::getHashValue(const StructType *ST) { + return getHashValue(KeyTy(ST)); +} + +bool IRMover::StructTypeKeyInfo::isEqual(const KeyTy &LHS, + const StructType *RHS) { + if (RHS == getEmptyKey() || RHS == getTombstoneKey()) + return false; + return LHS == KeyTy(RHS); +} + +bool IRMover::StructTypeKeyInfo::isEqual(const StructType *LHS, + const StructType *RHS) { + if (RHS == getEmptyKey()) + return LHS == getEmptyKey(); + + if (RHS == getTombstoneKey()) + return LHS == getTombstoneKey(); + + return KeyTy(LHS) == KeyTy(RHS); +} + +void IRMover::IdentifiedStructTypeSet::addNonOpaque(StructType *Ty) { + assert(!Ty->isOpaque()); + NonOpaqueStructTypes.insert(Ty); +} + +void IRMover::IdentifiedStructTypeSet::switchToNonOpaque(StructType *Ty) { + assert(!Ty->isOpaque()); + NonOpaqueStructTypes.insert(Ty); + bool Removed = OpaqueStructTypes.erase(Ty); + (void)Removed; + assert(Removed); +} + +void IRMover::IdentifiedStructTypeSet::addOpaque(StructType *Ty) { + assert(Ty->isOpaque()); + OpaqueStructTypes.insert(Ty); +} + +StructType * +IRMover::IdentifiedStructTypeSet::findNonOpaque(ArrayRef ETypes, + bool IsPacked) { + IRMover::StructTypeKeyInfo::KeyTy Key(ETypes, IsPacked); + auto I = NonOpaqueStructTypes.find_as(Key); + if (I == NonOpaqueStructTypes.end()) + return nullptr; + return *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; +} + +IRMover::IRMover(Module &M, DiagnosticHandlerFunction DiagnosticHandler) + : Composite(M), DiagnosticHandler(DiagnosticHandler) { + TypeFinder StructTypes; + StructTypes.run(M, true); + for (StructType *Ty : StructTypes) { + if (Ty->isOpaque()) + IdentifiedStructTypes.addOpaque(Ty); + else + IdentifiedStructTypes.addNonOpaque(Ty); + } +} + +bool IRMover::move( + Module &Src, ArrayRef ValuesToLink, + std::function AddLazyFor) { + ModuleLinker TheLinker(Composite, IdentifiedStructTypes, Src, + DiagnosticHandler, ValuesToLink, AddLazyFor); + bool RetCode = TheLinker.run(); + Composite.dropTriviallyDeadConstantArrays(); + return RetCode; +} Index: lib/Linker/LinkDiagnosticInfo.h =================================================================== --- /dev/null +++ lib/Linker/LinkDiagnosticInfo.h @@ -0,0 +1,25 @@ +//===- LinkDiagnosticInfo.h -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_LINKER_LINK_DIAGNOSTIC_INFO_H +#define LLVM_LIB_LINKER_LINK_DIAGNOSTIC_INFO_H + +#include "llvm/IR/DiagnosticInfo.h" + +namespace llvm { +class LinkDiagnosticInfo : public DiagnosticInfo { + const Twine &Msg; + +public: + LinkDiagnosticInfo(DiagnosticSeverity Severity, const Twine &Msg); + void print(DiagnosticPrinter &DP) const override; +}; +} + +#endif Index: lib/Linker/LinkModules.cpp =================================================================== --- lib/Linker/LinkModules.cpp +++ lib/Linker/LinkModules.cpp @@ -12,389 +12,23 @@ //===----------------------------------------------------------------------===// #include "llvm/Linker/Linker.h" +#include "LinkDiagnosticInfo.h" #include "llvm-c/Linker.h" #include "llvm/ADT/SetVector.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/Triple.h" -#include "llvm/IR/Constants.h" -#include "llvm/IR/DiagnosticInfo.h" +#include "llvm/ADT/StringSet.h" #include "llvm/IR/DiagnosticPrinter.h" -#include "llvm/IR/LLVMContext.h" -#include "llvm/IR/Module.h" -#include "llvm/IR/TypeFinder.h" -#include "llvm/Transforms/Utils/Cloning.h" using namespace llvm; -//===----------------------------------------------------------------------===// -// TypeMap implementation. -//===----------------------------------------------------------------------===// - namespace { -class TypeMapTy : public ValueMapTypeRemapper { - /// This is a mapping from a source type to a destination type to use. - DenseMap MappedTypes; - - /// 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; - - SmallVector SpeculativeDstOpaqueTypes; - - /// 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; - - /// This is the set of opaque types in the destination modules who are - /// getting a body from the source module. - SmallPtrSet DstResolvedOpaqueTypes; - -public: - TypeMapTy(Linker::IdentifiedStructTypeSet &DstStructTypesSet) - : DstStructTypesSet(DstStructTypesSet) {} - - Linker::IdentifiedStructTypeSet &DstStructTypesSet; - /// 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); - - /// Produce a body for an opaque type in the dest module from a type - /// definition in the source module. - void linkDefinedTypeBodies(); - - /// Return the mapped type to use for the specified input type from the - /// source module. - Type *get(Type *SrcTy); - Type *get(Type *SrcTy, SmallPtrSet &Visited); - - void finishType(StructType *DTy, StructType *STy, ArrayRef ETypes); - - FunctionType *get(FunctionType *T) { - return cast(get((Type *)T)); - } - - /// Dump out the type map for debugging purposes. - void dump() const { - for (auto &Pair : MappedTypes) { - dbgs() << "TypeMap: "; - Pair.first->print(dbgs()); - dbgs() << " => "; - Pair.second->print(dbgs()); - dbgs() << '\n'; - } - } - -private: - Type *remapType(Type *SrcTy) override { return get(SrcTy); } - - bool areTypesIsomorphic(Type *DstTy, Type *SrcTy); -}; -} - -void TypeMapTy::addTypeMapping(Type *DstTy, Type *SrcTy) { - assert(SpeculativeTypes.empty()); - assert(SpeculativeDstOpaqueTypes.empty()); - - // 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 (Type *Ty : SpeculativeTypes) - MappedTypes.erase(Ty); - - SrcDefinitionsToResolve.resize(SrcDefinitionsToResolve.size() - - SpeculativeDstOpaqueTypes.size()); - for (StructType *Ty : SpeculativeDstOpaqueTypes) - DstResolvedOpaqueTypes.erase(Ty); - } else { - for (Type *Ty : SpeculativeTypes) - if (auto *STy = dyn_cast(Ty)) - if (STy->hasName()) - STy->setName(""); - } - SpeculativeTypes.clear(); - SpeculativeDstOpaqueTypes.clear(); -} - -/// 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; - - // If we have an entry in the MappedTypes table, then we have our answer. - Type *&Entry = MappedTypes[SrcTy]; - if (Entry) - return Entry == DstTy; - - // Two identical types are clearly isomorphic. Remember this - // non-speculatively. - if (DstTy == SrcTy) { - Entry = DstTy; - return true; - } - - // Okay, we have two types with identical kinds that we haven't seen before. - - // If this is an opaque struct type, special case it. - if (StructType *SSTy = dyn_cast(SrcTy)) { - // Mapping an opaque type to any struct, just keep the dest struct. - if (SSTy->isOpaque()) { - Entry = DstTy; - SpeculativeTypes.push_back(SrcTy); - return true; - } - - // 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. 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)).second) - return false; - SrcDefinitionsToResolve.push_back(SSTy); - SpeculativeTypes.push_back(SrcTy); - SpeculativeDstOpaqueTypes.push_back(cast(DstTy)); - Entry = DstTy; - return true; - } - } - - // If the number of subtypes disagree between the two types, then we fail. - if (SrcTy->getNumContainedTypes() != DstTy->getNumContainedTypes()) - return false; - - // Fail if any of the extra properties (e.g. array size) of the type disagree. - if (isa(DstTy)) - return false; // bitwidth disagrees. - if (PointerType *PT = dyn_cast(DstTy)) { - if (PT->getAddressSpace() != cast(SrcTy)->getAddressSpace()) - return false; - - } else if (FunctionType *FT = dyn_cast(DstTy)) { - if (FT->isVarArg() != cast(SrcTy)->isVarArg()) - return false; - } else if (StructType *DSTy = dyn_cast(DstTy)) { - StructType *SSTy = cast(SrcTy); - if (DSTy->isLiteral() != SSTy->isLiteral() || - DSTy->isPacked() != SSTy->isPacked()) - return false; - } else if (ArrayType *DATy = dyn_cast(DstTy)) { - if (DATy->getNumElements() != cast(SrcTy)->getNumElements()) - return false; - } else if (VectorType *DVTy = dyn_cast(DstTy)) { - if (DVTy->getNumElements() != cast(SrcTy)->getNumElements()) - return false; - } - - // Otherwise, we speculate that these two types will line up and recursively - // check the subelements. - Entry = DstTy; - SpeculativeTypes.push_back(SrcTy); - - for (unsigned I = 0, E = SrcTy->getNumContainedTypes(); I != E; ++I) - if (!areTypesIsomorphic(DstTy->getContainedType(I), - SrcTy->getContainedType(I))) - return false; - - // If everything seems to have lined up, then everything is great. - return true; -} - -void TypeMapTy::linkDefinedTypeBodies() { - SmallVector Elements; - for (StructType *SrcSTy : SrcDefinitionsToResolve) { - StructType *DstSTy = cast(MappedTypes[SrcSTy]); - assert(DstSTy->isOpaque()); - - // Map the body of the source type over to a new body for the dest type. - Elements.resize(SrcSTy->getNumElements()); - for (unsigned I = 0, E = Elements.size(); I != E; ++I) - Elements[I] = get(SrcSTy->getElementType(I)); - - DstSTy->setBody(Elements, SrcSTy->isPacked()); - DstStructTypesSet.switchToNonOpaque(DstSTy); - } - SrcDefinitionsToResolve.clear(); - DstResolvedOpaqueTypes.clear(); -} - -void TypeMapTy::finishType(StructType *DTy, StructType *STy, - ArrayRef ETypes) { - DTy->setBody(ETypes, STy->isPacked()); - - // Steal STy's name. - if (STy->hasName()) { - SmallString<16> TmpName = STy->getName(); - STy->setName(""); - DTy->setName(TmpName); - } - - DstStructTypesSet.addNonOpaque(DTy); -} - -Type *TypeMapTy::get(Type *Ty) { - SmallPtrSet Visited; - return get(Ty, Visited); -} - -Type *TypeMapTy::get(Type *Ty, SmallPtrSet &Visited) { - // If we already have an entry for this type, return it. - Type **Entry = &MappedTypes[Ty]; - if (*Entry) - return *Entry; - - // These are types that LLVM itself will unique. - bool IsUniqued = !isa(Ty) || cast(Ty)->isLiteral(); - -#ifndef NDEBUG - if (!IsUniqued) { - for (auto &Pair : MappedTypes) { - assert(!(Pair.first != Ty && Pair.second == Ty) && - "mapping to a source type"); - } - } -#endif - - if (!IsUniqued && !Visited.insert(cast(Ty)).second) { - StructType *DTy = StructType::create(Ty->getContext()); - return *Entry = DTy; - } - - // If this is not a recursive type, then just map all of the elements and - // then rebuild the type from inside out. - SmallVector ElementTypes; - - // If there are no element types to map, then the type is itself. This is - // true for the anonymous {} struct, things like 'float', integers, etc. - if (Ty->getNumContainedTypes() == 0 && IsUniqued) - return *Entry = Ty; - - // Remap all of the elements, keeping track of whether any of them change. - bool AnyChange = false; - ElementTypes.resize(Ty->getNumContainedTypes()); - for (unsigned I = 0, E = Ty->getNumContainedTypes(); I != E; ++I) { - ElementTypes[I] = get(Ty->getContainedType(I), Visited); - AnyChange |= ElementTypes[I] != Ty->getContainedType(I); - } - - // If we found our type while recursively processing stuff, just use it. - Entry = &MappedTypes[Ty]; - if (*Entry) { - if (auto *DTy = dyn_cast(*Entry)) { - if (DTy->isOpaque()) { - auto *STy = cast(Ty); - finishType(DTy, STy, ElementTypes); - } - } - return *Entry; - } - - // If all of the element types mapped directly over and the type is not - // a nomed struct, then the type is usable as-is. - if (!AnyChange && IsUniqued) - return *Entry = Ty; - - // Otherwise, rebuild a modified type. - switch (Ty->getTypeID()) { - default: - llvm_unreachable("unknown derived type to remap"); - case Type::ArrayTyID: - return *Entry = ArrayType::get(ElementTypes[0], - cast(Ty)->getNumElements()); - case Type::VectorTyID: - return *Entry = VectorType::get(ElementTypes[0], - cast(Ty)->getNumElements()); - case Type::PointerTyID: - return *Entry = PointerType::get(ElementTypes[0], - cast(Ty)->getAddressSpace()); - case Type::FunctionTyID: - return *Entry = FunctionType::get(ElementTypes[0], - makeArrayRef(ElementTypes).slice(1), - cast(Ty)->isVarArg()); - case Type::StructTyID: { - auto *STy = cast(Ty); - bool IsPacked = STy->isPacked(); - if (IsUniqued) - return *Entry = StructType::get(Ty->getContext(), ElementTypes, IsPacked); - - // If the type is opaque, we can just use it directly. - if (STy->isOpaque()) { - DstStructTypesSet.addOpaque(STy); - return *Entry = Ty; - } - - if (StructType *OldT = - DstStructTypesSet.findNonOpaque(ElementTypes, IsPacked)) { - STy->setName(""); - return *Entry = OldT; - } - - if (!AnyChange) { - DstStructTypesSet.addNonOpaque(STy); - return *Entry = Ty; - } - - StructType *DTy = StructType::create(Ty->getContext()); - finishType(DTy, STy, ElementTypes); - return *Entry = DTy; - } - } -} - -//===----------------------------------------------------------------------===// -// ModuleLinker implementation. -//===----------------------------------------------------------------------===// - -namespace { -class ModuleLinker; - -/// 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 final : public ValueMaterializer { - ModuleLinker *ModLinker; - -public: - ValueMaterializerTy(ModuleLinker *ModLinker) : ModLinker(ModLinker) {} - - Value *materializeDeclFor(Value *V) override; - void materializeInitFor(GlobalValue *New, GlobalValue *Old) override; -}; - -class LinkDiagnosticInfo : public DiagnosticInfo { - const Twine &Msg; - -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; + IRMover &Mover; Module &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; - SetVector ValuesToLink; - - DiagnosticHandlerFunction DiagnosticHandler; + StringSet<> Internalize; /// For symbol clashes, prefer those from Src. unsigned Flags; @@ -413,12 +47,11 @@ /// as part of a different backend compilation process. bool HasExportedFunctions = false; - /// Set to true when all global value body linking is complete (including - /// lazy linking). Used to prevent metadata linking from creating new - /// references. - bool DoneLinkingBodies = false; - - bool HasError = false; + /// 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); bool shouldOverrideFromSrc() { return Flags & Linker::OverrideFromSrc; } bool shouldLinkOnlyNeeded() { return Flags & Linker::LinkOnlyNeeded; } @@ -426,27 +59,18 @@ return Flags & Linker::InternalizeLinkedSymbols; } - /// 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); - /// Check if we should promote the given local value to global scope. bool doPromoteLocalToGlobal(const GlobalValue *SGV); bool shouldLinkFromSource(bool &LinkFromSrc, const GlobalValue &Dest, const GlobalValue &Src); - /// Helper method for setting a message and returning an error code. + /// Should we have mover and linker error diag info? bool emitError(const Twine &Message) { - DiagnosticHandler(LinkDiagnosticInfo(DS_Error, Message)); - HasError = true; + Mover.getDiagnosticHandler()(LinkDiagnosticInfo(DS_Error, Message)); return true; } - void emitWarning(const Twine &Message) { - DiagnosticHandler(LinkDiagnosticInfo(DS_Warning, Message)); - } - bool getComdatLeader(Module &M, StringRef ComdatName, const GlobalVariable *&GVar); bool computeResultingSelectionKind(StringRef ComdatName, @@ -464,6 +88,7 @@ /// 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) { + Module &DstM = Mover.getModule(); // 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() || GlobalValue::isLocalLinkage(getLinkage(SrcGV))) @@ -483,25 +108,7 @@ return DGV; } - void computeTypeMapping(); - bool linkIfNeeded(GlobalValue &GV); - Constant *linkAppendingVarProto(GlobalVariable *DstGV, - const GlobalVariable *SrcGV); - - Constant *linkGlobalValueProto(GlobalValue *GV); - bool linkModuleFlagsMetadata(); - - void linkGlobalInit(GlobalVariable &Dst, GlobalVariable &Src); - bool linkFunctionBody(Function &Dst, Function &Src); - void linkAliasBody(GlobalAlias &Dst, GlobalAlias &Src); - bool linkGlobalValueBody(GlobalValue &Dst, GlobalValue &Src); - - /// Functions that take care of cloning a specific global value type - /// into the destination module. - GlobalVariable *copyGlobalVariableProto(const GlobalVariable *SGVar); - Function *copyFunctionProto(const Function *SF); - GlobalValue *copyGlobalAliasProto(const GlobalAlias *SGA); /// Helper methods to check if we are importing from or potentially /// exporting from the current source module. @@ -517,6 +124,11 @@ /// a local that is being promoted to global scope. std::string getName(const GlobalValue *SGV); + /// Promote local variables so that they can be reference externally by + /// thin lto imported globals. + 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. @@ -532,15 +144,11 @@ void setVisibility(GlobalValue *NewGV, const GlobalValue *SGV, const GlobalValue *DGV = nullptr); - void linkNamedMDNodes(); - public: - ModuleLinker(Module &DstM, Linker::IdentifiedStructTypeSet &Set, Module &SrcM, - DiagnosticHandlerFunction DiagnosticHandler, unsigned Flags, + ModuleLinker(IRMover &Mover, Module &SrcM, unsigned Flags, const FunctionInfoIndex *Index = nullptr, DenseSet *FunctionsToImport = nullptr) - : DstM(DstM), SrcM(SrcM), TypeMap(Set), ValMaterializer(this), - DiagnosticHandler(DiagnosticHandler), Flags(Flags), ImportIndex(Index), + : Mover(Mover), SrcM(SrcM), Flags(Flags), ImportIndex(Index), ImportFunction(FunctionsToImport) { assert((ImportIndex || !ImportFunction) && "Expect a FunctionInfoIndex when importing"); @@ -553,8 +161,6 @@ } bool run(); - Value *materializeDeclFor(Value *V); - void materializeInitFor(GlobalValue *New, GlobalValue *Old); }; } @@ -755,41 +361,6 @@ llvm_unreachable("unknown linkage type"); } -/// Loop through the global variables in the src module and merge them into the -/// dest module. -GlobalVariable * -ModuleLinker::copyGlobalVariableProto(const GlobalVariable *SGVar) { - // 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(), GlobalValue::ExternalLinkage, - /*init*/ nullptr, getName(SGVar), - /*insertbefore*/ nullptr, SGVar->getThreadLocalMode(), - SGVar->getType()->getAddressSpace()); - - return NewDGV; -} - -/// Link the function in the source module into the destination module if -/// needed, setting up mapping information. -Function *ModuleLinker::copyFunctionProto(const Function *SF) { - // If there is no linkage to be performed or we are linking from the source, - // bring SF over. - return Function::Create(TypeMap.get(SF->getFunctionType()), - GlobalValue::ExternalLinkage, getName(SF), &DstM); -} - -/// Set up prototypes for any aliases that come over from the source module. -GlobalValue *ModuleLinker::copyGlobalAliasProto(const GlobalAlias *SGA) { - // If there is no linkage to be performed or we're linking from the source, - // bring over SGA. - auto *Ty = TypeMap.get(SGA->getValueType()); - return GlobalAlias::create(Ty, SGA->getType()->getPointerAddressSpace(), - GlobalValue::ExternalLinkage, getName(SGA), &DstM); -} - static GlobalValue::VisibilityTypes getMinVisibility(GlobalValue::VisibilityTypes A, GlobalValue::VisibilityTypes B) { @@ -813,82 +384,6 @@ NewGV->setVisibility(Visibility); } -GlobalValue *ModuleLinker::copyGlobalValueProto(const GlobalValue *SGV, - bool ForDefinition) { - GlobalValue *NewGV; - if (auto *SGVar = dyn_cast(SGV)) { - NewGV = copyGlobalVariableProto(SGVar); - } else if (auto *SF = dyn_cast(SGV)) { - NewGV = copyFunctionProto(SF); - } else { - if (ForDefinition) - NewGV = copyGlobalAliasProto(cast(SGV)); - else - NewGV = new GlobalVariable( - DstM, TypeMap.get(SGV->getType()->getElementType()), - /*isConstant*/ false, GlobalValue::ExternalLinkage, - /*init*/ nullptr, getName(SGV), - /*insertbefore*/ nullptr, SGV->getThreadLocalMode(), - SGV->getType()->getAddressSpace()); - } - - if (ForDefinition) - NewGV->setLinkage(getLinkage(SGV)); - else if (SGV->hasAvailableExternallyLinkage() || SGV->hasWeakLinkage() || - SGV->hasLinkOnceLinkage()) - NewGV->setLinkage(GlobalValue::ExternalWeakLinkage); - - copyGVAttributes(NewGV, SGV); - return NewGV; -} - -Value *ValueMaterializerTy::materializeDeclFor(Value *V) { - return ModLinker->materializeDeclFor(V); -} - -Value *ModuleLinker::materializeDeclFor(Value *V) { - auto *SGV = dyn_cast(V); - if (!SGV) - return nullptr; - - return linkGlobalValueProto(SGV); -} - -void ValueMaterializerTy::materializeInitFor(GlobalValue *New, - GlobalValue *Old) { - return ModLinker->materializeInitFor(New, Old); -} - -static bool shouldLazyLink(const GlobalValue &GV) { - return GV.hasLocalLinkage() || GV.hasLinkOnceLinkage() || - GV.hasAvailableExternallyLinkage(); -} - -void ModuleLinker::materializeInitFor(GlobalValue *New, GlobalValue *Old) { - if (auto *F = dyn_cast(New)) { - if (!F->isDeclaration()) - return; - } else if (auto *V = dyn_cast(New)) { - if (V->hasInitializer()) - return; - } else { - auto *A = cast(New); - if (A->getAliasee()) - return; - } - - if (Old->isDeclaration()) - return; - - if (isPerformingImport() && !doImportAsDefinition(Old)) - return; - - if (!ValuesToLink.count(Old) && !shouldLazyLink(*Old)) - return; - - linkGlobalValueBody(*New, *Old); -} - bool ModuleLinker::getComdatLeader(Module &M, StringRef ComdatName, const GlobalVariable *&GVar) { const GlobalValue *GVal = M.getNamedValue(ComdatName); @@ -914,6 +409,7 @@ Comdat::SelectionKind Dst, Comdat::SelectionKind &Result, bool &LinkFromSrc) { + Module &DstM = Mover.getModule(); // The ability to mix Comdat::SelectionKind::Any with // Comdat::SelectionKind::Largest is a behavior that comes from COFF. bool DstAnyOrLargest = Dst == Comdat::SelectionKind::Any || @@ -981,6 +477,7 @@ bool ModuleLinker::getComdatResult(const Comdat *SrcC, Comdat::SelectionKind &Result, bool &LinkFromSrc) { + Module &DstM = Mover.getModule(); Comdat::SelectionKind SSK = SrcC->getSelectionKind(); StringRef ComdatName = SrcC->getName(); Module::ComdatSymTabType &ComdatSymTab = DstM.getComdatSymbolTable(); @@ -1110,601 +607,6 @@ "': symbol multiply defined!"); } -/// 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() { - for (GlobalValue &SGV : SrcM.globals()) { - GlobalValue *DGV = getLinkedToGlobal(&SGV); - if (!DGV) - continue; - - 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(SGV.getType()->getElementType()); - TypeMap.addTypeMapping(DAT->getElementType(), SAT->getElementType()); - } - - 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. - // 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 Types = SrcM.getIdentifiedStructTypes(); - for (StructType *ST : Types) { - if (!ST->hasName()) - continue; - - // Check to see if there is a dot in the name followed by a digit. - size_t DotPos = ST->getName().rfind('.'); - if (DotPos == 0 || DotPos == StringRef::npos || - ST->getName().back() == '.' || - !isdigit(static_cast(ST->getName()[DotPos + 1]))) - continue; - - // Check to see if the destination module has a struct with the prefix name. - StructType *DST = DstM.getTypeByName(ST->getName().substr(0, DotPos)); - if (!DST) - continue; - - // Don't use it if this actually came from the source module. They're in - // the same LLVMContext after all. Also don't use it unless the type is - // actually used in the destination module. This can happen in situations - // like this: - // - // Module A Module B - // -------- -------- - // %Z = type { %A } %B = type { %C.1 } - // %A = type { %B.1, [7 x i8] } %C.1 = type { i8* } - // %B.1 = type { %C } %A.2 = type { %B.3, [5 x i8] } - // %C = type { i8* } %B.3 = type { %C.1 } - // - // When we link Module B with Module A, the '%B' in Module B is - // used. However, that would then use '%C.1'. But when we process '%C.1', - // we prefer to take the '%C' version. So we are then left with both - // '%C.1' and '%C' being used for the same types. This leads to some - // variables using one type and some using the other. - if (TypeMap.DstStructTypesSet.hasType(DST)) - TypeMap.addTypeMapping(DST, ST); - } - - // 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(); -} - -static void getArrayElements(const Constant *C, - SmallVectorImpl &Dest) { - unsigned NumElements = cast(C->getType())->getNumElements(); - - for (unsigned i = 0; i != NumElements; ++i) - Dest.push_back(C->getAggregateElement(i)); -} - -/// If there were any appending global variables, link them together now. -/// Return true on error. -Constant *ModuleLinker::linkAppendingVarProto(GlobalVariable *DstGV, - const GlobalVariable *SrcGV) { - Type *EltTy = cast(TypeMap.get(SrcGV->getType()->getElementType())) - ->getElementType(); - - StringRef Name = SrcGV->getName(); - bool IsNewStructor = false; - bool IsOldStructor = false; - if (Name == "llvm.global_ctors" || Name == "llvm.global_dtors") { - if (cast(EltTy)->getNumElements() == 3) - IsNewStructor = true; - else - IsOldStructor = true; - } - - PointerType *VoidPtrTy = Type::getInt8Ty(SrcGV->getContext())->getPointerTo(); - if (IsOldStructor) { - auto &ST = *cast(EltTy); - Type *Tys[3] = {ST.getElementType(0), ST.getElementType(1), VoidPtrTy}; - EltTy = StructType::get(SrcGV->getContext(), Tys, false); - } - - if (DstGV) { - ArrayType *DstTy = cast(DstGV->getType()->getElementType()); - - if (!SrcGV->hasAppendingLinkage() || !DstGV->hasAppendingLinkage()) { - emitError( - "Linking globals named '" + SrcGV->getName() + - "': can only link appending global with another appending global!"); - return nullptr; - } - - // 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 (DstGV->getAlignment() != SrcGV->getAlignment()) { - emitError( - "Appending variables with different alignment need to be linked!"); - return nullptr; - } - - if (DstGV->getVisibility() != SrcGV->getVisibility()) { - emitError( - "Appending variables with different visibility need to be linked!"); - return nullptr; - } - - if (DstGV->hasUnnamedAddr() != SrcGV->hasUnnamedAddr()) { - emitError( - "Appending variables with different unnamed_addr need to be linked!"); - return nullptr; - } - - if (StringRef(DstGV->getSection()) != SrcGV->getSection()) { - emitError( - "Appending variables with different section name need to be linked!"); - return nullptr; - } - } - - SmallVector DstElements; - if (DstGV) - getArrayElements(DstGV->getInitializer(), DstElements); - - SmallVector SrcElements; - getArrayElements(SrcGV->getInitializer(), SrcElements); - - if (IsNewStructor) - SrcElements.erase( - std::remove_if(SrcElements.begin(), SrcElements.end(), - [this](Constant *E) { - auto *Key = dyn_cast( - E->getAggregateElement(2)->stripPointerCasts()); - return Key && !ValuesToLink.count(Key) && - !shouldLazyLink(*Key); - }), - SrcElements.end()); - uint64_t NewSize = DstElements.size() + SrcElements.size(); - ArrayType *NewType = ArrayType::get(EltTy, NewSize); - - // Create the new global variable. - GlobalVariable *NG = new GlobalVariable( - DstM, NewType, SrcGV->isConstant(), SrcGV->getLinkage(), - /*init*/ nullptr, /*name*/ "", DstGV, SrcGV->getThreadLocalMode(), - SrcGV->getType()->getAddressSpace()); - - // Propagate alignment, visibility and section info. - copyGVAttributes(NG, SrcGV); - - 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(V); - auto *E1 = MapValue(S->getOperand(0), ValueMap, RF_MoveDistinctMDs, - &TypeMap, &ValMaterializer); - auto *E2 = MapValue(S->getOperand(1), ValueMap, RF_MoveDistinctMDs, - &TypeMap, &ValMaterializer); - Value *Null = Constant::getNullValue(VoidPtrTy); - NewV = - ConstantStruct::get(cast(EltTy), E1, E2, Null, nullptr); - } else { - NewV = - MapValue(V, ValueMap, RF_MoveDistinctMDs, &TypeMap, &ValMaterializer); - } - DstElements.push_back(NewV); - } - - NG->setInitializer(ConstantArray::get(NewType, DstElements)); - - // Replace any uses of the two global variables with uses of the new - // global. - if (DstGV) { - DstGV->replaceAllUsesWith(ConstantExpr::getBitCast(NG, DstGV->getType())); - DstGV->eraseFromParent(); - } - - return Ret; -} - -Constant *ModuleLinker::linkGlobalValueProto(GlobalValue *SGV) { - GlobalValue *DGV = getLinkedToGlobal(SGV); - - // Handle the ultra special appending linkage case first. - assert(!DGV || SGV->hasAppendingLinkage() == DGV->hasAppendingLinkage()); - if (SGV->hasAppendingLinkage()) { - // Should have prevented importing for appending linkage in linkIfNeeded. - assert(!isPerformingImport()); - return linkAppendingVarProto(cast_or_null(DGV), - cast(SGV)); - } - - bool LinkFromSrc = true; - Comdat *C = nullptr; - bool HasUnnamedAddr = SGV->hasUnnamedAddr(); - - if (isPerformingImport() && !doImportAsDefinition(SGV)) { - LinkFromSrc = false; - } else if (const Comdat *SC = SGV->getComdat()) { - Comdat::SelectionKind SK; - std::tie(SK, LinkFromSrc) = ComdatsChosen[SC]; - C = DstM.getOrInsertComdat(SC->getName()); - C->setSelectionKind(SK); - if (SGV->hasLocalLinkage()) - LinkFromSrc = true; - } else if (DGV) { - if (shouldLinkFromSource(LinkFromSrc, *DGV, *SGV)) - return nullptr; - } - - if (DGV) - HasUnnamedAddr = HasUnnamedAddr && DGV->hasUnnamedAddr(); - - GlobalValue *NewGV; - if (!LinkFromSrc && DGV) { - NewGV = DGV; - } else { - // If we are done linking global value bodies (i.e. we are performing - // metadata linking), don't link in the global value due to this - // reference, simply map it to null. - if (DoneLinkingBodies) - return nullptr; - - NewGV = copyGlobalValueProto(SGV, LinkFromSrc); - } - - setVisibility(NewGV, SGV, DGV); - NewGV->setUnnamedAddr(HasUnnamedAddr); - - if (auto *NewGO = dyn_cast(NewGV)) { - if (C && LinkFromSrc) - NewGO->setComdat(C); - - if (DGV && DGV->hasCommonLinkage() && SGV->hasCommonLinkage()) - NewGO->setAlignment(std::max(DGV->getAlignment(), SGV->getAlignment())); - } - - if (auto *NewGVar = dyn_cast(NewGV)) { - auto *DGVar = dyn_cast_or_null(DGV); - auto *SGVar = dyn_cast(SGV); - if (DGVar && SGVar && DGVar->isDeclaration() && SGVar->isDeclaration() && - (!DGVar->isConstant() || !SGVar->isConstant())) - NewGVar->setConstant(false); - } - - if (NewGV != DGV && DGV) { - DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewGV, DGV->getType())); - DGV->eraseFromParent(); - } - - return ConstantExpr::getBitCast(NewGV, TypeMap.get(SGV->getType())); -} - -/// Update the initializers in the Dest module now that all globals that may be -/// referenced are in Dest. -void ModuleLinker::linkGlobalInit(GlobalVariable &Dst, GlobalVariable &Src) { - // Figure out what the initializer looks like in the dest module. - Dst.setInitializer(MapValue(Src.getInitializer(), ValueMap, - RF_MoveDistinctMDs, &TypeMap, &ValMaterializer)); -} - -/// 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 ModuleLinker::linkFunctionBody(Function &Dst, Function &Src) { - assert(Dst.isDeclaration() && !Src.isDeclaration()); - - // Materialize if needed. - if (std::error_code EC = Src.materialize()) - return emitError(EC.message()); - - // Link in the prefix data. - if (Src.hasPrefixData()) - Dst.setPrefixData(MapValue(Src.getPrefixData(), ValueMap, - RF_MoveDistinctMDs, &TypeMap, &ValMaterializer)); - - // Link in the prologue data. - if (Src.hasPrologueData()) - Dst.setPrologueData(MapValue(Src.getPrologueData(), ValueMap, - RF_MoveDistinctMDs, &TypeMap, - &ValMaterializer)); - - // Link in the personality function. - if (Src.hasPersonalityFn()) - Dst.setPersonalityFn(MapValue(Src.getPersonalityFn(), ValueMap, - RF_MoveDistinctMDs, &TypeMap, - &ValMaterializer)); - - // 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; - } - - // Copy over the metadata attachments. - SmallVector, 8> MDs; - Src.getAllMetadata(MDs); - for (const auto &I : MDs) - Dst.setMetadata(I.first, MapMetadata(I.second, ValueMap, RF_MoveDistinctMDs, - &TypeMap, &ValMaterializer)); - - // 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 (BasicBlock &BB : Dst) - for (Instruction &I : BB) - RemapInstruction(&I, ValueMap, - RF_IgnoreMissingEntries | RF_MoveDistinctMDs, &TypeMap, - &ValMaterializer); - - // There is no need to map the arguments anymore. - for (Argument &Arg : Src.args()) - ValueMap.erase(&Arg); - - Src.dematerialize(); - return false; -} - -void ModuleLinker::linkAliasBody(GlobalAlias &Dst, GlobalAlias &Src) { - Constant *Aliasee = Src.getAliasee(); - Constant *Val = MapValue(Aliasee, ValueMap, RF_MoveDistinctMDs, &TypeMap, - &ValMaterializer); - Dst.setAliasee(Val); -} - -bool ModuleLinker::linkGlobalValueBody(GlobalValue &Dst, GlobalValue &Src) { - if (const Comdat *SC = Src.getComdat()) { - // To ensure that we don't generate an incomplete comdat group, - // we must materialize and map in any other members that are not - // yet materialized in Dst, which also ensures their definitions - // are linked in. Otherwise, linkonce and other lazy linked GVs will - // not be materialized if they aren't referenced. - for (auto *SGV : ComdatMembers[SC]) { - auto *DGV = cast_or_null(ValueMap.lookup(SGV)); - if (DGV && !DGV->isDeclaration()) - continue; - MapValue(SGV, ValueMap, RF_MoveDistinctMDs, &TypeMap, &ValMaterializer); - } - } - if (shouldInternalizeLinkedSymbols()) - if (auto *DGV = dyn_cast(&Dst)) - DGV->setLinkage(GlobalValue::InternalLinkage); - if (auto *F = dyn_cast(&Src)) - return linkFunctionBody(cast(Dst), *F); - if (auto *GVar = dyn_cast(&Src)) { - linkGlobalInit(cast(Dst), *GVar); - return false; - } - linkAliasBody(cast(Dst), cast(Src)); - return false; -} - -/// Insert all of the named MDNodes in Src into the Dest module. -void ModuleLinker::linkNamedMDNodes() { - 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, RF_MoveDistinctMDs | RF_NullMapMissingGlobalValues, - &TypeMap, &ValMaterializer)); - } -} - -/// 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(); - if (!SrcModFlags) - return false; - - // If the destination module doesn't have module flags yet, then just copy - // over the source module's flags. - NamedMDNode *DstModFlags = DstM.getOrInsertModuleFlagsMetadata(); - if (DstModFlags->getNumOperands() == 0) { - for (unsigned I = 0, E = SrcModFlags->getNumOperands(); I != E; ++I) - DstModFlags->addOperand(SrcModFlags->getOperand(I)); - - return false; - } - - // First build a map of the existing module flags and requirements. - DenseMap> Flags; - SmallSetVector Requirements; - for (unsigned I = 0, E = DstModFlags->getNumOperands(); I != E; ++I) { - MDNode *Op = DstModFlags->getOperand(I); - ConstantInt *Behavior = mdconst::extract(Op->getOperand(0)); - MDString *ID = cast(Op->getOperand(1)); - - if (Behavior->getZExtValue() == Module::Require) { - Requirements.insert(cast(Op->getOperand(2))); - } else { - Flags[ID] = std::make_pair(Op, I); - } - } - - // Merge in the flags from the source module, and also collect its set of - // requirements. - for (unsigned I = 0, E = SrcModFlags->getNumOperands(); I != E; ++I) { - MDNode *SrcOp = SrcModFlags->getOperand(I); - ConstantInt *SrcBehavior = - mdconst::extract(SrcOp->getOperand(0)); - MDString *ID = cast(SrcOp->getOperand(1)); - MDNode *DstOp; - unsigned DstIndex; - std::tie(DstOp, DstIndex) = Flags.lookup(ID); - unsigned SrcBehaviorValue = SrcBehavior->getZExtValue(); - - // If this is a requirement, add it and continue. - if (SrcBehaviorValue == Module::Require) { - // If the destination module does not already have this requirement, add - // it. - if (Requirements.insert(cast(SrcOp->getOperand(2)))) { - DstModFlags->addOperand(SrcOp); - } - continue; - } - - // If there is no existing flag with this ID, just add it. - if (!DstOp) { - Flags[ID] = std::make_pair(SrcOp, DstModFlags->getNumOperands()); - DstModFlags->addOperand(SrcOp); - continue; - } - - // Otherwise, perform a merge. - ConstantInt *DstBehavior = - mdconst::extract(DstOp->getOperand(0)); - unsigned DstBehaviorValue = DstBehavior->getZExtValue(); - - // If either flag has override behavior, handle it first. - 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"); - } - continue; - } else if (SrcBehaviorValue == Module::Override) { - // Update the destination flag to that of the source. - DstModFlags->setOperand(DstIndex, SrcOp); - Flags[ID].first = SrcOp; - continue; - } - - // Diagnose inconsistent merge behavior types. - if (SrcBehaviorValue != DstBehaviorValue) { - emitError("linking module flags '" + ID->getString() + - "': IDs have conflicting behaviors"); - continue; - } - - auto replaceDstValue = [&](MDNode *New) { - Metadata *FlagOps[] = {DstOp->getOperand(0), ID, New}; - MDNode *Flag = MDNode::get(DstM.getContext(), FlagOps); - DstModFlags->setOperand(DstIndex, Flag); - Flags[ID].first = Flag; - }; - - // Perform the merge for standard behavior types. - switch (SrcBehaviorValue) { - case Module::Require: - case Module::Override: - 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"); - } - continue; - } - case Module::Warning: { - // Emit a warning if the values differ. - if (SrcOp->getOperand(2) != DstOp->getOperand(2)) { - emitWarning("linking module flags '" + ID->getString() + - "': IDs have conflicting values"); - } - continue; - } - case Module::Append: { - MDNode *DstValue = cast(DstOp->getOperand(2)); - MDNode *SrcValue = cast(SrcOp->getOperand(2)); - SmallVector MDs; - MDs.reserve(DstValue->getNumOperands() + SrcValue->getNumOperands()); - MDs.append(DstValue->op_begin(), DstValue->op_end()); - MDs.append(SrcValue->op_begin(), SrcValue->op_end()); - - replaceDstValue(MDNode::get(DstM.getContext(), MDs)); - break; - } - case Module::AppendUnique: { - SmallSetVector Elts; - MDNode *DstValue = cast(DstOp->getOperand(2)); - MDNode *SrcValue = cast(SrcOp->getOperand(2)); - Elts.insert(DstValue->op_begin(), DstValue->op_end()); - Elts.insert(SrcValue->op_begin(), SrcValue->op_end()); - - replaceDstValue(MDNode::get(DstM.getContext(), - makeArrayRef(Elts.begin(), Elts.end()))); - break; - } - } - } - - // Check all of the requirements. - for (unsigned I = 0, E = Requirements.size(); I != E; ++I) { - MDNode *Requirement = Requirements[I]; - MDString *Flag = cast(Requirement->getOperand(0)); - 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; - } - } - - return HasError; -} - -// This function returns true if the triples match. -static bool triplesMatch(const Triple &T0, const Triple &T1) { - // If vendor is apple, ignore the version number. - if (T0.getVendor() == Triple::Apple) - return T0.getArch() == T1.getArch() && T0.getSubArch() == T1.getSubArch() && - T0.getVendor() == T1.getVendor() && T0.getOS() == T1.getOS(); - - return T0 == T1; -} - -// This function returns the merged triple. -static std::string mergeTriples(const Triple &SrcTriple, - const Triple &DstTriple) { - // If vendor is apple, pick the triple with the larger version number. - if (SrcTriple.getVendor() == Triple::Apple) - if (DstTriple.isOSVersionLT(SrcTriple)) - return SrcTriple.str(); - - return DstTriple.str(); -} - bool ModuleLinker::linkIfNeeded(GlobalValue &GV) { GlobalValue *DGV = getLinkedToGlobal(&GV); @@ -1772,47 +674,49 @@ return false; } -bool ModuleLinker::run() { - // 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()); - - if (SrcM.getDataLayout() != DstM.getDataLayout()) { - emitWarning("Linking two modules of different data layouts: '" + - 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()); - - Triple SrcTriple(SrcM.getTargetTriple()), DstTriple(DstM.getTargetTriple()); +void ModuleLinker::addLazyFor(GlobalValue &GV, IRMover::ValueAdder Add) { + // Add these to the internalize list + if (!GV.hasLinkOnceLinkage()) + return; - 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"); + if (shouldInternalizeLinkedSymbols()) + Internalize.insert(GV.getName()); + Add(GV); - DstM.setTargetTriple(mergeTriples(SrcTriple, DstTriple)); + const Comdat *SC = GV.getComdat(); + if (!SC) + return; + for (GlobalValue *GV2 : ComdatMembers[SC]) { + if (!GV2->hasLocalLinkage() && shouldInternalizeLinkedSymbols()) + Internalize.insert(GV2->getName()); + Add(*GV2); + } +} - // Append the module inline asm string. - if (!SrcM.getModuleInlineAsm().empty()) { - if (DstM.getModuleInlineAsm().empty()) - DstM.setModuleInlineAsm(SrcM.getModuleInlineAsm()); - else - DstM.setModuleInlineAsm(DstM.getModuleInlineAsm() + "\n" + - SrcM.getModuleInlineAsm()); +void ModuleLinker::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()) + ValuesToLink.insert(&GV); + return; } + GV.setLinkage(getLinkage(&GV)); +} - // Loop over all of the linked values to compute type mappings. - computeTypeMapping(); +void ModuleLinker::processGlobalsForThinLTO() { + for (GlobalVariable &GV : SrcM.globals()) + processGlobalForThinLTO(GV); + for (Function &SF : SrcM) + processGlobalForThinLTO(SF); + for (GlobalAlias &GA : SrcM.aliases()) + processGlobalForThinLTO(GA); +} - ComdatsChosen.clear(); +bool ModuleLinker::run() { for (const auto &SMEC : SrcM.getComdatSymbolTable()) { const Comdat &C = SMEC.getValue(); if (ComdatsChosen.count(&C)) @@ -1850,138 +754,45 @@ if (linkIfNeeded(GA)) return true; - for (GlobalValue *GV : ValuesToLink) { - MapValue(GV, ValueMap, RF_MoveDistinctMDs, &TypeMap, &ValMaterializer); - if (HasError) - return true; - } + processGlobalsForThinLTO(); - // Note that we are done linking global value bodies. This prevents - // metadata linking from creating new references. - DoneLinkingBodies = true; + 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); + } - // 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. - linkNamedMDNodes(); + if (shouldInternalizeLinkedSymbols()) { + for (GlobalValue *GV : ValuesToLink) + Internalize.insert(GV->getName()); + } - // Merge the module flags into the DstM module. - if (linkModuleFlagsMetadata()) + if (Mover.move(SrcM, + makeArrayRef(&*ValuesToLink.begin(), ValuesToLink.size()), + [this](GlobalValue &GV, IRMover::ValueAdder Add) { + addLazyFor(GV, Add); + })) return true; + Module &DstM = Mover.getModule(); + for (auto &P : Internalize) { + GlobalValue *GV = DstM.getNamedValue(P.first()); + GV->setLinkage(GlobalValue::InternalLinkage); + } return false; } -Linker::StructTypeKeyInfo::KeyTy::KeyTy(ArrayRef E, bool P) - : ETypes(E), IsPacked(P) {} - -Linker::StructTypeKeyInfo::KeyTy::KeyTy(const StructType *ST) - : ETypes(ST->elements()), IsPacked(ST->isPacked()) {} - -bool Linker::StructTypeKeyInfo::KeyTy::operator==(const KeyTy &That) const { - if (IsPacked != That.IsPacked) - return false; - if (ETypes != That.ETypes) - return false; - return true; -} - -bool Linker::StructTypeKeyInfo::KeyTy::operator!=(const KeyTy &That) const { - return !this->operator==(That); -} - -StructType *Linker::StructTypeKeyInfo::getEmptyKey() { - return DenseMapInfo::getEmptyKey(); -} - -StructType *Linker::StructTypeKeyInfo::getTombstoneKey() { - return DenseMapInfo::getTombstoneKey(); -} - -unsigned Linker::StructTypeKeyInfo::getHashValue(const KeyTy &Key) { - return hash_combine(hash_combine_range(Key.ETypes.begin(), Key.ETypes.end()), - Key.IsPacked); -} - -unsigned Linker::StructTypeKeyInfo::getHashValue(const StructType *ST) { - return getHashValue(KeyTy(ST)); -} - -bool Linker::StructTypeKeyInfo::isEqual(const KeyTy &LHS, - const StructType *RHS) { - if (RHS == getEmptyKey() || RHS == getTombstoneKey()) - return false; - return LHS == KeyTy(RHS); -} - -bool Linker::StructTypeKeyInfo::isEqual(const StructType *LHS, - const StructType *RHS) { - if (RHS == getEmptyKey()) - return LHS == getEmptyKey(); - - if (RHS == getTombstoneKey()) - return LHS == getTombstoneKey(); - - return KeyTy(LHS) == KeyTy(RHS); -} - -void Linker::IdentifiedStructTypeSet::addNonOpaque(StructType *Ty) { - assert(!Ty->isOpaque()); - NonOpaqueStructTypes.insert(Ty); -} - -void Linker::IdentifiedStructTypeSet::switchToNonOpaque(StructType *Ty) { - assert(!Ty->isOpaque()); - NonOpaqueStructTypes.insert(Ty); - bool Removed = OpaqueStructTypes.erase(Ty); - (void)Removed; - assert(Removed); -} - -void Linker::IdentifiedStructTypeSet::addOpaque(StructType *Ty) { - assert(Ty->isOpaque()); - OpaqueStructTypes.insert(Ty); -} - -StructType * -Linker::IdentifiedStructTypeSet::findNonOpaque(ArrayRef ETypes, - bool IsPacked) { - Linker::StructTypeKeyInfo::KeyTy Key(ETypes, IsPacked); - auto I = NonOpaqueStructTypes.find_as(Key); - if (I == NonOpaqueStructTypes.end()) - return nullptr; - return *I; -} - -bool Linker::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; -} - Linker::Linker(Module &M, DiagnosticHandlerFunction DiagnosticHandler) - : Composite(M), DiagnosticHandler(DiagnosticHandler) { - TypeFinder StructTypes; - StructTypes.run(M, true); - for (StructType *Ty : StructTypes) { - if (Ty->isOpaque()) - IdentifiedStructTypes.addOpaque(Ty); - else - IdentifiedStructTypes.addNonOpaque(Ty); - } -} + : Mover(M, DiagnosticHandler) {} bool Linker::linkInModule(Module &Src, unsigned Flags, const FunctionInfoIndex *Index, DenseSet *FunctionsToImport) { - ModuleLinker TheLinker(Composite, IdentifiedStructTypes, Src, - DiagnosticHandler, Flags, Index, FunctionsToImport); - bool RetCode = TheLinker.run(); - Composite.dropTriviallyDeadConstantArrays(); - return RetCode; + ModuleLinker TheLinker(Mover, Src, Flags, Index, FunctionsToImport); + return TheLinker.run(); } //===----------------------------------------------------------------------===// Index: test/Linker/alias.ll =================================================================== --- test/Linker/alias.ll +++ test/Linker/alias.ll @@ -1,16 +1,37 @@ -; RUN: llvm-link %s %S/Inputs/alias.ll -S -o - | FileCheck %s -; RUN: llvm-link %S/Inputs/alias.ll %s -S -o - | FileCheck %s +; RUN: llvm-link %s %S/Inputs/alias.ll -S -o - | FileCheck --check-prefix=C1 %s +; RUN: llvm-link %S/Inputs/alias.ll %s -S -o - | FileCheck --check-prefix=C2 %s + +; FIXME: +; The C1 direction is incorrect. +; When moving an alias to an existing module and we want to discard the aliasee +; (the C2 case), the IRMover knows to copy the aliasee as internal. +; When moving a replacement to an aliasee to a module that has an alias (C1), +; a replace all uses with blindly changes the alias. +; The C1 case doesn't happen when using a system linker with a plugin because +; the linker does full symbol resolution first. +; Given that this is a problem only with llvm-link and its 1 module at a time +; linking, it should probably learn to changes the aliases in the destination +; before using the IRMover. @foo = weak global i32 0 -; CHECK-DAG: @foo = alias i32, i32* @zed +; C1-DAG: @foo = alias i32, i32* @zed +; C2-DAG: @foo = alias i32, i32* @zed @bar = alias i32, i32* @foo -; CHECK-DAG: @bar = alias i32, i32* @foo +; C1-DAG: @bar = alias i32, i32* @foo + +; C2-DAG: @foo.1 = internal global i32 0 +; C2-DAG: @bar = alias i32, i32* @foo.1 @foo2 = weak global i32 0 -; CHECK-DAG: @foo2 = alias i16, bitcast (i32* @zed to i16*) +; C1-DAG: @foo2 = alias i16, bitcast (i32* @zed to i16*) +; C2-DAG: @foo2 = alias i16, bitcast (i32* @zed to i16*) @bar2 = alias i32, i32* @foo2 -; CHECK-DAG: @bar2 = alias i32, bitcast (i16* @foo2 to i32*) +; C1-DAG: @bar2 = alias i32, bitcast (i16* @foo2 to i32*) + +; C2-DAG: @foo2.2 = internal global i32 0 +; C2-DAG: @bar2 = alias i32, i32* @foo2.2 -; CHECK-DAG: @zed = global i32 42 +; C1-DAG: @zed = global i32 42 +; C2-DAG: @zed = global i32 42 Index: test/tools/gold/X86/drop-linkage.ll =================================================================== --- test/tools/gold/X86/drop-linkage.ll +++ test/tools/gold/X86/drop-linkage.ll @@ -11,4 +11,4 @@ ret void } -; CHECK: declare void @foo(){{$}} +; CHECK: declare extern_weak void @foo(){{$}} Index: tools/gold/gold-plugin.cpp =================================================================== --- tools/gold/gold-plugin.cpp +++ tools/gold/gold-plugin.cpp @@ -29,7 +29,7 @@ #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" #include "llvm/IR/Verifier.h" -#include "llvm/Linker/Linker.h" +#include "llvm/Linker/IRMover.h" #include "llvm/MC/SubtargetFeature.h" #include "llvm/Object/FunctionIndexObjectFile.h" #include "llvm/Object/IRObjectFile.h" @@ -62,6 +62,17 @@ void *handle; std::vector syms; }; + +struct ResolutionInfo { + bool IsLinkonceOdr = true; + bool UnnamedAddr = true; + GlobalValue::VisibilityTypes Visibility = GlobalValue::DefaultVisibility; + bool CommonInternal = false; + bool UseCommon = false; + unsigned CommonSize = 0; + unsigned CommonAlign = 0; + claimed_file *CommonFile = nullptr; +}; } static ld_plugin_status discard_message(int level, const char *format, ...) { @@ -81,6 +92,7 @@ static Reloc::Model RelocationModel = Reloc::Default; static std::string output_name = ""; static std::list Modules; +static StringMap ResInfo; static std::vector Cleanup; static llvm::TargetOptions TargetOpts; @@ -332,6 +344,18 @@ diagnosticHandler(DI); } +static GlobalValue::VisibilityTypes +getMinVisibility(GlobalValue::VisibilityTypes A, + GlobalValue::VisibilityTypes B) { + if (A == GlobalValue::HiddenVisibility) + return A; + if (B == GlobalValue::HiddenVisibility) + return B; + if (A == GlobalValue::ProtectedVisibility) + return A; + return B; +} + /// Called by gold to see whether this file is one that our plugin can handle. /// We'll try to open it and register all the symbols with add_symbol if /// possible. @@ -411,8 +435,22 @@ const GlobalValue *GV = Obj->getSymbolGV(Sym.getRawDataRefImpl()); + ResolutionInfo &Res = ResInfo[sym.name]; + sym.visibility = LDPV_DEFAULT; if (GV) { + Res.UnnamedAddr &= GV->hasUnnamedAddr(); + Res.IsLinkonceOdr &= GV->hasLinkOnceLinkage(); + if (GV->hasCommonLinkage()) { + Res.CommonAlign = std::max(Res.CommonAlign, GV->getAlignment()); + const DataLayout &DL = GV->getParent()->getDataLayout(); + uint64_t Size = DL.getTypeAllocSize(GV->getType()->getElementType()); + if (Size >= Res.CommonSize) { + Res.CommonSize = Size; + Res.CommonFile = &cf; + } + } + Res.Visibility = getMinVisibility(Res.Visibility, GV->getVisibility()); switch (GV->getVisibility()) { case GlobalValue::DefaultVisibility: sym.visibility = LDPV_DEFAULT; @@ -466,27 +504,6 @@ return LDPS_OK; } -static void keepGlobalValue(GlobalValue &GV, - std::vector &KeptAliases) { - assert(!GV.hasLocalLinkage()); - - if (auto *GA = dyn_cast(&GV)) - KeptAliases.push_back(GA); - - switch (GV.getLinkage()) { - default: - break; - case GlobalValue::LinkOnceAnyLinkage: - GV.setLinkage(GlobalValue::WeakAnyLinkage); - break; - case GlobalValue::LinkOnceODRLinkage: - GV.setLinkage(GlobalValue::WeakODRLinkage); - break; - } - - assert(!GV.isDiscardableIfUnused()); -} - static void internalize(GlobalValue &GV) { if (GV.isDeclarationForLinker()) return; // We get here if there is a matching asm definition. @@ -494,33 +511,6 @@ GV.setLinkage(GlobalValue::InternalLinkage); } -static void drop(GlobalValue &GV) { - if (auto *F = dyn_cast(&GV)) { - F->deleteBody(); - F->setComdat(nullptr); // Should deleteBody do this? - return; - } - - if (auto *Var = dyn_cast(&GV)) { - Var->setInitializer(nullptr); - Var->setLinkage( - GlobalValue::ExternalLinkage); // Should setInitializer do this? - Var->setComdat(nullptr); // and this? - return; - } - - auto &Alias = cast(GV); - Module &M = *Alias.getParent(); - PointerType &Ty = *cast(Alias.getType()); - GlobalValue::LinkageTypes L = Alias.getLinkage(); - auto *Var = - new GlobalVariable(M, Ty.getElementType(), /*isConstant*/ false, L, - /*Initializer*/ nullptr); - Var->takeName(&Alias); - Alias.replaceAllUsesWith(Var); - Alias.eraseFromParent(); -} - static const char *getResolutionName(ld_plugin_symbol_resolution R) { switch (R) { case LDPR_UNKNOWN: @@ -547,58 +537,6 @@ llvm_unreachable("Unknown resolution"); } -namespace { -class LocalValueMaterializer final : public ValueMaterializer { - DenseSet &Dropped; - DenseMap LocalVersions; - -public: - LocalValueMaterializer(DenseSet &Dropped) : Dropped(Dropped) {} - Value *materializeDeclFor(Value *V) override; -}; -} - -Value *LocalValueMaterializer::materializeDeclFor(Value *V) { - auto *GO = dyn_cast(V); - if (!GO) - return nullptr; - - auto I = LocalVersions.find(GO); - if (I != LocalVersions.end()) - return I->second; - - if (!Dropped.count(GO)) - return nullptr; - - Module &M = *GO->getParent(); - GlobalValue::LinkageTypes L = GO->getLinkage(); - GlobalObject *Declaration; - if (auto *F = dyn_cast(GO)) { - Declaration = Function::Create(F->getFunctionType(), L, "", &M); - } else { - auto *Var = cast(GO); - Declaration = new GlobalVariable(M, Var->getType()->getElementType(), - Var->isConstant(), L, - /*Initializer*/ nullptr); - } - Declaration->takeName(GO); - Declaration->copyAttributesFrom(GO); - - GO->setLinkage(GlobalValue::InternalLinkage); - GO->setName(Declaration->getName()); - Dropped.erase(GO); - GO->replaceAllUsesWith(Declaration); - - LocalVersions[Declaration] = GO; - - return GO; -} - -static Constant *mapConstantToLocalCopy(Constant *C, ValueToValueMapTy &VM, - LocalValueMaterializer *Materializer) { - return MapValue(C, VM, RF_IgnoreMissingEntries, nullptr, Materializer); -} - static void freeSymName(ld_plugin_symbol &Sym) { free(Sym.name); free(Sym.comdat_key); @@ -640,7 +578,8 @@ static std::unique_ptr getModuleForFile(LLVMContext &Context, claimed_file &F, ld_plugin_input_file &Info, raw_fd_ostream *ApiFile, - StringSet<> &Internalize, StringSet<> &Maybe) { + StringSet<> &Internalize, StringSet<> &Maybe, + std::vector &Keep) { if (get_symbols(F.handle, F.syms.size(), F.syms.data()) != LDPS_OK) message(LDPL_FATAL, "Failed to get symbol information"); @@ -668,11 +607,12 @@ SmallPtrSet Used; collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false); - DenseSet Drop; - std::vector KeptAliases; - unsigned SymNum = 0; for (auto &ObjSym : Obj.symbols()) { + GlobalValue *GV = Obj.getSymbolGV(ObjSym.getRawDataRefImpl()); + if (GV && GV->hasAppendingLinkage()) + Keep.push_back(GV); + if (shouldSkip(ObjSym.getFlags())) continue; ld_plugin_symbol &Sym = F.syms[SymNum]; @@ -684,20 +624,37 @@ if (options::generate_api_file) *ApiFile << Sym.name << ' ' << getResolutionName(Resolution) << '\n'; - GlobalValue *GV = Obj.getSymbolGV(ObjSym.getRawDataRefImpl()); if (!GV) { freeSymName(Sym); continue; // Asm symbol. } - if (Resolution != LDPR_PREVAILING_DEF_IRONLY && GV->hasCommonLinkage()) { - // Common linkage is special. There is no single symbol that wins the - // resolution. Instead we have to collect the maximum alignment and size. - // The IR linker does that for us if we just pass it every common GV. - // We still have to keep track of LDPR_PREVAILING_DEF_IRONLY so we - // internalize once the IR linker has done its job. - freeSymName(Sym); - continue; + ResolutionInfo &Res = ResInfo[Sym.name]; + if (Resolution == LDPR_PREVAILING_DEF_IRONLY_EXP && !Res.IsLinkonceOdr) + Resolution = LDPR_PREVAILING_DEF; + + GV->setUnnamedAddr(Res.UnnamedAddr); + GV->setVisibility(Res.Visibility); + + // Override gold's resolution for common symbols. We want the largest + // one to win. + if (GV->hasCommonLinkage()) { + cast(GV)->setAlignment(Res.CommonAlign); + if (Resolution == LDPR_PREVAILING_DEF_IRONLY) + Res.CommonInternal = true; + + if (Resolution == LDPR_PREVAILING_DEF_IRONLY || + Resolution == LDPR_PREVAILING_DEF) + Res.UseCommon = true; + + if (Res.CommonFile == &F && Res.UseCommon) { + if (Res.CommonInternal) + Resolution = LDPR_PREVAILING_DEF_IRONLY; + else + Resolution = LDPR_PREVAILING_DEF; + } else { + Resolution = LDPR_PREEMPTED_IR; + } } switch (Resolution) { @@ -707,40 +664,37 @@ case LDPR_RESOLVED_IR: case LDPR_RESOLVED_EXEC: case LDPR_RESOLVED_DYN: - assert(GV->isDeclarationForLinker()); + case LDPR_PREEMPTED_IR: + case LDPR_PREEMPTED_REG: break; case LDPR_UNDEF: - if (!GV->isDeclarationForLinker()) { + if (!GV->isDeclarationForLinker()) assert(GV->hasComdat()); - Drop.insert(GV); - } break; case LDPR_PREVAILING_DEF_IRONLY: { - keepGlobalValue(*GV, KeptAliases); - if (!Used.count(GV)) { - // Since we use the regular lib/Linker, we cannot just internalize GV - // now or it will not be copied to the merged module. Instead we force - // it to be copied and then internalize it. + Keep.push_back(GV); + // The IR linker has to be able to map this value to a declaration, + // so we can only internalize after linking. + if (!Used.count(GV)) Internalize.insert(GV->getName()); - } break; } case LDPR_PREVAILING_DEF: - keepGlobalValue(*GV, KeptAliases); - break; - - case LDPR_PREEMPTED_IR: - // Gold might have selected a linkonce_odr and preempted a weak_odr. - // In that case we have to make sure we don't end up internalizing it. - if (!GV->isDiscardableIfUnused()) - Maybe.erase(GV->getName()); - - // fall-through - case LDPR_PREEMPTED_REG: - Drop.insert(GV); + Keep.push_back(GV); + // There is a non IR use, so we have to force optimizations to keep this. + switch (GV->getLinkage()) { + default: + break; + case GlobalValue::LinkOnceAnyLinkage: + GV->setLinkage(GlobalValue::WeakAnyLinkage); + break; + case GlobalValue::LinkOnceODRLinkage: + GV->setLinkage(GlobalValue::WeakODRLinkage); + break; + } break; case LDPR_PREVAILING_DEF_IRONLY_EXP: { @@ -748,9 +702,8 @@ // reason is that this GV might have a copy in another module // and in that module the address might be significant, but that // copy will be LDPR_PREEMPTED_IR. - if (GV->hasLinkOnceODRLinkage()) - Maybe.insert(GV->getName()); - keepGlobalValue(*GV, KeptAliases); + Maybe.insert(GV->getName()); + Keep.push_back(GV); break; } } @@ -758,19 +711,6 @@ freeSymName(Sym); } - ValueToValueMapTy VM; - LocalValueMaterializer Materializer(Drop); - for (GlobalAlias *GA : KeptAliases) { - // Gold told us to keep GA. It is possible that a GV usied in the aliasee - // expression is being dropped. If that is the case, that GV must be copied. - Constant *Aliasee = GA->getAliasee(); - Constant *Replacement = mapConstantToLocalCopy(Aliasee, VM, &Materializer); - GA->setAliasee(Replacement); - } - - for (auto *GV : Drop) - drop(*GV); - return Obj.takeModule(); } @@ -941,7 +881,7 @@ Context.setDiagnosticHandler(diagnosticHandlerForContext, nullptr, true); std::unique_ptr Combined(new Module("ld-temp.o", Context)); - Linker L(*Combined, diagnosticHandler); + IRMover L(*Combined, diagnosticHandler); std::string DefaultTriple = sys::getDefaultTargetTriple(); @@ -951,15 +891,15 @@ ld_plugin_input_file File; if (get_input_file(F.handle, &File) != LDPS_OK) message(LDPL_FATAL, "Failed to get file information"); + std::vector Keep; std::unique_ptr M = - getModuleForFile(Context, F, File, ApiFile, Internalize, Maybe); + getModuleForFile(Context, F, File, ApiFile, Internalize, Maybe, Keep); if (!options::triple.empty()) M->setTargetTriple(options::triple.c_str()); - else if (M->getTargetTriple().empty()) { + else if (M->getTargetTriple().empty()) M->setTargetTriple(DefaultTriple); - } - if (L.linkInModule(*M)) + if (L.move(*M, Keep, [](GlobalValue &, IRMover::ValueAdder) {})) message(LDPL_FATAL, "Failed to link module"); if (release_input_file(F.handle) != LDPS_OK) message(LDPL_FATAL, "Failed to release file information");