aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Linker
diff options
context:
space:
mode:
authorAnton Korobeynikov <asl@math.spbu.ru>2008-03-10 22:33:53 +0000
committerAnton Korobeynikov <asl@math.spbu.ru>2008-03-10 22:33:53 +0000
commit968e39a5aba998a126278425da8287aae358e7a7 (patch)
tree592f268ab05bb6bdd43fc4c68ddd4fdf677a615b /lib/Linker
parent2b48ef0450944c2c46633aec9baf6be835a3b503 (diff)
downloadexternal_llvm-968e39a5aba998a126278425da8287aae358e7a7.zip
external_llvm-968e39a5aba998a126278425da8287aae358e7a7.tar.gz
external_llvm-968e39a5aba998a126278425da8287aae358e7a7.tar.bz2
Remove the LinkGlobal weirderness in common linking phase.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48177 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Linker')
-rw-r--r--lib/Linker/LinkModules.cpp77
1 files changed, 44 insertions, 33 deletions
diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp
index 78cbf3e..e7183eb 100644
--- a/lib/Linker/LinkModules.cpp
+++ b/lib/Linker/LinkModules.cpp
@@ -374,7 +374,7 @@ static void CopyGVAttributes(GlobalValue *DestGV, const GlobalValue *SrcGV) {
/// 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.
-static bool GetLinkageResult(GlobalValue *Dest, GlobalValue *Src,
+static bool GetLinkageResult(GlobalValue *Dest, const GlobalValue *Src,
GlobalValue::LinkageTypes &LT, bool &LinkFromSrc,
std::string *Err) {
assert((!Dest || !Src->hasInternalLinkage()) &&
@@ -454,14 +454,14 @@ static bool GetLinkageResult(GlobalValue *Dest, GlobalValue *Src,
// LinkGlobals - Loop through the global variables in the src module and merge
// them into the dest module.
-static bool LinkGlobals(Module *Dest, Module *Src,
+static bool LinkGlobals(Module *Dest, const Module *Src,
std::map<const Value*, Value*> &ValueMap,
std::multimap<std::string, GlobalVariable *> &AppendingVars,
std::string *Err) {
// Loop over all of the globals in the src module, mapping them over as we go
- for (Module::global_iterator I = Src->global_begin(), E = Src->global_end();
+ for (Module::const_global_iterator I = Src->global_begin(), E = Src->global_end();
I != E; ++I) {
- GlobalVariable *SGV = I;
+ const GlobalVariable *SGV = I;
GlobalVariable *DGV = 0;
// Check to see if may have to link the global.
if (SGV->hasName() && !SGV->hasInternalLinkage()) {
@@ -528,42 +528,53 @@ static bool LinkGlobals(Module *Dest, Module *Src,
AppendingVars.insert(std::make_pair(SGV->getName(), NewDGV));
} else {
// Otherwise, perform the mapping as instructed by GetLinkageResult.
-
- // Propagate alignment, section, and visibility info.
- CopyGVAttributes(DGV, 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() != DGV->getType() && LinkFromSrc) {
- GlobalVariable *NewDGV =
- new GlobalVariable(SGV->getType()->getElementType(),
- DGV->isConstant(), DGV->getLinkage());
- CopyGVAttributes(NewDGV, DGV);
- Dest->getGlobalList().insert(DGV, NewDGV);
- DGV->replaceAllUsesWith(
- ConstantExpr::getBitCast(NewDGV, DGV->getType()));
- DGV->eraseFromParent();
- NewDGV->setName(SGV->getName());
- DGV = NewDGV;
- }
-
- DGV->setLinkage(NewLinkage);
-
if (LinkFromSrc) {
+ // Propagate alignment, section, and visibility info.
+ CopyGVAttributes(DGV, 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() != DGV->getType()) {
+ GlobalVariable *NewDGV =
+ new GlobalVariable(SGV->getType()->getElementType(),
+ DGV->isConstant(), DGV->getLinkage(),
+ /*init*/0, DGV->getName(), Dest);
+ CopyGVAttributes(NewDGV, DGV);
+ 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.
+ DGV->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());
+
+ DGV = NewDGV;
+ }
+
// Inherit const as appropriate
DGV->setConstant(SGV->isConstant());
+
+ // Set initializer to zero, so we can link the stuff later
DGV->setInitializer(0);
} else {
- if (SGV->isConstant() && !DGV->isConstant()) {
- if (DGV->isDeclaration())
- DGV->setConstant(true);
- }
- SGV->setLinkage(GlobalValue::ExternalLinkage);
- SGV->setInitializer(0);
+ // Special case for const propagation
+ if (DGV->isDeclaration() && SGV->isConstant() && !DGV->isConstant())
+ DGV->setConstant(true);
}
- ValueMap.insert(
- std::make_pair(SGV, ConstantExpr::getBitCast(DGV, SGV->getType())));
+ // Set calculated linkage
+ DGV->setLinkage(NewLinkage);
+
+ // Make sure to remember this mapping...
+ ValueMap.insert(std::make_pair(SGV,
+ ConstantExpr::getBitCast(DGV,
+ SGV->getType())));
}
}
return false;