[llvm-branch-commits] [llvm-branch] r133777 - /llvm/branches/type-system-rewrite/lib/Linker/LinkModules.cpp
Chris Lattner
sabre at nondot.org
Thu Jun 23 16:58:37 PDT 2011
Author: lattner
Date: Thu Jun 23 18:58:37 2011
New Revision: 133777
URL: http://llvm.org/viewvc/llvm-project?rev=133777&view=rev
Log:
rework the type reassociation logic, still unused though.
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=133777&r1=133776&r2=133777&view=diff
==============================================================================
--- llvm/branches/type-system-rewrite/lib/Linker/LinkModules.cpp (original)
+++ llvm/branches/type-system-rewrite/lib/Linker/LinkModules.cpp Thu Jun 23 18:58:37 2011
@@ -35,34 +35,74 @@
return true;
}
+namespace {
+class TypeMap {
+ /// MappedTypes - This is a mapping from a source type to a destination type
+ /// to use.
+ DenseMap<Type*, Type*> MappedTypes;
+public:
+
+ /// addTypeMapping - Indicate that the specified type in the destination
+ /// module is conceptually equivalent to the specified type in the source
+ /// module. This updates the type mapping for equivalent types, and returns
+ /// false. If there is a hard type conflict (maybe merging "int x" with
+ /// "extern float x") this returns true.
+ bool addTypeMapping(Type *DstTy, Type *SrcTy);
+
+ //void mapTypes(Value *Dst, Value *Src);
+
+private:
+ bool addTypeMappingRec(Type *DstTy, Type *SrcTy);
+};
+}
+
+bool TypeMap::addTypeMapping(Type *DstTy, Type *SrcTy) {
+ if (DstTy == SrcTy) return false; // If already equal, noop.
-// RecursiveResolveTypes - This is just like ResolveTypes, except that it
-// recurses down into derived types, merging the used types if the parent types
-// are compatible.
-static bool RecursiveResolveTypesI(Type *DstTy, Type *SrcTy,
- DenseMap<Type*, Type*> &MappedTypes) {
- if (DstTy == SrcTy) return false; // If already equal, noop
-
-#if 0
- // If we found our opaque type, resolve it now!
- if (DstTy->isOpaqueTy() || SrcTy->isOpaqueTy())
- return ResolveTypes(DstTy, SrcTy);
-#endif
+ if (Type *T = MappedTypes[SrcTy])
+ return T != DstTy;
+
+ return addTypeMappingRec(DstTy, SrcTy);
+}
+/// addTypeMappingRec - This is the implementation function for addTypeMapping,
+/// which optimizes out the map lookup in the recursive walk.
+bool TypeMap::addTypeMappingRec(Type *DstTy, Type *SrcTy) {
// Two types cannot be resolved together if they are of different primitive
// type. For example, we cannot resolve an int to a float.
if (DstTy->getTypeID() != SrcTy->getTypeID()) return true;
-#if 0
- // If neither type is abstract, then they really are just different types.
- if (!DstTy->isAbstract() && !SrcTy->isAbstract())
- return true;
-#endif
-
// Otherwise, resolve the used type used by this derived type...
switch (DstTy->getTypeID()) {
default:
return true;
+ case Type::StructTyID: {
+ StructType *DstST = cast<StructType>(DstTy);
+ StructType *SrcST = cast<StructType>(SrcTy);
+
+ // If the destination type is opaque, then it should be resolved to the
+ // input type. If the source type is opaque, then it gets whatever the
+ // destination type is.
+ if (DstST->isOpaque() || SrcST->isOpaque())
+ break;
+
+ if (DstST->getNumContainedTypes() != SrcST->getNumContainedTypes() ||
+ DstST->isPacked() != SrcST->isPacked())
+ return true;
+
+ // Otherwise, we speculatively assume that the structs can be merged, add an
+ // entry to the type map so we don't infinitely recurse.
+ MappedTypes[SrcST] = DstST;
+
+ // Then call addTypeMapping on each entry (not "Rec") so that we get the
+ // caching behavior of the map check for each element.
+ for (unsigned i = 0, e = DstST->getNumContainedTypes(); i != e; ++i) {
+ Type *SE = SrcST->getContainedType(i), *DE = DstST->getContainedType(i);
+ if (SE != DE && addTypeMapping(DE, SE))
+ return true;
+ }
+ return false;
+ }
case Type::FunctionTyID: {
const FunctionType *DstFT = cast<FunctionType>(DstTy);
const FunctionType *SrcFT = cast<FunctionType>(SrcTy);
@@ -70,82 +110,43 @@
DstFT->getNumContainedTypes() != SrcFT->getNumContainedTypes())
return true;
- // Use TypeHolder's so recursive resolution won't break us.
for (unsigned i = 0, e = DstFT->getNumContainedTypes(); i != e; ++i) {
Type *SE = SrcFT->getContainedType(i), *DE = DstFT->getContainedType(i);
- if (SE != DE && RecursiveResolveTypesI(DE, SE, MappedTypes))
- return true;
- }
- return false;
- }
- case Type::StructTyID: {
- StructType *DstST = cast<StructType>(DstTy);
- StructType *SrcST = cast<StructType>(SrcTy);
- if (DstST->getNumContainedTypes() != SrcST->getNumContainedTypes())
- return true;
-
- for (unsigned i = 0, e = DstST->getNumContainedTypes(); i != e; ++i) {
- Type *SE = SrcST->getContainedType(i), *DE = DstST->getContainedType(i);
- if (SE != DE && RecursiveResolveTypesI(DE, SE, MappedTypes))
+ if (SE != DE && addTypeMappingRec(DE, SE))
return true;
}
- return false;
+ break;
}
case Type::ArrayTyID: {
ArrayType *DAT = cast<ArrayType>(DstTy);
ArrayType *SAT = cast<ArrayType>(SrcTy);
- if (DAT->getNumElements() != SAT->getNumElements()) return true;
- return RecursiveResolveTypesI(DAT->getElementType(), SAT->getElementType(),
- MappedTypes);
+ if (DAT->getNumElements() != SAT->getNumElements() ||
+ addTypeMappingRec(DAT->getElementType(), SAT->getElementType()))
+ return true;
+ break;
}
case Type::VectorTyID: {
VectorType *DVT = cast<VectorType>(DstTy);
VectorType *SVT = cast<VectorType>(SrcTy);
- if (DVT->getNumElements() != SVT->getNumElements()) return true;
- return RecursiveResolveTypesI(DVT->getElementType(), SVT->getElementType(),
- MappedTypes);
+ if (DVT->getNumElements() != SVT->getNumElements() ||
+ addTypeMappingRec(DVT->getElementType(), SVT->getElementType()))
+ return true;
+ break;
}
case Type::PointerTyID: {
PointerType *DstPT = cast<PointerType>(DstTy);
PointerType *SrcPT = cast<PointerType>(SrcTy);
-
- if (DstPT->getAddressSpace() != SrcPT->getAddressSpace())
+ if (DstPT->getAddressSpace() != SrcPT->getAddressSpace() ||
+ addTypeMappingRec(DstPT->getElementType(), SrcPT->getElementType()))
return true;
-
-
-#if 0
- // If this is a pointer type, check to see if we have already seen it. If
- // so, we are in a recursive branch. Cut off the search now. We cannot use
- // an associative container for this search, because the type pointers (keys
- // in the container) change whenever types get resolved.
- if (SrcPT->isAbstract())
- if (const Type *ExistingDestTy = Pointers.lookup(SrcPT))
- return ExistingDestTy != DstPT;
-
- if (DstPT->isAbstract())
- if (const Type *ExistingSrcTy = Pointers.lookup(DstPT))
- return ExistingSrcTy != SrcPT;
- // Otherwise, add the current pointers to the vector to stop recursion on
- // this pair.
- if (DstPT->isAbstract())
- Pointers.insert(DstPT, SrcPT);
- if (SrcPT->isAbstract())
- Pointers.insert(SrcPT, DstPT);
-#endif
-
- return RecursiveResolveTypesI(DstPT->getElementType(),
- SrcPT->getElementType(), MappedTypes);
+ break;
}
}
+
+ MappedTypes[SrcTy] = DstTy;
+ return false;
}
-static bool RecursiveResolveTypes(Type *DestTy, Type *SrcTy) {
- return true;
- DenseMap<Type*, Type*> MappedTypes;
- return RecursiveResolveTypesI(DestTy, SrcTy, MappedTypes);
-}
-
-
/// ForceRenaming - The LLVM SymbolTable class autorenames globals that conflict
/// in the symbol table. This is good for all clients except for us. Go
/// through the trouble to force this back.
@@ -276,7 +277,7 @@
// LinkGlobals - Loop through the global variables in the src module and merge
// them into the dest module.
static bool LinkGlobals(Module *Dest, const Module *Src,
- ValueToValueMapTy &ValueMap,
+ ValueToValueMapTy &ValueMap, TypeMap &MappedTypes,
std::multimap<std::string, GlobalVariable *> &AppendingVars,
std::string *Err) {
ValueSymbolTable &DestSymTab = Dest->getValueSymbolTable();
@@ -299,7 +300,7 @@
// If types don't agree due to opaque types, try to resolve them.
if (DGV && DGV->getType() != SGV->getType())
- RecursiveResolveTypes(SGV->getType(), DGV->getType());
+ MappedTypes.addTypeMapping(DGV->getType(), SGV->getType());
assert((SGV->hasInitializer() || SGV->hasExternalWeakLinkage() ||
SGV->hasExternalLinkage() || SGV->hasDLLImportLinkage()) &&
@@ -476,7 +477,7 @@
/// the dest module. We're assuming that all functions/global variables were
/// already linked in.
static bool LinkAliases(Module *Dest, const Module *Src,
- ValueToValueMapTy &ValueMap,
+ ValueToValueMapTy &ValueMap, TypeMap &MappedTypes,
std::string *Err) {
// Loop over all alias in the src module
for (Module::const_alias_iterator I = Src->alias_begin(),
@@ -505,7 +506,7 @@
// If types don't agree due to opaque types, try to resolve them.
if (DGV && DGV->getType() != SGA->getType())
- RecursiveResolveTypes(SGA->getType(), DGV->getType());
+ MappedTypes.addTypeMapping(DGV->getType(), SGA->getType());
}
if (!DGV && !SGA->hasLocalLinkage()) {
@@ -513,7 +514,7 @@
// If types don't agree due to opaque types, try to resolve them.
if (DGV && DGV->getType() != SGA->getType())
- RecursiveResolveTypes(SGA->getType(), DGV->getType());
+ MappedTypes.addTypeMapping(DGV->getType(), SGA->getType());
}
if (!DGV && !SGA->hasLocalLinkage()) {
@@ -521,7 +522,7 @@
// If types don't agree due to opaque types, try to resolve them.
if (DGV && DGV->getType() != SGA->getType())
- RecursiveResolveTypes(SGA->getType(), DGV->getType());
+ MappedTypes.addTypeMapping(DGV->getType(), SGA->getType());
}
// No linking to be performed on internal stuff.
@@ -662,10 +663,10 @@
// LinkFunctionProtos - Link the functions together between the two modules,
// without doing function bodies... this just adds external function prototypes
-// to the Dest function...
+// to the Dest function.
//
static bool LinkFunctionProtos(Module *Dest, const Module *Src,
- ValueToValueMapTy &ValueMap,
+ ValueToValueMapTy &ValueMap,TypeMap &MappedTypes,
std::string *Err) {
ValueSymbolTable &DestSymTab = Dest->getValueSymbolTable();
@@ -686,7 +687,7 @@
// If types don't agree due to opaque types, try to resolve them.
if (DGV && DGV->getType() != SF->getType())
- RecursiveResolveTypes(SF->getType(), DGV->getType());
+ MappedTypes.addTypeMapping(DGV->getType(), SF->getType());
GlobalValue::LinkageTypes NewLinkage = GlobalValue::InternalLinkage;
bool LinkFromSrc = false;
@@ -1030,21 +1031,25 @@
AppendingVars.insert(std::make_pair(I->getName(), I));
}
+ TypeMap TheTypeMap;
+
// Insert all of the globals in src into the Dest module... without linking
// initializers (which could refer to functions not yet mapped over).
- if (LinkGlobals(Dest, Src, ValueMap, AppendingVars, ErrorMsg)) return true;
+ if (LinkGlobals(Dest, Src, ValueMap, TheTypeMap, AppendingVars, ErrorMsg))
+ return true;
// Link the functions together between the two modules, without doing function
// bodies... this just adds external function prototypes to the Dest
// function... We do this so that when we begin processing function bodies,
// all of the global values that may be referenced are available in our
// ValueMap.
- if (LinkFunctionProtos(Dest, Src, ValueMap, ErrorMsg)) return true;
+ if (LinkFunctionProtos(Dest, Src, ValueMap, TheTypeMap, ErrorMsg))
+ return true;
// If there were any aliases, link them now. We really need to do this now,
// because all of the aliases that may be referenced need to be available in
// ValueMap
- if (LinkAliases(Dest, Src, ValueMap, ErrorMsg)) return true;
+ if (LinkAliases(Dest, Src, ValueMap, TheTypeMap, ErrorMsg)) return true;
// Update the initializers in the Dest module now that all globals that may
// be referenced are in Dest.
More information about the llvm-branch-commits
mailing list