[llvm-branch-commits] [llvm-branch] r134604 - /llvm/branches/type-system-rewrite/lib/Linker/LinkModules.cpp
Chris Lattner
sabre at nondot.org
Wed Jul 6 23:56:03 PDT 2011
Author: lattner
Date: Thu Jul 7 01:56:03 2011
New Revision: 134604
URL: http://llvm.org/viewvc/llvm-project?rev=134604&view=rev
Log:
rewrite appending array handling, resolving some fixme's. This fixes a problem linking 252.eon.
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=134604&r1=134603&r2=134604&view=diff
==============================================================================
--- llvm/branches/type-system-rewrite/lib/Linker/LinkModules.cpp (original)
+++ llvm/branches/type-system-rewrite/lib/Linker/LinkModules.cpp Thu Jul 7 01:56:03 2011
@@ -329,6 +329,15 @@
/// some overhead due to the use of Value handles which the Linker doesn't
/// actually need, but this allows us to reuse the ValueMapper code.
ValueToValueMapTy ValueMap;
+
+ struct AppendingVarInfo {
+ GlobalVariable *NewGV; // New aggregate global in dest module.
+ Constant *DstInit; // Old initializer from dest module.
+ Constant *SrcInit; // Old initializer from src module.
+ };
+
+ std::vector<AppendingVarInfo> AppendingVars;
+
public:
std::string ErrorMsg;
@@ -372,11 +381,12 @@
void computeTypeMapping();
- bool linkAppendingVars(GlobalVariable *DstGV, GlobalVariable *SrcGV);
+ bool linkAppendingVarProto(GlobalVariable *DstGV, GlobalVariable *SrcGV);
bool linkGlobalProto(GlobalVariable *SrcGV);
bool linkFunctionProto(Function *SrcF);
bool linkAliasProto(GlobalAlias *SrcA);
+ void linkAppendingVarInit(const AppendingVarInfo &AVI);
void linkGlobalInits();
void linkFunctionBody(Function *Dst, Function *Src);
void linkAliasBodies();
@@ -500,18 +510,53 @@
return false;
}
-/// linkAppendingVars - If there were any appending global variables, link them
-/// together now. Return true on error.
-bool ModuleLinker::linkAppendingVars(GlobalVariable *DstGV,
- GlobalVariable *SrcGV) {
+/// computeTypeMapping - Loop over all of the linked values to compute type
+/// mappings. For example, if we link "extern Foo *x" and "Foo *x = NULL", then
+/// we have two struct types 'Foo' but one got renamed when the module was
+/// loaded into the same LLVMContext.
+void ModuleLinker::computeTypeMapping() {
+ // Incorporate globals.
+ for (Module::global_iterator I = SrcM->global_begin(),
+ E = SrcM->global_end(); I != E; ++I) {
+ GlobalValue *DGV = getLinkedToGlobal(I);
+ if (DGV == 0) continue;
+
+ if (!DGV->hasAppendingLinkage() || !I->hasAppendingLinkage()) {
+ TypeMap.addTypeMapping(DGV->getType(), I->getType());
+ continue;
+ }
+
+ // Unify the element type of appending arrays.
+ ArrayType *DAT = cast<ArrayType>(DGV->getType()->getElementType());
+ ArrayType *SAT = cast<ArrayType>(I->getType()->getElementType());
+ TypeMap.addTypeMapping(DAT->getElementType(), SAT->getElementType());
+ }
+
+ // Incorporate functions.
+ for (Module::iterator I = SrcM->begin(), E = SrcM->end(); I != E; ++I) {
+ if (GlobalValue *DGV = getLinkedToGlobal(I))
+ TypeMap.addTypeMapping(DGV->getType(), I->getType());
+ }
+
+ // Don't bother incorporating aliases, they aren't generally typed well.
+
+ // Now that we have discovered all of the type equivalences, get a body for
+ // any 'opaque' types in the dest module that are now resolved.
+ TypeMap.linkDefinedTypeBodies();
+}
+
+/// linkAppendingVarProto - If there were any appending global variables, link
+/// them together now. Return true on error.
+bool ModuleLinker::linkAppendingVarProto(GlobalVariable *DstGV,
+ GlobalVariable *SrcGV) {
if (!SrcGV->hasAppendingLinkage() || !DstGV->hasAppendingLinkage())
return emitError("Linking globals named '" + SrcGV->getName() +
"': can only link appending global with another appending global!");
ArrayType *DstTy = cast<ArrayType>(DstGV->getType()->getElementType());
- ArrayType *SrcTy = cast<ArrayType>(SrcGV->getType()->getElementType());
- // FIXME: Should map element type.
+ ArrayType *SrcTy =
+ cast<ArrayType>(TypeMap.get(SrcGV->getType()->getElementType()));
Type *EltTy = DstTy->getElementType();
// Check to see that they two arrays agree on type.
@@ -538,36 +583,22 @@
// Create the new global variable.
GlobalVariable *NG =
new GlobalVariable(*DstGV->getParent(), NewType, SrcGV->isConstant(),
- DstGV->getLinkage(), /*init*/0, SrcGV->getName(), DstGV,
+ DstGV->getLinkage(), /*init*/0, /*name*/"", DstGV,
DstGV->isThreadLocal(),
DstGV->getType()->getAddressSpace());
// Propagate alignment, visibility and section info.
CopyGVAttributes(NG, DstGV);
- // Merge the initializer.
- SmallVector<Constant*, 16> Elements;
- Elements.reserve(NewSize);
- if (ConstantArray *I = dyn_cast<ConstantArray>(DstGV->getInitializer())) {
- for (unsigned i = 0, e = DstTy->getNumElements(); i != e; ++i)
- Elements.push_back(I->getOperand(i));
- } else {
- assert(isa<ConstantAggregateZero>(DstGV->getInitializer()));
- Elements.append(DstTy->getNumElements(), Constant::getNullValue(EltTy));
- }
- if (const ConstantArray *I =dyn_cast<ConstantArray>(SrcGV->getInitializer())){
- // FIXME: Should map values from src to dest.
- for (unsigned i = 0, e = SrcTy->getNumElements(); i != e; ++i)
- Elements.push_back(I->getOperand(i));
- } else {
- assert(isa<ConstantAggregateZero>(SrcGV->getInitializer()));
- Elements.append(SrcTy->getNumElements(), Constant::getNullValue(EltTy));
- }
- NG->setInitializer(ConstantArray::get(NewType, Elements));
-
+ AppendingVarInfo AVI;
+ AVI.NewGV = NG;
+ AVI.DstInit = DstGV->getInitializer();
+ AVI.SrcInit = SrcGV->getInitializer();
+ AppendingVars.push_back(AVI);
+
// Replace any uses of the two global variables with uses of the new
// global.
- ValueMap[SrcGV] = ConstantExpr::getBitCast(NG, SrcGV->getType());
+ ValueMap[SrcGV] = ConstantExpr::getBitCast(NG, TypeMap.get(SrcGV->getType()));
DstGV->replaceAllUsesWith(ConstantExpr::getBitCast(NG, DstGV->getType()));
DstGV->eraseFromParent();
@@ -578,40 +609,15 @@
return false;
}
-/// computeTypeMapping - Loop over all of the linked values to compute type
-/// mappings. For example, if we link "extern Foo *x" and "Foo *x = NULL", then
-/// we have two struct types 'Foo' but one got renamed when the module was
-/// loaded into the same LLVMContext.
-void ModuleLinker::computeTypeMapping() {
- // Incorporate globals.
- for (Module::global_iterator I = SrcM->global_begin(),
- E = SrcM->global_end(); I != E; ++I) {
- if (GlobalValue *DGV = getLinkedToGlobal(I))
- TypeMap.addTypeMapping(DGV->getType(), I->getType());
- }
-
- // Incorporate functions.
- for (Module::iterator I = SrcM->begin(), E = SrcM->end(); I != E; ++I) {
- if (GlobalValue *DGV = getLinkedToGlobal(I))
- TypeMap.addTypeMapping(DGV->getType(), I->getType());
- }
-
- // Don't bother incorporating aliases, they aren't generally typed well.
-
- // Now that we have discovered all of the type equivalences, get a body for
- // any 'opaque' types in the dest module that are now resolved.
- TypeMap.linkDefinedTypeBodies();
-}
-
/// linkGlobalProto - Loop through the global variables in the src module and
/// merge them into the dest module.
bool ModuleLinker::linkGlobalProto(GlobalVariable *SGV) {
GlobalValue *DGV = getLinkedToGlobal(SGV);
if (DGV) {
- // Concatenation of appending linkage variables is magic.
+ // Concatenation of appending linkage variables is magic and handled later.
if (DGV->hasAppendingLinkage() || SGV->hasAppendingLinkage())
- return linkAppendingVars(cast<GlobalVariable>(DGV), SGV);
+ return linkAppendingVarProto(cast<GlobalVariable>(DGV), SGV);
// Determine whether linkage of these two globals follows the source
// module's definition or the destination module's definition.
@@ -746,6 +752,33 @@
return false;
}
+void ModuleLinker::linkAppendingVarInit(const AppendingVarInfo &AVI) {
+ // Merge the initializer.
+ SmallVector<Constant*, 16> Elements;
+ if (ConstantArray *I = dyn_cast<ConstantArray>(AVI.DstInit)) {
+ for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
+ Elements.push_back(I->getOperand(i));
+ } else {
+ assert(isa<ConstantAggregateZero>(AVI.DstInit));
+ ArrayType *DstAT = cast<ArrayType>(AVI.DstInit->getType());
+ Type *EltTy = DstAT->getElementType();
+ Elements.append(DstAT->getNumElements(), Constant::getNullValue(EltTy));
+ }
+
+ Constant *SrcInit = MapValue(AVI.SrcInit, ValueMap, RF_None, &TypeMap);
+ if (const ConstantArray *I = dyn_cast<ConstantArray>(SrcInit)) {
+ for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
+ Elements.push_back(I->getOperand(i));
+ } else {
+ assert(isa<ConstantAggregateZero>(SrcInit));
+ ArrayType *SrcAT = cast<ArrayType>(SrcInit->getType());
+ Type *EltTy = SrcAT->getElementType();
+ Elements.append(SrcAT->getNumElements(), Constant::getNullValue(EltTy));
+ }
+ ArrayType *NewType = cast<ArrayType>(AVI.NewGV->getType()->getElementType());
+ AVI.NewGV->setInitializer(ConstantArray::get(NewType, Elements));
+}
+
// linkGlobalInits - Update the initializers in the Dest module now that all
// globals that may be referenced are in Dest.
@@ -892,6 +925,9 @@
if (linkAliasProto(I))
return true;
+ for (unsigned i = 0, e = AppendingVars.size(); i != e; ++i)
+ linkAppendingVarInit(AppendingVars[i]);
+
// Update the initializers in the DstM module now that all globals that may
// be referenced are in DstM.
linkGlobalInits();
More information about the llvm-branch-commits
mailing list