[llvm-branch-commits] [llvm-branch] r134462 - /llvm/branches/type-system-rewrite/lib/Linker/LinkModules.cpp
Chris Lattner
sabre at nondot.org
Tue Jul 5 21:19:58 PDT 2011
Author: lattner
Date: Tue Jul 5 23:19:58 2011
New Revision: 134462
URL: http://llvm.org/viewvc/llvm-project?rev=134462&view=rev
Log:
add a large comment explaining a possible optimization, don't bother to implement it yet.
In the meantime allow mapping over of types used in a source module to the dest module
in a semantic preserving way.
Now that type mapping is done, we can move on to making the linker remap everything to the
appropriate type space.
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=134462&r1=134461&r2=134462&view=diff
==============================================================================
--- llvm/branches/type-system-rewrite/lib/Linker/LinkModules.cpp (original)
+++ llvm/branches/type-system-rewrite/lib/Linker/LinkModules.cpp Tue Jul 5 23:19:58 2011
@@ -32,7 +32,7 @@
/// DefinitionsToResolve - This is a list of non-opaque structs in the source
/// module that are mapped to an opaque struct in the destination module.
- std::vector<StructType*> DefinitionsToResolve;
+ SmallVector<StructType*, 16> DefinitionsToResolve;
public:
/// addTypeMapping - Indicate that the specified type in the destination
@@ -165,9 +165,12 @@
/// module from a type definition in the source module.
void TypeMapTy::linkDefinedTypeBodies() {
SmallVector<Type*, 16> Elements;
+ SmallString<16> TmpName;
- for (unsigned i = 0, e = DefinitionsToResolve.size(); i != e; ++i) {
- StructType *SrcSTy = DefinitionsToResolve[i];
+ // Note that processing entries in this loop (calling 'get') can add new
+ // entries to the DefinitionsToResolve vector.
+ while (!DefinitionsToResolve.empty()) {
+ StructType *SrcSTy = DefinitionsToResolve.pop_back_val();
StructType *DstSTy = cast<StructType>(MappedTypes[SrcSTy]);
// TypeMap is a many-to-one mapping, if there were multiple types that
@@ -182,9 +185,19 @@
Elements[i] = get(SrcSTy->getElementType(i));
DstSTy->setBody(Elements, SrcSTy->isPacked());
+
+ // If DstSTy has no name or has a longer name than STy, then viciously steal
+ // STy's name.
+ if (!SrcSTy->hasName()) continue;
+ StringRef SrcName = SrcSTy->getName();
+
+ if (!DstSTy->hasName() || DstSTy->getName().size() > SrcName.size()) {
+ TmpName.insert(TmpName.end(), SrcName.begin(), SrcName.end());
+ SrcSTy->setName("");
+ DstSTy->setName(TmpName.str());
+ TmpName.clear();
+ }
}
-
- DefinitionsToResolve.clear();
}
@@ -192,8 +205,8 @@
/// source module.
Type *TypeMapTy::get(Type *Ty) {
// If we already have an entry for this type, return it.
- DenseMap<Type*, Type*>::iterator I = MappedTypes.find(Ty);
- if (I != MappedTypes.end()) return I->second;
+ Type **Entry = &MappedTypes[Ty];
+ if (*Entry) return *Entry;
// If this is not a named struct type, then just map all of the elements and
// then rebuild the type from inside out.
@@ -201,7 +214,7 @@
// If there are no element types to map, then the type is itself. This is
// true for the anonymous {} struct, things like 'float', integers, etc.
if (Ty->getNumContainedTypes() == 0)
- return MappedTypes[Ty] = Ty;
+ return *Entry = Ty;
// Remap all of the elements, keeping track of whether any of them change.
bool AnyChange = false;
@@ -213,46 +226,63 @@
}
// If we found our type while recursively processing stuff, just use it.
- Type *&Entry = MappedTypes[Ty];
- if (Entry) return Entry;
+ Entry = &MappedTypes[Ty];
+ if (*Entry) return *Entry;
// If all of the element types mapped directly over, then the type is usable
// as-is.
if (!AnyChange)
- return Entry = Ty;
+ return *Entry = Ty;
// Otherwise, rebuild a modified type.
switch (Ty->getTypeID()) {
default: assert(0 && "unknown derived type to remap");
case Type::ArrayTyID:
- return Entry = ArrayType::get(ElementTypes[0],
- cast<ArrayType>(Ty)->getNumElements());
+ return *Entry = ArrayType::get(ElementTypes[0],
+ cast<ArrayType>(Ty)->getNumElements());
case Type::VectorTyID:
- return Entry = VectorType::get(ElementTypes[0],
- cast<VectorType>(Ty)->getNumElements());
+ return *Entry = VectorType::get(ElementTypes[0],
+ cast<VectorType>(Ty)->getNumElements());
case Type::PointerTyID:
- return Entry = PointerType::get(ElementTypes[0],
+ return *Entry = PointerType::get(ElementTypes[0],
cast<PointerType>(Ty)->getAddressSpace());
case Type::FunctionTyID:
- return Entry = FunctionType::get(ElementTypes[0],
- ArrayRef<Type*>(ElementTypes).slice(1),
- cast<FunctionType>(Ty)->isVarArg());
+ return *Entry = FunctionType::get(ElementTypes[0],
+ ArrayRef<Type*>(ElementTypes).slice(1),
+ cast<FunctionType>(Ty)->isVarArg());
case Type::StructTyID:
// Note that this is only reached for anonymous structs.
- return Entry = StructType::get(Ty->getContext(), ElementTypes,
- cast<StructType>(Ty)->isPacked());
+ return *Entry = StructType::get(Ty->getContext(), ElementTypes,
+ cast<StructType>(Ty)->isPacked());
}
}
- StructType *STy = cast<StructType>(Ty);
// Otherwise, this is an unmapped named struct. If the struct can be directly
- // mapped over, just use it. Otherwise, we have to make a new struct and
- // transfer the name over.
-
-
-
-
- return STy;
+ // mapped over, just use it as-is. This happens in a case when the linked-in
+ // module has something like:
+ // %T = type {%T*, i32}
+ // @GV = global %T* null
+ // where T does not exist at all in the destination module.
+ //
+ // The other case we watch for is when the type is not in the destination
+ // module, but that it has to be rebuilt because it refers to something that
+ // is already mapped. For example, if the destination module has:
+ // %A = type { i32 }
+ // and the source module has something like
+ // %A' = type { i32 }
+ // %B = type { %A'* }
+ // @GV = global %B* null
+ // then we want to create a new type: "%B = type { %A*}" and have it take the
+ // pristine "%B" name from the source module.
+ //
+ // To determine which case this is, we have to recursively walk the type graph
+ // speculating that we'll be able to reuse it unmodified. Only if this is
+ // safe would we map the entire thing over. Because this is an optimization,
+ // and is not required for the prettiness of the linked module, we just skip
+ // it and always rebuild a type here.
+ StructType *STy = cast<StructType>(Ty);
+ DefinitionsToResolve.push_back(STy);
+ return *Entry = StructType::createNamed(STy->getContext(), "");
}
@@ -1122,7 +1152,11 @@
// are properly remapped.
linkNamedMDNodes();
- return false;
+ // Now that all of the types from the source are used, resolve any structs
+ // copied over to the dest that didn't exist there.
+ TypeMap.linkDefinedTypeBodies();
+
+ return false;
}
//===----------------------------------------------------------------------===//
More information about the llvm-branch-commits
mailing list