[llvm-branch-commits] [llvm-branch] r134482 - /llvm/branches/type-system-rewrite/lib/Linker/LinkModules.cpp
Chris Lattner
sabre at nondot.org
Wed Jul 6 00:25:17 PDT 2011
Author: lattner
Date: Wed Jul 6 02:25:17 2011
New Revision: 134482
URL: http://llvm.org/viewvc/llvm-project?rev=134482&view=rev
Log:
Rip out the old and broken logic for linking aliases. Now aliases work just like
everything else. This defines away a ton of bugs. Previously the linker
would crash on aliases that pointed to other aliases, which is explicitly allowed
in LangRef.
Modified:
llvm/branches/type-system-rewrite/lib/Linker/LinkModules.cpp
Modified: llvm/branches/type-system-rewrite/lib/Linker/LinkModules.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/type-system-rewrite/lib/Linker/LinkModules.cpp?rev=134482&r1=134481&r2=134482&view=diff
==============================================================================
--- llvm/branches/type-system-rewrite/lib/Linker/LinkModules.cpp (original)
+++ llvm/branches/type-system-rewrite/lib/Linker/LinkModules.cpp Wed Jul 6 02:25:17 2011
@@ -624,11 +624,6 @@
if (LinkFromSrc) {
// Clear the name of DGV so we don't get a name conflict.
DGV->setName("");
-
- // 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(*DstM, TypeMap.get(SGV->getType()->getElementType()),
SGV->isConstant(), NewLinkage, /*init*/0,
@@ -698,10 +693,6 @@
if (LinkFromSrc) {
// Clear the name so we don't get a conflict.
DGV->setName("");
-
- // We have a definition of the same name but different type in the
- // source module. Copy the prototype to the destination and replace
- // uses of the destination's prototype with the new prototype.
Function *NewDF = Function::Create(TypeMap.get(SF->getFunctionType()),
NewLinkage, SF->getName(), DstM);
CopyGVAttributes(NewDF, SF);
@@ -727,158 +718,59 @@
return false;
}
-static GlobalValue::LinkageTypes
-CalculateAliasLinkage(const GlobalValue *SGV, const GlobalValue *DGV) {
- GlobalValue::LinkageTypes SL = SGV->getLinkage();
- GlobalValue::LinkageTypes DL = DGV->getLinkage();
- if (SL == GlobalValue::ExternalLinkage || DL == GlobalValue::ExternalLinkage)
- return GlobalValue::ExternalLinkage;
- if (SL == GlobalValue::WeakAnyLinkage || DL == GlobalValue::WeakAnyLinkage)
- return GlobalValue::WeakAnyLinkage;
- if (SL == GlobalValue::WeakODRLinkage || DL == GlobalValue::WeakODRLinkage)
- return GlobalValue::WeakODRLinkage;
- if (SL == GlobalValue::InternalLinkage && DL == GlobalValue::InternalLinkage)
- return GlobalValue::InternalLinkage;
- if (SL == GlobalValue::LinkerPrivateLinkage &&
- DL == GlobalValue::LinkerPrivateLinkage)
- return GlobalValue::LinkerPrivateLinkage;
- if (SL == GlobalValue::LinkerPrivateWeakLinkage &&
- DL == GlobalValue::LinkerPrivateWeakLinkage)
- return GlobalValue::LinkerPrivateWeakLinkage;
- if (SL == GlobalValue::LinkerPrivateWeakDefAutoLinkage &&
- DL == GlobalValue::LinkerPrivateWeakDefAutoLinkage)
- return GlobalValue::LinkerPrivateWeakDefAutoLinkage;
-
- assert(SL == GlobalValue::PrivateLinkage &&
- DL == GlobalValue::PrivateLinkage && "Unexpected linkage type");
- return GlobalValue::PrivateLinkage;
-}
-
/// LinkAliasProto - Set up prototypes for any aliases that come over from the
/// source module.
bool ModuleLinker::linkAliasProto(GlobalAlias *SGA) {
- const GlobalValue *SAliasee = SGA->getAliasedGlobal();
- GlobalAlias *NewGA = 0;
-
- // Globals were already linked, thus we can just query ValueMap for variant
- // of SAliasee in Dest.
- ValueToValueMapTy::const_iterator VMI = ValueMap.find(SAliasee);
- assert(VMI != ValueMap.end() && "Aliasee not linked");
- GlobalValue *DAliasee = cast<GlobalValue>(VMI->second);
- GlobalValue *DGV = 0;
-
- // Fixup aliases to bitcasts. Note that aliases to GEPs are still broken
- // by this, but aliases to GEPs are broken to a lot of other things, so
- // it's less important.
- Constant *DAliaseeConst = DAliasee;
- if (SGA->getType() != DAliasee->getType())
- DAliaseeConst = ConstantExpr::getBitCast(DAliasee, SGA->getType());
-
- // Try to find something 'similar' to SGA in destination module.
- if (!DGV && !SGA->hasLocalLinkage())
- DGV = DstM->getNamedAlias(SGA->getName());
-
- if (!DGV && !SGA->hasLocalLinkage())
- DGV = DstM->getGlobalVariable(SGA->getName());
-
- if (!DGV && !SGA->hasLocalLinkage())
- DGV = DstM->getFunction(SGA->getName());
-
- // No linking to be performed on internal stuff.
- if (DGV && DGV->hasLocalLinkage())
- DGV = NULL;
-
- if (GlobalAlias *DGA = dyn_cast_or_null<GlobalAlias>(DGV)) {
- // Types are known to be the same, check whether aliasees equal. As
- // globals are already linked we just need query ValueMap to find the
- // mapping.
- if (DAliasee == DGA->getAliasedGlobal()) {
- // This is just two copies of the same alias. Propagate linkage, if
- // necessary.
- DGA->setLinkage(CalculateAliasLinkage(SGA, DGA));
-
- NewGA = DGA;
- // Proceed to 'common' steps
- } else
- return emitError("Alias collision on '" + SGA->getName()+
- "': aliases have different aliasees");
- } else if (GlobalVariable *DGVar = dyn_cast_or_null<GlobalVariable>(DGV)) {
- // The only allowed way is to link alias with external declaration or weak
- // symbol..
- if (DGVar->isDeclaration() || DGVar->isWeakForLinker()) {
- // But only if aliasee is global too...
- if (!isa<GlobalVariable>(DAliasee))
- return emitError("Global alias collision on '" + SGA->getName() +
- "': aliasee is not global variable");
-
- NewGA = new GlobalAlias(SGA->getType(), SGA->getLinkage(),
- SGA->getName(), DAliaseeConst, DstM);
- CopyGVAttributes(NewGA, SGA);
-
- // Any uses of DGV need to change to NewGA, with cast, if needed.
- if (SGA->getType() != DGVar->getType())
- DGVar->replaceAllUsesWith(ConstantExpr::getBitCast(NewGA,
- DGVar->getType()));
- else
- DGVar->replaceAllUsesWith(NewGA);
-
- // DGVar will conflict with NewGA 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();
-
- // Proceed to 'common' steps
- } else
- return emitError("Global alias collision on '" + SGA->getName() +
- "': symbol multiple defined");
- } else if (Function *DF = dyn_cast_or_null<Function>(DGV)) {
- // The only allowed way is to link alias with external declaration or weak
- // symbol...
- if (DF->isDeclaration() || DF->isWeakForLinker()) {
- // But only if aliasee is function too.
- if (!isa<Function>(DAliasee))
- return emitError("Function alias collision on '" + SGA->getName() +
- "': aliasee is not function");
-
- NewGA = new GlobalAlias(SGA->getType(), SGA->getLinkage(),
- SGA->getName(), DAliaseeConst, DstM);
- CopyGVAttributes(NewGA, SGA);
-
- // Any uses of DF need to change to NewGA, with cast, if needed.
- if (SGA->getType() != DF->getType())
- DF->replaceAllUsesWith(ConstantExpr::getBitCast(NewGA,DF->getType()));
- else
- DF->replaceAllUsesWith(NewGA);
-
- // DF will conflict with NewGA because they both had the same
- // name. We must erase this now so forceRenaming doesn't assert
- // because DF might not have internal linkage.
- DF->eraseFromParent();
-
- // Proceed to 'common' steps
- } else
- return emitError("Function alias collision on '" + SGA->getName() +
- "': symbol multiple defined");
- } else {
- // No linking to be performed, simply create an identical version of the
- // alias over in the dest module...
- NewGA = new GlobalAlias(SGA->getType(), SGA->getLinkage(),
- SGA->getName(), DAliaseeConst, DstM);
- CopyGVAttributes(NewGA, SGA);
-
- // Proceed to 'common' steps.
- }
-
- assert(NewGA && "No alias was created in destination module!");
-
- // If the symbol table renamed the alias, but it is an externally visible
- // symbol, DGA must be an global value with internal linkage. Rename it.
- if (NewGA->getName() != SGA->getName() && !NewGA->hasLocalLinkage())
- forceRenaming(NewGA, SGA->getName());
-
- // Remember this mapping so uses in the source module get remapped
- // later by MapValue.
- ValueMap[SGA] = NewGA;
+ GlobalValue *DGV = getLinkedToGlobal(SGA);
+
+ // If there is no linkage to be performed, just bring over SGA without
+ // modifying it.
+ if (DGV == 0) {
+ // Alias does not already exist, simply insert an alias identical to SGA.
+ GlobalAlias *NewDA = new GlobalAlias(TypeMap.get(SGA->getType()),
+ SGA->getLinkage(), SGA->getName(),
+ /*aliasee*/0, DstM);
+ CopyGVAttributes(NewDA, SGA);
+
+ if (!NewDA->hasLocalLinkage() && NewDA->getName() != SGA->getName())
+ forceRenaming(NewDA, SGA->getName());
+
+ ValueMap[SGA] = NewDA;
+ return false;
+ }
+
+ GlobalValue::LinkageTypes NewLinkage = GlobalValue::InternalLinkage;
+ bool LinkFromSrc = false;
+ if (getLinkageResult(DGV, SGA, NewLinkage, LinkFromSrc))
+ return true;
+
+ if (LinkFromSrc) {
+ // Clear the name so we don't get a conflict.
+ DGV->setName("");
+
+ GlobalAlias *NewDA = new GlobalAlias(TypeMap.get(SGA->getType()),
+ SGA->getLinkage(), SGA->getName(),
+ /*aliasee*/0, DstM);
+ CopyGVAttributes(NewDA, SGA);
+
+ // Any uses of DGV need to change to NewDA, with cast.
+ DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewDA, DGV->getType()));
+ DGV->eraseFromParent();
+
+ // Remember this mapping so uses in the source module get remapped
+ // later by MapValue.
+ ValueMap[SGA] = NewDA;
+ return false;
+ }
+
+ // Set calculated linkage
+ DGV->setLinkage(NewLinkage);
+
+ // Make sure to remember this mapping.
+ ValueMap[SGA] = ConstantExpr::getBitCast(DGV, TypeMap.get(SGA->getType()));
+
+ // Remove the body from the source module so we don't attempt to remap it.
+ SGA->setAliasee(0);
return false;
}
@@ -943,26 +835,17 @@
for (Module::iterator SF = SrcM->begin(), E = SrcM->end(); SF != E; ++SF) {
if (SF->isDeclaration()) continue; // No body if function is external.
- Function *DF = dyn_cast<Function>(ValueMap[SF]); // Destination function
-
- // Only provide the function body if there isn't one already.
- if (DF && DF->isDeclaration())
- linkFunctionBody(DF, SF);
+ linkFunctionBody(cast<Function>(ValueMap[SF]), SF);
}
}
void ModuleLinker::linkAliasBodies() {
- for (Module::alias_iterator I = DstM->alias_begin(), E = DstM->alias_end();
+ for (Module::alias_iterator I = SrcM->alias_begin(), E = SrcM->alias_end();
I != E; ++I)
- // We can't sue resolveGlobalAlias here because we need to preserve
- // bitcasts and GEPs.
- if (const Constant *C = I->getAliasee()) {
- while (dyn_cast<GlobalAlias>(C))
- C = cast<GlobalAlias>(C)->getAliasee();
- const GlobalValue *GV = dyn_cast<GlobalValue>(C);
- if (C != I && !(GV && GV->isDeclaration()))
- I->replaceAllUsesWith(const_cast<Constant*>(C));
+ if (Constant *Aliasee = I->getAliasee()) {
+ GlobalAlias *DA = cast<GlobalAlias>(ValueMap[I]);
+ DA->setAliasee(MapValue(Aliasee, ValueMap, RF_None, &TypeMap));
}
}
More information about the llvm-branch-commits
mailing list