implement linking of globals to functions, in one direction

(replacing a function with a global).  This is needed when building
llvm itself with LTO on darwin, because of the EXPLICIT_SYMBOL hack
in lib/system/DynamicLibrary.cpp.

Implementation of linking the other way will need to wait for a 
cleanup of LinkFunctionProtos.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53546 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2008-07-14 06:49:45 +00:00
parent 0bb8757997
commit d1ec48c641
2 changed files with 87 additions and 80 deletions

View File

@ -534,27 +534,23 @@ static bool LinkGlobals(Module *Dest, const Module *Src,
std::map<const Value*, Value*> &ValueMap,
std::multimap<std::string, GlobalVariable *> &AppendingVars,
std::string *Err) {
ValueSymbolTable &DestSymTab = Dest->getValueSymbolTable();
// Loop over all of the globals in the src module, mapping them over as we go
for (Module::const_global_iterator I = Src->global_begin(),
E = Src->global_end(); I != E; ++I) {
const GlobalVariable *SGV = I;
GlobalValue *DGV = 0;
// Check to see if may have to link the global with the global
if (SGV->hasName() && !SGV->hasInternalLinkage()) {
DGV = Dest->getGlobalVariable(SGV->getName());
if (DGV && DGV->getType() != SGV->getType())
// If types don't agree due to opaque types, try to resolve them.
RecursiveResolveTypes(SGV->getType(), DGV->getType());
}
// Check to see if may have to link the global with the global, alias or
// function.
if (SGV->hasName() && !SGV->hasInternalLinkage())
DGV = cast_or_null<GlobalValue>(DestSymTab.lookup(SGV->getNameStart(),
SGV->getNameEnd()));
// Check to see if may have to link the global with the alias
if (!DGV && SGV->hasName() && !SGV->hasInternalLinkage()) {
DGV = Dest->getNamedAlias(SGV->getName());
if (DGV && DGV->getType() != SGV->getType())
// If types don't agree due to opaque types, try to resolve them.
if (DGV && DGV->getType() != SGV->getType())
RecursiveResolveTypes(SGV->getType(), DGV->getType());
}
if (DGV && DGV->hasInternalLinkage())
DGV = 0;
@ -571,7 +567,7 @@ static bool LinkGlobals(Module *Dest, const Module *Src,
if (!DGV) {
// No linking to be performed, simply create an identical version of the
// symbol over in the dest module... the initializer will be filled in
// later by LinkGlobalInits...
// later by LinkGlobalInits.
GlobalVariable *NewDGV =
new GlobalVariable(SGV->getType()->getElementType(),
SGV->isConstant(), SGV->getLinkage(), /*init*/0,
@ -589,8 +585,8 @@ static bool LinkGlobals(Module *Dest, const Module *Src,
// Make sure to remember this mapping...
ValueMap[SGV] = NewDGV;
// Keep track that this is an appending variable.
if (SGV->hasAppendingLinkage())
// Keep track that this is an appending variable...
AppendingVars.insert(std::make_pair(SGV->getName(), NewDGV));
} else if (DGV->hasAppendingLinkage()) {
// No linking is performed yet. Just insert a new copy of the global, and
@ -617,61 +613,64 @@ static bool LinkGlobals(Module *Dest, const Module *Src,
// SGV is global, but DGV is alias. The only valid mapping is when SGV is
// external declaration, which is effectively a no-op. Also make sure
// linkage calculation was correct.
if (SGV->isDeclaration() && !LinkFromSrc) {
// Make sure to remember this mapping...
ValueMap[SGV] = DGA;
} else
if (!SGV->isDeclaration() || LinkFromSrc)
return Error(Err, "Global-Alias Collision on '" + SGV->getName() +
"': symbol multiple defined");
} else if (GlobalVariable *DGVar = dyn_cast<GlobalVariable>(DGV)) {
// Otherwise, perform the global-global mapping as instructed by
// GetLinkageResult.
if (LinkFromSrc) {
// Propagate alignment, section, and visibility info.
CopyGVAttributes(DGVar, SGV);
// Make sure to remember this mapping.
ValueMap[SGV] = DGA;
} else if (LinkFromSrc) {
// If the types don't match, and if we are to link from the source, nuke
// DGV and create a new one of the appropriate type.
if (SGV->getType() != DGVar->getType()) {
// DGV and create a new one of the appropriate type. Note that the thing
// we are replacing may be a function (if a prototype, weak, etc) or a
// global variable.
GlobalVariable *NewDGV =
new GlobalVariable(SGV->getType()->getElementType(),
DGVar->isConstant(), DGVar->getLinkage(),
/*init*/0, DGVar->getName(), Dest, false,
SGV->isConstant(), SGV->getLinkage(),
/*init*/0, DGV->getName(), Dest, false,
SGV->getType()->getAddressSpace());
CopyGVAttributes(NewDGV, DGVar);
DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewDGV,
DGVar->getType()));
// DGVar will conflict with NewDGV because they both had the same
// Propagate alignment, section, and visibility info.
CopyGVAttributes(NewDGV, SGV);
DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewDGV, DGV->getType()));
// DGV will conflict with NewDGV because they both had the same
// name. We must erase this now so ForceRenaming doesn't assert
// because DGV might not have internal linkage.
DGVar->eraseFromParent();
if (GlobalVariable *Var = dyn_cast<GlobalVariable>(DGV))
Var->eraseFromParent();
else
cast<Function>(DGV)->eraseFromParent();
DGV = NewDGV;
// If the symbol table renamed the global, but it is an externally
// visible symbol, DGV must be an existing global with internal
// linkage. Rename it.
if (NewDGV->getName() != SGV->getName() &&
// If the symbol table renamed the global, but it is an externally visible
// symbol, DGV must be an existing global with internal linkage. Rename.
if (NewDGV->getValueName() != SGV->getValueName() &&
!NewDGV->hasInternalLinkage())
ForceRenaming(NewDGV, SGV->getName());
DGVar = NewDGV;
}
// Inherit const as appropriate
DGVar->setConstant(SGV->isConstant());
// Set initializer to zero, so we can link the stuff later
DGVar->setInitializer(0);
} else {
// Special case for const propagation
if (DGVar->isDeclaration() && SGV->isConstant() && !DGVar->isConstant())
DGVar->setConstant(true);
}
NewDGV->setConstant(SGV->isConstant());
// Set calculated linkage
DGVar->setLinkage(NewLinkage);
NewDGV->setLinkage(NewLinkage);
// Make sure to remember this mapping...
ValueMap[SGV] = ConstantExpr::getBitCast(DGVar, SGV->getType());
ValueMap[SGV] = ConstantExpr::getBitCast(NewDGV, SGV->getType());
} else {
// Not "link from source", keep the one in the DestModule and remap the
// input onto it.
// Special case for const propagation.
if (GlobalVariable *DGVar = dyn_cast<GlobalVariable>(DGV))
if (DGVar->isDeclaration() && SGV->isConstant() && !DGVar->isConstant())
DGVar->setConstant(true);
// Set calculated linkage
DGV->setLinkage(NewLinkage);
// Make sure to remember this mapping...
ValueMap[SGV] = ConstantExpr::getBitCast(DGV, SGV->getType());
}
}
return false;
@ -844,7 +843,6 @@ static bool LinkAlias(Module *Dest, const Module *Src,
static bool LinkGlobalInits(Module *Dest, const Module *Src,
std::map<const Value*, Value*> &ValueMap,
std::string *Err) {
// Loop over all of the globals in the src module, mapping them over as we go
for (Module::const_global_iterator I = Src->global_begin(),
E = Src->global_end(); I != E; ++I) {
@ -889,27 +887,23 @@ static bool LinkGlobalInits(Module *Dest, const Module *Src,
static bool LinkFunctionProtos(Module *Dest, const Module *Src,
std::map<const Value*, Value*> &ValueMap,
std::string *Err) {
ValueSymbolTable &DestSymTab = Dest->getValueSymbolTable();
// Loop over all of the functions in the src module, mapping them over
for (Module::const_iterator I = Src->begin(), E = Src->end(); I != E; ++I) {
const Function *SF = I; // SrcFunction
GlobalValue *DGV = 0;
Value *MappedDF;
// If this function is internal or has no name, it doesn't participate in
// linkage.
if (SF->hasName() && !SF->hasInternalLinkage()) {
// Check to see if may have to link the function.
DGV = Dest->getFunction(SF->getName());
}
// Check to see if may have to link the function with the global, alias or
// function.
if (SF->hasName() && !SF->hasInternalLinkage())
DGV = cast_or_null<GlobalValue>(DestSymTab.lookup(SF->getNameStart(),
SF->getNameEnd()));
// Check to see if may have to link the function with the alias
if (!DGV && SF->hasName() && !SF->hasInternalLinkage()) {
DGV = Dest->getNamedAlias(SF->getName());
if (DGV && DGV->getType() != SF->getType())
// If types don't agree due to opaque types, try to resolve them.
if (DGV && DGV->getType() != SF->getType())
RecursiveResolveTypes(SF->getType(), DGV->getType());
}
if (DGV && DGV->hasInternalLinkage())
DGV = 0;

View File

@ -0,0 +1,13 @@
; RUN: llvm-as %s -o %t1.bc -f
; RUN: echo {declare void @__eprintf(i8*, i8*, i32, i8*) noreturn define void @foo() { tail call void @__eprintf( i8* undef, i8* undef, i32 4, i8* null ) noreturn nounwind unreachable }} | llvm-as -o %t2.bc -f
; RUN: llvm-link %t2.bc %t1.bc -o - | llvm-dis | grep __eprintf
; RN: llvm-link %t1.bc %t2.bc -o - | llvm-dis | grep __eprintf
; rdar://6072702
@__eprintf = external global i8* ; <i8**> [#uses=1]
define i8* @test() {
%A = load i8** @__eprintf ; <i8*> [#uses=1]
ret i8* %A
}