mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00:00
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:
parent
0bb8757997
commit
d1ec48c641
@ -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 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.
|
||||
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()));
|
||||
|
||||
// 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);
|
||||
|
||||
// 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()) {
|
||||
GlobalVariable *NewDGV =
|
||||
new GlobalVariable(SGV->getType()->getElementType(),
|
||||
DGVar->isConstant(), DGVar->getLinkage(),
|
||||
/*init*/0, DGVar->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
|
||||
// name. We must erase this now so ForceRenaming doesn't assert
|
||||
// because DGV might not have internal linkage.
|
||||
DGVar->eraseFromParent();
|
||||
// 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. 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(),
|
||||
SGV->isConstant(), SGV->getLinkage(),
|
||||
/*init*/0, DGV->getName(), Dest, false,
|
||||
SGV->getType()->getAddressSpace());
|
||||
|
||||
// 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.
|
||||
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() &&
|
||||
!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 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());
|
||||
|
||||
// Inherit const as appropriate
|
||||
NewDGV->setConstant(SGV->isConstant());
|
||||
|
||||
// Set calculated linkage
|
||||
NewDGV->setLinkage(NewLinkage);
|
||||
|
||||
// Make sure to remember this mapping...
|
||||
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
|
||||
DGVar->setLinkage(NewLinkage);
|
||||
|
||||
DGV->setLinkage(NewLinkage);
|
||||
|
||||
// Make sure to remember this mapping...
|
||||
ValueMap[SGV] = ConstantExpr::getBitCast(DGVar, SGV->getType());
|
||||
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 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.
|
||||
RecursiveResolveTypes(SF->getType(), DGV->getType());
|
||||
}
|
||||
// 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()));
|
||||
|
||||
// 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;
|
||||
|
13
test/Linker/link-global-to-func.ll
Normal file
13
test/Linker/link-global-to-func.ll
Normal 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
|
||||
}
|
Loading…
Reference in New Issue
Block a user