diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/llvm-c/Core.h | 23 | ||||
-rw-r--r-- | include/llvm-c/Transforms/IPO.h | 3 | ||||
-rw-r--r-- | include/llvm/AbstractTypeUser.h | 205 | ||||
-rw-r--r-- | include/llvm/Bitcode/LLVMBitCodes.h | 57 | ||||
-rw-r--r-- | include/llvm/Constants.h | 16 | ||||
-rw-r--r-- | include/llvm/DefaultPasses.h | 1 | ||||
-rw-r--r-- | include/llvm/DerivedTypes.h | 192 | ||||
-rw-r--r-- | include/llvm/Function.h | 4 | ||||
-rw-r--r-- | include/llvm/GlobalAlias.h | 10 | ||||
-rw-r--r-- | include/llvm/GlobalValue.h | 4 | ||||
-rw-r--r-- | include/llvm/InitializePasses.h | 1 | ||||
-rw-r--r-- | include/llvm/Instructions.h | 82 | ||||
-rw-r--r-- | include/llvm/LinkAllPasses.h | 1 | ||||
-rw-r--r-- | include/llvm/Module.h | 76 | ||||
-rw-r--r-- | include/llvm/Support/PassManagerBuilder.h | 2 | ||||
-rw-r--r-- | include/llvm/Transforms/IPO.h | 7 | ||||
-rw-r--r-- | include/llvm/Transforms/Utils/ValueMapper.h | 34 | ||||
-rw-r--r-- | include/llvm/Type.h | 332 | ||||
-rw-r--r-- | include/llvm/TypeSymbolTable.h | 152 | ||||
-rw-r--r-- | include/llvm/Value.h | 23 |
20 files changed, 339 insertions, 886 deletions
diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h index 2eccc11..e7818c1 100644 --- a/include/llvm-c/Core.h +++ b/include/llvm-c/Core.h @@ -68,13 +68,6 @@ typedef struct LLVMOpaqueModule *LLVMModuleRef; */ typedef struct LLVMOpaqueType *LLVMTypeRef; -/** - * When building recursive types using LLVMRefineType, LLVMTypeRef values may - * become invalid; use LLVMTypeHandleRef to resolve this problem. See the - * llvm::AbstractTypeHolder class. - */ -typedef struct LLVMOpaqueTypeHandle *LLVMTypeHandleRef; - typedef struct LLVMOpaqueValue *LLVMValueRef; typedef struct LLVMOpaqueBasicBlock *LLVMBasicBlockRef; typedef struct LLVMOpaqueBuilder *LLVMBuilderRef; @@ -206,7 +199,6 @@ typedef enum { LLVMStructTypeKind, /**< Structures */ LLVMArrayTypeKind, /**< Arrays */ LLVMPointerTypeKind, /**< Pointers */ - LLVMOpaqueTypeKind, /**< Opaque: type with unknown structure */ LLVMVectorTypeKind, /**< SIMD 'packed' format, or other vector type */ LLVMMetadataTypeKind, /**< Metadata */ LLVMX86_MMXTypeKind /**< X86 MMX */ @@ -320,12 +312,6 @@ void LLVMSetDataLayout(LLVMModuleRef M, const char *Triple); const char *LLVMGetTarget(LLVMModuleRef M); void LLVMSetTarget(LLVMModuleRef M, const char *Triple); -/** See Module::addTypeName. */ -LLVMBool LLVMAddTypeName(LLVMModuleRef M, const char *Name, LLVMTypeRef Ty); -void LLVMDeleteTypeName(LLVMModuleRef M, const char *Name); -LLVMTypeRef LLVMGetTypeByName(LLVMModuleRef M, const char *Name); -const char *LLVMGetTypeName(LLVMModuleRef M, LLVMTypeRef Ty); - /** See Module::dump. */ void LLVMDumpModule(LLVMModuleRef M); @@ -418,7 +404,6 @@ unsigned LLVMGetVectorSize(LLVMTypeRef VectorTy); /* Operations on other types */ LLVMTypeRef LLVMVoidTypeInContext(LLVMContextRef C); LLVMTypeRef LLVMLabelTypeInContext(LLVMContextRef C); -LLVMTypeRef LLVMOpaqueTypeInContext(LLVMContextRef C); LLVMTypeRef LLVMX86MMXTypeInContext(LLVMContextRef C); LLVMTypeRef LLVMVoidType(void); @@ -426,13 +411,6 @@ LLVMTypeRef LLVMLabelType(void); LLVMTypeRef LLVMOpaqueType(void); LLVMTypeRef LLVMX86MMXType(void); -/* Operations on type handles */ -LLVMTypeHandleRef LLVMCreateTypeHandle(LLVMTypeRef PotentiallyAbstractTy); -void LLVMRefineType(LLVMTypeRef AbstractTy, LLVMTypeRef ConcreteTy); -LLVMTypeRef LLVMResolveTypeHandle(LLVMTypeHandleRef TypeHandle); -void LLVMDisposeTypeHandle(LLVMTypeHandleRef TypeHandle); - - /*===-- Values ------------------------------------------------------------===*/ /* The bulk of LLVM's object model consists of values, which comprise a very @@ -1117,7 +1095,6 @@ namespace llvm { DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Module, LLVMModuleRef ) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(BasicBlock, LLVMBasicBlockRef ) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(IRBuilder<>, LLVMBuilderRef ) - DEFINE_SIMPLE_CONVERSION_FUNCTIONS(PATypeHolder, LLVMTypeHandleRef ) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MemoryBuffer, LLVMMemoryBufferRef ) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMContext, LLVMContextRef ) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Use, LLVMUseRef ) diff --git a/include/llvm-c/Transforms/IPO.h b/include/llvm-c/Transforms/IPO.h index d16e858..89b1298 100644 --- a/include/llvm-c/Transforms/IPO.h +++ b/include/llvm-c/Transforms/IPO.h @@ -30,9 +30,6 @@ void LLVMAddConstantMergePass(LLVMPassManagerRef PM); /** See llvm::createDeadArgEliminationPass function. */ void LLVMAddDeadArgEliminationPass(LLVMPassManagerRef PM); -/** See llvm::createDeadTypeEliminationPass function. */ -void LLVMAddDeadTypeEliminationPass(LLVMPassManagerRef PM); - /** See llvm::createFunctionAttrsPass function. */ void LLVMAddFunctionAttrsPass(LLVMPassManagerRef PM); diff --git a/include/llvm/AbstractTypeUser.h b/include/llvm/AbstractTypeUser.h deleted file mode 100644 index 81f5c5c..0000000 --- a/include/llvm/AbstractTypeUser.h +++ /dev/null @@ -1,205 +0,0 @@ -//===-- llvm/AbstractTypeUser.h - AbstractTypeUser Interface ----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declares the AbstractTypeUser class. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ABSTRACT_TYPE_USER_H -#define LLVM_ABSTRACT_TYPE_USER_H - -#if !defined(LLVM_TYPE_H) && !defined(LLVM_VALUE_H) -#error Do not include this file directly. Include Type.h instead. -#error Some versions of GCC (e.g. 3.4 and 4.1) can not handle the inlined method -#error PATypeHolder::dropRef() correctly otherwise. -#endif - -// This is the "master" include for <cassert> Whether this file needs it or not, -// it must always include <cassert> for the files which include -// llvm/AbstractTypeUser.h -// -// In this way, most every LLVM source file will have access to the assert() -// macro without having to #include <cassert> directly. -// -#include <cassert> - -namespace llvm { - -class Value; -class Type; -class DerivedType; -template<typename T> struct simplify_type; - -/// The AbstractTypeUser class is an interface to be implemented by classes who -/// could possibly use an abstract type. Abstract types are denoted by the -/// isAbstract flag set to true in the Type class. These are classes that -/// contain an Opaque type in their structure somewhere. -/// -/// Classes must implement this interface so that they may be notified when an -/// abstract type is resolved. Abstract types may be resolved into more -/// concrete types through: linking, parsing, and bitcode reading. When this -/// happens, all of the users of the type must be updated to reference the new, -/// more concrete type. They are notified through the AbstractTypeUser -/// interface. -/// -/// In addition to this, AbstractTypeUsers must keep the use list of the -/// potentially abstract type that they reference up-to-date. To do this in a -/// nice, transparent way, the PATypeHandle class is used to hold "Potentially -/// Abstract Types", and keep the use list of the abstract types up-to-date. -/// @brief LLVM Abstract Type User Representation -class AbstractTypeUser { -protected: - virtual ~AbstractTypeUser(); // Derive from me - - /// setType - It's normally not possible to change a Value's type in place, - /// but an AbstractTypeUser subclass that knows what its doing can be - /// permitted to do so with care. - void setType(Value *V, const Type *NewTy); - -public: - - /// refineAbstractType - The callback method invoked when an abstract type is - /// resolved to another type. An object must override this method to update - /// its internal state to reference NewType instead of OldType. - /// - virtual void refineAbstractType(const DerivedType *OldTy, - const Type *NewTy) = 0; - - /// The other case which AbstractTypeUsers must be aware of is when a type - /// makes the transition from being abstract (where it has clients on its - /// AbstractTypeUsers list) to concrete (where it does not). This method - /// notifies ATU's when this occurs for a type. - /// - virtual void typeBecameConcrete(const DerivedType *AbsTy) = 0; - - // for debugging... - virtual void dump() const = 0; -}; - - -/// PATypeHandle - Handle to a Type subclass. This class is used to keep the -/// use list of abstract types up-to-date. -/// -class PATypeHandle { - const Type *Ty; - AbstractTypeUser * const User; - - // These functions are defined at the bottom of Type.h. See the comment there - // for justification. - void addUser(); - void removeUser(); -public: - // ctor - Add use to type if abstract. Note that Ty must not be null - inline PATypeHandle(const Type *ty, AbstractTypeUser *user) - : Ty(ty), User(user) { - addUser(); - } - - // ctor - Add use to type if abstract. - inline PATypeHandle(const PATypeHandle &T) : Ty(T.Ty), User(T.User) { - addUser(); - } - - // dtor - Remove reference to type... - inline ~PATypeHandle() { removeUser(); } - - // Automatic casting operator so that the handle may be used naturally - inline operator Type *() const { return const_cast<Type*>(Ty); } - inline Type *get() const { return const_cast<Type*>(Ty); } - - // operator= - Allow assignment to handle - inline Type *operator=(const Type *ty) { - if (Ty != ty) { // Ensure we don't accidentally drop last ref to Ty - removeUser(); - Ty = ty; - addUser(); - } - return get(); - } - - // operator= - Allow assignment to handle - inline const Type *operator=(const PATypeHandle &T) { - return operator=(T.Ty); - } - - inline bool operator==(const Type *ty) { - return Ty == ty; - } - - // operator-> - Allow user to dereference handle naturally... - inline const Type *operator->() const { return Ty; } -}; - - -/// PATypeHolder - Holder class for a potentially abstract type. This uses -/// efficient union-find techniques to handle dynamic type resolution. Unless -/// you need to do custom processing when types are resolved, you should always -/// use PATypeHolders in preference to PATypeHandles. -/// -class PATypeHolder { - mutable const Type *Ty; - void destroy(); -public: - PATypeHolder() : Ty(0) {} - PATypeHolder(const Type *ty) : Ty(ty) { - addRef(); - } - PATypeHolder(const PATypeHolder &T) : Ty(T.Ty) { - addRef(); - } - - ~PATypeHolder() { dropRef(); } - - operator Type *() const { return get(); } - Type *get() const; - - // operator-> - Allow user to dereference handle naturally... - Type *operator->() const { return get(); } - - // operator= - Allow assignment to handle - Type *operator=(const Type *ty) { - if (Ty != ty) { // Don't accidentally drop last ref to Ty. - dropRef(); - Ty = ty; - addRef(); - } - return get(); - } - Type *operator=(const PATypeHolder &H) { - return operator=(H.Ty); - } - - /// getRawType - This should only be used to implement the vmcore library. - /// - const Type *getRawType() const { return Ty; } - -private: - void addRef(); - void dropRef(); - friend class TypeMapBase; -}; - -// simplify_type - Allow clients to treat uses just like values when using -// casting operators. -template<> struct simplify_type<PATypeHolder> { - typedef const Type* SimpleType; - static SimpleType getSimplifiedValue(const PATypeHolder &Val) { - return static_cast<SimpleType>(Val.get()); - } -}; -template<> struct simplify_type<const PATypeHolder> { - typedef const Type* SimpleType; - static SimpleType getSimplifiedValue(const PATypeHolder &Val) { - return static_cast<SimpleType>(Val.get()); - } -}; - -} // End llvm namespace - -#endif diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h index d3fee54..df68bd5 100644 --- a/include/llvm/Bitcode/LLVMBitCodes.h +++ b/include/llvm/Bitcode/LLVMBitCodes.h @@ -29,13 +29,23 @@ namespace bitc { // Module sub-block id's. PARAMATTR_BLOCK_ID, - TYPE_BLOCK_ID, + + /// TYPE_BLOCK_ID_OLD - This is the type descriptor block in LLVM 2.9 and + /// earlier, replaced with TYPE_BLOCK_ID2. FIXME: Remove in LLVM 3.1. + TYPE_BLOCK_ID_OLD, + CONSTANTS_BLOCK_ID, FUNCTION_BLOCK_ID, - TYPE_SYMTAB_BLOCK_ID, + + /// TYPE_SYMTAB_BLOCK_ID_OLD - This type descriptor is from LLVM 2.9 and + /// earlier bitcode files. FIXME: Remove in LLVM 3.1 + TYPE_SYMTAB_BLOCK_ID_OLD, + VALUE_SYMTAB_BLOCK_ID, METADATA_BLOCK_ID, - METADATA_ATTACHMENT_ID + METADATA_ATTACHMENT_ID, + + TYPE_BLOCK_ID_NEW }; @@ -72,31 +82,38 @@ namespace bitc { /// TYPE blocks have codes for each type primitive they use. enum TypeCodes { - TYPE_CODE_NUMENTRY = 1, // NUMENTRY: [numentries] + TYPE_CODE_NUMENTRY = 1, // NUMENTRY: [numentries] // Type Codes - TYPE_CODE_VOID = 2, // VOID - TYPE_CODE_FLOAT = 3, // FLOAT - TYPE_CODE_DOUBLE = 4, // DOUBLE - TYPE_CODE_LABEL = 5, // LABEL - TYPE_CODE_OPAQUE = 6, // OPAQUE - TYPE_CODE_INTEGER = 7, // INTEGER: [width] - TYPE_CODE_POINTER = 8, // POINTER: [pointee type] - TYPE_CODE_FUNCTION = 9, // FUNCTION: [vararg, retty, paramty x N] - TYPE_CODE_STRUCT = 10, // STRUCT: [ispacked, eltty x N] - TYPE_CODE_ARRAY = 11, // ARRAY: [numelts, eltty] - TYPE_CODE_VECTOR = 12, // VECTOR: [numelts, eltty] + TYPE_CODE_VOID = 2, // VOID + TYPE_CODE_FLOAT = 3, // FLOAT + TYPE_CODE_DOUBLE = 4, // DOUBLE + TYPE_CODE_LABEL = 5, // LABEL + TYPE_CODE_OPAQUE = 6, // OPAQUE + TYPE_CODE_INTEGER = 7, // INTEGER: [width] + TYPE_CODE_POINTER = 8, // POINTER: [pointee type] + TYPE_CODE_FUNCTION = 9, // FUNCTION: [vararg, retty, paramty x N] + + // FIXME: This is the encoding used for structs in LLVM 2.9 and earlier. + // REMOVE this in LLVM 3.1 + TYPE_CODE_STRUCT_OLD = 10, // STRUCT: [ispacked, eltty x N] + TYPE_CODE_ARRAY = 11, // ARRAY: [numelts, eltty] + TYPE_CODE_VECTOR = 12, // VECTOR: [numelts, eltty] // These are not with the other floating point types because they're // a late addition, and putting them in the right place breaks // binary compatibility. - TYPE_CODE_X86_FP80 = 13, // X86 LONG DOUBLE - TYPE_CODE_FP128 = 14, // LONG DOUBLE (112 bit mantissa) - TYPE_CODE_PPC_FP128= 15, // PPC LONG DOUBLE (2 doubles) + TYPE_CODE_X86_FP80 = 13, // X86 LONG DOUBLE + TYPE_CODE_FP128 = 14, // LONG DOUBLE (112 bit mantissa) + TYPE_CODE_PPC_FP128= 15, // PPC LONG DOUBLE (2 doubles) - TYPE_CODE_METADATA = 16, // METADATA + TYPE_CODE_METADATA = 16, // METADATA - TYPE_CODE_X86_MMX = 17 // X86 MMX + TYPE_CODE_X86_MMX = 17, // X86 MMX + + TYPE_CODE_STRUCT_ANON = 18, // STRUCT_ANON: [ispacked, eltty x N] + TYPE_CODE_STRUCT_NAME = 19, // STRUCT_NAME: [strchr x N] + TYPE_CODE_STRUCT_NAMED = 20 // STRUCT_NAMED: [ispacked, eltty x N] }; // The type symbol table only has one code (TST_ENTRY_CODE). diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index 1afbb8a..3f0efd9 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -912,10 +912,18 @@ public: Constant *getWithOperandReplaced(unsigned OpNo, Constant *Op) const; /// getWithOperands - This returns the current constant expression with the - /// operands replaced with the specified values. The specified operands must - /// match count and type with the existing ones. - Constant *getWithOperands(ArrayRef<Constant*> Ops) const; - + /// operands replaced with the specified values. The specified array must + /// have the same number of operands as our current one. + Constant *getWithOperands(ArrayRef<Constant*> Ops) const { + return getWithOperands(Ops, getType()); + } + + /// getWithOperands - This returns the current constant expression with the + /// operands replaced with the specified values and with the specified result + /// type. The specified array must have the same number of operands as our + /// current one. + Constant *getWithOperands(ArrayRef<Constant*> Ops, const Type *Ty) const; + virtual void destroyConstant(); virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); diff --git a/include/llvm/DefaultPasses.h b/include/llvm/DefaultPasses.h index e2e58a5b..2e4145b 100644 --- a/include/llvm/DefaultPasses.h +++ b/include/llvm/DefaultPasses.h @@ -29,7 +29,6 @@ extern unsigned char ConstantMergeID; extern unsigned char CorrelatedValuePropagationID; extern unsigned char DeadArgEliminationID; extern unsigned char DeadStoreEliminationID; -extern unsigned char DeadTypeEliminationID; extern unsigned char EarlyCSEID; extern unsigned char FunctionAttrsID; extern unsigned char FunctionInliningID; diff --git a/include/llvm/DerivedTypes.h b/include/llvm/DerivedTypes.h index fe9f5f8..1cefcb2 100644 --- a/include/llvm/DerivedTypes.h +++ b/include/llvm/DerivedTypes.h @@ -24,51 +24,16 @@ namespace llvm { class Value; -template<class ValType, class TypeClass> class TypeMap; -class FunctionValType; -class ArrayValType; -class StructValType; -class PointerValType; -class VectorValType; -class IntegerValType; class APInt; class LLVMContext; template<typename T> class ArrayRef; +class StringRef; class DerivedType : public Type { - friend class Type; - protected: explicit DerivedType(LLVMContext &C, TypeID id) : Type(C, 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(); - public: - //===--------------------------------------------------------------------===// - // 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); - - void dump() const { Type::dump(); } - // Methods for support type inquiry through isa, cast, and dyn_cast. static inline bool classof(const DerivedType *) { return true; } static inline bool classof(const Type *T) { @@ -88,7 +53,6 @@ protected: DerivedType(C, IntegerTyID) { setSubclassData(NumBits); } - friend class TypeMap<IntegerValType, IntegerType>; public: /// This enum is just used to hold constants we need for IntegerType. enum { @@ -103,7 +67,7 @@ public: /// 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(LLVMContext &C, unsigned NumBits); + static IntegerType *get(LLVMContext &C, unsigned NumBits); /// @brief Get the number of bits in this IntegerType unsigned getBitWidth() const { return getSubclassData(); } @@ -143,11 +107,9 @@ public: /// FunctionType - Class to represent function types /// class FunctionType : public DerivedType { - friend class TypeMap<FunctionValType, FunctionType>; FunctionType(const FunctionType &); // Do not implement const FunctionType &operator=(const FunctionType &); // Do not implement - FunctionType(const Type *Result, ArrayRef<const Type*> Params, - bool IsVarArgs); + FunctionType(const Type *Result, ArrayRef<Type*> Params, bool IsVarArgs); public: /// FunctionType::get - This static method is the primary way of constructing @@ -155,6 +117,8 @@ public: /// static FunctionType *get(const Type *Result, ArrayRef<const Type*> Params, bool isVarArg); + static FunctionType *get(const Type *Result, + ArrayRef<Type*> Params, bool isVarArg); /// FunctionType::get - Create a FunctionType taking no parameters. /// @@ -169,24 +133,20 @@ public: static bool isValidArgumentType(const Type *ArgTy); bool isVarArg() const { return getSubclassData(); } - const Type *getReturnType() const { return ContainedTys[0]; } + 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]; } + 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; } - // 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 *) { return true; } static inline bool classof(const Type *T) { @@ -205,8 +165,8 @@ public: /// getTypeAtIndex - Given an index value into the type, return the type of /// the element. /// - const Type *getTypeAtIndex(const Value *V) const; - const Type *getTypeAtIndex(unsigned Idx) const; + Type *getTypeAtIndex(const Value *V) const; + Type *getTypeAtIndex(unsigned Idx) const; bool indexValid(const Value *V) const; bool indexValid(unsigned Idx) const; @@ -222,18 +182,49 @@ public: /// StructType - Class to represent struct types, both normal and packed. +/// Besides being optionally packed, structs can be either "anonymous" or may +/// have an identity. Anonymous structs are uniqued by structural equivalence, +/// but types are each unique when created, and optionally have a name. /// class StructType : public CompositeType { - friend class TypeMap<StructValType, StructType>; StructType(const StructType &); // Do not implement const StructType &operator=(const StructType &); // Do not implement - StructType(LLVMContext &C, ArrayRef<const Type*> Types, bool isPacked); + StructType(LLVMContext &C) + : CompositeType(C, StructTyID), SymbolTableEntry(0) {} + enum { + // This is the contents of the SubClassData field. + SCDB_HasBody = 1, + SCDB_Packed = 2, + SCDB_IsAnonymous = 4 + }; + + /// SymbolTableEntry - For a named struct that actually has a name, this is a + /// pointer to the symbol table entry (maintained by LLVMContext) for the + /// struct. This is null if the type is an anonymous struct or if it is + /// + void *SymbolTableEntry; public: + /// StructType::createNamed - This creates a named struct with no body + /// specified. If the name is empty, it creates an unnamed struct, which has + /// a unique identity but no actual name. + static StructType *createNamed(LLVMContext &Context, StringRef Name); + + static StructType *createNamed(StringRef Name, ArrayRef<Type*> Elements, + bool isPacked = false); + static StructType *createNamed(LLVMContext &Context, StringRef Name, + ArrayRef<Type*> Elements, + bool isPacked = false); + static StructType *createNamed(StringRef Name, Type *elt1, ...) END_WITH_NULL; + /// StructType::get - This static method is the primary way to create a /// StructType. /// + /// FIXME: Remove the 'const Type*' version of this when types are pervasively + /// de-constified. static StructType *get(LLVMContext &Context, ArrayRef<const Type*> Elements, bool isPacked = false); + static StructType *get(LLVMContext &Context, ArrayRef<Type*> Elements, + bool isPacked = false); /// StructType::get - Create an empty structure type. /// @@ -245,11 +236,37 @@ public: /// element type. static StructType *get(const Type *elt1, ...) END_WITH_NULL; + bool isPacked() const { return (getSubclassData() & SCDB_Packed) != 0; } + + /// isAnonymous - Return true if this type is uniqued by structural + /// equivalence, false if it has an identity. + bool isAnonymous() const {return (getSubclassData() & SCDB_IsAnonymous) != 0;} + + /// isOpaque - Return true if this is a type with an identity that has no body + /// specified yet. These prints as 'opaque' in .ll files. + bool isOpaque() const { return (getSubclassData() & SCDB_HasBody) == 0; } + + /// hasName - Return true if this is a named struct that has a non-empty name. + bool hasName() const { return SymbolTableEntry != 0; } + + /// getName - Return the name for this struct type if it has an identity. + /// This may return an empty string for an unnamed struct type. Do not call + /// this on an anonymous type. + StringRef getName() const; + + /// setName - Change the name of this type to the specified name, or to a name + /// with a suffix if there is a collision. Do not call this on an anonymous + /// type. + void setName(StringRef Name); + + /// setBody - Specify a body for an opaque type. + void setBody(ArrayRef<Type*> Elements, bool isPacked = false); + void setBody(Type *elt1, ...) END_WITH_NULL; + /// isValidElementType - Return true if the specified type is valid as a /// element type. static bool isValidElementType(const Type *ElemTy); - - bool isPacked() const { return getSubclassData() != 0 ? true : false; } + // Iterator access to the elements. typedef Type::subtype_iterator element_iterator; @@ -258,22 +275,15 @@ public: /// isLayoutIdentical - Return true if this is layout identical to the /// specified struct. - bool isLayoutIdentical(const StructType *Other) const { - return this == Other; - } - + bool isLayoutIdentical(const StructType *Other) const; // Random access to the elements unsigned getNumElements() const { return NumContainedTys; } - const Type *getElementType(unsigned N) const { + Type *getElementType(unsigned N) const { assert(N < NumContainedTys && "Element number out of range!"); return ContainedTys[N]; } - // 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 *) { return true; } static inline bool classof(const Type *T) { @@ -290,21 +300,19 @@ public: /// components out in memory identically. /// class SequentialType : public CompositeType { - PATypeHandle ContainedType; ///< Storage for the single contained type. + Type *ContainedType; ///< Storage for the single contained type. SequentialType(const SequentialType &); // Do not implement! const SequentialType &operator=(const SequentialType &); // Do not implement! - // avoiding warning: 'this' : used in base member initializer list - SequentialType *this_() { return this; } protected: - SequentialType(TypeID TID, const Type *ElType) - : CompositeType(ElType->getContext(), TID), ContainedType(ElType, this_()) { + SequentialType(TypeID TID, Type *ElType) + : CompositeType(ElType->getContext(), TID), ContainedType(ElType) { ContainedTys = &ContainedType; NumContainedTys = 1; } public: - const Type *getElementType() const { return ContainedTys[0]; } + Type *getElementType() const { return ContainedTys[0]; } // Methods for support type inquiry through isa, cast, and dyn_cast. static inline bool classof(const SequentialType *) { return true; } @@ -319,12 +327,11 @@ public: /// ArrayType - Class to represent array types. /// class ArrayType : public SequentialType { - friend class TypeMap<ArrayValType, ArrayType>; uint64_t NumElements; ArrayType(const ArrayType &); // Do not implement const ArrayType &operator=(const ArrayType &); // Do not implement - ArrayType(const Type *ElType, uint64_t NumEl); + ArrayType(Type *ElType, uint64_t NumEl); public: /// ArrayType::get - This static method is the primary way to construct an /// ArrayType @@ -337,10 +344,6 @@ public: 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); - // Methods for support type inquiry through isa, cast, and dyn_cast. static inline bool classof(const ArrayType *) { return true; } static inline bool classof(const Type *T) { @@ -351,12 +354,11 @@ public: /// VectorType - Class to represent vector types. /// class VectorType : public SequentialType { - friend class TypeMap<VectorValType, VectorType>; unsigned NumElements; VectorType(const VectorType &); // Do not implement const VectorType &operator=(const VectorType &); // Do not implement - VectorType(const Type *ElType, unsigned NumEl); + VectorType(Type *ElType, unsigned NumEl); public: /// VectorType::get - This static method is the primary way to construct an /// VectorType. @@ -369,7 +371,7 @@ public: /// static VectorType *getInteger(const VectorType *VTy) { unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); - const Type *EltTy = IntegerType::get(VTy->getContext(), EltBits); + Type *EltTy = IntegerType::get(VTy->getContext(), EltBits); return VectorType::get(EltTy, VTy->getNumElements()); } @@ -379,7 +381,7 @@ public: /// static VectorType *getExtendedElementVectorType(const VectorType *VTy) { unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); - const Type *EltTy = IntegerType::get(VTy->getContext(), EltBits * 2); + Type *EltTy = IntegerType::get(VTy->getContext(), EltBits * 2); return VectorType::get(EltTy, VTy->getNumElements()); } @@ -391,7 +393,7 @@ public: unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); assert((EltBits & 1) == 0 && "Cannot truncate vector element with odd bit-width"); - const Type *EltTy = IntegerType::get(VTy->getContext(), EltBits / 2); + Type *EltTy = IntegerType::get(VTy->getContext(), EltBits / 2); return VectorType::get(EltTy, VTy->getNumElements()); } @@ -407,10 +409,6 @@ public: 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 *) { return true; } static inline bool classof(const Type *T) { @@ -422,11 +420,9 @@ public: /// PointerType - Class to represent pointers. /// class PointerType : public SequentialType { - friend class TypeMap<PointerValType, PointerType>; - PointerType(const PointerType &); // Do not implement const PointerType &operator=(const PointerType &); // Do not implement - explicit PointerType(const Type *ElType, unsigned AddrSpace); + explicit PointerType(Type *ElType, unsigned AddrSpace); public: /// PointerType::get - This constructs a pointer to an object of the specified /// type in a numbered address space. @@ -445,10 +441,6 @@ public: /// @brief Return the address space of the Pointer type. inline unsigned getAddressSpace() const { return getSubclassData(); } - // Implement the AbstractTypeUser interface. - virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy); - virtual void typeBecameConcrete(const DerivedType *AbsTy); - // Implement support type inquiry through isa, cast, and dyn_cast. static inline bool classof(const PointerType *) { return true; } static inline bool classof(const Type *T) { @@ -456,26 +448,6 @@ public: } }; - -/// OpaqueType - Class to represent opaque types. -/// -class OpaqueType : public DerivedType { - friend class LLVMContextImpl; - OpaqueType(const OpaqueType &); // DO NOT IMPLEMENT - const OpaqueType &operator=(const OpaqueType &); // DO NOT IMPLEMENT - OpaqueType(LLVMContext &C); -public: - /// OpaqueType::get - Static factory method for the OpaqueType class. - /// - static OpaqueType *get(LLVMContext &C); - - // Implement support for type inquiry through isa, cast, and dyn_cast. - static inline bool classof(const OpaqueType *) { return true; } - static inline bool classof(const Type *T) { - return T->getTypeID() == OpaqueTyID; - } -}; - } // End llvm namespace #endif diff --git a/include/llvm/Function.h b/include/llvm/Function.h index 1edc176..093f8b5 100644 --- a/include/llvm/Function.h +++ b/include/llvm/Function.h @@ -128,8 +128,8 @@ public: ~Function(); - const Type *getReturnType() const; // Return the type of the ret val - const FunctionType *getFunctionType() const; // Return the FunctionType for me + Type *getReturnType() const; // Return the type of the ret val + FunctionType *getFunctionType() const; // Return the FunctionType for me /// getContext - Return a pointer to the LLVMContext associated with this /// function, or NULL if this function is not bound to a context yet. diff --git a/include/llvm/GlobalAlias.h b/include/llvm/GlobalAlias.h index f4af5b1..66eb11c 100644 --- a/include/llvm/GlobalAlias.h +++ b/include/llvm/GlobalAlias.h @@ -63,23 +63,23 @@ public: virtual void eraseFromParent(); /// set/getAliasee - These methods retrive and set alias target. - void setAliasee(Constant* GV); - const Constant* getAliasee() const { + void setAliasee(Constant *GV); + const Constant *getAliasee() const { return cast_or_null<Constant>(getOperand(0)); } - Constant* getAliasee() { + Constant *getAliasee() { return cast_or_null<Constant>(getOperand(0)); } /// getAliasedGlobal() - Aliasee can be either global or bitcast of /// global. This method retrives the global for both aliasee flavours. - const GlobalValue* getAliasedGlobal() const; + const GlobalValue *getAliasedGlobal() const; /// resolveAliasedGlobal() - This method tries to ultimately resolve the alias /// by going through the aliasing chain and trying to find the very last /// global. Returns NULL if a cycle was found. If stopOnWeak is false, then /// the whole chain aliasing chain is traversed, otherwise - only strong /// aliases. - const GlobalValue* resolveAliasedGlobal(bool stopOnWeak = true) const; + const GlobalValue *resolveAliasedGlobal(bool stopOnWeak = true) const; // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const GlobalAlias *) { return true; } diff --git a/include/llvm/GlobalValue.h b/include/llvm/GlobalValue.h index b184b8e..69995e1 100644 --- a/include/llvm/GlobalValue.h +++ b/include/llvm/GlobalValue.h @@ -106,8 +106,8 @@ public: bool use_empty_except_constants(); /// getType - Global values are always pointers. - inline const PointerType *getType() const { - return reinterpret_cast<const PointerType*>(User::getType()); + inline PointerType *getType() const { + return reinterpret_cast<PointerType*>(User::getType()); } static LinkageTypes getLinkOnceLinkage(bool ODR) { diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index 0cd1222..5462eb8 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -84,7 +84,6 @@ void initializeDAEPass(PassRegistry&); void initializeDAHPass(PassRegistry&); void initializeDCEPass(PassRegistry&); void initializeDSEPass(PassRegistry&); -void initializeDTEPass(PassRegistry&); void initializeDeadInstEliminationPass(PassRegistry&); void initializeDeadMachineInstructionElimPass(PassRegistry&); void initializeDomOnlyPrinterPass(PassRegistry&); diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index a51076d..4e20d88 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -76,7 +76,7 @@ public: /// getAllocatedType - Return the type that is being allocated by the /// instruction. /// - const Type *getAllocatedType() const; + Type *getAllocatedType() const; /// getAlignment - Return the alignment of the memory that is being allocated /// by the instruction. @@ -271,10 +271,10 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(StoreInst, Value) // GetElementPtrInst Class //===----------------------------------------------------------------------===// -// checkType - Simple wrapper function to give a better assertion failure +// checkGEPType - Simple wrapper function to give a better assertion failure // message on bad indexes for a gep instruction. // -static inline const Type *checkType(const Type *Ty) { +static inline const Type *checkGEPType(const Type *Ty) { assert(Ty && "Invalid GetElementPtrInst indices for type!"); return Ty; } @@ -315,13 +315,13 @@ class GetElementPtrInst : public Instruction { /// pointer type. /// template<typename RandomAccessIterator> - static const Type *getIndexedType(const Type *Ptr, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, - // This argument ensures that we - // have an iterator we can do - // arithmetic on in constant time - std::random_access_iterator_tag) { + static Type *getIndexedType(const Type *Ptr, + RandomAccessIterator IdxBegin, + RandomAccessIterator IdxEnd, + // This argument ensures that we + // have an iterator we can do + // arithmetic on in constant time + std::random_access_iterator_tag) { unsigned NumIdx = static_cast<unsigned>(std::distance(IdxBegin, IdxEnd)); if (NumIdx > 0) @@ -446,24 +446,22 @@ public: /// pointer type. /// template<typename RandomAccessIterator> - static const Type *getIndexedType(const Type *Ptr, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd) { + static Type *getIndexedType(const Type *Ptr, RandomAccessIterator IdxBegin, + RandomAccessIterator IdxEnd) { return getIndexedType(Ptr, IdxBegin, IdxEnd, typename std::iterator_traits<RandomAccessIterator>:: iterator_category()); } - static const Type *getIndexedType(const Type *Ptr, - Value* const *Idx, unsigned NumIdx); + // FIXME: Use ArrayRef + static Type *getIndexedType(const Type *Ptr, + Value* const *Idx, unsigned NumIdx); + static Type *getIndexedType(const Type *Ptr, + Constant* const *Idx, unsigned NumIdx); - static const Type *getIndexedType(const Type *Ptr, - Constant* const *Idx, unsigned NumIdx); - - static const Type *getIndexedType(const Type *Ptr, - uint64_t const *Idx, unsigned NumIdx); - - static const Type *getIndexedType(const Type *Ptr, Value *Idx); + static Type *getIndexedType(const Type *Ptr, + uint64_t const *Idx, unsigned NumIdx); + static Type *getIndexedType(const Type *Ptr, Value *Idx); inline op_iterator idx_begin() { return op_begin()+1; } inline const_op_iterator idx_begin() const { return op_begin()+1; } @@ -538,7 +536,7 @@ GetElementPtrInst::GetElementPtrInst(Value *Ptr, unsigned Values, const Twine &NameStr, Instruction *InsertBefore) - : Instruction(PointerType::get(checkType( + : Instruction(PointerType::get(checkGEPType( getIndexedType(Ptr->getType(), IdxBegin, IdxEnd)), cast<PointerType>(Ptr->getType()) @@ -557,7 +555,7 @@ GetElementPtrInst::GetElementPtrInst(Value *Ptr, unsigned Values, const Twine &NameStr, BasicBlock *InsertAtEnd) - : Instruction(PointerType::get(checkType( + : Instruction(PointerType::get(checkGEPType( getIndexedType(Ptr->getType(), IdxBegin, IdxEnd)), cast<PointerType>(Ptr->getType()) @@ -1459,17 +1457,18 @@ class ExtractValueInst : public UnaryInstruction { /// /// Null is returned if the indices are invalid for the specified type. /// - static const Type *getIndexedType(const Type *Agg, - const unsigned *Idx, unsigned NumIdx); + /// FIXME: Use ArrayRef + static Type *getIndexedType(const Type *Agg, + const unsigned *Idx, unsigned NumIdx); template<typename RandomAccessIterator> - static const Type *getIndexedType(const Type *Ptr, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, - // This argument ensures that we - // have an iterator we can do - // arithmetic on in constant time - std::random_access_iterator_tag) { + static Type *getIndexedType(const Type *Ptr, + RandomAccessIterator IdxBegin, + RandomAccessIterator IdxEnd, + // This argument ensures that we + // have an iterator we can do + // arithmetic on in constant time + std::random_access_iterator_tag) { unsigned NumIdx = static_cast<unsigned>(std::distance(IdxBegin, IdxEnd)); if (NumIdx > 0) @@ -1542,15 +1541,16 @@ public: /// /// Null is returned if the indices are invalid for the specified type. /// + /// FIXME: Remove the templates and just use ArrayRef. template<typename RandomAccessIterator> - static const Type *getIndexedType(const Type *Ptr, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd) { + static Type *getIndexedType(const Type *Ptr, + RandomAccessIterator IdxBegin, + RandomAccessIterator IdxEnd) { return getIndexedType(Ptr, IdxBegin, IdxEnd, typename std::iterator_traits<RandomAccessIterator>:: iterator_category()); } - static const Type *getIndexedType(const Type *Ptr, unsigned Idx); + static Type *getIndexedType(const Type *Ptr, unsigned Idx); typedef const unsigned* idx_iterator; inline idx_iterator idx_begin() const { return Indices.begin(); } @@ -1590,8 +1590,8 @@ ExtractValueInst::ExtractValueInst(Value *Agg, RandomAccessIterator IdxEnd, const Twine &NameStr, Instruction *InsertBefore) - : UnaryInstruction(checkType(getIndexedType(Agg->getType(), - IdxBegin, IdxEnd)), + : UnaryInstruction(checkGEPType(getIndexedType(Agg->getType(), + IdxBegin, IdxEnd)), ExtractValue, Agg, InsertBefore) { init(IdxBegin, IdxEnd, NameStr, typename std::iterator_traits<RandomAccessIterator> @@ -1603,8 +1603,8 @@ ExtractValueInst::ExtractValueInst(Value *Agg, RandomAccessIterator IdxEnd, const Twine &NameStr, BasicBlock *InsertAtEnd) - : UnaryInstruction(checkType(getIndexedType(Agg->getType(), - IdxBegin, IdxEnd)), + : UnaryInstruction(checkGEPType(getIndexedType(Agg->getType(), + IdxBegin, IdxEnd)), ExtractValue, Agg, InsertAtEnd) { init(IdxBegin, IdxEnd, NameStr, typename std::iterator_traits<RandomAccessIterator> diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h index a194548..8467d11 100644 --- a/include/llvm/LinkAllPasses.h +++ b/include/llvm/LinkAllPasses.h @@ -62,7 +62,6 @@ namespace { (void) llvm::createDeadCodeEliminationPass(); (void) llvm::createDeadInstEliminationPass(); (void) llvm::createDeadStoreEliminationPass(); - (void) llvm::createDeadTypeEliminationPass(); (void) llvm::createDomOnlyPrinterPass(); (void) llvm::createDomPrinterPass(); (void) llvm::createDomOnlyViewerPass(); diff --git a/include/llvm/Module.h b/include/llvm/Module.h index aef8eb8..47d23f3 100644 --- a/include/llvm/Module.h +++ b/include/llvm/Module.h @@ -28,6 +28,10 @@ namespace llvm { class FunctionType; class GVMaterializer; class LLVMContext; +class StructType; +template<typename T> struct DenseMapInfo; +template<typename KeyT, typename ValueT, + typename KeyInfoT, typename ValueInfoT> class DenseMap; template<> struct ilist_traits<Function> : public SymbolTableListTraits<Function, Module> { @@ -145,7 +149,6 @@ private: NamedMDListType NamedMDList; ///< The named metadata in the module std::string GlobalScopeAsm; ///< Inline Asm at global scope. ValueSymbolTable *ValSymTab; ///< Symbol table for values - TypeSymbolTable *TypeSymTab; ///< Symbol table for types OwningPtr<GVMaterializer> Materializer; ///< Used to materialize GlobalValues std::string ModuleID; ///< Human readable identifier for the module std::string TargetTriple; ///< Platform target triple Module compiled on @@ -231,7 +234,7 @@ public: /// @name Generic Value Accessors /// @{ - /// getNamedValue - Return the first global value in the module with + /// getNamedValue - Return the global value in the module with /// the specified name, of arbitrary type. This method returns null /// if a global with the specified name is not found. GlobalValue *getNamedValue(StringRef Name) const; @@ -244,6 +247,18 @@ public: /// custom metadata IDs registered in this LLVMContext. void getMDKindNames(SmallVectorImpl<StringRef> &Result) const; + + typedef DenseMap<StructType*, unsigned, DenseMapInfo<StructType*>, + DenseMapInfo<unsigned> > NumeredTypesMapTy; + + /// findUsedStructTypes - Walk the entire module and find all of the + /// struct types that are in use, returning them in a vector. + void findUsedStructTypes(std::vector<StructType*> &StructTypes) const; + + /// getTypeByName - Return the type with the specified name, or null if there + /// is none by that name. + StructType *getTypeByName(StringRef Name) const; + /// @} /// @name Function Accessors /// @{ @@ -296,7 +311,7 @@ public: GlobalVariable *getGlobalVariable(StringRef Name, bool AllowInternal = false) const; - /// getNamedGlobal - Return the first global variable in the module with the + /// getNamedGlobal - Return the global variable in the module with the /// specified name, of arbitrary type. This method returns null if a global /// with the specified name is not found. GlobalVariable *getNamedGlobal(StringRef Name) const { @@ -316,7 +331,7 @@ public: /// @name Global Alias Accessors /// @{ - /// getNamedAlias - Return the first global alias in the module with the + /// getNamedAlias - Return the global alias in the module with the /// specified name, of arbitrary type. This method returns null if a global /// with the specified name is not found. GlobalAlias *getNamedAlias(StringRef Name) const; @@ -325,12 +340,12 @@ public: /// @name Named Metadata Accessors /// @{ - /// getNamedMetadata - Return the first NamedMDNode in the module with the + /// getNamedMetadata - Return the NamedMDNode in the module with the /// specified name. This method returns null if a NamedMDNode with the /// specified name is not found. NamedMDNode *getNamedMetadata(const Twine &Name) const; - /// getOrInsertNamedMetadata - Return the first named MDNode in the module + /// getOrInsertNamedMetadata - Return the named MDNode in the module /// with the specified name. This method returns a new NamedMDNode if a /// NamedMDNode with the specified name is not found. NamedMDNode *getOrInsertNamedMetadata(StringRef Name); @@ -340,23 +355,6 @@ public: void eraseNamedMetadata(NamedMDNode *NMD); /// @} -/// @name Type Accessors -/// @{ - - /// addTypeName - Insert an entry in the symbol table mapping Str to Type. If - /// there is already an entry for this name, true is returned and the symbol - /// table is not modified. - bool addTypeName(StringRef Name, const Type *Ty); - - /// getTypeName - If there is at least one entry in the symbol table for the - /// specified type, return it. - std::string getTypeName(const Type *Ty) const; - - /// getTypeByName - Return the type with the specified name in this module, or - /// null if there is none by that name. - const Type *getTypeByName(StringRef Name) const; - -/// @} /// @name Materialization /// @{ @@ -429,41 +427,26 @@ public: const ValueSymbolTable &getValueSymbolTable() const { return *ValSymTab; } /// Get the Module's symbol table of global variable and function identifiers. ValueSymbolTable &getValueSymbolTable() { return *ValSymTab; } - /// Get the symbol table of types - const TypeSymbolTable &getTypeSymbolTable() const { return *TypeSymTab; } - /// Get the Module's symbol table of types - TypeSymbolTable &getTypeSymbolTable() { return *TypeSymTab; } /// @} /// @name Global Variable Iteration /// @{ - /// Get an iterator to the first global variable global_iterator global_begin() { return GlobalList.begin(); } - /// Get a constant iterator to the first global variable const_global_iterator global_begin() const { return GlobalList.begin(); } - /// Get an iterator to the last global variable global_iterator global_end () { return GlobalList.end(); } - /// Get a constant iterator to the last global variable const_global_iterator global_end () const { return GlobalList.end(); } - /// Determine if the list of globals is empty. bool global_empty() const { return GlobalList.empty(); } /// @} /// @name Function Iteration /// @{ - /// Get an iterator to the first function. iterator begin() { return FunctionList.begin(); } - /// Get a constant iterator to the first function. const_iterator begin() const { return FunctionList.begin(); } - /// Get an iterator to the last function. iterator end () { return FunctionList.end(); } - /// Get a constant iterator to the last function. const_iterator end () const { return FunctionList.end(); } - /// Determine how many functions are in the Module's list of functions. size_t size() const { return FunctionList.size(); } - /// Determine if the list of functions is empty. bool empty() const { return FunctionList.empty(); } /// @} @@ -487,17 +470,11 @@ public: /// @name Alias Iteration /// @{ - /// Get an iterator to the first alias. alias_iterator alias_begin() { return AliasList.begin(); } - /// Get a constant iterator to the first alias. const_alias_iterator alias_begin() const { return AliasList.begin(); } - /// Get an iterator to the last alias. alias_iterator alias_end () { return AliasList.end(); } - /// Get a constant iterator to the last alias. const_alias_iterator alias_end () const { return AliasList.end(); } - /// Determine how many aliases are in the Module's list of aliases. size_t alias_size () const { return AliasList.size(); } - /// Determine if the list of aliases is empty. bool alias_empty() const { return AliasList.empty(); } @@ -505,24 +482,17 @@ public: /// @name Named Metadata Iteration /// @{ - /// Get an iterator to the first named metadata. named_metadata_iterator named_metadata_begin() { return NamedMDList.begin(); } - /// Get a constant iterator to the first named metadata. const_named_metadata_iterator named_metadata_begin() const { return NamedMDList.begin(); } - /// Get an iterator to the last named metadata. named_metadata_iterator named_metadata_end() { return NamedMDList.end(); } - /// Get a constant iterator to the last named metadata. const_named_metadata_iterator named_metadata_end() const { return NamedMDList.end(); } - /// Determine how many NamedMDNodes are in the Module's list of named - /// metadata. size_t named_metadata_size() const { return NamedMDList.size(); } - /// Determine if the list of named metadata is empty. bool named_metadata_empty() const { return NamedMDList.empty(); } @@ -530,11 +500,13 @@ public: /// @name Utility functions for printing and dumping Module objects /// @{ - /// Print the module to an output stream with AssemblyAnnotationWriter. + /// Print the module to an output stream with an optional + /// AssemblyAnnotationWriter. void print(raw_ostream &OS, AssemblyAnnotationWriter *AAW) const; /// Dump the module to stderr (for debugging). void dump() const; + /// This function causes all the subinstructions to "let go" of all references /// that they are maintaining. This allows one to 'delete' a whole class at /// a time, even though there may be circular references... first all diff --git a/include/llvm/Support/PassManagerBuilder.h b/include/llvm/Support/PassManagerBuilder.h index ccb49e7..b0cec6e 100644 --- a/include/llvm/Support/PassManagerBuilder.h +++ b/include/llvm/Support/PassManagerBuilder.h @@ -237,8 +237,8 @@ public: MPM.add(createInstructionCombiningPass()); // Clean up after everything. if (!DisableUnitAtATime) { + // FIXME: We shouldn't bother with this anymore. MPM.add(createStripDeadPrototypesPass()); // Get rid of dead prototypes - MPM.add(createDeadTypeEliminationPass()); // Eliminate dead types // GlobalOpt already deletes dead functions and globals, at -O3 try a // late pass of GlobalDCE. It is capable of deleting dead cycles. diff --git a/include/llvm/Transforms/IPO.h b/include/llvm/Transforms/IPO.h index d12fd1d..f025e18 100644 --- a/include/llvm/Transforms/IPO.h +++ b/include/llvm/Transforms/IPO.h @@ -74,13 +74,6 @@ ModulePass *createGlobalOptimizerPass(); //===----------------------------------------------------------------------===// -/// createDeadTypeEliminationPass - Return a new pass that eliminates symbol -/// table entries for types that are never used. -/// -ModulePass *createDeadTypeEliminationPass(); - - -//===----------------------------------------------------------------------===// /// createGlobalDCEPass - This transform is designed to eliminate unreachable /// internal globals (functions or global variables) /// diff --git a/include/llvm/Transforms/Utils/ValueMapper.h b/include/llvm/Transforms/Utils/ValueMapper.h index d612213..c786342 100644 --- a/include/llvm/Transforms/Utils/ValueMapper.h +++ b/include/llvm/Transforms/Utils/ValueMapper.h @@ -22,6 +22,18 @@ namespace llvm { class Instruction; typedef ValueMap<const Value *, TrackingVH<Value> > ValueToValueMapTy; + /// ValueMapTypeRemapper - This is a class that can be implemented by clients + /// to remap types when cloning constants and instructions. + class ValueMapTypeRemapper { + virtual void Anchor(); // Out of line method. + public: + ~ValueMapTypeRemapper() {} + + /// remapType - The client should implement this method if they want to + /// remap types while mapping values. + virtual Type *remapType(Type *SrcTy) = 0; + }; + /// RemapFlags - These are flags that the value mapping APIs allow. enum RemapFlags { RF_None = 0, @@ -42,9 +54,27 @@ namespace llvm { } Value *MapValue(const Value *V, ValueToValueMapTy &VM, - RemapFlags Flags = RF_None); + RemapFlags Flags = RF_None, + ValueMapTypeRemapper *TypeMapper = 0); + void RemapInstruction(Instruction *I, ValueToValueMapTy &VM, - RemapFlags Flags = RF_None); + RemapFlags Flags = RF_None, + ValueMapTypeRemapper *TypeMapper = 0); + + /// MapValue - provide versions that preserve type safety for MDNode and + /// Constants. + inline MDNode *MapValue(const MDNode *V, ValueToValueMapTy &VM, + RemapFlags Flags = RF_None, + ValueMapTypeRemapper *TypeMapper = 0) { + return (MDNode*)MapValue((const Value*)V, VM, Flags, TypeMapper); + } + inline Constant *MapValue(const Constant *V, ValueToValueMapTy &VM, + RemapFlags Flags = RF_None, + ValueMapTypeRemapper *TypeMapper = 0) { + return (Constant*)MapValue((const Value*)V, VM, Flags, TypeMapper); + } + + } // End llvm namespace #endif diff --git a/include/llvm/Type.h b/include/llvm/Type.h index 6110154..da11d98 100644 --- a/include/llvm/Type.h +++ b/include/llvm/Type.h @@ -15,19 +15,17 @@ #ifndef LLVM_TYPE_H #define LLVM_TYPE_H -#include "llvm/AbstractTypeUser.h" #include "llvm/Support/Casting.h" -#include <vector> namespace llvm { class DerivedType; class PointerType; class IntegerType; -class TypeMapBase; class raw_ostream; class Module; class LLVMContext; +class LLVMContextImpl; template<class GraphType> struct GraphTraits; /// The instances of the Type class are immutable: once they are created, @@ -35,29 +33,10 @@ template<class GraphType> struct GraphTraits; /// type is ever created. Thus seeing if two types are equal is a matter of /// doing a trivial pointer comparison. To enforce that no two equal instances /// are created, Type instances can only be created via static factory methods -/// in class Type and in derived classes. +/// in class Type and in derived classes. Once allocated, Types are never +/// free'd. /// -/// Once allocated, Types are never free'd, unless they are an abstract type -/// that is resolved to a more concrete type. -/// -/// Types themself don't have a name, and can be named either by: -/// - using SymbolTable instance, typically from some Module, -/// - using convenience methods in the Module class (which uses module's -/// SymbolTable too). -/// -/// Opaque types are simple derived types with no state. There may be many -/// different Opaque type objects floating around, but two are only considered -/// identical if they are pointer equals of each other. This allows us to have -/// two opaque types that end up resolving to different concrete types later. -/// -/// Opaque types are also kinda weird and scary and different because they have -/// to keep a list of uses of the type. When, through linking, parsing, or -/// bitcode reading, they become resolved, they need to find and update all -/// users of the unknown type, causing them to reference a new, more concrete -/// type. Opaque types are deleted when their use list dwindles to zero users. -/// -/// @brief Root of type hierarchy -class Type : public AbstractTypeUser { +class Type { public: //===--------------------------------------------------------------------===// /// Definitions of all of the base types for the Type system. Based on this @@ -85,8 +64,7 @@ public: StructTyID, ///< 11: Structures ArrayTyID, ///< 12: Arrays PointerTyID, ///< 13: Pointers - OpaqueTyID, ///< 14: Opaque: type with unknown structure - VectorTyID, ///< 15: SIMD 'packed' format, or other vector type + VectorTyID, ///< 14: SIMD 'packed' format, or other vector type NumTypeIDs, // Must remain as last defined ID LastPrimitiveTyID = X86_MMXTyID, @@ -94,86 +72,42 @@ public: }; private: - TypeID ID : 8; // The current base type of this type. - bool Abstract : 1; // True if type contains an OpaqueType - unsigned SubclassData : 23; //Space for subclasses to store data - - /// RefCount - This counts the number of PATypeHolders that are pointing to - /// this type. When this number falls to zero, if the type is abstract and - /// has no AbstractTypeUsers, the type is deleted. This is only sensical for - /// derived types. - /// - mutable unsigned RefCount; - /// Context - This refers to the LLVMContext in which this type was uniqued. LLVMContext &Context; - friend class LLVMContextImpl; - const Type *getForwardedTypeInternal() const; - - // When the last reference to a forwarded type is removed, it is destroyed. - void destroy() const; + TypeID ID : 8; // The current base type of this type. + unsigned SubclassData : 24; // Space for subclasses to store data protected: - explicit Type(LLVMContext &C, TypeID id) : - ID(id), Abstract(false), SubclassData(0), - RefCount(0), Context(C), - ForwardType(0), NumContainedTys(0), - ContainedTys(0) {} - virtual ~Type() { - assert(AbstractTypeUsers.empty() && "Abstract types remain"); - } - - /// Types can become nonabstract later, if they are refined. - /// - inline void setAbstract(bool Val) { Abstract = Val; } - - unsigned getRefCount() const { return RefCount; } + friend class LLVMContextImpl; + explicit Type(LLVMContext &C, TypeID tid) + : Context(C), ID(tid), SubclassData(0), + NumContainedTys(0), ContainedTys(0) {} + ~Type() {} unsigned getSubclassData() const { return SubclassData; } - void setSubclassData(unsigned val) { SubclassData = val; } - - /// ForwardType - This field is used to implement the union find scheme for - /// abstract types. When types are refined to other types, this field is set - /// to the more refined type. Only abstract types can be forwarded. - mutable const Type *ForwardType; - - - /// 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. - /// - mutable std::vector<AbstractTypeUser *> AbstractTypeUsers; + void setSubclassData(unsigned val) { + SubclassData = val; + // Ensure we don't have any accidental truncation. + assert(SubclassData == val && "Subclass data too large for field"); + } - /// NumContainedTys - Keeps track of how many PATypeHandle instances there - /// are at the end of this type instance for the list of contained types. It - /// is the subclasses responsibility to set this up. Set to 0 if there are no - /// contained types in this type. + /// NumContainedTys - Keeps track of how many Type*'s there are in the + /// ContainedTys list. unsigned NumContainedTys; - /// ContainedTys - A pointer to the array of Types (PATypeHandle) contained - /// by this Type. For example, this includes the arguments of a function - /// type, the elements of a structure, the pointee of a pointer, the element - /// type of an array, etc. This pointer may be 0 for types that don't - /// contain other types (Integer, Double, Float). In general, the subclass - /// should arrange for space for the PATypeHandles to be included in the - /// allocation of the type object and set this pointer to the address of the - /// first element. This allows the Type class to manipulate the ContainedTys - /// without understanding the subclass's placement for this array. keeping - /// it here also allows the subtype_* members to be implemented MUCH more - /// efficiently, and dynamically very few types do not contain any elements. - PATypeHandle *ContainedTys; + /// ContainedTys - A pointer to the array of Types contained by this Type. + /// For example, this includes the arguments of a function type, the elements + /// of a structure, the pointee of a pointer, the element type of an array, + /// etc. This pointer may be 0 for types that don't contain other types + /// (Integer, Double, Float). + Type * const *ContainedTys; public: void print(raw_ostream &O) const; - - /// @brief Debugging support: print to stderr void dump() const; - /// @brief Debugging support: print to stderr (use type names from context - /// module). - void dump(const Module *Context) const; - - /// getContext - Fetch the LLVMContext in which this type was uniqued. + /// getContext - Return the LLVMContext in which this type was uniqued. LLVMContext &getContext() const { return Context; } //===--------------------------------------------------------------------===// @@ -205,8 +139,10 @@ public: /// isFloatingPointTy - Return true if this is one of the five floating point /// types - bool isFloatingPointTy() const { return ID == FloatTyID || ID == DoubleTyID || - ID == X86_FP80TyID || ID == FP128TyID || ID == PPC_FP128TyID; } + bool isFloatingPointTy() const { + return ID == FloatTyID || ID == DoubleTyID || + ID == X86_FP80TyID || ID == FP128TyID || ID == PPC_FP128TyID; + } /// isX86_MMXTy - Return true if this is X86 MMX. bool isX86_MMXTy() const { return ID == X86_MMXTyID; } @@ -249,19 +185,10 @@ public: /// bool isPointerTy() const { return ID == PointerTyID; } - /// isOpaqueTy - True if this is an instance of OpaqueType. - /// - bool isOpaqueTy() const { return ID == OpaqueTyID; } - /// isVectorTy - True if this is an instance of VectorType. /// bool isVectorTy() const { return ID == VectorTyID; } - /// isAbstract - True if the type is either an Opaque type, or is a derived - /// type that includes an opaque type somewhere in it. - /// - inline bool isAbstract() const { return Abstract; } - /// canLosslesslyBitCastTo - Return true if this type could be converted /// with a lossless BitCast to type 'Ty'. For example, i8* to i32*. BitCasts /// are valid for types of the same size only where no re-interpretation of @@ -276,24 +203,22 @@ public: /// Here are some useful little methods to query what type derived types are /// Note that all other types can just compare to see if this == Type::xxxTy; /// - inline bool isPrimitiveType() const { return ID <= LastPrimitiveTyID; } - inline bool isDerivedType() const { return ID >= FirstDerivedTyID; } + bool isPrimitiveType() const { return ID <= LastPrimitiveTyID; } + bool isDerivedType() const { return ID >= FirstDerivedTyID; } /// isFirstClassType - Return true if the type is "first class", meaning it /// is a valid type for a Value. /// - inline bool isFirstClassType() const { - // There are more first-class kinds than non-first-class kinds, so a - // negative test is simpler than a positive one. - return ID != FunctionTyID && ID != VoidTyID && ID != OpaqueTyID; + bool isFirstClassType() const { + return ID != FunctionTyID && ID != VoidTyID; } /// isSingleValueType - Return true if the type is a valid type for a - /// virtual register in codegen. This includes all first-class types - /// except struct and array types. + /// register in codegen. This includes all first-class types except struct + /// and array types. /// - inline bool isSingleValueType() const { - return (ID != VoidTyID && ID <= LastPrimitiveTyID) || + bool isSingleValueType() const { + return (ID != VoidTyID && isPrimitiveType()) || ID == IntegerTyID || ID == PointerTyID || ID == VectorTyID; } @@ -302,7 +227,7 @@ public: /// extractvalue instruction. This includes struct and array types, but /// does not include vector types. /// - inline bool isAggregateType() const { + bool isAggregateType() const { return ID == StructTyID || ID == ArrayTyID; } @@ -319,9 +244,8 @@ public: // it doesn't have a size. if (ID != StructTyID && ID != ArrayTyID && ID != VectorTyID) return false; - // If it is something that can have a size and it's concrete, it definitely - // has a size, otherwise we have to try harder to decide. - return !isAbstract() || isSizedDerivedType(); + // Otherwise we have to try harder to decide. + return isSizedDerivedType(); } /// getPrimitiveSizeInBits - Return the basic size of this type if it is a @@ -346,23 +270,14 @@ public: /// have a stable mantissa (e.g. ppc long double), this method returns -1. int getFPMantissaWidth() const; - /// getForwardedType - Return the type that this type has been resolved to if - /// it has been resolved to anything. This is used to implement the - /// union-find algorithm for type resolution, and shouldn't be used by general - /// purpose clients. - const Type *getForwardedType() const { - if (!ForwardType) return 0; - return getForwardedTypeInternal(); - } - /// getScalarType - If this is a vector type, return the element type, - /// otherwise return this. + /// otherwise return 'this'. const Type *getScalarType() const; //===--------------------------------------------------------------------===// - // Type Iteration support + // Type Iteration support. // - typedef PATypeHandle *subtype_iterator; + typedef Type * const *subtype_iterator; subtype_iterator subtype_begin() const { return ContainedTys; } subtype_iterator subtype_end() const { return &ContainedTys[NumContainedTys];} @@ -370,9 +285,9 @@ public: /// (defined a the end of the file). For derived types, this returns the /// types 'contained' in the derived type. /// - const Type *getContainedType(unsigned i) const { + Type *getContainedType(unsigned i) const { assert(i < NumContainedTys && "Index out of range!"); - return ContainedTys[i].get(); + return ContainedTys[i]; } /// getNumContainedTypes - Return the number of types in the derived type. @@ -385,140 +300,77 @@ public: // /// getPrimitiveType - Return a type based on an identifier. - static const Type *getPrimitiveType(LLVMContext &C, TypeID IDNumber); + static Type *getPrimitiveType(LLVMContext &C, TypeID IDNumber); //===--------------------------------------------------------------------===// - // These are the builtin types that are always available... + // These are the builtin types that are always available. // - static const Type *getVoidTy(LLVMContext &C); - static const Type *getLabelTy(LLVMContext &C); - static const Type *getFloatTy(LLVMContext &C); - static const Type *getDoubleTy(LLVMContext &C); - static const Type *getMetadataTy(LLVMContext &C); - static const Type *getX86_FP80Ty(LLVMContext &C); - static const Type *getFP128Ty(LLVMContext &C); - static const Type *getPPC_FP128Ty(LLVMContext &C); - static const Type *getX86_MMXTy(LLVMContext &C); - static const IntegerType *getIntNTy(LLVMContext &C, unsigned N); - static const IntegerType *getInt1Ty(LLVMContext &C); - static const IntegerType *getInt8Ty(LLVMContext &C); - static const IntegerType *getInt16Ty(LLVMContext &C); - static const IntegerType *getInt32Ty(LLVMContext &C); - static const IntegerType *getInt64Ty(LLVMContext &C); + static Type *getVoidTy(LLVMContext &C); + static Type *getLabelTy(LLVMContext &C); + static Type *getFloatTy(LLVMContext &C); + static Type *getDoubleTy(LLVMContext &C); + static Type *getMetadataTy(LLVMContext &C); + static Type *getX86_FP80Ty(LLVMContext &C); + static Type *getFP128Ty(LLVMContext &C); + static Type *getPPC_FP128Ty(LLVMContext &C); + static Type *getX86_MMXTy(LLVMContext &C); + static IntegerType *getIntNTy(LLVMContext &C, unsigned N); + static IntegerType *getInt1Ty(LLVMContext &C); + static IntegerType *getInt8Ty(LLVMContext &C); + static IntegerType *getInt16Ty(LLVMContext &C); + static IntegerType *getInt32Ty(LLVMContext &C); + static IntegerType *getInt64Ty(LLVMContext &C); //===--------------------------------------------------------------------===// // Convenience methods for getting pointer types with one of the above builtin // types as pointee. // - static const PointerType *getFloatPtrTy(LLVMContext &C, unsigned AS = 0); - static const PointerType *getDoublePtrTy(LLVMContext &C, unsigned AS = 0); - static const PointerType *getX86_FP80PtrTy(LLVMContext &C, unsigned AS = 0); - static const PointerType *getFP128PtrTy(LLVMContext &C, unsigned AS = 0); - static const PointerType *getPPC_FP128PtrTy(LLVMContext &C, unsigned AS = 0); - static const PointerType *getX86_MMXPtrTy(LLVMContext &C, unsigned AS = 0); - static const PointerType *getIntNPtrTy(LLVMContext &C, unsigned N, - unsigned AS = 0); - static const PointerType *getInt1PtrTy(LLVMContext &C, unsigned AS = 0); - static const PointerType *getInt8PtrTy(LLVMContext &C, unsigned AS = 0); - static const PointerType *getInt16PtrTy(LLVMContext &C, unsigned AS = 0); - static const PointerType *getInt32PtrTy(LLVMContext &C, unsigned AS = 0); - static const PointerType *getInt64PtrTy(LLVMContext &C, unsigned AS = 0); + static PointerType *getFloatPtrTy(LLVMContext &C, unsigned AS = 0); + static PointerType *getDoublePtrTy(LLVMContext &C, unsigned AS = 0); + static PointerType *getX86_FP80PtrTy(LLVMContext &C, unsigned AS = 0); + static PointerType *getFP128PtrTy(LLVMContext &C, unsigned AS = 0); + static PointerType *getPPC_FP128PtrTy(LLVMContext &C, unsigned AS = 0); + static PointerType *getX86_MMXPtrTy(LLVMContext &C, unsigned AS = 0); + static PointerType *getIntNPtrTy(LLVMContext &C, unsigned N, unsigned AS = 0); + static PointerType *getInt1PtrTy(LLVMContext &C, unsigned AS = 0); + static PointerType *getInt8PtrTy(LLVMContext &C, unsigned AS = 0); + static PointerType *getInt16PtrTy(LLVMContext &C, unsigned AS = 0); + static PointerType *getInt32PtrTy(LLVMContext &C, unsigned AS = 0); + static PointerType *getInt64PtrTy(LLVMContext &C, unsigned AS = 0); /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Type *) { return true; } - void addRef() const { - assert(isAbstract() && "Cannot add a reference to a non-abstract type!"); - ++RefCount; - } - - void dropRef() const { - assert(isAbstract() && "Cannot drop a reference to a non-abstract type!"); - assert(RefCount && "No objects are currently referencing this object!"); - - // If this is the last PATypeHolder using this object, and there are no - // PATypeHandles using it, the type is dead, delete it now. - if (--RefCount == 0 && AbstractTypeUsers.empty()) - this->destroy(); - } - - /// 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; - - /// 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 annihilated, because there is no way to get a reference to it ever - /// again. - /// - void removeAbstractTypeUser(AbstractTypeUser *U) const; - /// getPointerTo - Return a pointer to the current type. This is equivalent /// to PointerType::get(Foo, AddrSpace). - const PointerType *getPointerTo(unsigned AddrSpace = 0) const; + PointerType *getPointerTo(unsigned AddrSpace = 0) const; private: /// isSizedDerivedType - Derived types like structures and arrays are sized /// iff all of the members of the type are sized as well. Since asking for /// their size is relatively uncommon, move this operation out of line. bool isSizedDerivedType() const; - - virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy); - virtual void typeBecameConcrete(const DerivedType *AbsTy); - -protected: - // PromoteAbstractToConcrete - This is an internal method used to calculate - // change "Abstract" from true to false when types are refined. - void PromoteAbstractToConcrete(); - friend class TypeMapBase; }; -//===----------------------------------------------------------------------===// -// Define some inline methods for the AbstractTypeUser.h:PATypeHandle class. -// These are defined here because they MUST be inlined, yet are dependent on -// the definition of the Type class. -// -inline void PATypeHandle::addUser() { - assert(Ty && "Type Handle has a null type!"); - if (Ty->isAbstract()) - Ty->addAbstractTypeUser(User); -} -inline void PATypeHandle::removeUser() { - if (Ty->isAbstract()) - Ty->removeAbstractTypeUser(User); -} - -// Define inline methods for PATypeHolder. - -/// get - This implements the forwarding part of the union-find algorithm for -/// abstract types. Before every access to the Type*, we check to see if the -/// type we are pointing to is forwarding to a new type. If so, we drop our -/// reference to the type. -/// -inline Type *PATypeHolder::get() const { - if (Ty == 0) return 0; - const Type *NewTy = Ty->getForwardedType(); - if (!NewTy) return const_cast<Type*>(Ty); - return *const_cast<PATypeHolder*>(this) = NewTy; -} - -inline void PATypeHolder::addRef() { - if (Ty && Ty->isAbstract()) - Ty->addRef(); -} - -inline void PATypeHolder::dropRef() { - if (Ty && Ty->isAbstract()) - Ty->dropRef(); +// Printing of types. +static inline raw_ostream &operator<<(raw_ostream &OS, const Type &T) { + T.print(OS); + return OS; } +// allow isa<PointerType>(x) to work without DerivedTypes.h included. +template <> struct isa_impl<PointerType, Type> { + static inline bool doit(const Type &Ty) { + return Ty.getTypeID() == Type::PointerTyID; + } +}; + //===----------------------------------------------------------------------===// // Provide specializations of GraphTraits to be able to treat a type as a // graph of sub types. + template <> struct GraphTraits<Type*> { typedef Type NodeType; typedef Type::subtype_iterator ChildIteratorType; @@ -545,14 +397,6 @@ template <> struct GraphTraits<const Type*> { } }; -template <> struct isa_impl<PointerType, Type> { - static inline bool doit(const Type &Ty) { - return Ty.getTypeID() == Type::PointerTyID; - } -}; - -raw_ostream &operator<<(raw_ostream &OS, const Type &T); - } // End llvm namespace #endif diff --git a/include/llvm/TypeSymbolTable.h b/include/llvm/TypeSymbolTable.h deleted file mode 100644 index 89ad534..0000000 --- a/include/llvm/TypeSymbolTable.h +++ /dev/null @@ -1,152 +0,0 @@ -//===-- llvm/TypeSymbolTable.h - Implement a Type Symtab --------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the name/type symbol table for LLVM. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TYPE_SYMBOL_TABLE_H -#define LLVM_TYPE_SYMBOL_TABLE_H - -#include "llvm/Type.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/DataTypes.h" -#include <map> - -namespace llvm { - -/// This class provides a symbol table of name/type pairs with operations to -/// support constructing, searching and iterating over the symbol table. The -/// class derives from AbstractTypeUser so that the contents of the symbol -/// table can be updated when abstract types become concrete. -class TypeSymbolTable : public AbstractTypeUser { - -/// @name Types -/// @{ -public: - - /// @brief A mapping of names to types. - typedef std::map<const std::string, const Type*> TypeMap; - - /// @brief An iterator over the TypeMap. - typedef TypeMap::iterator iterator; - - /// @brief A const_iterator over the TypeMap. - typedef TypeMap::const_iterator const_iterator; - -/// @} -/// @name Constructors -/// @{ -public: - - TypeSymbolTable():LastUnique(0) {} - ~TypeSymbolTable(); - -/// @} -/// @name Accessors -/// @{ -public: - - /// Generates a unique name for a type based on the \p BaseName by - /// incrementing an integer and appending it to the name, if necessary - /// @returns the unique name - /// @brief Get a unique name for a type - std::string getUniqueName(StringRef BaseName) const; - - /// This method finds the type with the given \p name in the type map - /// and returns it. - /// @returns null if the name is not found, otherwise the Type - /// associated with the \p name. - /// @brief Lookup a type by name. - Type *lookup(StringRef name) const; - - /// Lookup the type associated with name. - /// @returns end() if the name is not found, or an iterator at the entry for - /// Type. - iterator find(StringRef Name) { - return tmap.find(Name); - } - - /// Lookup the type associated with name. - /// @returns end() if the name is not found, or an iterator at the entry for - /// Type. - const_iterator find(StringRef Name) const { - return tmap.find(Name); - } - - /// @returns true iff the symbol table is empty. - /// @brief Determine if the symbol table is empty - inline bool empty() const { return tmap.empty(); } - - /// @returns the size of the symbol table - /// @brief The number of name/type pairs is returned. - inline unsigned size() const { return unsigned(tmap.size()); } - - /// This function can be used from the debugger to display the - /// content of the symbol table while debugging. - /// @brief Print out symbol table on stderr - void dump() const; - -/// @} -/// @name Iteration -/// @{ -public: - /// Get an iterator to the start of the symbol table - inline iterator begin() { return tmap.begin(); } - - /// @brief Get a const_iterator to the start of the symbol table - inline const_iterator begin() const { return tmap.begin(); } - - /// Get an iterator to the end of the symbol table. - inline iterator end() { return tmap.end(); } - - /// Get a const_iterator to the end of the symbol table. - inline const_iterator end() const { return tmap.end(); } - -/// @} -/// @name Mutators -/// @{ -public: - - /// Inserts a type into the symbol table with the specified name. There can be - /// a many-to-one mapping between names and types. This method allows a type - /// with an existing entry in the symbol table to get a new name. - /// @brief Insert a type under a new name. - void insert(StringRef Name, const Type *Typ); - - /// Remove a type at the specified position in the symbol table. - /// @returns the removed Type. - /// @returns the Type that was erased from the symbol table. - Type* remove(iterator TI); - -/// @} -/// @name AbstractTypeUser Methods -/// @{ -private: - /// This function is called when one of the types in the type plane - /// is refined. - virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy); - - /// This function marks a type as being concrete (defined). - virtual void typeBecameConcrete(const DerivedType *AbsTy); - -/// @} -/// @name Internal Data -/// @{ -private: - TypeMap tmap; ///< This is the mapping of names to types. - mutable uint32_t LastUnique; ///< Counter for tracking unique names - -/// @} - -}; - -} // End llvm namespace - -#endif diff --git a/include/llvm/Value.h b/include/llvm/Value.h index 3a1c3ca..f787777 100644 --- a/include/llvm/Value.h +++ b/include/llvm/Value.h @@ -14,7 +14,6 @@ #ifndef LLVM_VALUE_H #define LLVM_VALUE_H -#include "llvm/AbstractTypeUser.h" #include "llvm/Use.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Casting.h" @@ -32,7 +31,6 @@ class GlobalVariable; class GlobalAlias; class InlineAsm; class ValueSymbolTable; -class TypeSymbolTable; template<typename ValueTy> class StringMapEntry; template <typename ValueTy = Value> class AssertingVH; @@ -43,6 +41,7 @@ class ValueHandleBase; class LLVMContext; class Twine; class MDNode; +class Type; //===----------------------------------------------------------------------===// // Value Class @@ -77,12 +76,11 @@ private: /// This field is initialized to zero by the ctor. unsigned short SubclassData; - PATypeHolder VTy; + Type *VTy; Use *UseList; friend class ValueSymbolTable; // Allow ValueSymbolTable to directly mod Name. friend class ValueHandleBase; - friend class AbstractTypeUser; ValueName *Name; void operator=(const Value &); // Do not implement @@ -107,13 +105,13 @@ public: /// All values are typed, get the type of this value. /// - inline const Type *getType() const { return VTy; } + Type *getType() const { return VTy; } /// All values hold a context through their type. LLVMContext &getContext() const; // All values can potentially be named... - inline bool hasName() const { return Name != 0; } + bool hasName() const { return Name != 0; } ValueName *getValueName() const { return Name; } /// getName() - Return a constant reference to the value's name. This is cheap @@ -279,10 +277,6 @@ public: return true; // Values are always values. } - /// getRawType - This should only be used to implement the vmcore library. - /// - const Type *getRawType() const { return VTy.getRawType(); } - /// stripPointerCasts - This method strips off any unneeded pointer /// casts from the specified value, returning the original uncasted value. /// Note that the returned value has pointer type if the specified value does. @@ -310,6 +304,15 @@ public: /// load, store, and alloca instructions, and global values. static const unsigned MaximumAlignment = 1u << 29; + /// mutateType - Mutate the type of this Value to be of the specified type. + /// Note that this is an extremely dangerous operation which can create + /// completely invalid IR very easily. It is strongly recommended that you + /// recreate IR objects with the right types instead of mutating them in + /// place. + void mutateType(Type *Ty) { + VTy = Ty; + } + protected: unsigned short getSubclassDataFromValue() const { return SubclassData; } void setValueSubclassData(unsigned short D) { SubclassData = D; } |