X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FLinker%2FLinkModules.cpp;h=563aed5daa0c1c5e0fe9b30590a7432d3410abcc;hb=1ee0ecf84a07693c3a517ba030fac8ac1f9f3fbc;hp=75efce0b182b8fccdf00d1f0d6ae787766fb6fcf;hpb=d24397a9319a41e80169f572ad274a711f41d64e;p=oota-llvm.git diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index 75efce0b182..563aed5daa0 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -17,6 +17,7 @@ #include "llvm/Instructions.h" #include "llvm/Module.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/Optional.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Path.h" #include "llvm/Transforms/Utils/Cloning.h" @@ -379,7 +380,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. @@ -451,15 +454,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() && @@ -521,13 +536,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; } @@ -665,6 +677,7 @@ bool ModuleLinker::linkAppendingVarProto(GlobalVariable *DstGV, /// merge them into the dest module. bool ModuleLinker::linkGlobalProto(GlobalVariable *SGV) { GlobalValue *DGV = getLinkedToGlobal(SGV); + llvm::Optional NewVisibility; if (DGV) { // Concatenation of appending linkage variables is magic and handled later. @@ -674,9 +687,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. @@ -686,9 +701,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())); @@ -711,6 +727,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())); @@ -726,17 +744,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 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())); @@ -753,6 +775,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. @@ -775,17 +799,21 @@ bool ModuleLinker::linkFunctionProto(Function *SF) { /// source module. bool ModuleLinker::linkAliasProto(GlobalAlias *SGA) { GlobalValue *DGV = getLinkedToGlobal(SGA); - + llvm::Optional 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())); @@ -802,6 +830,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. @@ -813,29 +843,32 @@ bool ModuleLinker::linkAliasProto(GlobalAlias *SGA) { return false; } +static void getArrayElements(Constant *C, SmallVectorImpl &Dest) { + if (ConstantArray *I = dyn_cast(C)) { + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) + Dest.push_back(I->getOperand(i)); + return; + } + + if (ConstantDataSequential *CDS = dyn_cast(C)) { + for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) + Dest.push_back(CDS->getElementAsConstant(i)); + return; + } + + ConstantAggregateZero *CAZ = cast(C); + Dest.append(cast(C->getType())->getNumElements(), + CAZ->getSequentialElement()); +} + void ModuleLinker::linkAppendingVarInit(const AppendingVarInfo &AVI) { // Merge the initializer. SmallVector Elements; - if (ConstantArray *I = dyn_cast(AVI.DstInit)) { - for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) - Elements.push_back(I->getOperand(i)); - } else { - assert(isa(AVI.DstInit)); - ArrayType *DstAT = cast(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(SrcInit)) { - for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) - Elements.push_back(I->getOperand(i)); - } else { - assert(isa(SrcInit)); - ArrayType *SrcAT = cast(SrcInit->getType()); - Type *EltTy = SrcAT->getElementType(); - Elements.append(SrcAT->getNumElements(), Constant::getNullValue(EltTy)); - } + getArrayElements(SrcInit, Elements); + ArrayType *NewType = cast(AVI.NewGV->getType()->getElementType()); AVI.NewGV->setInitializer(ConstantArray::get(NewType, Elements)); }