X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=include%2Fllvm%2FDerivedTypes.h;h=6013c265f0b1700ae86c76722d30231ef4408736;hb=2c783e46c3480c7fa8b91b10610a8e0d92e33ccd;hp=405a632d359381a283257a3fffc89612295b14f1;hpb=68498cefe602bf5364168b4acd0bd5806cdd72ec;p=oota-llvm.git diff --git a/include/llvm/DerivedTypes.h b/include/llvm/DerivedTypes.h index 405a632d359..6013c265f0b 100644 --- a/include/llvm/DerivedTypes.h +++ b/include/llvm/DerivedTypes.h @@ -1,6 +1,13 @@ -//===-- llvm/DerivedTypes.h - Classes for handling data types ----*- C++ -*--=// +//===-- llvm/DerivedTypes.h - Classes for handling data types ---*- C++ -*-===// // -// This file contains the declarations of classes that represent "derived +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the declarations of classes that represent "derived // types". These are things like "arrays of x" or "structure of x, y, z" or // "method returning x taking (y,z) as parameters", etc... // @@ -12,190 +19,409 @@ #define LLVM_DERIVED_TYPES_H #include "llvm/Type.h" -#include "llvm/CodeGen/TargetMachine.h" -#include -// Future derived types: SIMD packed format +namespace llvm { +class Value; +template class TypeMap; +class FunctionValType; +class ArrayValType; +class StructValType; +class PointerValType; +class VectorValType; +class IntegerValType; +class APInt; +class ParamAttrsList; -class MethodType : public Type { -public: - typedef vector ParamTypes; -private: - const Type *ResultType; - ParamTypes ParamTys; +class DerivedType : public Type { + friend class Type; - MethodType(const MethodType &); // Do not implement - const MethodType &operator=(const MethodType &); // Do not implement protected: - // This should really be private, but it squelches a bogus warning - // from GCC to make them protected: warning: `class MethodType' only - // defines private constructors and has no friends + explicit DerivedType(TypeID id) : Type(id) {} + + /// notifyUsesThatTypeBecameConcrete - Notify AbstractTypeUsers of this type + /// that the current type has transitioned from being abstract to being + /// concrete. + /// + void notifyUsesThatTypeBecameConcrete(); + + /// dropAllTypeUses - When this (abstract) type is resolved to be equal to + /// another (more concrete) type, we must eliminate all references to other + /// types, to avoid some circular reference problems. + /// + void dropAllTypeUses(); - // Private ctor - Only can be created by a static member... - MethodType(const Type *Result, const vector &Params, - const string &Name); public: - inline const Type *getReturnType() const { return ResultType; } - inline const ParamTypes &getParamTypes() const { return ParamTys; } + //===--------------------------------------------------------------------===// + // Abstract Type handling methods - These types have special lifetimes, which + // are managed by (add|remove)AbstractTypeUser. See comments in + // AbstractTypeUser.h for more information. + + /// 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); - static const MethodType *getMethodType(const Type *Result, - const ParamTypes &Params); - static const MethodType *get(const Type *Result, const ParamTypes &Params) { - return getMethodType(Result, Params); + void dump() const { Type::dump(); } + + // 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(); } }; +/// Class to represent integer types. Note that this class is also used to +/// represent the built-in integer types: Int1Ty, Int8Ty, Int16Ty, Int32Ty and +/// Int64Ty. +/// @brief Integer representation type +class IntegerType : public DerivedType { +protected: + explicit IntegerType(unsigned NumBits) : DerivedType(IntegerTyID) { + setSubclassData(NumBits); + } + friend class TypeMap; +public: + /// This enum is just used to hold constants we need for IntegerType. + enum { + MIN_INT_BITS = 1, ///< Minimum number of bits that can be specified + MAX_INT_BITS = (1<<23)-1 ///< Maximum number of bits that can be specified + ///< Note that bit width is stored in the Type classes SubclassData field + ///< which has 23 bits. This yields a maximum bit width of 8,388,607 bits. + }; + + /// This static method is the primary way of constructing an IntegerType. + /// If an IntegerType with the same NumBits value was previously instantiated, + /// that instance will be returned. Otherwise a new one will be created. Only + /// one instance with a given NumBits value is ever created. + /// @brief Get or create an IntegerType instance. + static const IntegerType* get(unsigned NumBits); + + /// @brief Get the number of bits in this IntegerType + unsigned getBitWidth() const { return getSubclassData(); } + + /// getBitMask - Return a bitmask with ones set for all of the bits + /// that can be set by an unsigned version of this type. This is 0xFF for + /// sbyte/ubyte, 0xFFFF for shorts, etc. + uint64_t getBitMask() const { + return ~uint64_t(0UL) >> (64-getBitWidth()); + } + /// getSignBit - Return a uint64_t with just the most significant bit set (the + /// sign bit, if the value is treated as a signed number). + uint64_t getSignBit() const { + return 1ULL << (getBitWidth()-1); + } + + /// For example, this is 0xFF for an 8 bit integer, 0xFFFF for i16, etc. + /// @returns a bit mask with ones set for all the bits of this type. + /// @brief Get a bit mask for this type. + APInt getMask() const; + + /// This method determines if the width of this IntegerType is a power-of-2 + /// in terms of 8 bit bytes. + /// @returns true if this is a power-of-2 byte width. + /// @brief Is this a power-of-2 byte-width IntegerType ? + bool isPowerOf2ByteWidth() const; + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const IntegerType *T) { return true; } + static inline bool classof(const Type *T) { + return T->getTypeID() == IntegerTyID; + } +}; -class ArrayType : public Type { -private: - const Type *ElementType; - int NumElements; // >= 0 for sized array, -1 for unbounded/unknown array - 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 +/// FunctionType - Class to represent function types +/// +class FunctionType : public DerivedType { + friend class TypeMap; + bool isVarArgs; + ParamAttrsList *ParamAttrs; + FunctionType(const FunctionType &); // Do not implement + const FunctionType &operator=(const FunctionType &); // Do not implement + FunctionType(const Type *Result, const std::vector &Params, + bool IsVarArgs, ParamAttrsList *Attrs = 0); - // Private ctor - Only can be created by a static member... - ArrayType(const Type *ElType, int NumEl, const string &Name); public: + /// FunctionType::get - This static method is the primary way of constructing + /// a FunctionType. + /// + static FunctionType *get( + const Type *Result, ///< The result type + const std::vector &Params, ///< The types of the parameters + bool isVarArg, ///< Whether this is a variable argument length function + ParamAttrsList *Attrs = 0 + ///< Indicates the parameter attributes to use, if any. The 0th entry + ///< in the list refers to the return type. Parameters are numbered + ///< starting at 1. This argument must be on the heap and FunctionType + ///< owns it after its passed here. + ); + + inline bool isVarArg() const { return isVarArgs; } + inline const Type *getReturnType() const { return ContainedTys[0]; } + + typedef Type::subtype_iterator param_iterator; + param_iterator param_begin() const { return ContainedTys + 1; } + param_iterator param_end() const { return &ContainedTys[NumContainedTys]; } + + // Parameter type accessors... + const Type *getParamType(unsigned i) const { return ContainedTys[i+1]; } + + /// getNumParams - Return the number of fixed parameters this function type + /// requires. This does not consider varargs. + /// + unsigned getNumParams() const { return NumContainedTys - 1; } + + bool isStructReturn() const; + + /// The parameter attributes for the \p ith parameter are returned. The 0th + /// parameter refers to the return type of the function. + /// @returns The ParameterAttributes for the \p ith parameter. + /// @brief Get the attributes for a parameter + const ParamAttrsList *getParamAttrs() const { return ParamAttrs; } + + // Implement the AbstractTypeUser interface. + virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy); + virtual void typeBecameConcrete(const DerivedType *AbsTy); + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const FunctionType *T) { return true; } + static inline bool classof(const Type *T) { + return T->getTypeID() == FunctionTyID; + } +}; - inline const Type *getElementType() const { return ElementType; } - inline int getNumElements() const { return NumElements; } - inline bool isSized() const { return NumElements >= 0; } - inline bool isUnsized() const { return NumElements == -1; } +/// CompositeType - Common super class of ArrayType, StructType, PointerType +/// and VectorType +class CompositeType : public DerivedType { +protected: + inline explicit CompositeType(TypeID id) : DerivedType(id) { } +public: - static const ArrayType *getArrayType(const Type *ElementType, - int NumElements = -1); - static const ArrayType *get(const Type *ElementType, int NumElements = -1) { - return getArrayType(ElementType, 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; + + // 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->getTypeID() == ArrayTyID || + T->getTypeID() == StructTyID || + T->getTypeID() == PointerTyID || + T->getTypeID() == VectorTyID; } }; -class StructType : public Type { -public: - typedef 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: +/// StructType - Class to represent struct types +/// +class StructType : public CompositeType { + friend class TypeMap; StructType(const StructType &); // Do not implement const StructType &operator=(const StructType &); // Do not implement - + StructType(const std::vector &Types, bool isPacked); +public: + /// StructType::get - This static method is the primary way to create a + /// StructType. + /// + static StructType *get(const std::vector &Params, + bool isPacked=false); + + // Iterator access to the elements + typedef Type::subtype_iterator element_iterator; + element_iterator element_begin() const { return ContainedTys; } + element_iterator element_end() const { return &ContainedTys[NumContainedTys];} + + // Random access to the elements + unsigned getNumElements() const { return NumContainedTys; } + const Type *getElementType(unsigned N) const { + assert(N < NumContainedTys && "Element number out of range!"); + return ContainedTys[N]; + } + + /// 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; + + // Implement the AbstractTypeUser interface. + virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy); + virtual void typeBecameConcrete(const DerivedType *AbsTy); + + // 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->getTypeID() == StructTyID; + } + + bool isPacked() const { return getSubclassData(); } +}; + + +/// SequentialType - This is the superclass of the array, pointer and packed +/// type classes. All of these represent "arrays" in memory. The array type +/// represents a specifically sized array, pointer types are unsized/unknown +/// size arrays, vector types represent specifically sized arrays that +/// allow for use of SIMD instructions. SequentialType holds the common +/// features of all, which stem from the fact that all three lay their +/// components out in memory identically. +/// +class SequentialType : public CompositeType { + PATypeHandle ContainedType; ///< Storage for the single contained type + SequentialType(const SequentialType &); // Do not implement! + const SequentialType &operator=(const SequentialType &); // 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 + SequentialType(TypeID TID, const Type *ElType) + : CompositeType(TID), ContainedType(ElType, this) { + ContainedTys = &ContainedType; + NumContainedTys = 1; + } - // 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; - public: + inline const Type *getElementType() const { return ContainedTys[0]; } - 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 bool indexValid(const Value *V) const; + + /// 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 ContainedTys[0]; + } + + // 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->getTypeID() == ArrayTyID || + T->getTypeID() == PointerTyID || + T->getTypeID() == VectorTyID; } - unsigned int getStorageSize(const TargetMachine& tmi) const; - unsigned int getElementOffset(int i, const TargetMachine& tmi) const; }; -inline unsigned int -StructType::getStorageSize(const TargetMachine& tmi) const -{ - if (layoutCache->targetInfo != NULL && ! (* 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; -} +/// ArrayType - Class to represent array types +/// +class ArrayType : public SequentialType { + friend class TypeMap; + uint64_t NumElements; + ArrayType(const ArrayType &); // Do not implement + const ArrayType &operator=(const ArrayType &); // Do not implement + ArrayType(const Type *ElType, uint64_t NumEl); +public: + /// ArrayType::get - This static method is the primary way to construct an + /// ArrayType + /// + static ArrayType *get(const Type *ElementType, uint64_t NumElements); -inline unsigned int -StructType::getElementOffset(int i, const TargetMachine& tmi) const -{ - if (layoutCache->targetInfo != NULL && ! (* layoutCache->targetInfo == tmi)) - {// target machine has changed (hey it could happen). discard cached info. - 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]; -} + inline uint64_t getNumElements() const { return NumElements; } + // Implement the AbstractTypeUser interface. + virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy); + virtual void typeBecameConcrete(const DerivedType *AbsTy); -inline void -StructType::ResetCachedInfo() const -{ - layoutCache->storageSize = -1; - layoutCache->memberOffsets.insert(layoutCache->memberOffsets.begin(), - ETypes.size(), -1); - layoutCache->targetInfo = NULL; -} + // 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->getTypeID() == ArrayTyID; + } +}; +/// VectorType - Class to represent vector types +/// +class VectorType : public SequentialType { + friend class TypeMap; + unsigned NumElements; + + VectorType(const VectorType &); // Do not implement + const VectorType &operator=(const VectorType &); // Do not implement + VectorType(const Type *ElType, unsigned NumEl); +public: + /// VectorType::get - This static method is the primary way to construct an + /// VectorType + /// + static VectorType *get(const Type *ElementType, unsigned NumElements); -class PointerType : public Type { -private: - const Type *ValueType; + /// @brief Return the number of elements in the Vector type. + inline unsigned getNumElements() const { return NumElements; } + /// @brief Return the number of bits in the Vector type. + inline unsigned getBitWidth() const { + return NumElements *getElementType()->getPrimitiveSizeInBits(); + } + + // Implement the AbstractTypeUser interface. + virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy); + virtual void typeBecameConcrete(const DerivedType *AbsTy); + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const VectorType *T) { return true; } + static inline bool classof(const Type *T) { + return T->getTypeID() == VectorTyID; + } +}; + + +/// PointerType - Class to represent pointers +/// +class PointerType : public SequentialType { + friend class TypeMap; PointerType(const PointerType &); // Do not implement const PointerType &operator=(const PointerType &); // Do not implement -protected: - // This should really be private, but it squelches a bogus warning - // from GCC to make them protected: warning: `class PointerType' only - // defines private constructors and has no friends + explicit PointerType(const Type *ElType); +public: + /// PointerType::get - This is the only way to construct a new pointer type. + static PointerType *get(const Type *ElementType); + // Implement the AbstractTypeUser interface. + virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy); + virtual void typeBecameConcrete(const DerivedType *AbsTy); - // Private ctor - Only can be created by a static member... - PointerType(const Type *ElType); -public: + // Implement 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->getTypeID() == PointerTyID; + } +}; - inline const Type *getValueType() const { return ValueType; } +/// OpaqueType - Class to represent abstract types +/// +class OpaqueType : public DerivedType { + OpaqueType(const OpaqueType &); // DO NOT IMPLEMENT + const OpaqueType &operator=(const OpaqueType &); // DO NOT IMPLEMENT + OpaqueType(); +public: + /// OpaqueType::get - Static factory method for the OpaqueType class... + /// + static OpaqueType *get() { + return new OpaqueType(); // All opaque types are distinct + } - static const PointerType *getPointerType(const Type *ElementType); - static const PointerType *get(const Type *ElementType) { - return getPointerType(ElementType); + // Implement the AbstractTypeUser interface. + virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy) { + abort(); // FIXME: this is not really an AbstractTypeUser! + } + virtual void typeBecameConcrete(const DerivedType *AbsTy) { + abort(); // FIXME: this is not really an AbstractTypeUser! + } + + // Implement support for 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->getTypeID() == OpaqueTyID; } }; +} // End llvm namespace + #endif