X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=include%2Fllvm%2FDerivedTypes.h;h=10ff57bd42238a8db0e89855fbae9c7f0a05e874;hb=e7506a366e8bd56c97d10beb68e4db953aebaeca;hp=f58d01da2fbcfd230119baea7f82790849c93b6c;hpb=50d89859e203bb0c43d5b636ea7a394cb48848a7;p=oota-llvm.git diff --git a/include/llvm/DerivedTypes.h b/include/llvm/DerivedTypes.h index f58d01da2fb..10ff57bd422 100644 --- a/include/llvm/DerivedTypes.h +++ b/include/llvm/DerivedTypes.h @@ -12,18 +12,93 @@ #define LLVM_DERIVED_TYPES_H #include "llvm/Type.h" -#include "llvm/CodeGen/TargetMachine.h" -#include -// Future derived types: SIMD packed format +class DerivedType : public Type { + // AbstractTypeUsers - Implement a list of the users that need to be notified + // if I am a type, and I get resolved into a more concrete type. + // + ///// FIXME: kill mutable nonsense when Type's are not const + mutable std::vector AbstractTypeUsers; + char isRefining; // Used for recursive types + +protected: + inline DerivedType(PrimitiveID id) : Type("", id) { + isRefining = false; + } + + // typeIsRefined - Notify AbstractTypeUsers of this type that the current type + // has been refined a bit. The pointer is still valid and still should be + // used, but the subtypes have changed. + // + void typeIsRefined(); + + // setDerivedTypeProperties - Based on the subtypes, set the name of this + // type so that it is printed nicely by the type printer. Also calculate + // whether this type is abstract or not. Used by the constructor and when + // the type is refined. + // + void setDerivedTypeProperties(); -class MethodType : public Type { public: - typedef vector ParamTypes; + + //===--------------------------------------------------------------------===// + // Abstract Type handling methods - These types have special lifetimes, which + // are managed by (add|remove)AbstractTypeUser. See comments in + // AbstractTypeUser.h for more information. + + // addAbstractTypeUser - Notify an abstract type that there is a new user of + // it. This function is called primarily by the PATypeHandle class. + // + void addAbstractTypeUser(AbstractTypeUser *U) const { + assert(isAbstract() && "addAbstractTypeUser: Current type not abstract!"); +#if 0 + cerr << " addAbstractTypeUser[" << (void*)this << ", " << getDescription() + << "][" << AbstractTypeUsers.size() << "] User = " << U << endl; +#endif + AbstractTypeUsers.push_back(U); + } + + // removeAbstractTypeUser - Notify an abstract type that a user of the class + // no longer has a handle to the type. This function is called primarily by + // the PATypeHandle class. When there are no users of the abstract type, it + // is anihilated, because there is no way to get a reference to it ever again. + // + void removeAbstractTypeUser(AbstractTypeUser *U) const; + + // getNumAbstractTypeUsers - Return the number of users registered to the type + inline unsigned getNumAbstractTypeUsers() const { + assert(isAbstract() && "getNumAbstractTypeUsers: Type not abstract!"); + return AbstractTypeUsers.size(); + } + + // refineAbstractTypeTo - This function is used to when it is discovered that + // the 'this' abstract type is actually equivalent to the NewType specified. + // This causes all users of 'this' to switch to reference the more concrete + // type NewType and for 'this' to be deleted. + // + void refineAbstractTypeTo(const Type *NewType); + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const DerivedType *T) { return true; } + static inline bool classof(const Type *T) { + return T->isDerivedType(); + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +}; + + + + +class MethodType : public DerivedType { +public: + typedef std::vector > ParamTypes; private: - const Type *ResultType; + PATypeHandle ResultType; ParamTypes ParamTys; + bool isVarArgs; MethodType(const MethodType &); // Do not implement const MethodType &operator=(const MethodType &); // Do not implement @@ -33,130 +108,221 @@ protected: // defines private constructors and has no friends // Private ctor - Only can be created by a static member... - MethodType(const Type *Result, const vector &Params, - const string &Name); + MethodType(const Type *Result, const std::vector &Params, + bool IsVarArgs); + public: + inline bool isVarArg() const { return isVarArgs; } inline const Type *getReturnType() const { return ResultType; } inline const ParamTypes &getParamTypes() const { return ParamTys; } - static const MethodType *getMethodType(const Type *Result, - const ParamTypes &Params); - static const MethodType *get(const Type *Result, const ParamTypes &Params) { - return getMethodType(Result, Params); + + virtual const Type *getContainedType(unsigned i) const { + return i == 0 ? ResultType : + (i <= ParamTys.size() ? ParamTys[i-1].get() : 0); } -}; + virtual unsigned getNumContainedTypes() const { return ParamTys.size()+1; } + // refineAbstractType - Called when a contained type is found to be more + // concrete - this could potentially change us from an abstract type to a + // concrete type. + // + virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy); -class ArrayType : public Type { -private: - const Type *ElementType; - int NumElements; // >= 0 for sized array, -1 for unbounded/unknown array + static MethodType *get(const Type *Result, + const std::vector &Params, + bool isVarArg); - ArrayType(const ArrayType &); // Do not implement - const ArrayType &operator=(const ArrayType &); // Do not implement -protected: - // This should really be private, but it squelches a bogus warning - // from GCC to make them protected: warning: `class ArrayType' only - // defines private constructors and has no friends + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const MethodType *T) { return true; } + static inline bool classof(const Type *T) { + return T->getPrimitiveID() == MethodTyID; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +}; + + +// CompositeType - Common super class of ArrayType, StructType, and PointerType +// +class CompositeType : public DerivedType { +protected: + inline CompositeType(PrimitiveID id) : DerivedType(id) { } - // Private ctor - Only can be created by a static member... - ArrayType(const Type *ElType, int NumEl, const string &Name); public: - inline const Type *getElementType() const { return ElementType; } - inline int getNumElements() const { return NumElements; } + // getTypeAtIndex - Given an index value into the type, return the type of the + // element. + // + virtual const Type *getTypeAtIndex(const Value *V) const = 0; + virtual bool indexValid(const Value *V) const = 0; + + // getIndexType - Return the type required of indices for this composite. + // For structures, this is ubyte, for arrays, this is uint + // + virtual const Type *getIndexType() const = 0; - inline bool isSized() const { return NumElements >= 0; } - inline bool isUnsized() const { return NumElements == -1; } - static const ArrayType *getArrayType(const Type *ElementType, - int NumElements = -1); - static const ArrayType *get(const Type *ElementType, int NumElements = -1) { - return getArrayType(ElementType, NumElements); + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const CompositeType *T) { return true; } + static inline bool classof(const Type *T) { + return T->getPrimitiveID() == ArrayTyID || + T->getPrimitiveID() == StructTyID || + T->getPrimitiveID() == PointerTyID; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); } }; -class StructType : public Type { +class StructType : public CompositeType { public: - typedef vector ElementTypes; + typedef std::vector > ElementTypes; private: - ElementTypes ETypes; - struct StructSizeAndOffsetInfo { - int storageSize; // -1 until the value is computd - vector memberOffsets; // -1 until values are computed - const TargetMachine* targetInfo; - } *layoutCache; - -private: + ElementTypes ETypes; // Element types of struct + StructType(const StructType &); // Do not implement const StructType &operator=(const StructType &); // Do not implement - + protected: // This should really be private, but it squelches a bogus warning // from GCC to make them protected: warning: `class StructType' only // defines private constructors and has no friends // Private ctor - Only can be created by a static member... - StructType(const vector &Types, const string &Name); - - // Reset cached info so it will be computed when first requested - void ResetCachedInfo() const { - layoutCache->storageSize = -1; - layoutCache->memberOffsets.insert(layoutCache->memberOffsets.begin(), - ETypes.size(), -1); - layoutCache->targetInfo = 0; - } + StructType(const std::vector &Types); public: inline const ElementTypes &getElementTypes() const { return ETypes; } - static const StructType *getStructType(const ElementTypes &Params); - static const StructType *get(const ElementTypes &Params) { - return getStructType(Params); + + virtual const Type *getContainedType(unsigned i) const { + return i < ETypes.size() ? ETypes[i].get() : 0; + } + virtual unsigned getNumContainedTypes() const { return ETypes.size(); } + + // getTypeAtIndex - Given an index value into the type, return the type of the + // element. For a structure type, this must be a constant value... + // + virtual const Type *getTypeAtIndex(const Value *V) const ; + virtual bool indexValid(const Value *V) const; + + // getIndexType - Return the type required of indices for this composite. + // For structures, this is ubyte, for arrays, this is uint + // + virtual const Type *getIndexType() const { return Type::UByteTy; } + + // refineAbstractType - Called when a contained type is found to be more + // concrete - this could potentially change us from an abstract type to a + // concrete type. + // + virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy); + + static StructType *get(const std::vector &Params); + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const StructType *T) { return true; } + static inline bool classof(const Type *T) { + return T->getPrimitiveID() == StructTyID; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); } +}; - unsigned int getStorageSize(const TargetMachine& tmi) const { - if (layoutCache->targetInfo && *layoutCache->targetInfo != tmi) { - // target machine has changed (hey it could happen). discard cached info. - ResetCachedInfo(); - layoutCache->targetInfo = &tmi; - } - - if (layoutCache->storageSize < 0) { - layoutCache->storageSize = tmi.findOptimalStorageSize(this); - assert(layoutCache->storageSize >= 0); - } - return layoutCache->storageSize; - } - unsigned int getElementOffset(int i, const TargetMachine& tmi) const { - // target machine has changed (hey it could happen). discard cached info. - if (layoutCache->targetInfo && *layoutCache->targetInfo != tmi) - ResetCachedInfo(); - - if (layoutCache->memberOffsets[i] < 0) { - layoutCache->targetInfo = &tmi; // remember which target was used - - unsigned int *offsetVec = tmi.findOptimalMemberOffsets(this); - for (unsigned i=0, N=layoutCache->memberOffsets.size(); i < N; ++i) { - layoutCache->memberOffsets[i] = offsetVec[i]; - assert(layoutCache->memberOffsets[i] >= 0); - } - delete[] offsetVec; - } - - return layoutCache->memberOffsets[i]; +// SequentialType - This is the superclass of the array and pointer type +// classes. Both of these represent "arrays" in memory. The array type +// represents a specifically sized array, pointer types are unsized/unknown size +// arrays. SequentialType holds the common features of both, which stem from +// the fact that both lay their components out in memory identically. +// +class SequentialType : public CompositeType { + SequentialType(const SequentialType &); // Do not implement! + const SequentialType &operator=(const SequentialType &); // Do not implement! +protected: + PATypeHandle ElementType; + + SequentialType(PrimitiveID TID, const Type *ElType) + : CompositeType(TID), ElementType(PATypeHandle(ElType, this)) { + } +public: + + inline const Type *getElementType() const { return ElementType; } + + virtual const Type *getContainedType(unsigned i) const { + return i == 0 ? ElementType.get() : 0; + } + virtual unsigned getNumContainedTypes() const { return 1; } + + // getTypeAtIndex - Given an index value into the type, return the type of the + // element. For sequential types, there is only one subtype... + // + virtual const Type *getTypeAtIndex(const Value *V) const { + return ElementType.get(); + } + virtual bool indexValid(const Value *V) const { + return V->getType() == Type::UIntTy; // Must be an unsigned int index + } + + // getIndexType() - Return the type required of indices for this composite. + // For structures, this is ubyte, for arrays, this is uint + // + virtual const Type *getIndexType() const { return Type::UIntTy; } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const SequentialType *T) { return true; } + static inline bool classof(const Type *T) { + return T->getPrimitiveID() == ArrayTyID || + T->getPrimitiveID() == PointerTyID; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); } }; -class PointerType : public Type { -private: - const Type *ValueType; +class ArrayType : public SequentialType { + unsigned NumElements; + + ArrayType(const ArrayType &); // Do not implement + const ArrayType &operator=(const ArrayType &); // Do not implement +protected: + // This should really be private, but it squelches a bogus warning + // from GCC to make them protected: warning: `class ArrayType' only + // defines private constructors and has no friends + + + // Private ctor - Only can be created by a static member... + ArrayType(const Type *ElType, unsigned NumEl); +public: + inline unsigned getNumElements() const { return NumElements; } + + // refineAbstractType - Called when a contained type is found to be more + // concrete - this could potentially change us from an abstract type to a + // concrete type. + // + virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy); + + static ArrayType *get(const Type *ElementType, unsigned NumElements); + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const ArrayType *T) { return true; } + static inline bool classof(const Type *T) { + return T->getPrimitiveID() == ArrayTyID; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +}; + + +class PointerType : public SequentialType { PointerType(const PointerType &); // Do not implement const PointerType &operator=(const PointerType &); // Do not implement protected: @@ -168,14 +334,76 @@ protected: // Private ctor - Only can be created by a static member... PointerType(const Type *ElType); public: + // PointerType::get - Named constructor for pointer types... + static PointerType *get(const Type *ElementType); + + // refineAbstractType - Called when a contained type is found to be more + // concrete - this could potentially change us from an abstract type to a + // concrete type. + // + virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy); + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const PointerType *T) { return true; } + static inline bool classof(const Type *T) { + return T->getPrimitiveID() == PointerTyID; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +}; + - inline const Type *getValueType() const { return ValueType; } +class OpaqueType : public DerivedType { +private: + OpaqueType(const OpaqueType &); // Do not implement + const OpaqueType &operator=(const OpaqueType &); // Do not implement +protected: + // This should really be private, but it squelches a bogus warning + // from GCC to make them protected: warning: `class OpaqueType' only + // defines private constructors and has no friends + // Private ctor - Only can be created by a static member... + OpaqueType(); + +public: - static const PointerType *getPointerType(const Type *ElementType); - static const PointerType *get(const Type *ElementType) { - return getPointerType(ElementType); + // get - Static factory method for the OpaqueType class... + static OpaqueType *get() { + return new OpaqueType(); // All opaque types are distinct + } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const OpaqueType *T) { return true; } + static inline bool classof(const Type *T) { + return T->getPrimitiveID() == OpaqueTyID; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); } }; + +// Define some inline methods for the AbstractTypeUser.h:PATypeHandle class. +// These are defined here because they MUST be inlined, yet are dependant on +// the definition of the Type class. Of course Type derives from Value, which +// contains an AbstractTypeUser instance, so there is no good way to factor out +// the code. Hence this bit of uglyness. +// +template void PATypeHandle::addUser() { + assert(Ty && "Type Handle has a null type!"); + if (Ty->isAbstract()) + cast(Ty)->addAbstractTypeUser(User); +} +template void PATypeHandle::removeUser() { + if (Ty->isAbstract()) + cast(Ty)->removeAbstractTypeUser(User); +} + +template +void PATypeHandle::removeUserFromConcrete() { + if (!Ty->isAbstract()) + cast(Ty)->removeAbstractTypeUser(User); +} + #endif