Move some methods around. Refactor the parts of TypeMap that do not depend

on its template arguments into a base class so that the code isn't duplicated
5 times.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24343 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2005-11-13 03:14:09 +00:00
parent 1c6a80d31c
commit cfe822728f

View File

@ -43,14 +43,13 @@ AbstractTypeUser::~AbstractTypeUser() {}
static std::map<const Type*, std::string> ConcreteTypeDescriptions;
static std::map<const Type*, std::string> AbstractTypeDescriptions;
Type::Type( const std::string& name, TypeID id )
: RefCount(0), ForwardType(0) {
if (!name.empty())
ConcreteTypeDescriptions[this] = name;
ID = id;
Abstract = false;
Type::Type(const char *Name, TypeID id)
: ID(id), Abstract(false), RefCount(0), ForwardType(0) {
assert(Name && Name[0] && "Should use other ctor if no name!");
ConcreteTypeDescriptions[this] = Name;
}
const Type *Type::getPrimitiveType(TypeID IDNumber) {
switch (IDNumber) {
case VoidTyID : return VoidTy;
@ -678,31 +677,56 @@ static bool TypeHasCycleThroughItself(const Type *Ty) {
// Derived Type Factory Functions
//===----------------------------------------------------------------------===//
// TypeMap - Make sure that only one instance of a particular type may be
// created on any given run of the compiler... note that this involves updating
// our map if an abstract type gets refined somehow.
//
namespace llvm {
template<class ValType, class TypeClass>
class TypeMap {
std::map<ValType, PATypeHolder> Map;
class TypeMapBase {
protected:
/// TypesByHash - Keep track of types by their structure hash value. Note
/// that we only keep track of types that have cycles through themselves in
/// this map.
///
std::multimap<unsigned, PATypeHolder> TypesByHash;
friend void Type::clearAllTypeMaps();
private:
void clear(std::vector<Type *> &DerivedTypes) {
for (typename std::map<ValType, PATypeHolder>::iterator I = Map.begin(),
E = Map.end(); I != E; ++I)
DerivedTypes.push_back(I->second.get());
TypesByHash.clear();
Map.clear();
public:
void RemoveFromTypesByHash(unsigned Hash, const Type *Ty) {
std::multimap<unsigned, PATypeHolder>::iterator I =
TypesByHash.lower_bound(Hash);
while (I->second != Ty) {
++I;
assert(I != TypesByHash.end() && I->first == Hash);
}
TypesByHash.erase(I);
}
/// TypeBecameConcrete - When Ty gets a notification that TheType just became
/// concrete, drop uses and make Ty non-abstract if we should.
void TypeBecameConcrete(DerivedType *Ty, const DerivedType *TheType) {
// If the element just became concrete, remove 'ty' from the abstract
// type user list for the type. Do this for as many times as Ty uses
// OldType.
for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end();
I != E; ++I)
if (I->get() == TheType)
TheType->removeAbstractTypeUser(Ty);
// If the type is currently thought to be abstract, rescan all of our
// subtypes to see if the type has just become concrete! Note that this
// may send out notifications to AbstractTypeUsers that types become
// concrete.
if (Ty->isAbstract())
Ty->PromoteAbstractToConcrete();
}
};
}
// TypeMap - Make sure that only one instance of a particular type may be
// created on any given run of the compiler... note that this involves updating
// our map if an abstract type gets refined somehow.
//
namespace llvm {
template<class ValType, class TypeClass>
class TypeMap : public TypeMapBase {
std::map<ValType, PATypeHolder> Map;
public:
typedef typename std::map<ValType, PATypeHolder>::iterator iterator;
~TypeMap() { print("ON EXIT"); }
@ -719,36 +743,16 @@ public:
TypesByHash.insert(std::make_pair(ValType::hashTypeStructure(Ty), Ty));
print("add");
}
void RemoveFromTypesByHash(unsigned Hash, const Type *Ty) {
std::multimap<unsigned, PATypeHolder>::iterator I =
TypesByHash.lower_bound(Hash);
while (I->second != Ty) {
++I;
assert(I != TypesByHash.end() && I->first == Hash);
}
TypesByHash.erase(I);
}
/// TypeBecameConcrete - When Ty gets a notification that TheType just became
/// concrete, drop uses and make Ty non-abstract if we should.
void TypeBecameConcrete(TypeClass *Ty, const DerivedType *TheType) {
// If the element just became concrete, remove 'ty' from the abstract
// type user list for the type. Do this for as many times as Ty uses
// OldType.
for (unsigned i = 0, e = Ty->ContainedTys.size(); i != e; ++i)
if (Ty->ContainedTys[i] == TheType)
TheType->removeAbstractTypeUser(Ty);
// If the type is currently thought to be abstract, rescan all of our
// subtypes to see if the type has just become concrete! Note that this
// may send out notifications to AbstractTypeUsers that types become
// concrete.
if (Ty->isAbstract())
Ty->PromoteAbstractToConcrete();
}
/// RefineAbstractType - This method is called after we have merged a type
void clear(std::vector<Type *> &DerivedTypes) {
for (typename std::map<ValType, PATypeHolder>::iterator I = Map.begin(),
E = Map.end(); I != E; ++I)
DerivedTypes.push_back(I->second.get());
TypesByHash.clear();
Map.clear();
}
/// RefineAbstractType - This method is called after we have merged a type
/// with another one. We must now either merge the type away with
/// some other type or reinstall it in the map with it's new configuration.
void RefineAbstractType(TypeClass *Ty, const DerivedType *OldType,
@ -762,7 +766,7 @@ public:
// OldType must have been abstract, making us abstract.
assert(Ty->isAbstract() && "Refining a non-abstract type!");
assert(OldType != NewType);
// Make a temporary type holder for the type so that it doesn't disappear on
// us when we erase the entry from the map.
PATypeHolder TyHolder = Ty;
@ -826,7 +830,6 @@ public:
}
Entry = I;
}
TypesByHash.erase(Entry);
Ty->refineAbstractTypeTo(NewTy);
return;
@ -1148,7 +1151,6 @@ PointerType *PointerType::get(const Type *ValueType) {
return PT;
}
//===----------------------------------------------------------------------===//
// Derived Type Refinement Functions
//===----------------------------------------------------------------------===//
@ -1158,7 +1160,7 @@ PointerType *PointerType::get(const Type *ValueType) {
// the PATypeHandle class. When there are no users of the abstract type, it
// is annihilated, because there is no way to get a reference to it ever again.
//
void DerivedType::removeAbstractTypeUser(AbstractTypeUser *U) const {
void Type::removeAbstractTypeUser(AbstractTypeUser *U) const {
// Search from back to front because we will notify users from back to
// front. Also, it is likely that there will be a stack like behavior to
// users that register and unregister users.