X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FLinker%2FLinkModules.cpp;h=4d939a62f4bb76fac4d530cb58834cf7de8aca7c;hb=3beddeee6c59c4941da9c4b3659e42b9c92cd61d;hp=06710240c943d5fb28fc4347f4a372d84da338cf;hpb=968f0454b85489b7ee19e73774a50cff383fdafb;p=oota-llvm.git diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index 06710240c94..4d939a62f4b 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -18,7 +18,9 @@ #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Statistic.h" +#include "llvm/ADT/Triple.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DebugInfo.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/DiagnosticPrinter.h" #include "llvm/IR/LLVMContext.h" @@ -224,6 +226,7 @@ void TypeMapTy::linkDefinedTypeBodies() { Elements[I] = get(SrcSTy->getElementType(I)); DstSTy->setBody(Elements, SrcSTy->isPacked()); + DstStructTypesSet.switchToNonOpaque(DstSTy); } SrcDefinitionsToResolve.clear(); DstResolvedOpaqueTypes.clear(); @@ -365,13 +368,13 @@ class ModuleLinker; class ValueMaterializerTy : public ValueMaterializer { TypeMapTy &TypeMap; Module *DstM; - std::vector &LazilyLinkFunctions; + std::vector &LazilyLinkGlobalValues; public: ValueMaterializerTy(TypeMapTy &TypeMap, Module *DstM, - std::vector &LazilyLinkFunctions) + std::vector &LazilyLinkGlobalValues) : ValueMaterializer(), TypeMap(TypeMap), DstM(DstM), - LazilyLinkFunctions(LazilyLinkFunctions) {} + LazilyLinkGlobalValues(LazilyLinkGlobalValues) {} Value *materializeValueFor(Value *V) override; }; @@ -413,20 +416,32 @@ class ModuleLinker { // Set of items not to link in from source. SmallPtrSet DoNotLinkFromSource; - // Vector of functions to lazily link in. - std::vector LazilyLinkFunctions; + // Vector of GlobalValues to lazily link in. + std::vector LazilyLinkGlobalValues; - Linker::DiagnosticHandlerFunction DiagnosticHandler; + /// Functions that have replaced other functions. + SmallPtrSet OverridingFunctions; + + DiagnosticHandlerFunction DiagnosticHandler; + + /// For symbol clashes, prefer those from Src. + unsigned Flags; public: ModuleLinker(Module *dstM, Linker::IdentifiedStructTypeSet &Set, Module *srcM, - Linker::DiagnosticHandlerFunction DiagnosticHandler) + DiagnosticHandlerFunction DiagnosticHandler, unsigned Flags) : DstM(dstM), SrcM(srcM), TypeMap(Set), - ValMaterializer(TypeMap, DstM, LazilyLinkFunctions), - DiagnosticHandler(DiagnosticHandler) {} + ValMaterializer(TypeMap, DstM, LazilyLinkGlobalValues), + DiagnosticHandler(DiagnosticHandler), Flags(Flags) {} bool run(); + bool shouldOverrideFromSrc() { return Flags & Linker::OverrideFromSrc; } + bool shouldLinkOnlyNeeded() { return Flags & Linker::LinkOnlyNeeded; } + bool shouldInternalizeLinkedSymbols() { + return Flags & Linker::InternalizeLinkedSymbols; + } + private: bool shouldLinkFromSource(bool &LinkFromSrc, const GlobalValue &Dest, const GlobalValue &Src); @@ -484,17 +499,17 @@ private: const GlobalVariable *SrcGV); bool linkGlobalValueProto(GlobalValue *GV); - GlobalValue *linkGlobalVariableProto(const GlobalVariable *SGVar); - GlobalValue *linkFunctionProto(const Function *SF, GlobalValue *DGV); - GlobalValue *linkGlobalAliasProto(const GlobalAlias *SGA); - bool linkModuleFlagsMetadata(); void linkAppendingVarInit(const AppendingVarInfo &AVI); - void linkGlobalInits(); - bool linkFunctionBody(Function &Src); - void linkAliasBodies(); + + void linkGlobalInit(GlobalVariable &Dst, GlobalVariable &Src); + bool linkFunctionBody(Function &Dst, Function &Src); + void linkAliasBody(GlobalAlias &Dst, GlobalAlias &Src); + bool linkGlobalValueBody(GlobalValue &Src); + void linkNamedMDNodes(); + void stripReplacedSubprograms(); }; } @@ -539,22 +554,71 @@ static bool isLessConstraining(GlobalValue::VisibilityTypes a, return false; } +/// Loop through the global variables in the src module and merge them into the +/// dest module. +static GlobalVariable *copyGlobalVariableProto(TypeMapTy &TypeMap, Module &DstM, + 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(), SGVar->getLinkage(), /*init*/ nullptr, + SGVar->getName(), /*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. +static Function *copyFunctionProto(TypeMapTy &TypeMap, Module &DstM, + 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()), SF->getLinkage(), + SF->getName(), &DstM); +} + +/// Set up prototypes for any aliases that come over from the source module. +static GlobalAlias *copyGlobalAliasProto(TypeMapTy &TypeMap, Module &DstM, + 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(), + SGA->getLinkage(), SGA->getName(), &DstM); +} + +static GlobalValue *copyGlobalValueProto(TypeMapTy &TypeMap, Module &DstM, + const GlobalValue *SGV) { + GlobalValue *NewGV; + if (auto *SGVar = dyn_cast(SGV)) + NewGV = copyGlobalVariableProto(TypeMap, DstM, SGVar); + else if (auto *SF = dyn_cast(SGV)) + NewGV = copyFunctionProto(TypeMap, DstM, SF); + else + NewGV = copyGlobalAliasProto(TypeMap, DstM, cast(SGV)); + copyGVAttributes(NewGV, SGV); + return NewGV; +} + Value *ValueMaterializerTy::materializeValueFor(Value *V) { - Function *SF = dyn_cast(V); - if (!SF) + auto *SGV = dyn_cast(V); + if (!SGV) return nullptr; - Function *DF = Function::Create(TypeMap.get(SF->getFunctionType()), - SF->getLinkage(), SF->getName(), DstM); - copyGVAttributes(DF, SF); + GlobalValue *DGV = copyGlobalValueProto(TypeMap, *DstM, SGV); - if (Comdat *SC = SF->getComdat()) { - Comdat *DC = DstM->getOrInsertComdat(SC->getName()); - DF->setComdat(DC); + if (Comdat *SC = SGV->getComdat()) { + if (auto *DGO = dyn_cast(DGV)) { + Comdat *DC = DstM->getOrInsertComdat(SC->getName()); + DGO->setComdat(DC); + } } - LazilyLinkFunctions.push_back(SF); - return DF; + LazilyLinkGlobalValues.push_back(SGV); + return DGV; } bool ModuleLinker::getComdatLeader(Module *M, StringRef ComdatName, @@ -618,17 +682,12 @@ bool ModuleLinker::computeResultingSelectionKind(StringRef ComdatName, getComdatLeader(SrcM, ComdatName, SrcGV)) return true; - const DataLayout *DstDL = DstM->getDataLayout(); - const DataLayout *SrcDL = SrcM->getDataLayout(); - if (!DstDL || !SrcDL) { - return emitError( - "Linking COMDATs named '" + ComdatName + - "': can't do size dependent selection without DataLayout!"); - } + const DataLayout &DstDL = DstM->getDataLayout(); + const DataLayout &SrcDL = SrcM->getDataLayout(); uint64_t DstSize = - DstDL->getTypeAllocSize(DstGV->getType()->getPointerElementType()); + DstDL.getTypeAllocSize(DstGV->getType()->getPointerElementType()); uint64_t SrcSize = - SrcDL->getTypeAllocSize(SrcGV->getType()->getPointerElementType()); + SrcDL.getTypeAllocSize(SrcGV->getType()->getPointerElementType()); if (Result == Comdat::SelectionKind::ExactMatch) { if (SrcGV->getInitializer() != DstGV->getInitializer()) return emitError("Linking COMDATs named '" + ComdatName + @@ -675,6 +734,12 @@ bool ModuleLinker::getComdatResult(const Comdat *SrcC, bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc, const GlobalValue &Dest, const GlobalValue &Src) { + // Should we unconditionally use the Src? + if (shouldOverrideFromSrc()) { + LinkFromSrc = true; + return false; + } + // We always have to add Src if it has appending linkage. if (Src.hasAppendingLinkage()) { LinkFromSrc = true; @@ -714,9 +779,7 @@ bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc, return false; } - // FIXME: Make datalayout mandatory and just use getDataLayout(). - DataLayout DL(Dest.getParent()); - + const DataLayout &DL = Dest.getParent()->getDataLayout(); uint64_t DestSize = DL.getTypeAllocSize(Dest.getType()->getElementType()); uint64_t SrcSize = DL.getTypeAllocSize(Src.getType()->getElementType()); LinkFromSrc = SrcSize > DestSize; @@ -1021,19 +1084,28 @@ bool ModuleLinker::linkGlobalValueProto(GlobalValue *SGV) { if (!LinkFromSrc) { NewGV = DGV; } else { - if (auto *SGVar = dyn_cast(SGV)) - NewGV = linkGlobalVariableProto(SGVar); - else if (auto *SF = dyn_cast(SGV)) - NewGV = linkFunctionProto(SF, DGV); - else - NewGV = linkGlobalAliasProto(cast(SGV)); - } + // If the GV is to be lazily linked, don't create it just yet. + // The ValueMaterializerTy will deal with creating it if it's used. + if (!DGV && !shouldOverrideFromSrc() && + (SGV->hasLocalLinkage() || SGV->hasLinkOnceLinkage() || + SGV->hasAvailableExternallyLinkage())) { + DoNotLinkFromSource.insert(SGV); + return false; + } - if (!NewGV) - return false; + // When we only want to link in unresolved dependencies, blacklist + // the symbol unless unless DestM has a matching declaration (DGV). + if (shouldLinkOnlyNeeded() && !(DGV && DGV->isDeclaration())) { + DoNotLinkFromSource.insert(SGV); + return false; + } + + NewGV = copyGlobalValueProto(TypeMap, *DstM, SGV); - if (NewGV != DGV) - copyGVAttributes(NewGV, SGV); + if (DGV && isa(DGV)) + if (auto *NewF = dyn_cast(NewGV)) + OverridingFunctions.insert(NewF); + } NewGV->setUnnamedAddr(HasUnnamedAddr); NewGV->setVisibility(Visibility); @@ -1066,49 +1138,6 @@ bool ModuleLinker::linkGlobalValueProto(GlobalValue *SGV) { return false; } -/// Loop through the global variables in the src module and merge them into the -/// dest module. -GlobalValue * -ModuleLinker::linkGlobalVariableProto(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(), SGVar->getLinkage(), /*init*/ nullptr, - SGVar->getName(), /*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. -GlobalValue *ModuleLinker::linkFunctionProto(const Function *SF, - GlobalValue *DGV) { - // If the function is to be lazily linked, don't create it just yet. - // The ValueMaterializerTy will deal with creating it if it's used. - if (!DGV && (SF->hasLocalLinkage() || SF->hasLinkOnceLinkage() || - SF->hasAvailableExternallyLinkage())) { - DoNotLinkFromSource.insert(SF); - return nullptr; - } - - // 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()), SF->getLinkage(), - SF->getName(), DstM); -} - -/// Set up prototypes for any aliases that come over from the source module. -GlobalValue *ModuleLinker::linkGlobalAliasProto(const GlobalAlias *SGA) { - // If there is no linkage to be performed or we're linking from the source, - // bring over SGA. - auto *PTy = cast(TypeMap.get(SGA->getType())); - return GlobalAlias::create(PTy->getElementType(), PTy->getAddressSpace(), - SGA->getLinkage(), SGA->getName(), DstM); -} - static void getArrayElements(const Constant *C, SmallVectorImpl &Dest) { unsigned NumElements = cast(C->getType())->getNumElements(); @@ -1139,7 +1168,7 @@ void ModuleLinker::linkAppendingVarInit(const AppendingVarInfo &AVI) { continue; } DstElements.push_back( - MapValue(V, ValueMap, RF_None, &TypeMap, &ValMaterializer)); + MapValue(V, ValueMap, RF_MoveDistinctMDs, &TypeMap, &ValMaterializer)); } if (IsNewStructor) { NewType = ArrayType::get(NewType->getElementType(), DstElements.size()); @@ -1151,27 +1180,17 @@ void ModuleLinker::linkAppendingVarInit(const AppendingVarInfo &AVI) { /// Update the initializers in the Dest module now that all globals that may be /// referenced are in Dest. -void ModuleLinker::linkGlobalInits() { - // Loop over all of the globals in the src module, mapping them over as we go - for (GlobalVariable &Src : SrcM->globals()) { - // Only process initialized GV's or ones not already in dest. - if (!Src.hasInitializer() || DoNotLinkFromSource.count(&Src)) - continue; - - // Grab destination global variable. - GlobalVariable *Dst = cast(ValueMap[&Src]); - // Figure out what the initializer looks like in the dest module. - Dst->setInitializer(MapValue(Src.getInitializer(), ValueMap, RF_None, - &TypeMap, &ValMaterializer)); - } +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 &Src) { - Function *Dst = cast(ValueMap[&Src]); - assert(Dst && Dst->isDeclaration() && !Src.isDeclaration()); +bool ModuleLinker::linkFunctionBody(Function &Dst, Function &Src) { + assert(Dst.isDeclaration() && !Src.isDeclaration()); // Materialize if needed. if (std::error_code EC = Src.materialize()) @@ -1179,17 +1198,23 @@ bool ModuleLinker::linkFunctionBody(Function &Src) { // Link in the prefix data. if (Src.hasPrefixData()) - Dst->setPrefixData(MapValue(Src.getPrefixData(), ValueMap, RF_None, - &TypeMap, &ValMaterializer)); + 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_None, - &TypeMap, &ValMaterializer)); + 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(); + Function::arg_iterator DI = Dst.arg_begin(); for (Argument &Arg : Src.args()) { DI->setName(Arg.getName()); // Copy the name over. @@ -1198,52 +1223,104 @@ bool ModuleLinker::linkFunctionBody(Function &Src) { ++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()); + 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 (BasicBlock &BB : Dst) for (Instruction &I : BB) - RemapInstruction(&I, ValueMap, RF_IgnoreMissingEntries, &TypeMap, + 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(); + Src.dematerialize(); return false; } -/// Insert all of the aliases in Src into the Dest module. -void ModuleLinker::linkAliasBodies() { - for (GlobalAlias &Src : SrcM->aliases()) { - if (DoNotLinkFromSource.count(&Src)) - continue; - if (Constant *Aliasee = Src.getAliasee()) { - GlobalAlias *DA = cast(ValueMap[&Src]); - Constant *Val = - MapValue(Aliasee, ValueMap, RF_None, &TypeMap, &ValMaterializer); - DA->setAliasee(Val); - } +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 &Src) { + Value *Dst = ValueMap[&Src]; + assert(Dst); + 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 (Module::const_named_metadata_iterator I = SrcM->named_metadata_begin(), - E = SrcM->named_metadata_end(); I != E; ++I) { + for (const NamedMDNode &NMD : SrcM->named_metadata()) { // Don't link module flags here. Do them separately. - if (&*I == SrcModFlags) continue; - NamedMDNode *DestNMD = DstM->getOrInsertNamedMetadata(I->getName()); + if (&NMD == SrcModFlags) + continue; + NamedMDNode *DestNMD = DstM->getOrInsertNamedMetadata(NMD.getName()); // Add Src elements into Dest node. - for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) - DestNMD->addOperand(MapValue(I->getOperand(i), ValueMap, - RF_None, &TypeMap, &ValMaterializer)); + for (const MDNode *op : NMD.operands()) + DestNMD->addOperand(MapMetadata(op, ValueMap, RF_MoveDistinctMDs, + &TypeMap, &ValMaterializer)); + } +} + +/// Drop DISubprograms that have been superseded. +/// +/// FIXME: this creates an asymmetric result: we strip functions from losing +/// subprograms in DstM, but leave losing subprograms in SrcM. +/// TODO: Remove this logic once the backend can correctly determine canonical +/// subprograms. +void ModuleLinker::stripReplacedSubprograms() { + // Avoid quadratic runtime by returning early when there's nothing to do. + if (OverridingFunctions.empty()) + return; + + // Move the functions now, so the set gets cleared even on early returns. + auto Functions = std::move(OverridingFunctions); + OverridingFunctions.clear(); + + // Drop functions from subprograms if they've been overridden by the new + // compile unit. + NamedMDNode *CompileUnits = DstM->getNamedMetadata("llvm.dbg.cu"); + if (!CompileUnits) + return; + for (unsigned I = 0, E = CompileUnits->getNumOperands(); I != E; ++I) { + auto *CU = cast(CompileUnits->getOperand(I)); + assert(CU && "Expected valid compile unit"); + + for (DISubprogram *SP : CU->getSubprograms()) { + if (!SP || !SP->getFunction() || !Functions.count(SP->getFunction())) + continue; + + // Prevent DebugInfoFinder from tagging this as the canonical subprogram, + // since the canonical one is in the incoming module. + SP->replaceFunction(nullptr); + } } } @@ -1264,17 +1341,17 @@ bool ModuleLinker::linkModuleFlagsMetadata() { } // First build a map of the existing module flags and requirements. - DenseMap Flags; + DenseMap> Flags; SmallSetVector Requirements; for (unsigned I = 0, E = DstModFlags->getNumOperands(); I != E; ++I) { MDNode *Op = DstModFlags->getOperand(I); - ConstantInt *Behavior = cast(Op->getOperand(0)); + 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] = Op; + Flags[ID] = std::make_pair(Op, I); } } @@ -1283,9 +1360,12 @@ bool ModuleLinker::linkModuleFlagsMetadata() { bool HasErr = false; for (unsigned I = 0, E = SrcModFlags->getNumOperands(); I != E; ++I) { MDNode *SrcOp = SrcModFlags->getOperand(I); - ConstantInt *SrcBehavior = cast(SrcOp->getOperand(0)); + ConstantInt *SrcBehavior = + mdconst::extract(SrcOp->getOperand(0)); MDString *ID = cast(SrcOp->getOperand(1)); - MDNode *DstOp = Flags.lookup(ID); + MDNode *DstOp; + unsigned DstIndex; + std::tie(DstOp, DstIndex) = Flags.lookup(ID); unsigned SrcBehaviorValue = SrcBehavior->getZExtValue(); // If this is a requirement, add it and continue. @@ -1300,13 +1380,14 @@ bool ModuleLinker::linkModuleFlagsMetadata() { // If there is no existing flag with this ID, just add it. if (!DstOp) { - Flags[ID] = SrcOp; + Flags[ID] = std::make_pair(SrcOp, DstModFlags->getNumOperands()); DstModFlags->addOperand(SrcOp); continue; } // Otherwise, perform a merge. - ConstantInt *DstBehavior = cast(DstOp->getOperand(0)); + ConstantInt *DstBehavior = + mdconst::extract(DstOp->getOperand(0)); unsigned DstBehaviorValue = DstBehavior->getZExtValue(); // If either flag has override behavior, handle it first. @@ -1320,8 +1401,8 @@ bool ModuleLinker::linkModuleFlagsMetadata() { continue; } else if (SrcBehaviorValue == Module::Override) { // Update the destination flag to that of the source. - DstOp->replaceOperandWith(0, SrcBehavior); - DstOp->replaceOperandWith(2, SrcOp->getOperand(2)); + DstModFlags->setOperand(DstIndex, SrcOp); + Flags[ID].first = SrcOp; continue; } @@ -1332,6 +1413,13 @@ bool ModuleLinker::linkModuleFlagsMetadata() { 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: @@ -1355,29 +1443,23 @@ bool ModuleLinker::linkModuleFlagsMetadata() { case Module::Append: { MDNode *DstValue = cast(DstOp->getOperand(2)); MDNode *SrcValue = cast(SrcOp->getOperand(2)); - unsigned NumOps = DstValue->getNumOperands() + SrcValue->getNumOperands(); - Value **VP, **Values = VP = new Value*[NumOps]; - for (unsigned i = 0, e = DstValue->getNumOperands(); i != e; ++i, ++VP) - *VP = DstValue->getOperand(i); - for (unsigned i = 0, e = SrcValue->getNumOperands(); i != e; ++i, ++VP) - *VP = SrcValue->getOperand(i); - DstOp->replaceOperandWith(2, MDNode::get(DstM->getContext(), - ArrayRef(Values, - NumOps))); - delete[] Values; + 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; + SmallSetVector Elts; MDNode *DstValue = cast(DstOp->getOperand(2)); MDNode *SrcValue = cast(SrcOp->getOperand(2)); - for (unsigned i = 0, e = DstValue->getNumOperands(); i != e; ++i) - Elts.insert(DstValue->getOperand(i)); - for (unsigned i = 0, e = SrcValue->getNumOperands(); i != e; ++i) - Elts.insert(SrcValue->getOperand(i)); - DstOp->replaceOperandWith(2, MDNode::get(DstM->getContext(), - ArrayRef(Elts.begin(), - Elts.end()))); + 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; } } @@ -1387,9 +1469,9 @@ bool ModuleLinker::linkModuleFlagsMetadata() { for (unsigned I = 0, E = Requirements.size(); I != E; ++I) { MDNode *Requirement = Requirements[I]; MDString *Flag = cast(Requirement->getOperand(0)); - Value *ReqValue = Requirement->getOperand(1); + Metadata *ReqValue = Requirement->getOperand(1); - MDNode *Op = Flags[Flag]; + MDNode *Op = Flags[Flag].first; if (!Op || Op->getOperand(2) != ReqValue) { HasErr |= emitError("linking module flags '" + Flag->getString() + "': does not have the required value"); @@ -1400,35 +1482,59 @@ bool ModuleLinker::linkModuleFlagsMetadata() { return HasErr; } +// 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() { assert(DstM && "Null destination module"); assert(SrcM && "Null source module"); // Inherit the target data from the source module if the destination module // doesn't have one already. - if (!DstM->getDataLayout() && SrcM->getDataLayout()) + if (DstM->getDataLayout().isDefault()) DstM->setDataLayout(SrcM->getDataLayout()); - // Copy the target triple from the source to dest if the dest's is empty. - if (DstM->getTargetTriple().empty() && !SrcM->getTargetTriple().empty()) - DstM->setTargetTriple(SrcM->getTargetTriple()); - - if (SrcM->getDataLayout() && DstM->getDataLayout() && - *SrcM->getDataLayout() != *DstM->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"); } - if (!SrcM->getTargetTriple().empty() && - DstM->getTargetTriple() != SrcM->getTargetTriple()) { + + // 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()) { @@ -1459,9 +1565,8 @@ bool ModuleLinker::run() { // Insert all of the globals in src into the DstM module... without linking // initializers (which could refer to functions not yet mapped over). - for (Module::global_iterator I = SrcM->global_begin(), - E = SrcM->global_end(); I != E; ++I) - if (linkGlobalValueProto(I)) + for (GlobalVariable &GV : SrcM->globals()) + if (linkGlobalValueProto(&GV)) return true; // Link the functions together between the two modules, without doing function @@ -1469,18 +1574,33 @@ bool ModuleLinker::run() { // function... We do this so that when we begin processing function bodies, // all of the global values that may be referenced are available in our // ValueMap. - for (Module::iterator I = SrcM->begin(), E = SrcM->end(); I != E; ++I) - if (linkGlobalValueProto(I)) + for (Function &F :*SrcM) + if (linkGlobalValueProto(&F)) return true; // If there were any aliases, link them now. - for (Module::alias_iterator I = SrcM->alias_begin(), - E = SrcM->alias_end(); I != E; ++I) - if (linkGlobalValueProto(I)) + for (GlobalAlias &GA : SrcM->aliases()) + if (linkGlobalValueProto(&GA)) return true; - for (unsigned i = 0, e = AppendingVars.size(); i != e; ++i) - linkAppendingVarInit(AppendingVars[i]); + for (const AppendingVarInfo &AppendingVar : AppendingVars) + linkAppendingVarInit(AppendingVar); + + for (const auto &Entry : DstM->getComdatSymbolTable()) { + const Comdat &C = Entry.getValue(); + if (C.getSelectionKind() == Comdat::Any) + continue; + const GlobalValue *GV = SrcM->getNamedValue(C.getName()); + if (GV) + MapValue(GV, ValueMap, RF_MoveDistinctMDs, &TypeMap, &ValMaterializer); + } + + // Strip replaced subprograms before mapping any metadata -- so that we're + // not changing metadata from the source module (note that + // linkGlobalValueBody() eventually calls RemapInstruction() and therefore + // MapMetadata()) -- but after linking global value protocols -- so that + // OverridingFunctions has been built. + stripReplacedSubprograms(); // Link in the function bodies that are defined in the source module into // DstM. @@ -1493,12 +1613,16 @@ bool ModuleLinker::run() { if (DoNotLinkFromSource.count(&SF)) continue; - if (linkFunctionBody(SF)) + if (linkGlobalValueBody(SF)) return true; } // Resolve all uses of aliases with aliasees. - linkAliasBodies(); + for (GlobalAlias &Src : SrcM->aliases()) { + if (DoNotLinkFromSource.count(&Src)) + continue; + linkGlobalValueBody(Src); + } // Remap all of the named MDNodes in Src into the DstM module. We do this // after linking GlobalValues so that MDNodes that reference GlobalValues @@ -1511,14 +1635,25 @@ bool ModuleLinker::run() { // Update the initializers in the DstM module now that all globals that may // be referenced are in DstM. - linkGlobalInits(); + for (GlobalVariable &Src : SrcM->globals()) { + // Only process initialized GV's or ones not already in dest. + if (!Src.hasInitializer() || DoNotLinkFromSource.count(&Src)) + continue; + linkGlobalValueBody(Src); + } // Process vector of lazily linked in functions. - while (!LazilyLinkFunctions.empty()) { - Function *SF = LazilyLinkFunctions.back(); - LazilyLinkFunctions.pop_back(); + while (!LazilyLinkGlobalValues.empty()) { + GlobalValue *SGV = LazilyLinkGlobalValues.back(); + LazilyLinkGlobalValues.pop_back(); + + // Skip declarations that ValueMaterializer may have created in + // case we link in only some of SrcM. + if (shouldLinkOnlyNeeded() && SGV->isDeclaration()) + continue; - if (linkFunctionBody(*SF)) + assert(!SGV->isDeclaration() && "users should not pass down decls"); + if (linkGlobalValueBody(*SGV)) return true; } @@ -1583,6 +1718,14 @@ void Linker::IdentifiedStructTypeSet::addNonOpaque(StructType *Ty) { 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); @@ -1631,18 +1774,21 @@ Linker::Linker(Module *M) { }); } -Linker::~Linker() { -} - void Linker::deleteModule() { delete Composite; Composite = nullptr; } -bool Linker::linkInModule(Module *Src) { +bool Linker::linkInModule(Module *Src, unsigned Flags) { ModuleLinker TheLinker(Composite, IdentifiedStructTypes, Src, - DiagnosticHandler); - return TheLinker.run(); + DiagnosticHandler, Flags); + bool RetCode = TheLinker.run(); + Composite->dropTriviallyDeadConstantArrays(); + return RetCode; +} + +void Linker::setModule(Module *Dst) { + init(Dst, DiagnosticHandler); } //===----------------------------------------------------------------------===// @@ -1655,14 +1801,15 @@ bool Linker::linkInModule(Module *Src) { /// Upon failure, the Dest module could be in a modified state, and shouldn't be /// relied on to be consistent. bool Linker::LinkModules(Module *Dest, Module *Src, - DiagnosticHandlerFunction DiagnosticHandler) { + DiagnosticHandlerFunction DiagnosticHandler, + unsigned Flags) { Linker L(Dest, DiagnosticHandler); - return L.linkInModule(Src); + return L.linkInModule(Src, Flags); } -bool Linker::LinkModules(Module *Dest, Module *Src) { +bool Linker::LinkModules(Module *Dest, Module *Src, unsigned Flags) { Linker L(Dest); - return L.linkInModule(Src); + return L.linkInModule(Src, Flags); } //===----------------------------------------------------------------------===// @@ -1670,7 +1817,7 @@ bool Linker::LinkModules(Module *Dest, Module *Src) { //===----------------------------------------------------------------------===// LLVMBool LLVMLinkModules(LLVMModuleRef Dest, LLVMModuleRef Src, - LLVMLinkerMode Mode, char **OutMessages) { + LLVMLinkerMode Unused, char **OutMessages) { Module *D = unwrap(Dest); std::string Message; raw_string_ostream Stream(Message); @@ -1679,7 +1826,9 @@ LLVMBool LLVMLinkModules(LLVMModuleRef Dest, LLVMModuleRef Src, LLVMBool Result = Linker::LinkModules( D, unwrap(Src), [&](const DiagnosticInfo &DI) { DI.print(DP); }); - if (OutMessages && Result) + if (OutMessages && Result) { + Stream.flush(); *OutMessages = strdup(Message.c_str()); + } return Result; }