diff options
Diffstat (limited to 'lib/Linker')
-rw-r--r-- | lib/Linker/LinkArchives.cpp | 5 | ||||
-rw-r--r-- | lib/Linker/LinkModules.cpp | 370 | ||||
-rw-r--r-- | lib/Linker/Linker.cpp | 1 |
3 files changed, 312 insertions, 64 deletions
diff --git a/lib/Linker/LinkArchives.cpp b/lib/Linker/LinkArchives.cpp index 2c4ed7f..c16d195 100644 --- a/lib/Linker/LinkArchives.cpp +++ b/lib/Linker/LinkArchives.cpp @@ -16,7 +16,6 @@ #include "llvm/Module.h" #include "llvm/ADT/SetOperations.h" #include "llvm/Bitcode/Archive.h" -#include "llvm/Config/config.h" #include <memory> #include <set> using namespace llvm; @@ -141,7 +140,7 @@ Linker::LinkInArchive(const sys::Path &Filename, bool &is_native) { // Find the modules we need to link into the target module. Note that arch // keeps ownership of these modules and may return the same Module* from a // subsequent call. - std::set<Module*> Modules; + SmallVector<Module*, 16> Modules; if (!arch->findModulesDefiningSymbols(UndefinedSymbols, Modules, &ErrMsg)) return error("Cannot find symbols in '" + Filename.str() + "': " + ErrMsg); @@ -158,7 +157,7 @@ Linker::LinkInArchive(const sys::Path &Filename, bool &is_native) { UndefinedSymbols.end()); // Loop over all the Modules that we got back from the archive - for (std::set<Module*>::iterator I=Modules.begin(), E=Modules.end(); + for (SmallVectorImpl<Module*>::iterator I=Modules.begin(), E=Modules.end(); I != E; ++I) { // Get the module we must link in. diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index ab099bb..f19e6e3 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -16,11 +16,15 @@ #include "llvm/DerivedTypes.h" #include "llvm/Instructions.h" #include "llvm/Module.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Path.h" #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Transforms/Utils/ValueMapper.h" +#include <cctype> using namespace llvm; //===----------------------------------------------------------------------===// @@ -38,9 +42,14 @@ class TypeMapTy : public ValueMapTypeRemapper { /// case we need to roll back. SmallVector<Type*, 16> SpeculativeTypes; - /// DefinitionsToResolve - This is a list of non-opaque structs in the source - /// module that are mapped to an opaque struct in the destination module. - SmallVector<StructType*, 16> DefinitionsToResolve; + /// SrcDefinitionsToResolve - This is a list of non-opaque structs in the + /// source module that are mapped to an opaque struct in the destination + /// module. + SmallVector<StructType*, 16> SrcDefinitionsToResolve; + + /// DstResolvedOpaqueTypes - This is the set of opaque types in the + /// destination modules who are getting a body from the source module. + SmallPtrSet<StructType*, 16> DstResolvedOpaqueTypes; public: /// addTypeMapping - Indicate that the specified type in the destination @@ -118,11 +127,17 @@ bool TypeMapTy::areTypesIsomorphic(Type *DstTy, Type *SrcTy) { return true; } - // Mapping a non-opaque source type to an opaque dest. Keep the dest, but - // fill it in later. This doesn't need to be speculative. + // Mapping a non-opaque source type to an opaque dest. If this is the first + // type that we're mapping onto this destination type then we succeed. Keep + // the dest, but fill it in later. This doesn't need to be speculative. If + // this is the second (different) type that we're trying to map onto the + // same opaque type then we fail. if (cast<StructType>(DstTy)->isOpaque()) { + // We can only map one source type onto the opaque destination type. + if (!DstResolvedOpaqueTypes.insert(cast<StructType>(DstTy))) + return false; + SrcDefinitionsToResolve.push_back(SSTy); Entry = DstTy; - DefinitionsToResolve.push_back(SSTy); return true; } } @@ -137,6 +152,7 @@ bool TypeMapTy::areTypesIsomorphic(Type *DstTy, Type *SrcTy) { if (PointerType *PT = dyn_cast<PointerType>(DstTy)) { if (PT->getAddressSpace() != cast<PointerType>(SrcTy)->getAddressSpace()) return false; + } else if (FunctionType *FT = dyn_cast<FunctionType>(DstTy)) { if (FT->isVarArg() != cast<FunctionType>(SrcTy)->isVarArg()) return false; @@ -174,9 +190,9 @@ void TypeMapTy::linkDefinedTypeBodies() { SmallString<16> TmpName; // Note that processing entries in this loop (calling 'get') can add new - // entries to the DefinitionsToResolve vector. - while (!DefinitionsToResolve.empty()) { - StructType *SrcSTy = DefinitionsToResolve.pop_back_val(); + // entries to the SrcDefinitionsToResolve vector. + while (!SrcDefinitionsToResolve.empty()) { + StructType *SrcSTy = SrcDefinitionsToResolve.pop_back_val(); StructType *DstSTy = cast<StructType>(MappedTypes[SrcSTy]); // TypeMap is a many-to-one mapping, if there were multiple types that @@ -204,6 +220,8 @@ void TypeMapTy::linkDefinedTypeBodies() { TmpName.clear(); } } + + DstResolvedOpaqueTypes.clear(); } @@ -213,7 +231,7 @@ Type *TypeMapTy::get(Type *Ty) { Type *Result = getImpl(Ty); // If this caused a reference to any struct type, resolve it before returning. - if (!DefinitionsToResolve.empty()) + if (!SrcDefinitionsToResolve.empty()) linkDefinedTypeBodies(); return Result; } @@ -252,7 +270,7 @@ Type *TypeMapTy::getImpl(Type *Ty) { // Otherwise, rebuild a modified type. switch (Ty->getTypeID()) { - default: assert(0 && "unknown derived type to remap"); + default: llvm_unreachable("unknown derived type to remap"); case Type::ArrayTyID: return *Entry = ArrayType::get(ElementTypes[0], cast<ArrayType>(Ty)->getNumElements()); @@ -304,8 +322,10 @@ Type *TypeMapTy::getImpl(Type *Ty) { // Otherwise we create a new type and resolve its body later. This will be // resolved by the top level of get(). - DefinitionsToResolve.push_back(STy); - return *Entry = StructType::create(STy->getContext()); + SrcDefinitionsToResolve.push_back(STy); + StructType *DTy = StructType::create(STy->getContext()); + DstResolvedOpaqueTypes.insert(DTy); + return *Entry = DTy; } @@ -363,7 +383,9 @@ namespace { /// getLinkageResult - This analyzes the two global values and determines /// what the result will look like in the destination module. bool getLinkageResult(GlobalValue *Dest, const GlobalValue *Src, - GlobalValue::LinkageTypes <, bool &LinkFromSrc); + GlobalValue::LinkageTypes <, + GlobalValue::VisibilityTypes &Vis, + bool &LinkFromSrc); /// getLinkedToGlobal - Given a global in the source module, return the /// global in the destination module that is being linked to, if any. @@ -387,11 +409,19 @@ namespace { } void computeTypeMapping(); + bool categorizeModuleFlagNodes(const NamedMDNode *ModFlags, + DenseMap<MDString*, MDNode*> &ErrorNode, + DenseMap<MDString*, MDNode*> &WarningNode, + DenseMap<MDString*, MDNode*> &OverrideNode, + DenseMap<MDString*, + SmallSetVector<MDNode*, 8> > &RequireNodes, + SmallSetVector<MDString*, 16> &SeenIDs); bool linkAppendingVarProto(GlobalVariable *DstGV, GlobalVariable *SrcGV); bool linkGlobalProto(GlobalVariable *SrcGV); bool linkFunctionProto(Function *SrcF); bool linkAliasProto(GlobalAlias *SrcA); + bool linkModuleFlagsMetadata(); void linkAppendingVarInit(const AppendingVarInfo &AVI); void linkGlobalInits(); @@ -435,15 +465,27 @@ static void CopyGVAttributes(GlobalValue *DestGV, const GlobalValue *SrcGV) { forceRenaming(DestGV, SrcGV->getName()); } +static bool isLessConstraining(GlobalValue::VisibilityTypes a, + GlobalValue::VisibilityTypes b) { + if (a == GlobalValue::HiddenVisibility) + return false; + if (b == GlobalValue::HiddenVisibility) + return true; + if (a == GlobalValue::ProtectedVisibility) + return false; + if (b == GlobalValue::ProtectedVisibility) + return true; + return false; +} + /// getLinkageResult - This analyzes the two global values and determines what /// the result will look like in the destination module. In particular, it -/// computes the resultant linkage type, computes whether the global in the -/// source should be copied over to the destination (replacing the existing -/// one), and computes whether this linkage is an error or not. It also performs -/// visibility checks: we cannot link together two symbols with different -/// visibilities. +/// computes the resultant linkage type and visibility, computes whether the +/// global in the source should be copied over to the destination (replacing +/// the existing one), and computes whether this linkage is an error or not. bool ModuleLinker::getLinkageResult(GlobalValue *Dest, const GlobalValue *Src, - GlobalValue::LinkageTypes <, + GlobalValue::LinkageTypes <, + GlobalValue::VisibilityTypes &Vis, bool &LinkFromSrc) { assert(Dest && "Must have two globals being queried"); assert(!Src->hasLocalLinkage() && @@ -505,13 +547,10 @@ bool ModuleLinker::getLinkageResult(GlobalValue *Dest, const GlobalValue *Src, "': symbol multiply defined!"); } - // Check visibility - if (Src->getVisibility() != Dest->getVisibility() && - !SrcIsDeclaration && !DestIsDeclaration && - !Src->hasAvailableExternallyLinkage() && - !Dest->hasAvailableExternallyLinkage()) - return emitError("Linking globals named '" + Src->getName() + - "': symbols have different visibilities!"); + // Compute the visibility. We follow the rules in the System V Application + // Binary Interface. + Vis = isLessConstraining(Src->getVisibility(), Dest->getVisibility()) ? + Dest->getVisibility() : Src->getVisibility(); return false; } @@ -542,7 +581,37 @@ void ModuleLinker::computeTypeMapping() { if (GlobalValue *DGV = getLinkedToGlobal(I)) TypeMap.addTypeMapping(DGV->getType(), I->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 }". + // Though it isn't required for correctness, attempt to link these up to clean + // up the IR. + std::vector<StructType*> SrcStructTypes; + SrcM->findUsedStructTypes(SrcStructTypes); + SmallPtrSet<StructType*, 32> SrcStructTypesSet(SrcStructTypes.begin(), + SrcStructTypes.end()); + + for (unsigned i = 0, e = SrcStructTypes.size(); i != e; ++i) { + StructType *ST = SrcStructTypes[i]; + 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(ST->getName()[DotPos+1])) + continue; + + // Check to see if the destination module has a struct with the prefix name. + if (StructType *DST = DstM->getTypeByName(ST->getName().substr(0, DotPos))) + // Don't use it if this actually came from the source module. They're in + // the same LLVMContext after all. + if (!SrcStructTypesSet.count(DST)) + TypeMap.addTypeMapping(DST, ST); + } + // Don't bother incorporating aliases, they aren't generally typed well. // Now that we have discovered all of the type equivalences, get a body for @@ -618,6 +687,7 @@ bool ModuleLinker::linkAppendingVarProto(GlobalVariable *DstGV, /// merge them into the dest module. bool ModuleLinker::linkGlobalProto(GlobalVariable *SGV) { GlobalValue *DGV = getLinkedToGlobal(SGV); + llvm::Optional<GlobalValue::VisibilityTypes> NewVisibility; if (DGV) { // Concatenation of appending linkage variables is magic and handled later. @@ -627,9 +697,11 @@ bool ModuleLinker::linkGlobalProto(GlobalVariable *SGV) { // Determine whether linkage of these two globals follows the source // module's definition or the destination module's definition. GlobalValue::LinkageTypes NewLinkage = GlobalValue::InternalLinkage; + GlobalValue::VisibilityTypes NV; bool LinkFromSrc = false; - if (getLinkageResult(DGV, SGV, NewLinkage, LinkFromSrc)) + if (getLinkageResult(DGV, SGV, NewLinkage, NV, LinkFromSrc)) return true; + NewVisibility = NV; // If we're not linking from the source, then keep the definition that we // have. @@ -639,9 +711,10 @@ bool ModuleLinker::linkGlobalProto(GlobalVariable *SGV) { if (DGVar->isDeclaration() && SGV->isConstant() && !DGVar->isConstant()) DGVar->setConstant(true); - // Set calculated linkage. + // Set calculated linkage and visibility. DGV->setLinkage(NewLinkage); - + DGV->setVisibility(*NewVisibility); + // Make sure to remember this mapping. ValueMap[SGV] = ConstantExpr::getBitCast(DGV,TypeMap.get(SGV->getType())); @@ -664,6 +737,8 @@ bool ModuleLinker::linkGlobalProto(GlobalVariable *SGV) { SGV->getType()->getAddressSpace()); // Propagate alignment, visibility and section info. CopyGVAttributes(NewDGV, SGV); + if (NewVisibility) + NewDGV->setVisibility(*NewVisibility); if (DGV) { DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewDGV, DGV->getType())); @@ -679,17 +754,21 @@ bool ModuleLinker::linkGlobalProto(GlobalVariable *SGV) { /// destination module if needed, setting up mapping information. bool ModuleLinker::linkFunctionProto(Function *SF) { GlobalValue *DGV = getLinkedToGlobal(SF); + llvm::Optional<GlobalValue::VisibilityTypes> NewVisibility; if (DGV) { GlobalValue::LinkageTypes NewLinkage = GlobalValue::InternalLinkage; bool LinkFromSrc = false; - if (getLinkageResult(DGV, SF, NewLinkage, LinkFromSrc)) + GlobalValue::VisibilityTypes NV; + if (getLinkageResult(DGV, SF, NewLinkage, NV, LinkFromSrc)) return true; - + NewVisibility = NV; + if (!LinkFromSrc) { // Set calculated linkage DGV->setLinkage(NewLinkage); - + DGV->setVisibility(*NewVisibility); + // Make sure to remember this mapping. ValueMap[SF] = ConstantExpr::getBitCast(DGV, TypeMap.get(SF->getType())); @@ -706,6 +785,8 @@ bool ModuleLinker::linkFunctionProto(Function *SF) { Function *NewDF = Function::Create(TypeMap.get(SF->getFunctionType()), SF->getLinkage(), SF->getName(), DstM); CopyGVAttributes(NewDF, SF); + if (NewVisibility) + NewDF->setVisibility(*NewVisibility); if (DGV) { // Any uses of DF need to change to NewDF, with cast. @@ -728,17 +809,21 @@ bool ModuleLinker::linkFunctionProto(Function *SF) { /// source module. bool ModuleLinker::linkAliasProto(GlobalAlias *SGA) { GlobalValue *DGV = getLinkedToGlobal(SGA); - + llvm::Optional<GlobalValue::VisibilityTypes> NewVisibility; + if (DGV) { GlobalValue::LinkageTypes NewLinkage = GlobalValue::InternalLinkage; + GlobalValue::VisibilityTypes NV; bool LinkFromSrc = false; - if (getLinkageResult(DGV, SGA, NewLinkage, LinkFromSrc)) + if (getLinkageResult(DGV, SGA, NewLinkage, NV, LinkFromSrc)) return true; - + NewVisibility = NV; + if (!LinkFromSrc) { // Set calculated linkage. DGV->setLinkage(NewLinkage); - + DGV->setVisibility(*NewVisibility); + // Make sure to remember this mapping. ValueMap[SGA] = ConstantExpr::getBitCast(DGV,TypeMap.get(SGA->getType())); @@ -755,6 +840,8 @@ bool ModuleLinker::linkAliasProto(GlobalAlias *SGA) { SGA->getLinkage(), SGA->getName(), /*aliasee*/0, DstM); CopyGVAttributes(NewDA, SGA); + if (NewVisibility) + NewDA->setVisibility(*NewVisibility); if (DGV) { // Any uses of DGV need to change to NewDA, with cast. @@ -766,29 +853,21 @@ bool ModuleLinker::linkAliasProto(GlobalAlias *SGA) { return false; } +static void getArrayElements(Constant *C, SmallVectorImpl<Constant*> &Dest) { + unsigned NumElements = cast<ArrayType>(C->getType())->getNumElements(); + + for (unsigned i = 0; i != NumElements; ++i) + Dest.push_back(C->getAggregateElement(i)); +} + void ModuleLinker::linkAppendingVarInit(const AppendingVarInfo &AVI) { // Merge the initializer. SmallVector<Constant*, 16> Elements; - if (ConstantArray *I = dyn_cast<ConstantArray>(AVI.DstInit)) { - for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) - Elements.push_back(I->getOperand(i)); - } else { - assert(isa<ConstantAggregateZero>(AVI.DstInit)); - ArrayType *DstAT = cast<ArrayType>(AVI.DstInit->getType()); - Type *EltTy = DstAT->getElementType(); - Elements.append(DstAT->getNumElements(), Constant::getNullValue(EltTy)); - } + getArrayElements(AVI.DstInit, Elements); Constant *SrcInit = MapValue(AVI.SrcInit, ValueMap, RF_None, &TypeMap); - if (const ConstantArray *I = dyn_cast<ConstantArray>(SrcInit)) { - for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) - Elements.push_back(I->getOperand(i)); - } else { - assert(isa<ConstantAggregateZero>(SrcInit)); - ArrayType *SrcAT = cast<ArrayType>(SrcInit->getType()); - Type *EltTy = SrcAT->getElementType(); - Elements.append(SrcAT->getNumElements(), Constant::getNullValue(EltTy)); - } + getArrayElements(SrcInit, Elements); + ArrayType *NewType = cast<ArrayType>(AVI.NewGV->getType()->getElementType()); AVI.NewGV->setInitializer(ConstantArray::get(NewType, Elements)); } @@ -843,7 +922,7 @@ void ModuleLinker::linkFunctionBody(Function *Dst, Function *Src) { } else { // Clone the body of the function into the dest function. SmallVector<ReturnInst*, 8> Returns; // Ignore returns. - CloneFunctionInto(Dst, Src, ValueMap, false, Returns); + CloneFunctionInto(Dst, Src, ValueMap, false, Returns, "", NULL, &TypeMap); } // There is no need to map the arguments anymore. @@ -869,8 +948,11 @@ void ModuleLinker::linkAliasBodies() { /// linkNamedMDNodes - 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) { + // Don't link module flags here. Do them separately. + if (&*I == SrcModFlags) continue; NamedMDNode *DestNMD = DstM->getOrInsertNamedMetadata(I->getName()); // Add Src elements into Dest node. for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) @@ -878,10 +960,175 @@ void ModuleLinker::linkNamedMDNodes() { RF_None, &TypeMap)); } } + +/// categorizeModuleFlagNodes - +bool ModuleLinker:: +categorizeModuleFlagNodes(const NamedMDNode *ModFlags, + DenseMap<MDString*, MDNode*> &ErrorNode, + DenseMap<MDString*, MDNode*> &WarningNode, + DenseMap<MDString*, MDNode*> &OverrideNode, + DenseMap<MDString*, + SmallSetVector<MDNode*, 8> > &RequireNodes, + SmallSetVector<MDString*, 16> &SeenIDs) { + bool HasErr = false; + + for (unsigned I = 0, E = ModFlags->getNumOperands(); I != E; ++I) { + MDNode *Op = ModFlags->getOperand(I); + assert(Op->getNumOperands() == 3 && "Invalid module flag metadata!"); + assert(isa<ConstantInt>(Op->getOperand(0)) && + "Module flag's first operand must be an integer!"); + assert(isa<MDString>(Op->getOperand(1)) && + "Module flag's second operand must be an MDString!"); + + ConstantInt *Behavior = cast<ConstantInt>(Op->getOperand(0)); + MDString *ID = cast<MDString>(Op->getOperand(1)); + Value *Val = Op->getOperand(2); + switch (Behavior->getZExtValue()) { + default: + assert(false && "Invalid behavior in module flag metadata!"); + break; + case Module::Error: { + MDNode *&ErrNode = ErrorNode[ID]; + if (!ErrNode) ErrNode = Op; + if (ErrNode->getOperand(2) != Val) + HasErr = emitError("linking module flags '" + ID->getString() + + "': IDs have conflicting values"); + break; + } + case Module::Warning: { + MDNode *&WarnNode = WarningNode[ID]; + if (!WarnNode) WarnNode = Op; + if (WarnNode->getOperand(2) != Val) + errs() << "WARNING: linking module flags '" << ID->getString() + << "': IDs have conflicting values"; + break; + } + case Module::Require: RequireNodes[ID].insert(Op); break; + case Module::Override: { + MDNode *&OvrNode = OverrideNode[ID]; + if (!OvrNode) OvrNode = Op; + if (OvrNode->getOperand(2) != Val) + HasErr = emitError("linking module flags '" + ID->getString() + + "': IDs have conflicting override values"); + break; + } + } + + SeenIDs.insert(ID); + } + + return HasErr; +} + +/// linkModuleFlagsMetadata - Merge the linker flags in Src into the Dest +/// module. +bool ModuleLinker::linkModuleFlagsMetadata() { + const NamedMDNode *SrcModFlags = SrcM->getModuleFlagsMetadata(); + if (!SrcModFlags) return false; + + NamedMDNode *DstModFlags = DstM->getOrInsertModuleFlagsMetadata(); + + // If the destination module doesn't have module flags yet, then just copy + // over the source module's flags. + if (DstModFlags->getNumOperands() == 0) { + for (unsigned I = 0, E = SrcModFlags->getNumOperands(); I != E; ++I) + DstModFlags->addOperand(SrcModFlags->getOperand(I)); + + return false; + } + + bool HasErr = false; + + // Otherwise, we have to merge them based on their behaviors. First, + // categorize all of the nodes in the modules' module flags. If an error or + // warning occurs, then emit the appropriate message(s). + DenseMap<MDString*, MDNode*> ErrorNode; + DenseMap<MDString*, MDNode*> WarningNode; + DenseMap<MDString*, MDNode*> OverrideNode; + DenseMap<MDString*, SmallSetVector<MDNode*, 8> > RequireNodes; + SmallSetVector<MDString*, 16> SeenIDs; + + HasErr |= categorizeModuleFlagNodes(SrcModFlags, ErrorNode, WarningNode, + OverrideNode, RequireNodes, SeenIDs); + HasErr |= categorizeModuleFlagNodes(DstModFlags, ErrorNode, WarningNode, + OverrideNode, RequireNodes, SeenIDs); + + // Check that there isn't both an error and warning node for a flag. + for (SmallSetVector<MDString*, 16>::iterator + I = SeenIDs.begin(), E = SeenIDs.end(); I != E; ++I) { + MDString *ID = *I; + if (ErrorNode[ID] && WarningNode[ID]) + HasErr = emitError("linking module flags '" + ID->getString() + + "': IDs have conflicting behaviors"); + } + + // Early exit if we had an error. + if (HasErr) return true; + + // Get the destination's module flags ready for new operands. + DstModFlags->dropAllReferences(); + + // Add all of the module flags to the destination module. + DenseMap<MDString*, SmallVector<MDNode*, 4> > AddedNodes; + for (SmallSetVector<MDString*, 16>::iterator + I = SeenIDs.begin(), E = SeenIDs.end(); I != E; ++I) { + MDString *ID = *I; + if (OverrideNode[ID]) { + DstModFlags->addOperand(OverrideNode[ID]); + AddedNodes[ID].push_back(OverrideNode[ID]); + } else if (ErrorNode[ID]) { + DstModFlags->addOperand(ErrorNode[ID]); + AddedNodes[ID].push_back(ErrorNode[ID]); + } else if (WarningNode[ID]) { + DstModFlags->addOperand(WarningNode[ID]); + AddedNodes[ID].push_back(WarningNode[ID]); + } + + for (SmallSetVector<MDNode*, 8>::iterator + II = RequireNodes[ID].begin(), IE = RequireNodes[ID].end(); + II != IE; ++II) + DstModFlags->addOperand(*II); + } + + // Now check that all of the requirements have been satisfied. + for (SmallSetVector<MDString*, 16>::iterator + I = SeenIDs.begin(), E = SeenIDs.end(); I != E; ++I) { + MDString *ID = *I; + SmallSetVector<MDNode*, 8> &Set = RequireNodes[ID]; + + for (SmallSetVector<MDNode*, 8>::iterator + II = Set.begin(), IE = Set.end(); II != IE; ++II) { + MDNode *Node = *II; + assert(isa<MDNode>(Node->getOperand(2)) && + "Module flag's third operand must be an MDNode!"); + MDNode *Val = cast<MDNode>(Node->getOperand(2)); + + MDString *ReqID = cast<MDString>(Val->getOperand(0)); + Value *ReqVal = Val->getOperand(1); + + bool HasValue = false; + for (SmallVectorImpl<MDNode*>::iterator + RI = AddedNodes[ReqID].begin(), RE = AddedNodes[ReqID].end(); + RI != RE; ++RI) { + MDNode *ReqNode = *RI; + if (ReqNode->getOperand(2) == ReqVal) { + HasValue = true; + break; + } + } + + if (!HasValue) + HasErr = emitError("linking module flags '" + ReqID->getString() + + "': does not have the required value"); + } + } + + return HasErr; +} bool ModuleLinker::run() { - assert(DstM && "Null Destination module"); - assert(SrcM && "Null Source Module"); + 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. @@ -961,7 +1208,6 @@ bool ModuleLinker::run() { // Link in the function bodies that are defined in the source module into // DstM. for (Module::iterator SF = SrcM->begin(), E = SrcM->end(); SF != E; ++SF) { - // Skip if not linking from source. if (DoNotLinkFromSource.count(SF)) continue; @@ -979,11 +1225,15 @@ bool ModuleLinker::run() { // Resolve all uses of aliases with aliasees. linkAliasBodies(); - // Remap all of the named mdnoes in Src into the DstM module. We do this + // 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; + // Process vector of lazily linked in functions. bool LinkedInAnyFunctions; do { diff --git a/lib/Linker/Linker.cpp b/lib/Linker/Linker.cpp index 59fbceb..7c6cf4f 100644 --- a/lib/Linker/Linker.cpp +++ b/lib/Linker/Linker.cpp @@ -17,7 +17,6 @@ #include "llvm/Support/Path.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Config/config.h" #include "llvm/Support/system_error.h" using namespace llvm; |