#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ManagedStatic.h"
#include <algorithm>
#include <iostream>
using namespace llvm;
// for types as they are needed. Because resolution of types must invalidate
// all of the abstract type descriptions, we keep them in a seperate map to make
// this easy.
-static std::map<const Type*, std::string> ConcreteTypeDescriptions;
-static std::map<const Type*, std::string> AbstractTypeDescriptions;
+static ManagedStatic<std::map<const Type*,
+ std::string> > ConcreteTypeDescriptions;
+static ManagedStatic<std::map<const Type*,
+ std::string> > AbstractTypeDescriptions;
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;
+ (*ConcreteTypeDescriptions)[this] = Name;
}
std::vector<const Type *> &TypeStack) {
if (isa<OpaqueType>(Ty)) { // Base case for the recursion
std::map<const Type*, std::string>::iterator I =
- AbstractTypeDescriptions.lower_bound(Ty);
- if (I != AbstractTypeDescriptions.end() && I->first == Ty)
+ AbstractTypeDescriptions->lower_bound(Ty);
+ if (I != AbstractTypeDescriptions->end() && I->first == Ty)
return I->second;
std::string Desc = "opaque";
- AbstractTypeDescriptions.insert(std::make_pair(Ty, Desc));
+ AbstractTypeDescriptions->insert(std::make_pair(Ty, Desc));
return Desc;
}
if (!Ty->isAbstract()) { // Base case for the recursion
std::map<const Type*, std::string>::iterator I =
- ConcreteTypeDescriptions.find(Ty);
- if (I != ConcreteTypeDescriptions.end()) return I->second;
+ ConcreteTypeDescriptions->find(Ty);
+ if (I != ConcreteTypeDescriptions->end()) return I->second;
}
// Check to see if the Type is already on the stack...
const std::string &Type::getDescription() const {
if (isAbstract())
- return getOrCreateDesc(AbstractTypeDescriptions, this);
+ return getOrCreateDesc(*AbstractTypeDescriptions, this);
else
- return getOrCreateDesc(ConcreteTypeDescriptions, this);
+ return getOrCreateDesc(*ConcreteTypeDescriptions, this);
}
// Static 'Type' data
//===----------------------------------------------------------------------===//
-namespace {
- struct VISIBILITY_HIDDEN PrimType : public Type {
- PrimType(const char *S, TypeID ID) : Type(S, ID) {}
- };
-}
+#define DeclarePrimType(TY, Str) \
+ struct VISIBILITY_HIDDEN TY##Type : public Type { \
+ TY##Type() : Type(Str, Type::TY##TyID) {} \
+ }; \
+ static ManagedStatic<TY##Type> The##TY##Ty
-static PrimType TheVoidTy ("void" , Type::VoidTyID);
-static PrimType TheBoolTy ("bool" , Type::BoolTyID);
-static PrimType TheSByteTy ("sbyte" , Type::SByteTyID);
-static PrimType TheUByteTy ("ubyte" , Type::UByteTyID);
-static PrimType TheShortTy ("short" , Type::ShortTyID);
-static PrimType TheUShortTy("ushort", Type::UShortTyID);
-static PrimType TheIntTy ("int" , Type::IntTyID);
-static PrimType TheUIntTy ("uint" , Type::UIntTyID);
-static PrimType TheLongTy ("long" , Type::LongTyID);
-static PrimType TheULongTy ("ulong" , Type::ULongTyID);
-static PrimType TheFloatTy ("float" , Type::FloatTyID);
-static PrimType TheDoubleTy("double", Type::DoubleTyID);
-static PrimType TheLabelTy ("label" , Type::LabelTyID);
-
-Type *Type::VoidTy = &TheVoidTy;
-Type *Type::BoolTy = &TheBoolTy;
-Type *Type::SByteTy = &TheSByteTy;
-Type *Type::UByteTy = &TheUByteTy;
-Type *Type::ShortTy = &TheShortTy;
-Type *Type::UShortTy = &TheUShortTy;
-Type *Type::IntTy = &TheIntTy;
-Type *Type::UIntTy = &TheUIntTy;
-Type *Type::LongTy = &TheLongTy;
-Type *Type::ULongTy = &TheULongTy;
-Type *Type::FloatTy = &TheFloatTy;
-Type *Type::DoubleTy = &TheDoubleTy;
-Type *Type::LabelTy = &TheLabelTy;
+namespace {
+ DeclarePrimType(Void, "void");
+ DeclarePrimType(Bool, "bool");
+ DeclarePrimType(SByte, "sbyte");
+ DeclarePrimType(UByte, "ubyte");
+ DeclarePrimType(Short, "short");
+ DeclarePrimType(UShort, "ushort");
+ DeclarePrimType(Int, "int");
+ DeclarePrimType(UInt, "uint");
+ DeclarePrimType(Long, "long");
+ DeclarePrimType(ULong, "ulong");
+ DeclarePrimType(Float, "float");
+ DeclarePrimType(Double, "double");
+ DeclarePrimType(Label, "label");
+}
+
+Type *Type::VoidTy = &*TheVoidTy;
+Type *Type::BoolTy = &*TheBoolTy;
+Type *Type::SByteTy = &*TheSByteTy;
+Type *Type::UByteTy = &*TheUByteTy;
+Type *Type::ShortTy = &*TheShortTy;
+Type *Type::UShortTy = &*TheUShortTy;
+Type *Type::IntTy = &*TheIntTy;
+Type *Type::UIntTy = &*TheUIntTy;
+Type *Type::LongTy = &*TheLongTy;
+Type *Type::ULongTy = &*TheULongTy;
+Type *Type::FloatTy = &*TheFloatTy;
+Type *Type::DoubleTy = &*TheDoubleTy;
+Type *Type::LabelTy = &*TheLabelTy;
//===----------------------------------------------------------------------===//
}
// Define the actual map itself now...
-static TypeMap<FunctionValType, FunctionType> FunctionTypes;
+static ManagedStatic<TypeMap<FunctionValType, FunctionType> > FunctionTypes;
FunctionValType FunctionValType::get(const FunctionType *FT) {
// Build up a FunctionValType
const std::vector<const Type*> &Params,
bool isVarArg) {
FunctionValType VT(ReturnType, Params, isVarArg);
- FunctionType *MT = FunctionTypes.get(VT);
+ FunctionType *MT = FunctionTypes->get(VT);
if (MT) return MT;
- FunctionTypes.add(VT, MT = new FunctionType(ReturnType, Params, isVarArg));
+ FunctionTypes->add(VT, MT = new FunctionType(ReturnType, Params, isVarArg));
#ifdef DEBUG_MERGE_TYPES
std::cerr << "Derived new type: " << MT << "\n";
}
};
}
-static TypeMap<ArrayValType, ArrayType> ArrayTypes;
+static ManagedStatic<TypeMap<ArrayValType, ArrayType> > ArrayTypes;
ArrayType *ArrayType::get(const Type *ElementType, uint64_t NumElements) {
assert(ElementType && "Can't get array of null types!");
ArrayValType AVT(ElementType, NumElements);
- ArrayType *AT = ArrayTypes.get(AVT);
+ ArrayType *AT = ArrayTypes->get(AVT);
if (AT) return AT; // Found a match, return it!
// Value not found. Derive a new type!
- ArrayTypes.add(AVT, AT = new ArrayType(ElementType, NumElements));
+ ArrayTypes->add(AVT, AT = new ArrayType(ElementType, NumElements));
#ifdef DEBUG_MERGE_TYPES
std::cerr << "Derived new type: " << *AT << "\n";
}
};
}
-static TypeMap<PackedValType, PackedType> PackedTypes;
+static ManagedStatic<TypeMap<PackedValType, PackedType> > PackedTypes;
PackedType *PackedType::get(const Type *ElementType, unsigned NumElements) {
assert(isPowerOf2_32(NumElements) && "Vector length should be a power of 2!");
PackedValType PVT(ElementType, NumElements);
- PackedType *PT = PackedTypes.get(PVT);
+ PackedType *PT = PackedTypes->get(PVT);
if (PT) return PT; // Found a match, return it!
// Value not found. Derive a new type!
- PackedTypes.add(PVT, PT = new PackedType(ElementType, NumElements));
+ PackedTypes->add(PVT, PT = new PackedType(ElementType, NumElements));
#ifdef DEBUG_MERGE_TYPES
std::cerr << "Derived new type: " << *PT << "\n";
};
}
-static TypeMap<StructValType, StructType> StructTypes;
+static ManagedStatic<TypeMap<StructValType, StructType> > StructTypes;
StructType *StructType::get(const std::vector<const Type*> &ETypes) {
StructValType STV(ETypes);
- StructType *ST = StructTypes.get(STV);
+ StructType *ST = StructTypes->get(STV);
if (ST) return ST;
// Value not found. Derive a new type!
- StructTypes.add(STV, ST = new StructType(ETypes));
+ StructTypes->add(STV, ST = new StructType(ETypes));
#ifdef DEBUG_MERGE_TYPES
std::cerr << "Derived new type: " << *ST << "\n";
};
}
-static TypeMap<PointerValType, PointerType> PointerTypes;
+static ManagedStatic<TypeMap<PointerValType, PointerType> > PointerTypes;
PointerType *PointerType::get(const Type *ValueType) {
assert(ValueType && "Can't get a pointer to <null> type!");
"Pointer to void is not valid, use sbyte* instead!");
PointerValType PVT(ValueType);
- PointerType *PT = PointerTypes.get(PVT);
+ PointerType *PT = PointerTypes->get(PVT);
if (PT) return PT;
// Value not found. Derive a new type!
- PointerTypes.add(PVT, PT = new PointerType(ValueType));
+ PointerTypes->add(PVT, PT = new PointerType(ValueType));
#ifdef DEBUG_MERGE_TYPES
std::cerr << "Derived new type: " << *PT << "\n";
assert(ForwardType == 0 && "This type has already been refined!");
// The descriptions may be out of date. Conservatively clear them all!
- AbstractTypeDescriptions.clear();
+ AbstractTypeDescriptions->clear();
#ifdef DEBUG_MERGE_TYPES
std::cerr << "REFINING abstract type [" << (void*)this << " "
//
void FunctionType::refineAbstractType(const DerivedType *OldType,
const Type *NewType) {
- FunctionTypes.RefineAbstractType(this, OldType, NewType);
+ FunctionTypes->RefineAbstractType(this, OldType, NewType);
}
void FunctionType::typeBecameConcrete(const DerivedType *AbsTy) {
- FunctionTypes.TypeBecameConcrete(this, AbsTy);
+ FunctionTypes->TypeBecameConcrete(this, AbsTy);
}
//
void ArrayType::refineAbstractType(const DerivedType *OldType,
const Type *NewType) {
- ArrayTypes.RefineAbstractType(this, OldType, NewType);
+ ArrayTypes->RefineAbstractType(this, OldType, NewType);
}
void ArrayType::typeBecameConcrete(const DerivedType *AbsTy) {
- ArrayTypes.TypeBecameConcrete(this, AbsTy);
+ ArrayTypes->TypeBecameConcrete(this, AbsTy);
}
// refineAbstractType - Called when a contained type is found to be more
//
void PackedType::refineAbstractType(const DerivedType *OldType,
const Type *NewType) {
- PackedTypes.RefineAbstractType(this, OldType, NewType);
+ PackedTypes->RefineAbstractType(this, OldType, NewType);
}
void PackedType::typeBecameConcrete(const DerivedType *AbsTy) {
- PackedTypes.TypeBecameConcrete(this, AbsTy);
+ PackedTypes->TypeBecameConcrete(this, AbsTy);
}
// refineAbstractType - Called when a contained type is found to be more
//
void StructType::refineAbstractType(const DerivedType *OldType,
const Type *NewType) {
- StructTypes.RefineAbstractType(this, OldType, NewType);
+ StructTypes->RefineAbstractType(this, OldType, NewType);
}
void StructType::typeBecameConcrete(const DerivedType *AbsTy) {
- StructTypes.TypeBecameConcrete(this, AbsTy);
+ StructTypes->TypeBecameConcrete(this, AbsTy);
}
// refineAbstractType - Called when a contained type is found to be more
//
void PointerType::refineAbstractType(const DerivedType *OldType,
const Type *NewType) {
- PointerTypes.RefineAbstractType(this, OldType, NewType);
+ PointerTypes->RefineAbstractType(this, OldType, NewType);
}
void PointerType::typeBecameConcrete(const DerivedType *AbsTy) {
- PointerTypes.TypeBecameConcrete(this, AbsTy);
+ PointerTypes->TypeBecameConcrete(this, AbsTy);
}
bool SequentialType::indexValid(const Value *V) const {
return OS;
}
}
-
-/// clearAllTypeMaps - This method frees all internal memory used by the
-/// type subsystem, which can be used in environments where this memory is
-/// otherwise reported as a leak.
-void Type::clearAllTypeMaps() {
- std::vector<Type *> DerivedTypes;
-
- FunctionTypes.clear(DerivedTypes);
- PointerTypes.clear(DerivedTypes);
- StructTypes.clear(DerivedTypes);
- ArrayTypes.clear(DerivedTypes);
- PackedTypes.clear(DerivedTypes);
-
- for(std::vector<Type *>::iterator I = DerivedTypes.begin(),
- E = DerivedTypes.end(); I != E; ++I)
- (*I)->ContainedTys.clear();
- for(std::vector<Type *>::iterator I = DerivedTypes.begin(),
- E = DerivedTypes.end(); I != E; ++I)
- delete *I;
- DerivedTypes.clear();
-}
-
-// vim: sw=2