X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FLinker%2FLinkModules.cpp;h=529fb7714893841f231833524c1d6a8e51972b22;hb=0d6c5b6489b9abb634a1506d183ba47f1bf4d1f0;hp=24449ea9f691769a9165c5c35af5dfc29c8d7b6e;hpb=e3092c94ad2e3af96f37a0a8186149acbbd9700a;p=oota-llvm.git diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index 24449ea9f69..529fb771489 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -1,4 +1,11 @@ //===- Linker.cpp - Module Linker Implementation --------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// // // This file implements the LLVM module linker. // @@ -10,11 +17,13 @@ //===----------------------------------------------------------------------===// #include "llvm/Transforms/Utils/Linker.h" +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" #include "llvm/Module.h" #include "llvm/SymbolTable.h" -#include "llvm/DerivedTypes.h" #include "llvm/iOther.h" -#include "llvm/Constants.h" +#include "llvm/Assembly/Writer.h" +using namespace llvm; // Error - Simple wrapper function to conditionally assign to E and return true. // This just makes error return conditions a little bit simpler... @@ -24,8 +33,23 @@ static inline bool Error(std::string *E, const std::string &Message) { return true; } -// ResolveTypes - Attempt to link the two specified types together. Return true -// if there is an error and they cannot yet be linked. +// +// Function: ResolveTypes() +// +// Description: +// Attempt to link the two specified types together. +// +// Inputs: +// DestTy - The type to which we wish to resolve. +// SrcTy - The original type which we want to resolve. +// Name - The name of the type. +// +// Outputs: +// DestST - The symbol table in which the new type should be placed. +// +// Return value: +// true - There is an error and the types cannot yet be linked. +// false - No errors. // static bool ResolveTypes(const Type *DestTy, const Type *SrcTy, SymbolTable *DestST, const std::string &Name) { @@ -79,7 +103,9 @@ static bool RecursiveResolveTypesI(const PATypeHolder &DestTy, switch (DestTyT->getPrimitiveID()) { case Type::FunctionTyID: { if (cast(DestTyT)->isVarArg() != - cast(SrcTyT)->isVarArg()) + cast(SrcTyT)->isVarArg() || + cast(DestTyT)->getNumContainedTypes() != + cast(SrcTyT)->getNumContainedTypes()) return true; for (unsigned i = 0, e = getFT(DestTy)->getNumContainedTypes(); i != e; ++i) if (RecursiveResolveTypesI(getFT(DestTy)->getContainedType(i), @@ -149,9 +175,9 @@ static bool LinkTypes(Module *Dest, const Module *Src, std::string *Err) { SymbolTable::const_iterator PI = SrcST->find(Type::TypeTy); if (PI == SrcST->end()) return false; // No named types, do nothing. - // Some types cannot be resolved immediately becuse they depend on other types - // being resolved to each other first. This contains a list of types we are - // waiting to recheck. + // Some types cannot be resolved immediately because they depend on other + // types being resolved to each other first. This contains a list of types we + // are waiting to recheck. std::vector DelayedTypesToResolve; const SymbolTable::VarMap &VM = PI->second; @@ -206,20 +232,21 @@ static bool LinkTypes(Module *Dest, const Module *Src, std::string *Err) { } // If we STILL cannot resolve the types, then there is something wrong. - // Report the error. + // Report the warning and delete one of the names. if (DelayedTypesToResolve.size() == OldSize) { - // Build up an error message of all of the mismatched types. - std::string ErrorMessage; - for (unsigned i = 0, e = DelayedTypesToResolve.size(); i != e; ++i) { - const std::string &Name = DelayedTypesToResolve[i]; - const Type *T1 = cast(VM.find(Name)->second); - const Type *T2 = cast(DestST->lookup(Type::TypeTy, Name)); - ErrorMessage += " Type named '" + Name + - "' conflicts.\n Src='" + T1->getDescription() + - "'.\n Dest='" + T2->getDescription() + "'\n"; - } - return Error(Err, "Type conflict between types in modules:\n" + - ErrorMessage); + const std::string &Name = DelayedTypesToResolve.back(); + + const Type *T1 = cast(VM.find(Name)->second); + const Type *T2 = cast(DestST->lookup(Type::TypeTy, Name)); + std::cerr << "WARNING: Type conflict between types named '" << Name + << "'.\n Src='"; + WriteTypeSymbolic(std::cerr, T1, Src); + std::cerr << "'.\n Dest='"; + WriteTypeSymbolic(std::cerr, T2, Dest); + std::cerr << "'\n"; + + // Remove the symbol name from the destination. + DelayedTypesToResolve.pop_back(); } } } @@ -257,7 +284,8 @@ static Value *RemapOperand(const Value *In, // Check to see if it's a constant that we are interesting in transforming... if (const Constant *CPV = dyn_cast(In)) { - if (!isa(CPV->getType()) && !isa(CPV)) + if ((!isa(CPV->getType()) && !isa(CPV)) || + isa(CPV)) return const_cast(CPV); // Simple constants stay identical... Constant *Result = 0; @@ -303,7 +331,7 @@ static Value *RemapOperand(const Value *In, Value *V2 = RemapOperand(CE->getOperand(1), LocalMap, GlobalMap); Result = ConstantExpr::get(CE->getOpcode(), cast(V1), - cast(V2)); + cast(V2)); } else { assert(0 && "Unknown constant expr type!"); } @@ -347,17 +375,32 @@ static GlobalValue *FindGlobalNamed(const std::string &Name, const Type *Ty, // It doesn't exist exactly, scan through all of the type planes in the symbol // table, checking each of them for a type-compatible version. // - for (SymbolTable::iterator I = ST->begin(), E = ST->end(); I != E; ++I) { - SymbolTable::VarMap &VM = I->second; - // Does this type plane contain an entry with the specified name? - SymbolTable::type_iterator TI = VM.find(Name); - if (TI != VM.end()) { - // Determine whether we can fold the two types together, resolving them. - // If so, we can use this value. - if (!RecursiveResolveTypes(Ty, I->first, ST, "")) - return cast(TI->second); + for (SymbolTable::iterator I = ST->begin(), E = ST->end(); I != E; ++I) + if (I->first != Type::TypeTy) { + SymbolTable::VarMap &VM = I->second; + + // Does this type plane contain an entry with the specified name? + SymbolTable::type_iterator TI = VM.find(Name); + if (TI != VM.end()) { + // + // Ensure that this type if placed correctly into the symbol table. + // + assert(TI->second->getType() == I->first && "Type conflict!"); + + // + // Save a reference to the new type. Resolving the type can modify the + // symbol table, invalidating the TI variable. + // + Value *ValPtr = TI->second; + + // + // Determine whether we can fold the two types together, resolving them. + // If so, we can use this value. + // + if (!RecursiveResolveTypes(Ty, I->first, ST, "")) + return cast(ValPtr); + } } - } return 0; // Otherwise, nothing could be found. } @@ -430,29 +473,56 @@ static bool LinkGlobals(Module *Dest, const Module *Src, } else if (DGV->isExternal()) { // If DGV is external but SGV is not... ValueMap.insert(std::make_pair(SGV, DGV)); DGV->setLinkage(SGV->getLinkage()); // Inherit linkage! + } else if (SGV->hasWeakLinkage() || SGV->hasLinkOnceLinkage()) { + // At this point we know that DGV has LinkOnce, Appending, Weak, or + // External linkage. If DGV is Appending, this is an error. + if (DGV->hasAppendingLinkage()) + return Error(Err, "Linking globals named '" + SGV->getName() + + " ' with 'weak' and 'appending' linkage is not allowed!"); + + if (SGV->isConstant() != DGV->isConstant()) + return Error(Err, "Global Variable Collision on '" + + SGV->getType()->getDescription() + " %" + SGV->getName() + + "' - Global variables differ in const'ness"); + + // Otherwise, just perform the link. + ValueMap.insert(std::make_pair(SGV, DGV)); + + // Linkonce+Weak = Weak + if (DGV->hasLinkOnceLinkage() && SGV->hasWeakLinkage()) + DGV->setLinkage(SGV->getLinkage()); + + } else if (DGV->hasWeakLinkage() || DGV->hasLinkOnceLinkage()) { + // At this point we know that SGV has LinkOnce, Appending, or External + // linkage. If SGV is Appending, this is an error. + if (SGV->hasAppendingLinkage()) + return Error(Err, "Linking globals named '" + SGV->getName() + + " ' with 'weak' and 'appending' linkage is not allowed!"); + + if (SGV->isConstant() != DGV->isConstant()) + return Error(Err, "Global Variable Collision on '" + + SGV->getType()->getDescription() + " %" + SGV->getName() + + "' - Global variables differ in const'ness"); + + if (!SGV->hasLinkOnceLinkage()) + DGV->setLinkage(SGV->getLinkage()); // Inherit linkage! + ValueMap.insert(std::make_pair(SGV, DGV)); + } else if (SGV->getLinkage() != DGV->getLinkage()) { return Error(Err, "Global variables named '" + SGV->getName() + "' have different linkage specifiers!"); } else if (SGV->hasExternalLinkage()) { // Allow linking two exactly identical external global variables... - if (SGV->isConstant() != DGV->isConstant() || - SGV->getInitializer() != DGV->getInitializer()) + if (SGV->isConstant() != DGV->isConstant()) return Error(Err, "Global Variable Collision on '" + SGV->getType()->getDescription() + " %" + SGV->getName() + "' - Global variables differ in const'ness"); - ValueMap.insert(std::make_pair(SGV, DGV)); - } else if (SGV->hasLinkOnceLinkage()) { - // If the global variable has a name, and that name is already in use in - // the Dest module, make sure that the name is a compatible global - // variable... - // - // Check to see if the two GV's have the same Const'ness... - if (SGV->isConstant() != DGV->isConstant()) + + if (SGV->getInitializer() != DGV->getInitializer()) return Error(Err, "Global Variable Collision on '" + SGV->getType()->getDescription() + " %" + SGV->getName() + - "' - Global variables differ in const'ness"); + "' - External linkage globals have different initializers"); - // Okay, everything is cool, remember the mapping... ValueMap.insert(std::make_pair(SGV, DGV)); } else if (SGV->hasAppendingLinkage()) { // No linking is performed yet. Just insert a new copy of the global, and @@ -496,13 +566,15 @@ static bool LinkGlobalInits(Module *Dest, const Module *Src, GlobalVariable *DGV = cast(ValueMap[SGV]); if (DGV->hasInitializer()) { - assert(SGV->getLinkage() == DGV->getLinkage()); if (SGV->hasExternalLinkage()) { if (DGV->getInitializer() != SInit) return Error(Err, "Global Variable Collision on '" + SGV->getType()->getDescription() +"':%"+SGV->getName()+ " - Global variables have different initializers"); - } else if (DGV->hasLinkOnceLinkage()) { + } else if (DGV->hasLinkOnceLinkage() || DGV->hasWeakLinkage()) { + // Nothing is required, mapped values will take the new global + // automatically. + } else if (SGV->hasLinkOnceLinkage() || SGV->hasWeakLinkage()) { // Nothing is required, mapped values will take the new global // automatically. } else if (DGV->hasAppendingLinkage()) { @@ -571,6 +643,20 @@ static bool LinkFunctionProtos(Module *Dest, const Module *Src, ValueMap.insert(std::make_pair(SF, DF)); DF->setLinkage(SF->getLinkage()); + } else if (SF->hasWeakLinkage() || SF->hasLinkOnceLinkage()) { + // At this point we know that DF has LinkOnce, Weak, or External linkage. + ValueMap.insert(std::make_pair(SF, DF)); + + // Linkonce+Weak = Weak + if (DF->hasLinkOnceLinkage() && SF->hasWeakLinkage()) + DF->setLinkage(SF->getLinkage()); + + } else if (DF->hasWeakLinkage() || DF->hasLinkOnceLinkage()) { + // At this point we know that SF has LinkOnce or External linkage. + ValueMap.insert(std::make_pair(SF, DF)); + if (!SF->hasLinkOnceLinkage()) // Don't inherit linkonce linkage + DF->setLinkage(SF->getLinkage()); + } else if (SF->getLinkage() != DF->getLinkage()) { return Error(Err, "Functions named '" + SF->getName() + "' have different linkage specifiers!"); @@ -579,9 +665,6 @@ static bool LinkFunctionProtos(Module *Dest, const Module *Src, return Error(Err, "Function '" + SF->getFunctionType()->getDescription() + "':\"" + SF->getName() + "\" - Function is already defined!"); - } else if (SF->hasLinkOnceLinkage()) { - // Completely ignore the source function. - ValueMap.insert(std::make_pair(SF, DF)); } else { assert(0 && "Unknown linkage configuration found!"); } @@ -662,15 +745,11 @@ static bool LinkFunctionBodies(Module *Dest, const Module *Src, Function *DF = cast(ValueMap[SF]); // Destination function // DF not external SF external? - if (!DF->isExternal()) { - if (DF->hasLinkOnceLinkage()) continue; // No relinkage for link-once! - if (Err) - *Err = "Function '" + (SF->hasName() ? SF->getName() :std::string("")) - + "' body multiply defined!"; - return true; + if (DF->isExternal()) { + // Only provide the function body if there isn't one already. + if (LinkFunctionBody(DF, SF, ValueMap, Err)) + return true; } - - if (LinkFunctionBody(DF, SF, ValueMap, Err)) return true; } } return false; @@ -720,12 +799,24 @@ static bool LinkAppendingVars(Module *M, // Merge the initializer... Inits.reserve(NewSize); - ConstantArray *I = cast(G1->getInitializer()); - for (unsigned i = 0, e = T1->getNumElements(); i != e; ++i) - Inits.push_back(cast(I->getValues()[i])); - I = cast(G2->getInitializer()); - for (unsigned i = 0, e = T2->getNumElements(); i != e; ++i) - Inits.push_back(cast(I->getValues()[i])); + if (ConstantArray *I = dyn_cast(G1->getInitializer())) { + for (unsigned i = 0, e = T1->getNumElements(); i != e; ++i) + Inits.push_back(cast(I->getValues()[i])); + } else { + assert(isa(G1->getInitializer())); + Constant *CV = Constant::getNullValue(T1->getElementType()); + for (unsigned i = 0, e = T1->getNumElements(); i != e; ++i) + Inits.push_back(CV); + } + if (ConstantArray *I = dyn_cast(G2->getInitializer())) { + for (unsigned i = 0, e = T2->getNumElements(); i != e; ++i) + Inits.push_back(cast(I->getValues()[i])); + } else { + assert(isa(G2->getInitializer())); + Constant *CV = Constant::getNullValue(T2->getElementType()); + for (unsigned i = 0, e = T2->getNumElements(); i != e; ++i) + Inits.push_back(CV); + } NG->setInitializer(ConstantArray::get(NewType, Inits)); Inits.clear(); @@ -759,10 +850,17 @@ static bool LinkAppendingVars(Module *M, // the problem. Upon failure, the Dest module could be in a modified state, and // shouldn't be relied on to be consistent. // -bool LinkModules(Module *Dest, const Module *Src, std::string *ErrorMsg) { - if (Dest->getEndianness() != Src->getEndianness()) +bool llvm::LinkModules(Module *Dest, const Module *Src, std::string *ErrorMsg) { + if (Dest->getEndianness() == Module::AnyEndianness) + Dest->setEndianness(Src->getEndianness()); + if (Dest->getPointerSize() == Module::AnyPointerSize) + Dest->setPointerSize(Src->getPointerSize()); + + if (Src->getEndianness() != Module::AnyEndianness && + Dest->getEndianness() != Src->getEndianness()) std::cerr << "WARNING: Linking two modules of different endianness!\n"; - if (Dest->getPointerSize() != Src->getPointerSize()) + if (Src->getPointerSize() != Module::AnyPointerSize && + Dest->getPointerSize() != Src->getPointerSize()) std::cerr << "WARNING: Linking two modules of different pointer size!\n"; // LinkTypes - Go through the symbol table of the Src module and see if any