summaryrefslogtreecommitdiff
path: root/lib/Linker
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-07-14 06:49:45 +0000
committerChris Lattner <sabre@nondot.org>2008-07-14 06:49:45 +0000
commitd1ec48c641f76d4c0e5b7cb357a1333d4fb75c4a (patch)
tree3d1ecbd6559d1eb32d37371a04a7ff980f218213 /lib/Linker
parent0bb8757997392ee18ca9de0f1fab29463f8e7aeb (diff)
downloadllvm-d1ec48c641f76d4c0e5b7cb357a1333d4fb75c4a.tar.gz
llvm-d1ec48c641f76d4c0e5b7cb357a1333d4fb75c4a.tar.bz2
llvm-d1ec48c641f76d4c0e5b7cb357a1333d4fb75c4a.tar.xz
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
Diffstat (limited to 'lib/Linker')
-rw-r--r--lib/Linker/LinkModules.cpp156
1 files changed, 75 insertions, 81 deletions
diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp
index d771d053ad..5979dc6fbc 100644
--- a/lib/Linker/LinkModules.cpp
+++ b/lib/Linker/LinkModules.cpp
@@ -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();
-
- // 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
+ // 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.
+ 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;