X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FInstructions.h;h=6fa434cccfad5ecaafb4d92abd833d15118d8ad7;hb=ab9238e876dcf6da101d8ae626925bcd9e537a7e;hp=76190f146d50312f690d16839646b5c232bb0b06;hpb=f4a5498ab44f06b2b74da7fda92521f34bb22367;p=oota-llvm.git diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index 76190f146d5..6fa434cccfa 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -16,20 +16,20 @@ #ifndef LLVM_INSTRUCTIONS_H #define LLVM_INSTRUCTIONS_H -#include - #include "llvm/InstrTypes.h" #include "llvm/DerivedTypes.h" +#include "llvm/Attributes.h" +#include "llvm/BasicBlock.h" +#include "llvm/LLVMContext.h" +#include "llvm/ADT/SmallVector.h" +#include namespace llvm { -class BasicBlock; class ConstantInt; -class PointerType; -class VectorType; class ConstantRange; class APInt; -class ParamAttrsList; +class LLVMContext; //===----------------------------------------------------------------------===// // AllocationInst Class @@ -39,14 +39,15 @@ class ParamAttrsList; /// AllocaInst. /// class AllocationInst : public UnaryInstruction { - unsigned Alignment; protected: - AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, unsigned Align, - const std::string &Name = "", Instruction *InsertBefore = 0); - AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, unsigned Align, - const std::string &Name, BasicBlock *InsertAtEnd); + AllocationInst(const Type *Ty, Value *ArraySize, + unsigned iTy, unsigned Align, const std::string &Name = "", + Instruction *InsertBefore = 0); + AllocationInst(const Type *Ty, Value *ArraySize, + unsigned iTy, unsigned Align, const std::string &Name, + BasicBlock *InsertAtEnd); public: - // Out of line virtual method, so the vtable, etc has a home. + // Out of line virtual method, so the vtable, etc. has a home. virtual ~AllocationInst(); /// isArrayAllocation - Return true if there is an allocation size parameter @@ -54,15 +55,15 @@ public: /// bool isArrayAllocation() const; - /// getArraySize - Get the number of element allocated, for a simple + /// getArraySize - Get the number of elements allocated. For a simple /// allocation of a single element, this will return a constant 1 value. /// - inline const Value *getArraySize() const { return getOperand(0); } - inline Value *getArraySize() { return getOperand(0); } + const Value *getArraySize() const { return getOperand(0); } + Value *getArraySize() { return getOperand(0); } /// getType - Overload to return most specific pointer type /// - inline const PointerType *getType() const { + const PointerType *getType() const { return reinterpret_cast(Instruction::getType()); } @@ -74,13 +75,10 @@ public: /// getAlignment - Return the alignment of the memory that is being allocated /// by the instruction. /// - unsigned getAlignment() const { return Alignment; } - void setAlignment(unsigned Align) { - assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!"); - Alignment = Align; - } + unsigned getAlignment() const { return (1u << SubclassData) >> 1; } + void setAlignment(unsigned Align); - virtual Instruction *clone() const = 0; + virtual Instruction *clone(LLVMContext &Context) const = 0; // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const AllocationInst *) { return true; } @@ -104,28 +102,33 @@ class MallocInst : public AllocationInst { MallocInst(const MallocInst &MI); public: explicit MallocInst(const Type *Ty, Value *ArraySize = 0, - const std::string &Name = "", + const std::string &NameStr = "", Instruction *InsertBefore = 0) - : AllocationInst(Ty, ArraySize, Malloc, 0, Name, InsertBefore) {} - MallocInst(const Type *Ty, Value *ArraySize, const std::string &Name, + : AllocationInst(Ty, ArraySize, Malloc, + 0, NameStr, InsertBefore) {} + MallocInst(const Type *Ty, Value *ArraySize, + const std::string &NameStr, BasicBlock *InsertAtEnd) + : AllocationInst(Ty, ArraySize, Malloc, 0, NameStr, InsertAtEnd) {} + + MallocInst(const Type *Ty, const std::string &NameStr, + Instruction *InsertBefore = 0) + : AllocationInst(Ty, 0, Malloc, 0, NameStr, InsertBefore) {} + MallocInst(const Type *Ty, const std::string &NameStr, BasicBlock *InsertAtEnd) - : AllocationInst(Ty, ArraySize, Malloc, 0, Name, InsertAtEnd) {} + : AllocationInst(Ty, 0, Malloc, 0, NameStr, InsertAtEnd) {} - MallocInst(const Type *Ty, const std::string &Name, + MallocInst(const Type *Ty, Value *ArraySize, + unsigned Align, const std::string &NameStr, + BasicBlock *InsertAtEnd) + : AllocationInst(Ty, ArraySize, Malloc, + Align, NameStr, InsertAtEnd) {} + MallocInst(const Type *Ty, Value *ArraySize, + unsigned Align, const std::string &NameStr = "", Instruction *InsertBefore = 0) - : AllocationInst(Ty, 0, Malloc, 0, Name, InsertBefore) {} - MallocInst(const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd) - : AllocationInst(Ty, 0, Malloc, 0, Name, InsertAtEnd) {} - - MallocInst(const Type *Ty, Value *ArraySize, unsigned Align, - const std::string &Name, BasicBlock *InsertAtEnd) - : AllocationInst(Ty, ArraySize, Malloc, Align, Name, InsertAtEnd) {} - MallocInst(const Type *Ty, Value *ArraySize, unsigned Align, - const std::string &Name = "", - Instruction *InsertBefore = 0) - : AllocationInst(Ty, ArraySize, Malloc, Align, Name, InsertBefore) {} + : AllocationInst(Ty, ArraySize, + Malloc, Align, NameStr, InsertBefore) {} - virtual MallocInst *clone() const; + virtual MallocInst *clone(LLVMContext &Context) const; // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const MallocInst *) { return true; } @@ -147,28 +150,41 @@ public: class AllocaInst : public AllocationInst { AllocaInst(const AllocaInst &); public: - explicit AllocaInst(const Type *Ty, Value *ArraySize = 0, - const std::string &Name = "", + explicit AllocaInst(const Type *Ty, + Value *ArraySize = 0, + const std::string &NameStr = "", Instruction *InsertBefore = 0) - : AllocationInst(Ty, ArraySize, Alloca, 0, Name, InsertBefore) {} - AllocaInst(const Type *Ty, Value *ArraySize, const std::string &Name, + : AllocationInst(Ty, ArraySize, Alloca, + 0, NameStr, InsertBefore) {} + AllocaInst(const Type *Ty, + Value *ArraySize, const std::string &NameStr, BasicBlock *InsertAtEnd) - : AllocationInst(Ty, ArraySize, Alloca, 0, Name, InsertAtEnd) {} + : AllocationInst(Ty, ArraySize, Alloca, 0, NameStr, InsertAtEnd) {} - AllocaInst(const Type *Ty, const std::string &Name, + AllocaInst(const Type *Ty, const std::string &NameStr, Instruction *InsertBefore = 0) - : AllocationInst(Ty, 0, Alloca, 0, Name, InsertBefore) {} - AllocaInst(const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd) - : AllocationInst(Ty, 0, Alloca, 0, Name, InsertAtEnd) {} + : AllocationInst(Ty, 0, Alloca, 0, NameStr, InsertBefore) {} + AllocaInst(const Type *Ty, const std::string &NameStr, + BasicBlock *InsertAtEnd) + : AllocationInst(Ty, 0, Alloca, 0, NameStr, InsertAtEnd) {} - AllocaInst(const Type *Ty, Value *ArraySize, unsigned Align, - const std::string &Name = "", Instruction *InsertBefore = 0) - : AllocationInst(Ty, ArraySize, Alloca, Align, Name, InsertBefore) {} - AllocaInst(const Type *Ty, Value *ArraySize, unsigned Align, - const std::string &Name, BasicBlock *InsertAtEnd) - : AllocationInst(Ty, ArraySize, Alloca, Align, Name, InsertAtEnd) {} + AllocaInst(const Type *Ty, Value *ArraySize, + unsigned Align, const std::string &NameStr = "", + Instruction *InsertBefore = 0) + : AllocationInst(Ty, ArraySize, Alloca, + Align, NameStr, InsertBefore) {} + AllocaInst(const Type *Ty, Value *ArraySize, + unsigned Align, const std::string &NameStr, + BasicBlock *InsertAtEnd) + : AllocationInst(Ty, ArraySize, Alloca, + Align, NameStr, InsertAtEnd) {} + + virtual AllocaInst *clone(LLVMContext &Context) const; - virtual AllocaInst *clone() const; + /// isStaticAlloca - Return true if this alloca is in the entry block of the + /// function and is a constant size. If so, the code generator will fold it + /// into the prolog/epilog code, so it is basically free. + bool isStaticAlloca() const; // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const AllocaInst *) { return true; } @@ -193,8 +209,8 @@ public: explicit FreeInst(Value *Ptr, Instruction *InsertBefore = 0); FreeInst(Value *Ptr, BasicBlock *InsertAfter); - virtual FreeInst *clone() const; - + virtual FreeInst *clone(LLVMContext &Context) const; + // Accessor methods for consistency with other memory operations Value *getPointerOperand() { return getOperand(0); } const Value *getPointerOperand() const { return getOperand(0); } @@ -230,24 +246,24 @@ class LoadInst : public UnaryInstruction { } void AssertOK(); public: - LoadInst(Value *Ptr, const std::string &Name, Instruction *InsertBefore); - LoadInst(Value *Ptr, const std::string &Name, BasicBlock *InsertAtEnd); - LoadInst(Value *Ptr, const std::string &Name, bool isVolatile = false, - Instruction *InsertBefore = 0); - LoadInst(Value *Ptr, const std::string &Name, bool isVolatile, unsigned Align, + LoadInst(Value *Ptr, const std::string &NameStr, Instruction *InsertBefore); + LoadInst(Value *Ptr, const std::string &NameStr, BasicBlock *InsertAtEnd); + LoadInst(Value *Ptr, const std::string &NameStr, bool isVolatile = false, Instruction *InsertBefore = 0); - LoadInst(Value *Ptr, const std::string &Name, bool isVolatile, + LoadInst(Value *Ptr, const std::string &NameStr, bool isVolatile, + unsigned Align, Instruction *InsertBefore = 0); + LoadInst(Value *Ptr, const std::string &NameStr, bool isVolatile, BasicBlock *InsertAtEnd); - LoadInst(Value *Ptr, const std::string &Name, bool isVolatile, unsigned Align, + LoadInst(Value *Ptr, const std::string &NameStr, bool isVolatile, + unsigned Align, BasicBlock *InsertAtEnd); + + LoadInst(Value *Ptr, const char *NameStr, Instruction *InsertBefore); + LoadInst(Value *Ptr, const char *NameStr, BasicBlock *InsertAtEnd); + explicit LoadInst(Value *Ptr, const char *NameStr = 0, + bool isVolatile = false, Instruction *InsertBefore = 0); + LoadInst(Value *Ptr, const char *NameStr, bool isVolatile, BasicBlock *InsertAtEnd); - LoadInst(Value *Ptr, const char *Name, Instruction *InsertBefore); - LoadInst(Value *Ptr, const char *Name, BasicBlock *InsertAtEnd); - explicit LoadInst(Value *Ptr, const char *Name = 0, bool isVolatile = false, - Instruction *InsertBefore = 0); - LoadInst(Value *Ptr, const char *Name, bool isVolatile, - BasicBlock *InsertAtEnd); - /// isVolatile - Return true if this is a load from a volatile memory /// location. /// @@ -255,18 +271,18 @@ public: /// setVolatile - Specify whether this is a volatile load or not. /// - void setVolatile(bool V) { - SubclassData = (SubclassData & ~1) | (V ? 1 : 0); + void setVolatile(bool V) { + SubclassData = (SubclassData & ~1) | (V ? 1 : 0); } - virtual LoadInst *clone() const; + virtual LoadInst *clone(LLVMContext &Context) const; /// getAlignment - Return the alignment of the access that is being performed /// unsigned getAlignment() const { return (1 << (SubclassData>>1)) >> 1; } - + void setAlignment(unsigned Align); Value *getPointerOperand() { return getOperand(0); } @@ -291,20 +307,25 @@ public: /// StoreInst - an instruction for storing to memory /// class StoreInst : public Instruction { - Use Ops[2]; - - StoreInst(const StoreInst &SI) : Instruction(SI.getType(), Store, Ops, 2) { - Ops[0].init(SI.Ops[0], this); - Ops[1].init(SI.Ops[1], this); + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT + + StoreInst(const StoreInst &SI) : Instruction(SI.getType(), Store, + &Op<0>(), 2) { + Op<0>() = SI.Op<0>(); + Op<1>() = SI.Op<1>(); setVolatile(SI.isVolatile()); setAlignment(SI.getAlignment()); - + #ifndef NDEBUG AssertOK(); #endif } void AssertOK(); public: + // allocate space for exactly two operands + void *operator new(size_t s) { + return User::operator new(s, 2); + } StoreInst(Value *Val, Value *Ptr, Instruction *InsertBefore); StoreInst(Value *Val, Value *Ptr, BasicBlock *InsertAtEnd); StoreInst(Value *Val, Value *Ptr, bool isVolatile = false, @@ -323,30 +344,22 @@ public: /// setVolatile - Specify whether this is a volatile load or not. /// - void setVolatile(bool V) { - SubclassData = (SubclassData & ~1) | (V ? 1 : 0); + void setVolatile(bool V) { + SubclassData = (SubclassData & ~1) | (V ? 1 : 0); } /// Transparently provide more efficient getOperand methods. - Value *getOperand(unsigned i) const { - assert(i < 2 && "getOperand() out of range!"); - return Ops[i]; - } - void setOperand(unsigned i, Value *Val) { - assert(i < 2 && "setOperand() out of range!"); - Ops[i] = Val; - } - unsigned getNumOperands() const { return 2; } + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); /// getAlignment - Return the alignment of the access that is being performed /// unsigned getAlignment() const { return (1 << (SubclassData>>1)) >> 1; } - + void setAlignment(unsigned Align); - - virtual StoreInst *clone() const; + + virtual StoreInst *clone(LLVMContext &Context) const; Value *getPointerOperand() { return getOperand(1); } const Value *getPointerOperand() const { return getOperand(1); } @@ -362,6 +375,11 @@ public: } }; +template <> +struct OperandTraits : FixedNumOperandTraits<2> { +}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(StoreInst, Value) //===----------------------------------------------------------------------===// // GetElementPtrInst Class @@ -379,129 +397,140 @@ static inline const Type *checkType(const Type *Ty) { /// access elements of arrays and structs /// class GetElementPtrInst : public Instruction { - GetElementPtrInst(const GetElementPtrInst &GEPI) - : Instruction(reinterpret_cast(GEPI.getType()), GetElementPtr, - 0, GEPI.getNumOperands()) { - Use *OL = OperandList = new Use[NumOperands]; - Use *GEPIOL = GEPI.OperandList; - for (unsigned i = 0, E = NumOperands; i != E; ++i) - OL[i].init(GEPIOL[i], this); - } - void init(Value *Ptr, Value* const *Idx, unsigned NumIdx); - void init(Value *Ptr, Value *Idx); + GetElementPtrInst(const GetElementPtrInst &GEPI); + void init(Value *Ptr, Value* const *Idx, unsigned NumIdx, + const std::string &NameStr); + void init(Value *Ptr, Value *Idx, const std::string &NameStr); template void init(Value *Ptr, InputIterator IdxBegin, InputIterator IdxEnd, - const std::string &Name, + const std::string &NameStr, // This argument ensures that we have an iterator we can // do arithmetic on in constant time std::random_access_iterator_tag) { - typename std::iterator_traits::difference_type NumIdx = - std::distance(IdxBegin, IdxEnd); - + unsigned NumIdx = static_cast(std::distance(IdxBegin, IdxEnd)); + if (NumIdx > 0) { - // This requires that the itoerator points to contiguous memory. - init(Ptr, &*IdxBegin, NumIdx); + // This requires that the iterator points to contiguous memory. + init(Ptr, &*IdxBegin, NumIdx, NameStr); // FIXME: for the general case + // we have to build an array here } else { - init(Ptr, 0, NumIdx); + init(Ptr, 0, NumIdx, NameStr); } - - setName(Name); } /// getIndexedType - Returns the type of the element that would be loaded with /// a load instruction with the specified parameters. /// - /// A null type is returned if the indices are invalid for the specified + /// Null is returned if the indices are invalid for the specified /// pointer type. /// - static const Type *getIndexedType(const Type *Ptr, - Value* const *Idx, unsigned NumIdx, - bool AllowStructLeaf = false); - template static const Type *getIndexedType(const Type *Ptr, - InputIterator IdxBegin, + InputIterator IdxBegin, InputIterator IdxEnd, - bool AllowStructLeaf, // This argument ensures that we // have an iterator we can do // arithmetic on in constant time std::random_access_iterator_tag) { - typename std::iterator_traits::difference_type NumIdx = - std::distance(IdxBegin, IdxEnd); + unsigned NumIdx = static_cast(std::distance(IdxBegin, IdxEnd)); - if (NumIdx > 0) { + if (NumIdx > 0) // This requires that the iterator points to contiguous memory. - return(getIndexedType(Ptr, (Value *const *)&*IdxBegin, NumIdx, - AllowStructLeaf)); - } - else { - return(getIndexedType(Ptr, (Value *const*)0, NumIdx, AllowStructLeaf)); - } + return getIndexedType(Ptr, &*IdxBegin, NumIdx); + else + return getIndexedType(Ptr, (Value *const*)0, NumIdx); } -public: /// Constructors - Create a getelementptr instruction with a base pointer an /// list of indices. The first ctor can optionally insert before an existing /// instruction, the second appends the new instruction to the specified /// BasicBlock. template - GetElementPtrInst(Value *Ptr, InputIterator IdxBegin, - InputIterator IdxEnd, - const std::string &Name = "", - Instruction *InsertBefore =0) - : Instruction(PointerType::get( - checkType(getIndexedType(Ptr->getType(), - IdxBegin, IdxEnd, true)), - cast(Ptr->getType())->getAddressSpace()), - GetElementPtr, 0, 0, InsertBefore) { - init(Ptr, IdxBegin, IdxEnd, Name, - typename std::iterator_traits::iterator_category()); - } + inline GetElementPtrInst(Value *Ptr, InputIterator IdxBegin, + InputIterator IdxEnd, + unsigned Values, + const std::string &NameStr, + Instruction *InsertBefore); template - GetElementPtrInst(Value *Ptr, InputIterator IdxBegin, InputIterator IdxEnd, - const std::string &Name, BasicBlock *InsertAtEnd) - : Instruction(PointerType::get( - checkType(getIndexedType(Ptr->getType(), - IdxBegin, IdxEnd, true)), - cast(Ptr->getType())->getAddressSpace()), - GetElementPtr, 0, 0, InsertAtEnd) { - init(Ptr, IdxBegin, IdxEnd, Name, - typename std::iterator_traits::iterator_category()); - } + inline GetElementPtrInst(Value *Ptr, + InputIterator IdxBegin, InputIterator IdxEnd, + unsigned Values, + const std::string &NameStr, BasicBlock *InsertAtEnd); /// Constructors - These two constructors are convenience methods because one /// and two index getelementptr instructions are so common. + GetElementPtrInst(Value *Ptr, Value *Idx, const std::string &NameStr = "", + Instruction *InsertBefore = 0); GetElementPtrInst(Value *Ptr, Value *Idx, - const std::string &Name = "", Instruction *InsertBefore =0); - GetElementPtrInst(Value *Ptr, Value *Idx, - const std::string &Name, BasicBlock *InsertAtEnd); - ~GetElementPtrInst(); + const std::string &NameStr, BasicBlock *InsertAtEnd); +public: + template + static GetElementPtrInst *Create(Value *Ptr, InputIterator IdxBegin, + InputIterator IdxEnd, + const std::string &NameStr = "", + Instruction *InsertBefore = 0) { + typename std::iterator_traits::difference_type Values = + 1 + std::distance(IdxBegin, IdxEnd); + return new(Values) + GetElementPtrInst(Ptr, IdxBegin, IdxEnd, Values, NameStr, InsertBefore); + } + template + static GetElementPtrInst *Create(Value *Ptr, + InputIterator IdxBegin, InputIterator IdxEnd, + const std::string &NameStr, + BasicBlock *InsertAtEnd) { + typename std::iterator_traits::difference_type Values = + 1 + std::distance(IdxBegin, IdxEnd); + return new(Values) + GetElementPtrInst(Ptr, IdxBegin, IdxEnd, Values, NameStr, InsertAtEnd); + } + + /// Constructors - These two creators are convenience methods because one + /// index getelementptr instructions are so common. + static GetElementPtrInst *Create(Value *Ptr, Value *Idx, + const std::string &NameStr = "", + Instruction *InsertBefore = 0) { + return new(2) GetElementPtrInst(Ptr, Idx, NameStr, InsertBefore); + } + static GetElementPtrInst *Create(Value *Ptr, Value *Idx, + const std::string &NameStr, + BasicBlock *InsertAtEnd) { + return new(2) GetElementPtrInst(Ptr, Idx, NameStr, InsertAtEnd); + } + + virtual GetElementPtrInst *clone(LLVMContext &Context) const; - virtual GetElementPtrInst *clone() const; + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); // getType - Overload to return most specific pointer type... - inline const PointerType *getType() const { + const PointerType *getType() const { return reinterpret_cast(Instruction::getType()); } /// getIndexedType - Returns the type of the element that would be loaded with /// a load instruction with the specified parameters. /// - /// A null type is returned if the indices are invalid for the specified + /// Null is returned if the indices are invalid for the specified /// pointer type. /// template static const Type *getIndexedType(const Type *Ptr, InputIterator IdxBegin, - InputIterator IdxEnd, - bool AllowStructLeaf = false) { - return(getIndexedType(Ptr, IdxBegin, IdxEnd, AllowStructLeaf, + InputIterator IdxEnd) { + return getIndexedType(Ptr, IdxBegin, IdxEnd, typename std::iterator_traits:: - iterator_category())); - } + iterator_category()); + } + + static const Type *getIndexedType(const Type *Ptr, + Value* 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); inline op_iterator idx_begin() { return op_begin()+1; } @@ -519,24 +548,31 @@ public: return 0U; // get index for modifying correct operand } - inline unsigned getNumIndices() const { // Note: always non-negative + /// getPointerOperandType - Method to return the pointer operand as a + /// PointerType. + const PointerType *getPointerOperandType() const { + return reinterpret_cast(getPointerOperand()->getType()); + } + + + unsigned getNumIndices() const { // Note: always non-negative return getNumOperands() - 1; } - inline bool hasIndices() const { + bool hasIndices() const { return getNumOperands() > 1; } - + /// hasAllZeroIndices - Return true if all of the indices of this GEP are /// zeros. If so, the result pointer and the first operand have the same /// value, just potentially different types. bool hasAllZeroIndices() const; - + /// hasAllConstantIndices - Return true if all of the indices of this GEP are /// constant integers. If so, the result pointer and the first operand have /// a constant offset between them. bool hasAllConstantIndices() const; - + // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const GetElementPtrInst *) { return true; } @@ -548,88 +584,124 @@ public: } }; +template <> +struct OperandTraits : VariadicOperandTraits<1> { +}; + +template +GetElementPtrInst::GetElementPtrInst(Value *Ptr, + InputIterator IdxBegin, + InputIterator IdxEnd, + unsigned Values, + const std::string &NameStr, + Instruction *InsertBefore) + : Instruction(PointerType::get(checkType( + getIndexedType(Ptr->getType(), + IdxBegin, IdxEnd)), + cast(Ptr->getType()) + ->getAddressSpace()), + GetElementPtr, + OperandTraits::op_end(this) - Values, + Values, InsertBefore) { + init(Ptr, IdxBegin, IdxEnd, NameStr, + typename std::iterator_traits::iterator_category()); +} +template +GetElementPtrInst::GetElementPtrInst(Value *Ptr, + InputIterator IdxBegin, + InputIterator IdxEnd, + unsigned Values, + const std::string &NameStr, + BasicBlock *InsertAtEnd) + : Instruction(PointerType::get(checkType( + getIndexedType(Ptr->getType(), + IdxBegin, IdxEnd)), + cast(Ptr->getType()) + ->getAddressSpace()), + GetElementPtr, + OperandTraits::op_end(this) - Values, + Values, InsertAtEnd) { + init(Ptr, IdxBegin, IdxEnd, NameStr, + typename std::iterator_traits::iterator_category()); +} + + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrInst, Value) + + //===----------------------------------------------------------------------===// // ICmpInst Class //===----------------------------------------------------------------------===// /// This instruction compares its operands according to the predicate given -/// to the constructor. It only operates on integers, pointers, or packed -/// vectors of integrals. The two operands must be the same type. +/// to the constructor. It only operates on integers or pointers. The operands +/// must be identical types. /// @brief Represent an integer comparison operator. class ICmpInst: public CmpInst { public: - /// This enumeration lists the possible predicates for the ICmpInst. The - /// values in the range 0-31 are reserved for FCmpInst while values in the - /// range 32-64 are reserved for ICmpInst. This is necessary to ensure the - /// predicate values are not overlapping between the classes. - enum Predicate { - ICMP_EQ = 32, ///< equal - ICMP_NE = 33, ///< not equal - ICMP_UGT = 34, ///< unsigned greater than - ICMP_UGE = 35, ///< unsigned greater or equal - ICMP_ULT = 36, ///< unsigned less than - ICMP_ULE = 37, ///< unsigned less or equal - ICMP_SGT = 38, ///< signed greater than - ICMP_SGE = 39, ///< signed greater or equal - ICMP_SLT = 40, ///< signed less than - ICMP_SLE = 41, ///< signed less or equal - FIRST_ICMP_PREDICATE = ICMP_EQ, - LAST_ICMP_PREDICATE = ICMP_SLE, - BAD_ICMP_PREDICATE = ICMP_SLE + 1 - }; - /// @brief Constructor with insert-before-instruction semantics. ICmpInst( + Instruction *InsertBefore, ///< Where to insert Predicate pred, ///< The predicate to use for the comparison Value *LHS, ///< The left-hand-side of the expression Value *RHS, ///< The right-hand-side of the expression - const std::string &Name = "", ///< Name of the instruction - Instruction *InsertBefore = 0 ///< Where to insert - ) : CmpInst(Instruction::ICmp, pred, LHS, RHS, Name, InsertBefore) { + const std::string &NameStr = "" ///< Name of the instruction + ) : CmpInst(InsertBefore->getParent()->getContext()-> + makeCmpResultType(LHS->getType()), + Instruction::ICmp, pred, LHS, RHS, NameStr, + InsertBefore) { + assert(pred >= CmpInst::FIRST_ICMP_PREDICATE && + pred <= CmpInst::LAST_ICMP_PREDICATE && + "Invalid ICmp predicate value"); + assert(getOperand(0)->getType() == getOperand(1)->getType() && + "Both operands to ICmp instruction are not of the same type!"); + // Check that the operands are the right type + assert((getOperand(0)->getType()->isIntOrIntVector() || + isa(getOperand(0)->getType())) && + "Invalid operand types for ICmp instruction"); } - /// @brief Constructor with insert-at-block-end semantics. + /// @brief Constructor with insert-at-end semantics. ICmpInst( + BasicBlock &InsertAtEnd, ///< Block to insert into. + Predicate pred, ///< The predicate to use for the comparison + Value *LHS, ///< The left-hand-side of the expression + Value *RHS, ///< The right-hand-side of the expression + const std::string &NameStr = "" ///< Name of the instruction + ) : CmpInst(InsertAtEnd.getContext()->makeCmpResultType(LHS->getType()), + Instruction::ICmp, pred, LHS, RHS, NameStr, + &InsertAtEnd) { + assert(pred >= CmpInst::FIRST_ICMP_PREDICATE && + pred <= CmpInst::LAST_ICMP_PREDICATE && + "Invalid ICmp predicate value"); + assert(getOperand(0)->getType() == getOperand(1)->getType() && + "Both operands to ICmp instruction are not of the same type!"); + // Check that the operands are the right type + assert((getOperand(0)->getType()->isIntOrIntVector() || + isa(getOperand(0)->getType())) && + "Invalid operand types for ICmp instruction"); + } + + /// @brief Constructor with no-insertion semantics + ICmpInst( + LLVMContext &Context, ///< Context to construct within Predicate pred, ///< The predicate to use for the comparison Value *LHS, ///< The left-hand-side of the expression Value *RHS, ///< The right-hand-side of the expression - const std::string &Name, ///< Name of the instruction - BasicBlock *InsertAtEnd ///< Block to insert into. - ) : CmpInst(Instruction::ICmp, pred, LHS, RHS, Name, InsertAtEnd) { - } - - /// @brief Return the predicate for this instruction. - Predicate getPredicate() const { return Predicate(SubclassData); } - - /// @brief Set the predicate for this instruction to the specified value. - void setPredicate(Predicate P) { SubclassData = P; } - - /// For example, EQ -> NE, UGT -> ULE, SLT -> SGE, etc. - /// @returns the inverse predicate for the instruction's current predicate. - /// @brief Return the inverse of the instruction's predicate. - Predicate getInversePredicate() const { - return getInversePredicate(getPredicate()); + const std::string &NameStr = "" ///< Name of the instruction + ) : CmpInst(Context.makeCmpResultType(LHS->getType()), + Instruction::ICmp, pred, LHS, RHS, NameStr) { + assert(pred >= CmpInst::FIRST_ICMP_PREDICATE && + pred <= CmpInst::LAST_ICMP_PREDICATE && + "Invalid ICmp predicate value"); + assert(getOperand(0)->getType() == getOperand(1)->getType() && + "Both operands to ICmp instruction are not of the same type!"); + // Check that the operands are the right type + assert((getOperand(0)->getType()->isIntOrIntVector() || + isa(getOperand(0)->getType())) && + "Invalid operand types for ICmp instruction"); } - /// For example, EQ -> NE, UGT -> ULE, SLT -> SGE, etc. - /// @returns the inverse predicate for predicate provided in \p pred. - /// @brief Return the inverse of a given predicate - static Predicate getInversePredicate(Predicate pred); - - /// For example, EQ->EQ, SLE->SGE, ULT->UGT, etc. - /// @returns the predicate that would be the result of exchanging the two - /// operands of the ICmpInst instruction without changing the result - /// produced. - /// @brief Return the predicate as if the operands were swapped - Predicate getSwappedPredicate() const { - return getSwappedPredicate(getPredicate()); - } - - /// This is a static version that you can use without an instruction - /// available. - /// @brief Return the predicate as if the operands were swapped. - static Predicate getSwappedPredicate(Predicate pred); - /// For example, EQ->EQ, SLE->SLE, UGT->SGT, etc. /// @returns the predicate that would be the result if the operand were /// regarded as signed. @@ -642,12 +714,24 @@ public: /// @brief Return the signed version of the predicate. static Predicate getSignedPredicate(Predicate pred); + /// For example, EQ->EQ, SLE->ULE, UGT->UGT, etc. + /// @returns the predicate that would be the result if the operand were + /// regarded as unsigned. + /// @brief Return the unsigned version of the predicate + Predicate getUnsignedPredicate() const { + return getUnsignedPredicate(getPredicate()); + } + + /// This is a static version that you can use without an instruction. + /// @brief Return the unsigned version of the predicate. + static Predicate getUnsignedPredicate(Predicate pred); + /// isEquality - Return true if this predicate is either EQ or NE. This also /// tests for commutativity. static bool isEquality(Predicate P) { return P == ICMP_EQ || P == ICMP_NE; } - + /// isEquality - Return true if this predicate is either EQ or NE. This also /// tests for commutativity. bool isEquality() const { @@ -658,18 +742,18 @@ public: /// @brief Determine if this relation is commutative. bool isCommutative() const { return isEquality(); } - /// isRelational - Return true if the predicate is relational (not EQ or NE). + /// isRelational - Return true if the predicate is relational (not EQ or NE). /// bool isRelational() const { return !isEquality(); } - /// isRelational - Return true if the predicate is relational (not EQ or NE). + /// isRelational - Return true if the predicate is relational (not EQ or NE). /// static bool isRelational(Predicate P) { return !isEquality(P); } - + /// @returns true if the predicate of this ICmpInst is signed, false otherwise /// @brief Determine if this instruction's predicate is signed. bool isSignedPredicate() const { return isSignedPredicate(getPredicate()); } @@ -678,21 +762,37 @@ public: /// @brief Determine if the predicate is signed. static bool isSignedPredicate(Predicate pred); - /// Initialize a set of values that all satisfy the predicate with C. + /// @returns true if the specified compare predicate is + /// true when both operands are equal... + /// @brief Determine if the icmp is true when both operands are equal + static bool isTrueWhenEqual(ICmpInst::Predicate pred) { + return pred == ICmpInst::ICMP_EQ || pred == ICmpInst::ICMP_UGE || + pred == ICmpInst::ICMP_SGE || pred == ICmpInst::ICMP_ULE || + pred == ICmpInst::ICMP_SLE; + } + + /// @returns true if the specified compare instruction is + /// true when both operands are equal... + /// @brief Determine if the ICmpInst returns true when both operands are equal + bool isTrueWhenEqual() { + return isTrueWhenEqual(getPredicate()); + } + + /// Initialize a set of values that all satisfy the predicate with C. /// @brief Make a ConstantRange for a relation with a constant value. static ConstantRange makeConstantRange(Predicate pred, const APInt &C); /// Exchange the two operands to this instruction in such a way that it does /// not modify the semantics of the instruction. The predicate value may be /// changed to retain the same result if the predicate is order dependent - /// (e.g. ult). + /// (e.g. ult). /// @brief Swap operands and adjust predicate. void swapOperands() { SubclassData = getSwappedPredicate(); - std::swap(Ops[0], Ops[1]); + Op<0>().swap(Op<1>()); } - virtual ICmpInst *clone() const; + virtual ICmpInst *clone(LLVMContext &Context) const; // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const ICmpInst *) { return true; } @@ -702,6 +802,7 @@ public: static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + }; //===----------------------------------------------------------------------===// @@ -709,114 +810,100 @@ public: //===----------------------------------------------------------------------===// /// This instruction compares its operands according to the predicate given -/// to the constructor. It only operates on floating point values or packed +/// to the constructor. It only operates on floating point values or packed /// vectors of floating point values. The operands must be identical types. /// @brief Represents a floating point comparison operator. class FCmpInst: public CmpInst { public: - /// This enumeration lists the possible predicates for the FCmpInst. Values - /// in the range 0-31 are reserved for FCmpInst. - enum Predicate { - // Opcode U L G E Intuitive operation - FCMP_FALSE = 0, ///< 0 0 0 0 Always false (always folded) - FCMP_OEQ = 1, ///< 0 0 0 1 True if ordered and equal - FCMP_OGT = 2, ///< 0 0 1 0 True if ordered and greater than - FCMP_OGE = 3, ///< 0 0 1 1 True if ordered and greater than or equal - FCMP_OLT = 4, ///< 0 1 0 0 True if ordered and less than - FCMP_OLE = 5, ///< 0 1 0 1 True if ordered and less than or equal - FCMP_ONE = 6, ///< 0 1 1 0 True if ordered and operands are unequal - FCMP_ORD = 7, ///< 0 1 1 1 True if ordered (no nans) - FCMP_UNO = 8, ///< 1 0 0 0 True if unordered: isnan(X) | isnan(Y) - FCMP_UEQ = 9, ///< 1 0 0 1 True if unordered or equal - FCMP_UGT =10, ///< 1 0 1 0 True if unordered or greater than - FCMP_UGE =11, ///< 1 0 1 1 True if unordered, greater than, or equal - FCMP_ULT =12, ///< 1 1 0 0 True if unordered or less than - FCMP_ULE =13, ///< 1 1 0 1 True if unordered, less than, or equal - FCMP_UNE =14, ///< 1 1 1 0 True if unordered or not equal - FCMP_TRUE =15, ///< 1 1 1 1 Always true (always folded) - FIRST_FCMP_PREDICATE = FCMP_FALSE, - LAST_FCMP_PREDICATE = FCMP_TRUE, - BAD_FCMP_PREDICATE = FCMP_TRUE + 1 - }; - /// @brief Constructor with insert-before-instruction semantics. FCmpInst( + Instruction *InsertBefore, ///< Where to insert Predicate pred, ///< The predicate to use for the comparison Value *LHS, ///< The left-hand-side of the expression Value *RHS, ///< The right-hand-side of the expression - const std::string &Name = "", ///< Name of the instruction - Instruction *InsertBefore = 0 ///< Where to insert - ) : CmpInst(Instruction::FCmp, pred, LHS, RHS, Name, InsertBefore) { + const std::string &NameStr = "" ///< Name of the instruction + ) : CmpInst(InsertBefore->getParent()->getContext()-> + makeCmpResultType(LHS->getType()), + Instruction::FCmp, pred, LHS, RHS, NameStr, + InsertBefore) { + assert(pred <= FCmpInst::LAST_FCMP_PREDICATE && + "Invalid FCmp predicate value"); + assert(getOperand(0)->getType() == getOperand(1)->getType() && + "Both operands to FCmp instruction are not of the same type!"); + // Check that the operands are the right type + assert(getOperand(0)->getType()->isFPOrFPVector() && + "Invalid operand types for FCmp instruction"); } - - /// @brief Constructor with insert-at-block-end semantics. + + /// @brief Constructor with insert-at-end semantics. + FCmpInst( + BasicBlock &InsertAtEnd, ///< Block to insert into. + Predicate pred, ///< The predicate to use for the comparison + Value *LHS, ///< The left-hand-side of the expression + Value *RHS, ///< The right-hand-side of the expression + const std::string &NameStr = "" ///< Name of the instruction + ) : CmpInst(InsertAtEnd.getContext()->makeCmpResultType(LHS->getType()), + Instruction::FCmp, pred, LHS, RHS, NameStr, + &InsertAtEnd) { + assert(pred <= FCmpInst::LAST_FCMP_PREDICATE && + "Invalid FCmp predicate value"); + assert(getOperand(0)->getType() == getOperand(1)->getType() && + "Both operands to FCmp instruction are not of the same type!"); + // Check that the operands are the right type + assert(getOperand(0)->getType()->isFPOrFPVector() && + "Invalid operand types for FCmp instruction"); + } + + /// @brief Constructor with no-insertion semantics FCmpInst( + LLVMContext &Context, ///< Context to build in Predicate pred, ///< The predicate to use for the comparison Value *LHS, ///< The left-hand-side of the expression Value *RHS, ///< The right-hand-side of the expression - const std::string &Name, ///< Name of the instruction - BasicBlock *InsertAtEnd ///< Block to insert into. - ) : CmpInst(Instruction::FCmp, pred, LHS, RHS, Name, InsertAtEnd) { - } - - /// @brief Return the predicate for this instruction. - Predicate getPredicate() const { return Predicate(SubclassData); } - - /// @brief Set the predicate for this instruction to the specified value. - void setPredicate(Predicate P) { SubclassData = P; } - - /// For example, OEQ -> UNE, UGT -> OLE, OLT -> UGE, etc. - /// @returns the inverse predicate for the instructions current predicate. - /// @brief Return the inverse of the predicate - Predicate getInversePredicate() const { - return getInversePredicate(getPredicate()); - } - - /// For example, OEQ -> UNE, UGT -> OLE, OLT -> UGE, etc. - /// @returns the inverse predicate for \p pred. - /// @brief Return the inverse of a given predicate - static Predicate getInversePredicate(Predicate pred); - - /// For example, OEQ->OEQ, ULE->UGE, OLT->OGT, etc. - /// @returns the predicate that would be the result of exchanging the two - /// operands of the ICmpInst instruction without changing the result - /// produced. - /// @brief Return the predicate as if the operands were swapped - Predicate getSwappedPredicate() const { - return getSwappedPredicate(getPredicate()); + const std::string &NameStr = "" ///< Name of the instruction + ) : CmpInst(Context.makeCmpResultType(LHS->getType()), + Instruction::FCmp, pred, LHS, RHS, NameStr) { + assert(pred <= FCmpInst::LAST_FCMP_PREDICATE && + "Invalid FCmp predicate value"); + assert(getOperand(0)->getType() == getOperand(1)->getType() && + "Both operands to FCmp instruction are not of the same type!"); + // Check that the operands are the right type + assert(getOperand(0)->getType()->isFPOrFPVector() && + "Invalid operand types for FCmp instruction"); } - /// This is a static version that you can use without an instruction - /// available. - /// @brief Return the predicate as if the operands were swapped. - static Predicate getSwappedPredicate(Predicate Opcode); - - /// This also tests for commutativity. If isEquality() returns true then - /// the predicate is also commutative. Only the equality predicates are - /// commutative. /// @returns true if the predicate of this instruction is EQ or NE. /// @brief Determine if this is an equality predicate. bool isEquality() const { return SubclassData == FCMP_OEQ || SubclassData == FCMP_ONE || SubclassData == FCMP_UEQ || SubclassData == FCMP_UNE; } - bool isCommutative() const { return isEquality(); } - /// @returns true if the predicate is relational (not EQ or NE). + /// @returns true if the predicate of this instruction is commutative. + /// @brief Determine if this is a commutative predicate. + bool isCommutative() const { + return isEquality() || + SubclassData == FCMP_FALSE || + SubclassData == FCMP_TRUE || + SubclassData == FCMP_ORD || + SubclassData == FCMP_UNO; + } + + /// @returns true if the predicate is relational (not EQ or NE). /// @brief Determine if this a relational predicate. bool isRelational() const { return !isEquality(); } /// Exchange the two operands to this instruction in such a way that it does /// not modify the semantics of the instruction. The predicate value may be /// changed to retain the same result if the predicate is order dependent - /// (e.g. ult). + /// (e.g. ult). /// @brief Swap operands and adjust predicate. void swapOperands() { SubclassData = getSwappedPredicate(); - std::swap(Ops[0], Ops[1]); + Op<0>().swap(Op<1>()); } - virtual FCmpInst *clone() const; + virtual FCmpInst *clone(LLVMContext &Context) const; /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const FCmpInst *) { return true; } @@ -826,6 +913,7 @@ public: static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + }; //===----------------------------------------------------------------------===// @@ -838,7 +926,7 @@ public: /// class CallInst : public Instruction { - const ParamAttrsList *ParamAttrs; ///< parameter attributes for call + AttrListPtr AttributeList; ///< parameter attributes for call CallInst(const CallInst &CI); void init(Value *Func, Value* const *Params, unsigned NumParams); void init(Value *Func, Value *Actual1, Value *Actual2); @@ -847,18 +935,17 @@ class CallInst : public Instruction { template void init(Value *Func, InputIterator ArgBegin, InputIterator ArgEnd, - const std::string &Name, + const std::string &NameStr, // This argument ensures that we have an iterator we can // do arithmetic on in constant time std::random_access_iterator_tag) { unsigned NumArgs = (unsigned)std::distance(ArgBegin, ArgEnd); - + // This requires that the iterator points to contiguous memory. init(Func, NumArgs ? &*ArgBegin : 0, NumArgs); - setName(Name); + setName(NameStr); } -public: /// Construct a CallInst given a range of arguments. InputIterator /// must be a random-access iterator pointing to contiguous storage /// (e.g. a std::vector<>::iterator). Checks are made for @@ -867,13 +954,7 @@ public: /// @brief Construct a CallInst from a range of arguments template CallInst(Value *Func, InputIterator ArgBegin, InputIterator ArgEnd, - const std::string &Name = "", Instruction *InsertBefore = 0) - : Instruction(cast(cast(Func->getType()) - ->getElementType())->getReturnType(), - Instruction::Call, 0, 0, InsertBefore) { - init(Func, ArgBegin, ArgEnd, Name, - typename std::iterator_traits::iterator_category()); - } + const std::string &NameStr, Instruction *InsertBefore); /// Construct a CallInst given a range of arguments. InputIterator /// must be a random-access iterator pointing to contiguous storage @@ -882,31 +963,62 @@ public: /// incur runtime overhead. /// @brief Construct a CallInst from a range of arguments template - CallInst(Value *Func, InputIterator ArgBegin, InputIterator ArgEnd, - const std::string &Name, BasicBlock *InsertAtEnd) - : Instruction(cast(cast(Func->getType()) - ->getElementType())->getReturnType(), - Instruction::Call, 0, 0, InsertAtEnd) { - init(Func, ArgBegin, ArgEnd, Name, - typename std::iterator_traits::iterator_category()); - } + inline CallInst(Value *Func, InputIterator ArgBegin, InputIterator ArgEnd, + const std::string &NameStr, BasicBlock *InsertAtEnd); - CallInst(Value *F, Value *Actual, const std::string& Name = "", - Instruction *InsertBefore = 0); - CallInst(Value *F, Value *Actual, const std::string& Name, + CallInst(Value *F, Value *Actual, const std::string& NameStr, + Instruction *InsertBefore); + CallInst(Value *F, Value *Actual, const std::string& NameStr, BasicBlock *InsertAtEnd); - explicit CallInst(Value *F, const std::string &Name = "", - Instruction *InsertBefore = 0); - CallInst(Value *F, const std::string &Name, BasicBlock *InsertAtEnd); + explicit CallInst(Value *F, const std::string &NameStr, + Instruction *InsertBefore); + CallInst(Value *F, const std::string &NameStr, BasicBlock *InsertAtEnd); +public: + template + static CallInst *Create(Value *Func, + InputIterator ArgBegin, InputIterator ArgEnd, + const std::string &NameStr = "", + Instruction *InsertBefore = 0) { + return new((unsigned)(ArgEnd - ArgBegin + 1)) + CallInst(Func, ArgBegin, ArgEnd, NameStr, InsertBefore); + } + template + static CallInst *Create(Value *Func, + InputIterator ArgBegin, InputIterator ArgEnd, + const std::string &NameStr, BasicBlock *InsertAtEnd) { + return new((unsigned)(ArgEnd - ArgBegin + 1)) + CallInst(Func, ArgBegin, ArgEnd, NameStr, InsertAtEnd); + } + static CallInst *Create(Value *F, Value *Actual, + const std::string& NameStr = "", + Instruction *InsertBefore = 0) { + return new(2) CallInst(F, Actual, NameStr, InsertBefore); + } + static CallInst *Create(Value *F, Value *Actual, const std::string& NameStr, + BasicBlock *InsertAtEnd) { + return new(2) CallInst(F, Actual, NameStr, InsertAtEnd); + } + static CallInst *Create(Value *F, const std::string &NameStr = "", + Instruction *InsertBefore = 0) { + return new(1) CallInst(F, NameStr, InsertBefore); + } + static CallInst *Create(Value *F, const std::string &NameStr, + BasicBlock *InsertAtEnd) { + return new(1) CallInst(F, NameStr, InsertAtEnd); + } + ~CallInst(); - virtual CallInst *clone() const; - bool isTailCall() const { return SubclassData & 1; } - void setTailCall(bool isTailCall = true) { - SubclassData = (SubclassData & ~1) | unsigned(isTailCall); + void setTailCall(bool isTC = true) { + SubclassData = (SubclassData & ~1) | unsigned(isTC); } + virtual CallInst *clone(LLVMContext &Context) const; + + /// Provide fast operand accessors + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + /// getCallingConv/setCallingConv - Get or set the calling convention of this /// function call. unsigned getCallingConv() const { return SubclassData >> 1; } @@ -914,50 +1026,87 @@ public: SubclassData = (SubclassData & 1) | (CC << 1); } - /// Obtains a pointer to the ParamAttrsList object which holds the - /// parameter attributes information, if any. - /// @returns 0 if no attributes have been set. - /// @brief Get the parameter attributes. - const ParamAttrsList *getParamAttrs() const { return ParamAttrs; } + /// getAttributes - Return the parameter attributes for this call. + /// + const AttrListPtr &getAttributes() const { return AttributeList; } + + /// setAttributes - Set the parameter attributes for this call. + /// + void setAttributes(const AttrListPtr &Attrs) { AttributeList = Attrs; } + + /// addAttribute - adds the attribute to the list of attributes. + void addAttribute(unsigned i, Attributes attr); - /// Sets the parameter attributes for this CallInst. To construct a - /// ParamAttrsList, see ParameterAttributes.h - /// @brief Set the parameter attributes. - void setParamAttrs(const ParamAttrsList *attrs); + /// removeAttribute - removes the attribute from the list of attributes. + void removeAttribute(unsigned i, Attributes attr); /// @brief Determine whether the call or the callee has the given attribute. - bool paramHasAttr(uint16_t i, unsigned attr) const; + bool paramHasAttr(unsigned i, Attributes attr) const; + + /// @brief Extract the alignment for a call or parameter (0=unknown). + unsigned getParamAlignment(unsigned i) const { + return AttributeList.getParamAlignment(i); + } /// @brief Determine if the call does not access memory. - bool doesNotAccessMemory() const; - + bool doesNotAccessMemory() const { + return paramHasAttr(~0, Attribute::ReadNone); + } + void setDoesNotAccessMemory(bool NotAccessMemory = true) { + if (NotAccessMemory) addAttribute(~0, Attribute::ReadNone); + else removeAttribute(~0, Attribute::ReadNone); + } + /// @brief Determine if the call does not access or only reads memory. - bool onlyReadsMemory() const; - + bool onlyReadsMemory() const { + return doesNotAccessMemory() || paramHasAttr(~0, Attribute::ReadOnly); + } + void setOnlyReadsMemory(bool OnlyReadsMemory = true) { + if (OnlyReadsMemory) addAttribute(~0, Attribute::ReadOnly); + else removeAttribute(~0, Attribute::ReadOnly | Attribute::ReadNone); + } + /// @brief Determine if the call cannot return. - bool doesNotReturn() const; + bool doesNotReturn() const { + return paramHasAttr(~0, Attribute::NoReturn); + } + void setDoesNotReturn(bool DoesNotReturn = true) { + if (DoesNotReturn) addAttribute(~0, Attribute::NoReturn); + else removeAttribute(~0, Attribute::NoReturn); + } /// @brief Determine if the call cannot unwind. - bool doesNotThrow() const; - void setDoesNotThrow(bool doesNotThrow = true); + bool doesNotThrow() const { + return paramHasAttr(~0, Attribute::NoUnwind); + } + void setDoesNotThrow(bool DoesNotThrow = true) { + if (DoesNotThrow) addAttribute(~0, Attribute::NoUnwind); + else removeAttribute(~0, Attribute::NoUnwind); + } - /// @brief Determine if the call returns a structure. - bool isStructReturn() const; + /// @brief Determine if the call returns a structure through first + /// pointer argument. + bool hasStructRetAttr() const { + // Be friendly and also check the callee. + return paramHasAttr(1, Attribute::StructRet); + } /// @brief Determine if any call argument is an aggregate passed by value. - bool hasByValArgument() const; + bool hasByValArgument() const { + return AttributeList.hasAttrSomewhere(Attribute::ByVal); + } - /// getCalledFunction - Return the function being called by this instruction - /// if it is a direct call. If it is a call through a function pointer, - /// return null. + /// getCalledFunction - Return the function called, or null if this is an + /// indirect function invocation. + /// Function *getCalledFunction() const { - return dyn_cast(getOperand(0)); + return dyn_cast(Op<0>()); } - /// getCalledValue - Get a pointer to the function that is invoked by this + /// getCalledValue - Get a pointer to the function that is invoked by this /// instruction - inline const Value *getCalledValue() const { return getOperand(0); } - inline Value *getCalledValue() { return getOperand(0); } + const Value *getCalledValue() const { return Op<0>(); } + Value *getCalledValue() { return Op<0>(); } // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const CallInst *) { return true; } @@ -969,6 +1118,36 @@ public: } }; +template <> +struct OperandTraits : VariadicOperandTraits<1> { +}; + +template +CallInst::CallInst(Value *Func, InputIterator ArgBegin, InputIterator ArgEnd, + const std::string &NameStr, BasicBlock *InsertAtEnd) + : Instruction(cast(cast(Func->getType()) + ->getElementType())->getReturnType(), + Instruction::Call, + OperandTraits::op_end(this) - (ArgEnd - ArgBegin + 1), + (unsigned)(ArgEnd - ArgBegin + 1), InsertAtEnd) { + init(Func, ArgBegin, ArgEnd, NameStr, + typename std::iterator_traits::iterator_category()); +} + +template +CallInst::CallInst(Value *Func, InputIterator ArgBegin, InputIterator ArgEnd, + const std::string &NameStr, Instruction *InsertBefore) + : Instruction(cast(cast(Func->getType()) + ->getElementType())->getReturnType(), + Instruction::Call, + OperandTraits::op_end(this) - (ArgEnd - ArgBegin + 1), + (unsigned)(ArgEnd - ArgBegin + 1), InsertBefore) { + init(Func, ArgBegin, ArgEnd, NameStr, + typename std::iterator_traits::iterator_category()); +} + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CallInst, Value) + //===----------------------------------------------------------------------===// // SelectInst Class //===----------------------------------------------------------------------===// @@ -976,52 +1155,59 @@ public: /// SelectInst - This class represents the LLVM 'select' instruction. /// class SelectInst : public Instruction { - Use Ops[3]; - void init(Value *C, Value *S1, Value *S2) { - Ops[0].init(C, this); - Ops[1].init(S1, this); - Ops[2].init(S2, this); + assert(!areInvalidOperands(C, S1, S2) && "Invalid operands for select"); + Op<0>() = C; + Op<1>() = S1; + Op<2>() = S2; } SelectInst(const SelectInst &SI) - : Instruction(SI.getType(), SI.getOpcode(), Ops, 3) { - init(SI.Ops[0], SI.Ops[1], SI.Ops[2]); + : Instruction(SI.getType(), SI.getOpcode(), &Op<0>(), 3) { + init(SI.Op<0>(), SI.Op<1>(), SI.Op<2>()); } -public: - SelectInst(Value *C, Value *S1, Value *S2, const std::string &Name = "", - Instruction *InsertBefore = 0) - : Instruction(S1->getType(), Instruction::Select, Ops, 3, InsertBefore) { + SelectInst(Value *C, Value *S1, Value *S2, const std::string &NameStr, + Instruction *InsertBefore) + : Instruction(S1->getType(), Instruction::Select, + &Op<0>(), 3, InsertBefore) { init(C, S1, S2); - setName(Name); + setName(NameStr); } - SelectInst(Value *C, Value *S1, Value *S2, const std::string &Name, + SelectInst(Value *C, Value *S1, Value *S2, const std::string &NameStr, BasicBlock *InsertAtEnd) - : Instruction(S1->getType(), Instruction::Select, Ops, 3, InsertAtEnd) { + : Instruction(S1->getType(), Instruction::Select, + &Op<0>(), 3, InsertAtEnd) { init(C, S1, S2); - setName(Name); + setName(NameStr); } +public: + static SelectInst *Create(Value *C, Value *S1, Value *S2, + const std::string &NameStr = "", + Instruction *InsertBefore = 0) { + return new(3) SelectInst(C, S1, S2, NameStr, InsertBefore); + } + static SelectInst *Create(Value *C, Value *S1, Value *S2, + const std::string &NameStr, + BasicBlock *InsertAtEnd) { + return new(3) SelectInst(C, S1, S2, NameStr, InsertAtEnd); + } + + Value *getCondition() const { return Op<0>(); } + Value *getTrueValue() const { return Op<1>(); } + Value *getFalseValue() const { return Op<2>(); } - Value *getCondition() const { return Ops[0]; } - Value *getTrueValue() const { return Ops[1]; } - Value *getFalseValue() const { return Ops[2]; } + /// areInvalidOperands - Return a string if the specified operands are invalid + /// for a select operation, otherwise return null. + static const char *areInvalidOperands(Value *Cond, Value *True, Value *False); /// Transparently provide more efficient getOperand methods. - Value *getOperand(unsigned i) const { - assert(i < 3 && "getOperand() out of range!"); - return Ops[i]; - } - void setOperand(unsigned i, Value *Val) { - assert(i < 3 && "setOperand() out of range!"); - Ops[i] = Val; - } - unsigned getNumOperands() const { return 3; } + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); OtherOps getOpcode() const { return static_cast(Instruction::getOpcode()); } - virtual SelectInst *clone() const; + virtual SelectInst *clone(LLVMContext &Context) const; // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const SelectInst *) { return true; } @@ -1033,6 +1219,12 @@ public: } }; +template <> +struct OperandTraits : FixedNumOperandTraits<3> { +}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectInst, Value) + //===----------------------------------------------------------------------===// // VAArgInst Class //===----------------------------------------------------------------------===// @@ -1044,18 +1236,18 @@ class VAArgInst : public UnaryInstruction { VAArgInst(const VAArgInst &VAA) : UnaryInstruction(VAA.getType(), VAArg, VAA.getOperand(0)) {} public: - VAArgInst(Value *List, const Type *Ty, const std::string &Name = "", + VAArgInst(Value *List, const Type *Ty, const std::string &NameStr = "", Instruction *InsertBefore = 0) : UnaryInstruction(Ty, VAArg, List, InsertBefore) { - setName(Name); + setName(NameStr); } - VAArgInst(Value *List, const Type *Ty, const std::string &Name, + VAArgInst(Value *List, const Type *Ty, const std::string &NameStr, BasicBlock *InsertAtEnd) : UnaryInstruction(Ty, VAArg, List, InsertAtEnd) { - setName(Name); + setName(NameStr); } - virtual VAArgInst *clone() const; + virtual VAArgInst *clone(LLVMContext &Context) const; // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const VAArgInst *) { return true; } @@ -1075,39 +1267,30 @@ public: /// element from a VectorType value /// class ExtractElementInst : public Instruction { - Use Ops[2]; ExtractElementInst(const ExtractElementInst &EE) : - Instruction(EE.getType(), ExtractElement, Ops, 2) { - Ops[0].init(EE.Ops[0], this); - Ops[1].init(EE.Ops[1], this); + Instruction(EE.getType(), ExtractElement, &Op<0>(), 2) { + Op<0>() = EE.Op<0>(); + Op<1>() = EE.Op<1>(); } public: - ExtractElementInst(Value *Vec, Value *Idx, const std::string &Name = "", - Instruction *InsertBefore = 0); - ExtractElementInst(Value *Vec, unsigned Idx, const std::string &Name = "", + // allocate space for exactly two operands + void *operator new(size_t s) { + return User::operator new(s, 2); // FIXME: "unsigned Idx" forms of ctor? + } + ExtractElementInst(Value *Vec, Value *Idx, const std::string &NameStr = "", Instruction *InsertBefore = 0); - ExtractElementInst(Value *Vec, Value *Idx, const std::string &Name, - BasicBlock *InsertAtEnd); - ExtractElementInst(Value *Vec, unsigned Idx, const std::string &Name, + ExtractElementInst(Value *Vec, Value *Idx, const std::string &NameStr, BasicBlock *InsertAtEnd); /// isValidOperands - Return true if an extractelement instruction can be /// formed with the specified operands. static bool isValidOperands(const Value *Vec, const Value *Idx); - virtual ExtractElementInst *clone() const; + virtual ExtractElementInst *clone(LLVMContext &Context) const; /// Transparently provide more efficient getOperand methods. - Value *getOperand(unsigned i) const { - assert(i < 2 && "getOperand() out of range!"); - return Ops[i]; - } - void setOperand(unsigned i, Value *Val) { - assert(i < 2 && "setOperand() out of range!"); - Ops[i] = Val; - } - unsigned getNumOperands() const { return 2; } + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const ExtractElementInst *) { return true; } @@ -1119,6 +1302,12 @@ public: } }; +template <> +struct OperandTraits : FixedNumOperandTraits<2> { +}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractElementInst, Value) + //===----------------------------------------------------------------------===// // InsertElementInst Class //===----------------------------------------------------------------------===// @@ -1127,41 +1316,42 @@ public: /// element into a VectorType value /// class InsertElementInst : public Instruction { - Use Ops[3]; InsertElementInst(const InsertElementInst &IE); -public: InsertElementInst(Value *Vec, Value *NewElt, Value *Idx, - const std::string &Name = "",Instruction *InsertBefore = 0); - InsertElementInst(Value *Vec, Value *NewElt, unsigned Idx, - const std::string &Name = "",Instruction *InsertBefore = 0); + const std::string &NameStr = "", + Instruction *InsertBefore = 0); InsertElementInst(Value *Vec, Value *NewElt, Value *Idx, - const std::string &Name, BasicBlock *InsertAtEnd); - InsertElementInst(Value *Vec, Value *NewElt, unsigned Idx, - const std::string &Name, BasicBlock *InsertAtEnd); + const std::string &NameStr, BasicBlock *InsertAtEnd); +public: + static InsertElementInst *Create(const InsertElementInst &IE) { + return new(IE.getNumOperands()) InsertElementInst(IE); + } + static InsertElementInst *Create(Value *Vec, Value *NewElt, Value *Idx, + const std::string &NameStr = "", + Instruction *InsertBefore = 0) { + return new(3) InsertElementInst(Vec, NewElt, Idx, NameStr, InsertBefore); + } + static InsertElementInst *Create(Value *Vec, Value *NewElt, Value *Idx, + const std::string &NameStr, + BasicBlock *InsertAtEnd) { + return new(3) InsertElementInst(Vec, NewElt, Idx, NameStr, InsertAtEnd); + } /// isValidOperands - Return true if an insertelement instruction can be /// formed with the specified operands. static bool isValidOperands(const Value *Vec, const Value *NewElt, const Value *Idx); - virtual InsertElementInst *clone() const; + virtual InsertElementInst *clone(LLVMContext &Context) const; /// getType - Overload to return most specific vector type. /// - inline const VectorType *getType() const { + const VectorType *getType() const { return reinterpret_cast(Instruction::getType()); } /// Transparently provide more efficient getOperand methods. - Value *getOperand(unsigned i) const { - assert(i < 3 && "getOperand() out of range!"); - return Ops[i]; - } - void setOperand(unsigned i, Value *Val) { - assert(i < 3 && "setOperand() out of range!"); - Ops[i] = Val; - } - unsigned getNumOperands() const { return 3; } + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const InsertElementInst *) { return true; } @@ -1173,6 +1363,12 @@ public: } }; +template <> +struct OperandTraits : FixedNumOperandTraits<3> { +}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementInst, Value) + //===----------------------------------------------------------------------===// // ShuffleVectorInst Class //===----------------------------------------------------------------------===// @@ -1181,37 +1377,38 @@ public: /// input vectors. /// class ShuffleVectorInst : public Instruction { - Use Ops[3]; ShuffleVectorInst(const ShuffleVectorInst &IE); public: + // allocate space for exactly three operands + void *operator new(size_t s) { + return User::operator new(s, 3); + } ShuffleVectorInst(Value *V1, Value *V2, Value *Mask, - const std::string &Name = "", Instruction *InsertBefor = 0); + const std::string &NameStr = "", + Instruction *InsertBefor = 0); ShuffleVectorInst(Value *V1, Value *V2, Value *Mask, - const std::string &Name, BasicBlock *InsertAtEnd); + const std::string &NameStr, BasicBlock *InsertAtEnd); /// isValidOperands - Return true if a shufflevector instruction can be /// formed with the specified operands. static bool isValidOperands(const Value *V1, const Value *V2, const Value *Mask); - virtual ShuffleVectorInst *clone() const; + virtual ShuffleVectorInst *clone(LLVMContext &Context) const; /// getType - Overload to return most specific vector type. /// - inline const VectorType *getType() const { + const VectorType *getType() const { return reinterpret_cast(Instruction::getType()); } /// Transparently provide more efficient getOperand methods. - Value *getOperand(unsigned i) const { - assert(i < 3 && "getOperand() out of range!"); - return Ops[i]; - } - void setOperand(unsigned i, Value *Val) { - assert(i < 3 && "setOperand() out of range!"); - Ops[i] = Val; - } - unsigned getNumOperands() const { return 3; } + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + + /// getMaskValue - Return the index from the shuffle mask for the specified + /// output result. This is either -1 if the element is undef or a number less + /// than 2*numelements. + int getMaskValue(unsigned i) const; // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const ShuffleVectorInst *) { return true; } @@ -1223,6 +1420,373 @@ public: } }; +template <> +struct OperandTraits : FixedNumOperandTraits<3> { +}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorInst, Value) + +//===----------------------------------------------------------------------===// +// ExtractValueInst Class +//===----------------------------------------------------------------------===// + +/// ExtractValueInst - This instruction extracts a struct member or array +/// element value from an aggregate value. +/// +class ExtractValueInst : public UnaryInstruction { + SmallVector Indices; + + ExtractValueInst(const ExtractValueInst &EVI); + void init(const unsigned *Idx, unsigned NumIdx, + const std::string &NameStr); + void init(unsigned Idx, const std::string &NameStr); + + template + void init(InputIterator IdxBegin, InputIterator IdxEnd, + const std::string &NameStr, + // 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(std::distance(IdxBegin, IdxEnd)); + + // There's no fundamental reason why we require at least one index + // (other than weirdness with &*IdxBegin being invalid; see + // getelementptr's init routine for example). But there's no + // present need to support it. + assert(NumIdx > 0 && "ExtractValueInst must have at least one index"); + + // This requires that the iterator points to contiguous memory. + init(&*IdxBegin, NumIdx, NameStr); // FIXME: for the general case + // we have to build an array here + } + + /// getIndexedType - Returns the type of the element that would be extracted + /// with an extractvalue instruction with the specified parameters. + /// + /// Null is returned if the indices are invalid for the specified + /// pointer type. + /// + static const Type *getIndexedType(const Type *Agg, + const unsigned *Idx, unsigned NumIdx); + + template + static const Type *getIndexedType(const Type *Ptr, + InputIterator IdxBegin, + InputIterator 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(std::distance(IdxBegin, IdxEnd)); + + if (NumIdx > 0) + // This requires that the iterator points to contiguous memory. + return getIndexedType(Ptr, &*IdxBegin, NumIdx); + else + return getIndexedType(Ptr, (const unsigned *)0, NumIdx); + } + + /// Constructors - Create a extractvalue instruction with a base aggregate + /// value and a list of indices. The first ctor can optionally insert before + /// an existing instruction, the second appends the new instruction to the + /// specified BasicBlock. + template + inline ExtractValueInst(Value *Agg, InputIterator IdxBegin, + InputIterator IdxEnd, + const std::string &NameStr, + Instruction *InsertBefore); + template + inline ExtractValueInst(Value *Agg, + InputIterator IdxBegin, InputIterator IdxEnd, + const std::string &NameStr, BasicBlock *InsertAtEnd); + + // allocate space for exactly one operand + void *operator new(size_t s) { + return User::operator new(s, 1); + } + +public: + template + static ExtractValueInst *Create(Value *Agg, InputIterator IdxBegin, + InputIterator IdxEnd, + const std::string &NameStr = "", + Instruction *InsertBefore = 0) { + return new + ExtractValueInst(Agg, IdxBegin, IdxEnd, NameStr, InsertBefore); + } + template + static ExtractValueInst *Create(Value *Agg, + InputIterator IdxBegin, InputIterator IdxEnd, + const std::string &NameStr, + BasicBlock *InsertAtEnd) { + return new ExtractValueInst(Agg, IdxBegin, IdxEnd, NameStr, InsertAtEnd); + } + + /// Constructors - These two creators are convenience methods because one + /// index extractvalue instructions are much more common than those with + /// more than one. + static ExtractValueInst *Create(Value *Agg, unsigned Idx, + const std::string &NameStr = "", + Instruction *InsertBefore = 0) { + unsigned Idxs[1] = { Idx }; + return new ExtractValueInst(Agg, Idxs, Idxs + 1, NameStr, InsertBefore); + } + static ExtractValueInst *Create(Value *Agg, unsigned Idx, + const std::string &NameStr, + BasicBlock *InsertAtEnd) { + unsigned Idxs[1] = { Idx }; + return new ExtractValueInst(Agg, Idxs, Idxs + 1, NameStr, InsertAtEnd); + } + + virtual ExtractValueInst *clone(LLVMContext &Context) const; + + /// getIndexedType - Returns the type of the element that would be extracted + /// with an extractvalue instruction with the specified parameters. + /// + /// Null is returned if the indices are invalid for the specified + /// pointer type. + /// + template + static const Type *getIndexedType(const Type *Ptr, + InputIterator IdxBegin, + InputIterator IdxEnd) { + return getIndexedType(Ptr, IdxBegin, IdxEnd, + typename std::iterator_traits:: + iterator_category()); + } + static const Type *getIndexedType(const Type *Ptr, unsigned Idx); + + typedef const unsigned* idx_iterator; + inline idx_iterator idx_begin() const { return Indices.begin(); } + inline idx_iterator idx_end() const { return Indices.end(); } + + Value *getAggregateOperand() { + return getOperand(0); + } + const Value *getAggregateOperand() const { + return getOperand(0); + } + static unsigned getAggregateOperandIndex() { + return 0U; // get index for modifying correct operand + } + + unsigned getNumIndices() const { // Note: always non-negative + return (unsigned)Indices.size(); + } + + bool hasIndices() const { + return true; + } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const ExtractValueInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == Instruction::ExtractValue; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +}; + +template +ExtractValueInst::ExtractValueInst(Value *Agg, + InputIterator IdxBegin, + InputIterator IdxEnd, + const std::string &NameStr, + Instruction *InsertBefore) + : UnaryInstruction(checkType(getIndexedType(Agg->getType(), + IdxBegin, IdxEnd)), + ExtractValue, Agg, InsertBefore) { + init(IdxBegin, IdxEnd, NameStr, + typename std::iterator_traits::iterator_category()); +} +template +ExtractValueInst::ExtractValueInst(Value *Agg, + InputIterator IdxBegin, + InputIterator IdxEnd, + const std::string &NameStr, + BasicBlock *InsertAtEnd) + : UnaryInstruction(checkType(getIndexedType(Agg->getType(), + IdxBegin, IdxEnd)), + ExtractValue, Agg, InsertAtEnd) { + init(IdxBegin, IdxEnd, NameStr, + typename std::iterator_traits::iterator_category()); +} + + +//===----------------------------------------------------------------------===// +// InsertValueInst Class +//===----------------------------------------------------------------------===// + +/// InsertValueInst - This instruction inserts a struct field of array element +/// value into an aggregate value. +/// +class InsertValueInst : public Instruction { + SmallVector Indices; + + void *operator new(size_t, unsigned); // Do not implement + InsertValueInst(const InsertValueInst &IVI); + void init(Value *Agg, Value *Val, const unsigned *Idx, unsigned NumIdx, + const std::string &NameStr); + void init(Value *Agg, Value *Val, unsigned Idx, const std::string &NameStr); + + template + void init(Value *Agg, Value *Val, + InputIterator IdxBegin, InputIterator IdxEnd, + const std::string &NameStr, + // 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(std::distance(IdxBegin, IdxEnd)); + + // There's no fundamental reason why we require at least one index + // (other than weirdness with &*IdxBegin being invalid; see + // getelementptr's init routine for example). But there's no + // present need to support it. + assert(NumIdx > 0 && "InsertValueInst must have at least one index"); + + // This requires that the iterator points to contiguous memory. + init(Agg, Val, &*IdxBegin, NumIdx, NameStr); // FIXME: for the general case + // we have to build an array here + } + + /// Constructors - Create a insertvalue instruction with a base aggregate + /// value, a value to insert, and a list of indices. The first ctor can + /// optionally insert before an existing instruction, the second appends + /// the new instruction to the specified BasicBlock. + template + inline InsertValueInst(Value *Agg, Value *Val, InputIterator IdxBegin, + InputIterator IdxEnd, + const std::string &NameStr, + Instruction *InsertBefore); + template + inline InsertValueInst(Value *Agg, Value *Val, + InputIterator IdxBegin, InputIterator IdxEnd, + const std::string &NameStr, BasicBlock *InsertAtEnd); + + /// Constructors - These two constructors are convenience methods because one + /// and two index insertvalue instructions are so common. + InsertValueInst(Value *Agg, Value *Val, + unsigned Idx, const std::string &NameStr = "", + Instruction *InsertBefore = 0); + InsertValueInst(Value *Agg, Value *Val, unsigned Idx, + const std::string &NameStr, BasicBlock *InsertAtEnd); +public: + // allocate space for exactly two operands + void *operator new(size_t s) { + return User::operator new(s, 2); + } + + template + static InsertValueInst *Create(Value *Agg, Value *Val, InputIterator IdxBegin, + InputIterator IdxEnd, + const std::string &NameStr = "", + Instruction *InsertBefore = 0) { + return new InsertValueInst(Agg, Val, IdxBegin, IdxEnd, + NameStr, InsertBefore); + } + template + static InsertValueInst *Create(Value *Agg, Value *Val, + InputIterator IdxBegin, InputIterator IdxEnd, + const std::string &NameStr, + BasicBlock *InsertAtEnd) { + return new InsertValueInst(Agg, Val, IdxBegin, IdxEnd, + NameStr, InsertAtEnd); + } + + /// Constructors - These two creators are convenience methods because one + /// index insertvalue instructions are much more common than those with + /// more than one. + static InsertValueInst *Create(Value *Agg, Value *Val, unsigned Idx, + const std::string &NameStr = "", + Instruction *InsertBefore = 0) { + return new InsertValueInst(Agg, Val, Idx, NameStr, InsertBefore); + } + static InsertValueInst *Create(Value *Agg, Value *Val, unsigned Idx, + const std::string &NameStr, + BasicBlock *InsertAtEnd) { + return new InsertValueInst(Agg, Val, Idx, NameStr, InsertAtEnd); + } + + virtual InsertValueInst *clone(LLVMContext &Context) const; + + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + + typedef const unsigned* idx_iterator; + inline idx_iterator idx_begin() const { return Indices.begin(); } + inline idx_iterator idx_end() const { return Indices.end(); } + + Value *getAggregateOperand() { + return getOperand(0); + } + const Value *getAggregateOperand() const { + return getOperand(0); + } + static unsigned getAggregateOperandIndex() { + return 0U; // get index for modifying correct operand + } + + Value *getInsertedValueOperand() { + return getOperand(1); + } + const Value *getInsertedValueOperand() const { + return getOperand(1); + } + static unsigned getInsertedValueOperandIndex() { + return 1U; // get index for modifying correct operand + } + + unsigned getNumIndices() const { // Note: always non-negative + return (unsigned)Indices.size(); + } + + bool hasIndices() const { + return true; + } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const InsertValueInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == Instruction::InsertValue; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +}; + +template <> +struct OperandTraits : FixedNumOperandTraits<2> { +}; + +template +InsertValueInst::InsertValueInst(Value *Agg, + Value *Val, + InputIterator IdxBegin, + InputIterator IdxEnd, + const std::string &NameStr, + Instruction *InsertBefore) + : Instruction(Agg->getType(), InsertValue, + OperandTraits::op_begin(this), + 2, InsertBefore) { + init(Agg, Val, IdxBegin, IdxEnd, NameStr, + typename std::iterator_traits::iterator_category()); +} +template +InsertValueInst::InsertValueInst(Value *Agg, + Value *Val, + InputIterator IdxBegin, + InputIterator IdxEnd, + const std::string &NameStr, + BasicBlock *InsertAtEnd) + : Instruction(Agg->getType(), InsertValue, + OperandTraits::op_begin(this), + 2, InsertAtEnd) { + init(Agg, Val, IdxBegin, IdxEnd, NameStr, + typename std::iterator_traits::iterator_category()); +} + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueInst, Value) //===----------------------------------------------------------------------===// // PHINode Class @@ -1233,24 +1797,36 @@ public: // scientist's overactive imagination. // class PHINode : public Instruction { + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT /// ReservedSpace - The number of operands actually allocated. NumOperands is /// the number actually in use. unsigned ReservedSpace; PHINode(const PHINode &PN); -public: - explicit PHINode(const Type *Ty, const std::string &Name = "", + // allocate space for exactly zero operands + void *operator new(size_t s) { + return User::operator new(s, 0); + } + explicit PHINode(const Type *Ty, const std::string &NameStr = "", Instruction *InsertBefore = 0) : Instruction(Ty, Instruction::PHI, 0, 0, InsertBefore), ReservedSpace(0) { - setName(Name); + setName(NameStr); } - PHINode(const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd) + PHINode(const Type *Ty, const std::string &NameStr, BasicBlock *InsertAtEnd) : Instruction(Ty, Instruction::PHI, 0, 0, InsertAtEnd), ReservedSpace(0) { - setName(Name); + setName(NameStr); + } +public: + static PHINode *Create(const Type *Ty, const std::string &NameStr = "", + Instruction *InsertBefore = 0) { + return new PHINode(Ty, NameStr, InsertBefore); + } + static PHINode *Create(const Type *Ty, const std::string &NameStr, + BasicBlock *InsertAtEnd) { + return new PHINode(Ty, NameStr, InsertAtEnd); } - ~PHINode(); /// reserveOperandSpace - This method can be used to avoid repeated @@ -1261,7 +1837,10 @@ public: resizeOperands(NumValues*2); } - virtual PHINode *clone() const; + virtual PHINode *clone(LLVMContext &Context) const; + + /// Provide fast operand accessors + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); /// getNumIncomingValues - Return the number of incoming edges /// @@ -1277,25 +1856,43 @@ public: assert(i*2 < getNumOperands() && "Invalid value number!"); setOperand(i*2, V); } - unsigned getOperandNumForIncomingValue(unsigned i) { + static unsigned getOperandNumForIncomingValue(unsigned i) { return i*2; } + static unsigned getIncomingValueNumForOperand(unsigned i) { + assert(i % 2 == 0 && "Invalid incoming-value operand index!"); + return i/2; + } + /// getIncomingBlock - Return incoming basic block corresponding + /// to value use iterator + /// + template + BasicBlock *getIncomingBlock(value_use_iterator I) const { + assert(this == *I && "Iterator doesn't point to PHI's Uses?"); + return static_cast((&I.getUse() + 1)->get()); + } /// getIncomingBlock - Return incoming basic block number x /// BasicBlock *getIncomingBlock(unsigned i) const { - return reinterpret_cast(getOperand(i*2+1)); + return static_cast(getOperand(i*2+1)); } void setIncomingBlock(unsigned i, BasicBlock *BB) { - setOperand(i*2+1, reinterpret_cast(BB)); + setOperand(i*2+1, BB); } - unsigned getOperandNumForIncomingBlock(unsigned i) { + static unsigned getOperandNumForIncomingBlock(unsigned i) { return i*2+1; } + static unsigned getIncomingBlockNumForOperand(unsigned i) { + assert(i % 2 == 1 && "Invalid incoming-block operand index!"); + return i/2; + } /// addIncoming - Add an incoming value to the end of the PHI list /// void addIncoming(Value *V, BasicBlock *BB) { + assert(V && "PHI node got a null value!"); + assert(BB && "PHI node got a null basic block!"); assert(getType() == V->getType() && "All operands to PHI node must be the same type as the PHI node!"); unsigned OpNo = NumOperands; @@ -1303,8 +1900,8 @@ public: resizeOperands(0); // Get more space! // Initialize some new operands. NumOperands = OpNo+2; - OperandList[OpNo].init(V, this); - OperandList[OpNo+1].init(reinterpret_cast(BB), this); + OperandList[OpNo] = V; + OperandList[OpNo+1] = BB; } /// removeIncomingValue - Remove an incoming value. This is useful if a @@ -1317,7 +1914,7 @@ public: /// Value *removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty = true); - Value *removeIncomingValue(const BasicBlock *BB, bool DeletePHIIfEmpty =true){ + Value *removeIncomingValue(const BasicBlock *BB, bool DeletePHIIfEmpty=true) { int Idx = getBasicBlockIndex(BB); assert(Idx >= 0 && "Invalid basic block argument to remove!"); return removeIncomingValue(Idx, DeletePHIIfEmpty); @@ -1329,7 +1926,7 @@ public: int getBasicBlockIndex(const BasicBlock *BB) const { Use *OL = OperandList; for (unsigned i = 0, e = getNumOperands(); i != e; i += 2) - if (OL[i+1] == reinterpret_cast(BB)) return i/2; + if (OL[i+1].get() == BB) return i/2; return -1; } @@ -1354,6 +1951,13 @@ public: void resizeOperands(unsigned NumOperands); }; +template <> +struct OperandTraits : HungoffOperandTraits<2> { +}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(PHINode, Value) + + //===----------------------------------------------------------------------===// // ReturnInst Class //===----------------------------------------------------------------------===// @@ -1363,39 +1967,46 @@ public: /// does not continue in this function any longer. /// class ReturnInst : public TerminatorInst { - Use RetVal; // Return Value: null if 'void'. ReturnInst(const ReturnInst &RI); - void init(Value *RetVal); -public: +private: // ReturnInst constructors: // ReturnInst() - 'ret void' instruction // ReturnInst( null) - 'ret void' instruction // ReturnInst(Value* X) - 'ret X' instruction - // ReturnInst( null, Inst *) - 'ret void' instruction, insert before I + // ReturnInst( null, Inst *I) - 'ret void' instruction, insert before I // ReturnInst(Value* X, Inst *I) - 'ret X' instruction, insert before I - // ReturnInst( null, BB *B) - 'ret void' instruction, insert @ end of BB - // ReturnInst(Value* X, BB *B) - 'ret X' instruction, insert @ end of BB + // ReturnInst( null, BB *B) - 'ret void' instruction, insert @ end of B + // ReturnInst(Value* X, BB *B) - 'ret X' instruction, insert @ end of B // // NOTE: If the Value* passed is of type void then the constructor behaves as // if it was passed NULL. explicit ReturnInst(Value *retVal = 0, Instruction *InsertBefore = 0); ReturnInst(Value *retVal, BasicBlock *InsertAtEnd); explicit ReturnInst(BasicBlock *InsertAtEnd); - - virtual ReturnInst *clone() const; - - // Transparently provide more efficient getOperand methods. - Value *getOperand(unsigned i) const { - assert(i < getNumOperands() && "getOperand() out of range!"); - return RetVal; +public: + static ReturnInst* Create(Value *retVal = 0, Instruction *InsertBefore = 0) { + return new(!!retVal) ReturnInst(retVal, InsertBefore); } - void setOperand(unsigned i, Value *Val) { - assert(i < getNumOperands() && "setOperand() out of range!"); - RetVal = Val; + static ReturnInst* Create(Value *retVal, BasicBlock *InsertAtEnd) { + return new(!!retVal) ReturnInst(retVal, InsertAtEnd); } + static ReturnInst* Create(BasicBlock *InsertAtEnd) { + return new(0) ReturnInst(InsertAtEnd); + } + virtual ~ReturnInst(); + + virtual ReturnInst *clone(LLVMContext &Context) const; + + /// Provide fast operand accessors + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); - Value *getReturnValue() const { return RetVal; } + /// Convenience accessor + Value *getReturnValue(unsigned n = 0) const { + return n < getNumOperands() + ? getOperand(n) + : 0; + } unsigned getNumSuccessors() const { return 0; } @@ -1413,6 +2024,12 @@ public: virtual void setSuccessorV(unsigned idx, BasicBlock *B); }; +template <> +struct OperandTraits : OptionalOperandTraits<> { +}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ReturnInst, Value) + //===----------------------------------------------------------------------===// // BranchInst Class //===----------------------------------------------------------------------===// @@ -1422,12 +2039,11 @@ public: /// class BranchInst : public TerminatorInst { /// Ops list - Branches are strange. The operands are ordered: - /// TrueDest, FalseDest, Cond. This makes some accessors faster because - /// they don't have to check for cond/uncond branchness. - Use Ops[3]; + /// [Cond, FalseDest,] TrueDest. This makes some accessors faster because + /// they don't have to check for cond/uncond branchness. These are mostly + /// accessed relative from op_end(). BranchInst(const BranchInst &BI); void AssertOK(); -public: // BranchInst constructors (where {B, T, F} are blocks, and C is a condition): // BranchInst(BB *B) - 'br B' // BranchInst(BB* T, BB *F, Value *C) - 'br C, T, F' @@ -1441,54 +2057,65 @@ public: BranchInst(BasicBlock *IfTrue, BasicBlock *InsertAtEnd); BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond, BasicBlock *InsertAtEnd); - - /// Transparently provide more efficient getOperand methods. - Value *getOperand(unsigned i) const { - assert(i < getNumOperands() && "getOperand() out of range!"); - return Ops[i]; +public: + static BranchInst *Create(BasicBlock *IfTrue, Instruction *InsertBefore = 0) { + return new(1, true) BranchInst(IfTrue, InsertBefore); + } + static BranchInst *Create(BasicBlock *IfTrue, BasicBlock *IfFalse, + Value *Cond, Instruction *InsertBefore = 0) { + return new(3) BranchInst(IfTrue, IfFalse, Cond, InsertBefore); } - void setOperand(unsigned i, Value *Val) { - assert(i < getNumOperands() && "setOperand() out of range!"); - Ops[i] = Val; + static BranchInst *Create(BasicBlock *IfTrue, BasicBlock *InsertAtEnd) { + return new(1, true) BranchInst(IfTrue, InsertAtEnd); + } + static BranchInst *Create(BasicBlock *IfTrue, BasicBlock *IfFalse, + Value *Cond, BasicBlock *InsertAtEnd) { + return new(3) BranchInst(IfTrue, IfFalse, Cond, InsertAtEnd); } - virtual BranchInst *clone() const; + ~BranchInst(); - inline bool isUnconditional() const { return getNumOperands() == 1; } - inline bool isConditional() const { return getNumOperands() == 3; } + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); - inline Value *getCondition() const { + virtual BranchInst *clone(LLVMContext &Context) const; + + bool isUnconditional() const { return getNumOperands() == 1; } + bool isConditional() const { return getNumOperands() == 3; } + + Value *getCondition() const { assert(isConditional() && "Cannot get condition of an uncond branch!"); - return getOperand(2); + return Op<-3>(); } void setCondition(Value *V) { assert(isConditional() && "Cannot set condition of unconditional branch!"); - setOperand(2, V); + Op<-3>() = V; } // setUnconditionalDest - Change the current branch to an unconditional branch // targeting the specified block. // FIXME: Eliminate this ugly method. void setUnconditionalDest(BasicBlock *Dest) { + Op<-1>() = Dest; if (isConditional()) { // Convert this to an uncond branch. + Op<-2>() = 0; + Op<-3>() = 0; NumOperands = 1; - Ops[1].set(0); - Ops[2].set(0); + OperandList = op_begin(); } - setOperand(0, reinterpret_cast(Dest)); } unsigned getNumSuccessors() const { return 1+isConditional(); } BasicBlock *getSuccessor(unsigned i) const { assert(i < getNumSuccessors() && "Successor # out of range for Branch!"); - return cast(getOperand(i)); + return cast_or_null((&Op<-1>() - i)->get()); } void setSuccessor(unsigned idx, BasicBlock *NewSucc) { assert(idx < getNumSuccessors() && "Successor # out of range for Branch!"); - setOperand(idx, reinterpret_cast(NewSucc)); + *(&Op<-1>() - idx) = NewSucc; } // Methods for support type inquiry through isa, cast, and dyn_cast: @@ -1505,6 +2132,11 @@ private: virtual void setSuccessorV(unsigned idx, BasicBlock *B); }; +template <> +struct OperandTraits : VariadicOperandTraits<1> {}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BranchInst, Value) + //===----------------------------------------------------------------------===// // SwitchInst Class //===----------------------------------------------------------------------===// @@ -1513,6 +2145,7 @@ private: /// SwitchInst - Multiway switch /// class SwitchInst : public TerminatorInst { + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT unsigned ReservedSpace; // Operand[0] = Value to switch on // Operand[1] = Default basic block destination @@ -1521,28 +2154,42 @@ class SwitchInst : public TerminatorInst { SwitchInst(const SwitchInst &RI); void init(Value *Value, BasicBlock *Default, unsigned NumCases); void resizeOperands(unsigned No); -public: + // allocate space for exactly zero operands + void *operator new(size_t s) { + return User::operator new(s, 0); + } /// SwitchInst ctor - Create a new switch instruction, specifying a value to /// switch on and a default destination. The number of additional cases can /// be specified here to make memory allocation more efficient. This /// constructor can also autoinsert before another instruction. SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases, Instruction *InsertBefore = 0); - + /// SwitchInst ctor - Create a new switch instruction, specifying a value to /// switch on and a default destination. The number of additional cases can /// be specified here to make memory allocation more efficient. This /// constructor also autoinserts at the end of the specified BasicBlock. SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases, BasicBlock *InsertAtEnd); +public: + static SwitchInst *Create(Value *Value, BasicBlock *Default, + unsigned NumCases, Instruction *InsertBefore = 0) { + return new SwitchInst(Value, Default, NumCases, InsertBefore); + } + static SwitchInst *Create(Value *Value, BasicBlock *Default, + unsigned NumCases, BasicBlock *InsertAtEnd) { + return new SwitchInst(Value, Default, NumCases, InsertAtEnd); + } ~SwitchInst(); + /// Provide fast operand accessors + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); // Accessor Methods for Switch stmt - inline Value *getCondition() const { return getOperand(0); } + Value *getCondition() const { return getOperand(0); } void setCondition(Value *V) { setOperand(0, V); } - inline BasicBlock *getDefaultDest() const { + BasicBlock *getDefaultDest() const { return cast(getOperand(1)); } @@ -1601,7 +2248,7 @@ public: /// void removeCase(unsigned idx); - virtual SwitchInst *clone() const; + virtual SwitchInst *clone(LLVMContext &Context) const; unsigned getNumSuccessors() const { return getNumOperands()/2; } BasicBlock *getSuccessor(unsigned idx) const { @@ -1610,12 +2257,12 @@ public: } void setSuccessor(unsigned idx, BasicBlock *NewSucc) { assert(idx < getNumSuccessors() && "Successor # out of range for switch!"); - setOperand(idx*2+1, reinterpret_cast(NewSucc)); + setOperand(idx*2+1, NewSucc); } // getSuccessorValue - Return the value associated with the specified // successor. - inline ConstantInt *getSuccessorValue(unsigned idx) const { + ConstantInt *getSuccessorValue(unsigned idx) const { assert(idx < getNumSuccessors() && "Successor # out of range!"); return reinterpret_cast(getOperand(idx*2)); } @@ -1634,17 +2281,22 @@ private: virtual void setSuccessorV(unsigned idx, BasicBlock *B); }; +template <> +struct OperandTraits : HungoffOperandTraits<2> { +}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SwitchInst, Value) + + //===----------------------------------------------------------------------===// // InvokeInst Class //===----------------------------------------------------------------------===// -//===--------------------------------------------------------------------------- - /// InvokeInst - Invoke instruction. The SubclassData field is used to hold the /// calling convention of the call. /// class InvokeInst : public TerminatorInst { - const ParamAttrsList *ParamAttrs; + AttrListPtr AttributeList; InvokeInst(const InvokeInst &BI); void init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException, Value* const *Args, unsigned NumArgs); @@ -1652,18 +2304,17 @@ class InvokeInst : public TerminatorInst { template void init(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, InputIterator ArgBegin, InputIterator ArgEnd, - const std::string &Name, + const std::string &NameStr, // This argument ensures that we have an iterator we can // do arithmetic on in constant time std::random_access_iterator_tag) { unsigned NumArgs = (unsigned)std::distance(ArgBegin, ArgEnd); - + // This requires that the iterator points to contiguous memory. init(Func, IfNormal, IfException, NumArgs ? &*ArgBegin : 0, NumArgs); - setName(Name); + setName(NameStr); } -public: /// Construct an InvokeInst given a range of arguments. /// InputIterator must be a random-access iterator pointing to /// contiguous storage (e.g. a std::vector<>::iterator). Checks are @@ -1672,15 +2323,10 @@ public: /// /// @brief Construct an InvokeInst from a range of arguments template - InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, - InputIterator ArgBegin, InputIterator ArgEnd, - const std::string &Name = "", Instruction *InsertBefore = 0) - : TerminatorInst(cast(cast(Func->getType()) - ->getElementType())->getReturnType(), - Instruction::Invoke, 0, 0, InsertBefore) { - init(Func, IfNormal, IfException, ArgBegin, ArgEnd, Name, - typename std::iterator_traits::iterator_category()); - } + inline InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, + InputIterator ArgBegin, InputIterator ArgEnd, + unsigned Values, + const std::string &NameStr, Instruction *InsertBefore); /// Construct an InvokeInst given a range of arguments. /// InputIterator must be a random-access iterator pointing to @@ -1690,19 +2336,36 @@ public: /// /// @brief Construct an InvokeInst from a range of arguments template - InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, - InputIterator ArgBegin, InputIterator ArgEnd, - const std::string &Name, BasicBlock *InsertAtEnd) - : TerminatorInst(cast(cast(Func->getType()) - ->getElementType())->getReturnType(), - Instruction::Invoke, 0, 0, InsertAtEnd) { - init(Func, IfNormal, IfException, ArgBegin, ArgEnd, Name, - typename std::iterator_traits::iterator_category()); + inline InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, + InputIterator ArgBegin, InputIterator ArgEnd, + unsigned Values, + const std::string &NameStr, BasicBlock *InsertAtEnd); +public: + template + static InvokeInst *Create(Value *Func, + BasicBlock *IfNormal, BasicBlock *IfException, + InputIterator ArgBegin, InputIterator ArgEnd, + const std::string &NameStr = "", + Instruction *InsertBefore = 0) { + unsigned Values(ArgEnd - ArgBegin + 3); + return new(Values) InvokeInst(Func, IfNormal, IfException, ArgBegin, ArgEnd, + Values, NameStr, InsertBefore); + } + template + static InvokeInst *Create(Value *Func, + BasicBlock *IfNormal, BasicBlock *IfException, + InputIterator ArgBegin, InputIterator ArgEnd, + const std::string &NameStr, + BasicBlock *InsertAtEnd) { + unsigned Values(ArgEnd - ArgBegin + 3); + return new(Values) InvokeInst(Func, IfNormal, IfException, ArgBegin, ArgEnd, + Values, NameStr, InsertAtEnd); } - ~InvokeInst(); + virtual InvokeInst *clone(LLVMContext &Context) const; - virtual InvokeInst *clone() const; + /// Provide fast operand accessors + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); /// getCallingConv/setCallingConv - Get or set the calling convention of this /// function call. @@ -1711,35 +2374,75 @@ public: SubclassData = CC; } - /// Obtains a pointer to the ParamAttrsList object which holds the - /// parameter attributes information, if any. - /// @returns 0 if no attributes have been set. - /// @brief Get the parameter attributes. - const ParamAttrsList *getParamAttrs() const { return ParamAttrs; } + /// getAttributes - Return the parameter attributes for this invoke. + /// + const AttrListPtr &getAttributes() const { return AttributeList; } + + /// setAttributes - Set the parameter attributes for this invoke. + /// + void setAttributes(const AttrListPtr &Attrs) { AttributeList = Attrs; } + + /// addAttribute - adds the attribute to the list of attributes. + void addAttribute(unsigned i, Attributes attr); - /// Sets the parameter attributes for this InvokeInst. To construct a - /// ParamAttrsList, see ParameterAttributes.h - /// @brief Set the parameter attributes. - void setParamAttrs(const ParamAttrsList *attrs); + /// removeAttribute - removes the attribute from the list of attributes. + void removeAttribute(unsigned i, Attributes attr); /// @brief Determine whether the call or the callee has the given attribute. - bool paramHasAttr(uint16_t i, unsigned attr) const; + bool paramHasAttr(unsigned i, Attributes attr) const; + + /// @brief Extract the alignment for a call or parameter (0=unknown). + unsigned getParamAlignment(unsigned i) const { + return AttributeList.getParamAlignment(i); + } /// @brief Determine if the call does not access memory. - bool doesNotAccessMemory() const; + bool doesNotAccessMemory() const { + return paramHasAttr(0, Attribute::ReadNone); + } + void setDoesNotAccessMemory(bool NotAccessMemory = true) { + if (NotAccessMemory) addAttribute(~0, Attribute::ReadNone); + else removeAttribute(~0, Attribute::ReadNone); + } /// @brief Determine if the call does not access or only reads memory. - bool onlyReadsMemory() const; + bool onlyReadsMemory() const { + return doesNotAccessMemory() || paramHasAttr(~0, Attribute::ReadOnly); + } + void setOnlyReadsMemory(bool OnlyReadsMemory = true) { + if (OnlyReadsMemory) addAttribute(~0, Attribute::ReadOnly); + else removeAttribute(~0, Attribute::ReadOnly | Attribute::ReadNone); + } /// @brief Determine if the call cannot return. - bool doesNotReturn() const; + bool doesNotReturn() const { + return paramHasAttr(~0, Attribute::NoReturn); + } + void setDoesNotReturn(bool DoesNotReturn = true) { + if (DoesNotReturn) addAttribute(~0, Attribute::NoReturn); + else removeAttribute(~0, Attribute::NoReturn); + } /// @brief Determine if the call cannot unwind. - bool doesNotThrow() const; - void setDoesNotThrow(bool doesNotThrow = true); + bool doesNotThrow() const { + return paramHasAttr(~0, Attribute::NoUnwind); + } + void setDoesNotThrow(bool DoesNotThrow = true) { + if (DoesNotThrow) addAttribute(~0, Attribute::NoUnwind); + else removeAttribute(~0, Attribute::NoUnwind); + } - /// @brief Determine if the call returns a structure. - bool isStructReturn() const; + /// @brief Determine if the call returns a structure through first + /// pointer argument. + bool hasStructRetAttr() const { + // Be friendly and also check the callee. + return paramHasAttr(1, Attribute::StructRet); + } + + /// @brief Determine if any call argument is an aggregate passed by value. + bool hasByValArgument() const { + return AttributeList.hasAttrSomewhere(Attribute::ByVal); + } /// getCalledFunction - Return the function called, or null if this is an /// indirect function invocation. @@ -1748,8 +2451,10 @@ public: return dyn_cast(getOperand(0)); } - // getCalledValue - Get a pointer to a function that is invoked by this inst. - inline Value *getCalledValue() const { return getOperand(0); } + /// getCalledValue - Get a pointer to the function that is invoked by this + /// instruction + const Value *getCalledValue() const { return getOperand(0); } + Value *getCalledValue() { return getOperand(0); } // get*Dest - Return the destination basic blocks... BasicBlock *getNormalDest() const { @@ -1759,21 +2464,21 @@ public: return cast(getOperand(2)); } void setNormalDest(BasicBlock *B) { - setOperand(1, reinterpret_cast(B)); + setOperand(1, B); } void setUnwindDest(BasicBlock *B) { - setOperand(2, reinterpret_cast(B)); + setOperand(2, B); } - inline BasicBlock *getSuccessor(unsigned i) const { + BasicBlock *getSuccessor(unsigned i) const { assert(i < 2 && "Successor # out of range for invoke!"); return i == 0 ? getNormalDest() : getUnwindDest(); } void setSuccessor(unsigned idx, BasicBlock *NewSucc) { assert(idx < 2 && "Successor # out of range for invoke!"); - setOperand(idx+1, reinterpret_cast(NewSucc)); + setOperand(idx+1, NewSucc); } unsigned getNumSuccessors() const { return 2; } @@ -1792,6 +2497,40 @@ private: virtual void setSuccessorV(unsigned idx, BasicBlock *B); }; +template <> +struct OperandTraits : VariadicOperandTraits<3> { +}; + +template +InvokeInst::InvokeInst(Value *Func, + BasicBlock *IfNormal, BasicBlock *IfException, + InputIterator ArgBegin, InputIterator ArgEnd, + unsigned Values, + const std::string &NameStr, Instruction *InsertBefore) + : TerminatorInst(cast(cast(Func->getType()) + ->getElementType())->getReturnType(), + Instruction::Invoke, + OperandTraits::op_end(this) - Values, + Values, InsertBefore) { + init(Func, IfNormal, IfException, ArgBegin, ArgEnd, NameStr, + typename std::iterator_traits::iterator_category()); +} +template +InvokeInst::InvokeInst(Value *Func, + BasicBlock *IfNormal, BasicBlock *IfException, + InputIterator ArgBegin, InputIterator ArgEnd, + unsigned Values, + const std::string &NameStr, BasicBlock *InsertAtEnd) + : TerminatorInst(cast(cast(Func->getType()) + ->getElementType())->getReturnType(), + Instruction::Invoke, + OperandTraits::op_end(this) - Values, + Values, InsertAtEnd) { + init(Func, IfNormal, IfException, ArgBegin, ArgEnd, NameStr, + typename std::iterator_traits::iterator_category()); +} + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InvokeInst, Value) //===----------------------------------------------------------------------===// // UnwindInst Class @@ -1802,11 +2541,16 @@ private: /// until an invoke instruction is found. /// class UnwindInst : public TerminatorInst { + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT public: + // allocate space for exactly zero operands + void *operator new(size_t s) { + return User::operator new(s, 0); + } explicit UnwindInst(Instruction *InsertBefore = 0); explicit UnwindInst(BasicBlock *InsertAtEnd); - virtual UnwindInst *clone() const; + virtual UnwindInst *clone(LLVMContext &Context) const; unsigned getNumSuccessors() const { return 0; } @@ -1834,11 +2578,16 @@ private: /// end of the block cannot be reached. /// class UnreachableInst : public TerminatorInst { + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT public: + // allocate space for exactly zero operands + void *operator new(size_t s) { + return User::operator new(s, 0); + } explicit UnreachableInst(Instruction *InsertBefore = 0); explicit UnreachableInst(BasicBlock *InsertAtEnd); - virtual UnreachableInst *clone() const; + virtual UnreachableInst *clone(LLVMContext &Context) const; unsigned getNumSuccessors() const { return 0; } @@ -1871,7 +2620,7 @@ public: TruncInst( Value *S, ///< The value to be truncated const Type *Ty, ///< The (smaller) type to truncate to - const std::string &Name = "", ///< A name for the new instruction + const std::string &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); @@ -1879,12 +2628,12 @@ public: TruncInst( Value *S, ///< The value to be truncated const Type *Ty, ///< The (smaller) type to truncate to - const std::string &Name, ///< A name for the new instruction + const std::string &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); /// @brief Clone an identical TruncInst - virtual CastInst *clone() const; + virtual CastInst *clone(LLVMContext &Context) const; /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const TruncInst *) { return true; } @@ -1911,7 +2660,7 @@ public: ZExtInst( Value *S, ///< The value to be zero extended const Type *Ty, ///< The type to zero extend to - const std::string &Name = "", ///< A name for the new instruction + const std::string &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); @@ -1919,12 +2668,12 @@ public: ZExtInst( Value *S, ///< The value to be zero extended const Type *Ty, ///< The type to zero extend to - const std::string &Name, ///< A name for the new instruction + const std::string &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); /// @brief Clone an identical ZExtInst - virtual CastInst *clone() const; + virtual CastInst *clone(LLVMContext &Context) const; /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const ZExtInst *) { return true; } @@ -1951,7 +2700,7 @@ public: SExtInst( Value *S, ///< The value to be sign extended const Type *Ty, ///< The type to sign extend to - const std::string &Name = "", ///< A name for the new instruction + const std::string &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); @@ -1959,12 +2708,12 @@ public: SExtInst( Value *S, ///< The value to be sign extended const Type *Ty, ///< The type to sign extend to - const std::string &Name, ///< A name for the new instruction + const std::string &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); /// @brief Clone an identical SExtInst - virtual CastInst *clone() const; + virtual CastInst *clone(LLVMContext &Context) const; /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const SExtInst *) { return true; } @@ -1990,7 +2739,7 @@ public: FPTruncInst( Value *S, ///< The value to be truncated const Type *Ty, ///< The type to truncate to - const std::string &Name = "", ///< A name for the new instruction + const std::string &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); @@ -1998,12 +2747,12 @@ public: FPTruncInst( Value *S, ///< The value to be truncated const Type *Ty, ///< The type to truncate to - const std::string &Name, ///< A name for the new instruction + const std::string &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); /// @brief Clone an identical FPTruncInst - virtual CastInst *clone() const; + virtual CastInst *clone(LLVMContext &Context) const; /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const FPTruncInst *) { return true; } @@ -2029,7 +2778,7 @@ public: FPExtInst( Value *S, ///< The value to be extended const Type *Ty, ///< The type to extend to - const std::string &Name = "", ///< A name for the new instruction + const std::string &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); @@ -2037,12 +2786,12 @@ public: FPExtInst( Value *S, ///< The value to be extended const Type *Ty, ///< The type to extend to - const std::string &Name, ///< A name for the new instruction + const std::string &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); /// @brief Clone an identical FPExtInst - virtual CastInst *clone() const; + virtual CastInst *clone(LLVMContext &Context) const; /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const FPExtInst *) { return true; } @@ -2068,7 +2817,7 @@ public: UIToFPInst( Value *S, ///< The value to be converted const Type *Ty, ///< The type to convert to - const std::string &Name = "", ///< A name for the new instruction + const std::string &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); @@ -2076,12 +2825,12 @@ public: UIToFPInst( Value *S, ///< The value to be converted const Type *Ty, ///< The type to convert to - const std::string &Name, ///< A name for the new instruction + const std::string &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); /// @brief Clone an identical UIToFPInst - virtual CastInst *clone() const; + virtual CastInst *clone(LLVMContext &Context) const; /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const UIToFPInst *) { return true; } @@ -2107,7 +2856,7 @@ public: SIToFPInst( Value *S, ///< The value to be converted const Type *Ty, ///< The type to convert to - const std::string &Name = "", ///< A name for the new instruction + const std::string &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); @@ -2115,12 +2864,12 @@ public: SIToFPInst( Value *S, ///< The value to be converted const Type *Ty, ///< The type to convert to - const std::string &Name, ///< A name for the new instruction + const std::string &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); /// @brief Clone an identical SIToFPInst - virtual CastInst *clone() const; + virtual CastInst *clone(LLVMContext &Context) const; /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const SIToFPInst *) { return true; } @@ -2146,7 +2895,7 @@ public: FPToUIInst( Value *S, ///< The value to be converted const Type *Ty, ///< The type to convert to - const std::string &Name = "", ///< A name for the new instruction + const std::string &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); @@ -2154,12 +2903,12 @@ public: FPToUIInst( Value *S, ///< The value to be converted const Type *Ty, ///< The type to convert to - const std::string &Name, ///< A name for the new instruction + const std::string &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< Where to insert the new instruction ); /// @brief Clone an identical FPToUIInst - virtual CastInst *clone() const; + virtual CastInst *clone(LLVMContext &Context) const; /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const FPToUIInst *) { return true; } @@ -2185,7 +2934,7 @@ public: FPToSIInst( Value *S, ///< The value to be converted const Type *Ty, ///< The type to convert to - const std::string &Name = "", ///< A name for the new instruction + const std::string &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); @@ -2193,12 +2942,12 @@ public: FPToSIInst( Value *S, ///< The value to be converted const Type *Ty, ///< The type to convert to - const std::string &Name, ///< A name for the new instruction + const std::string &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); /// @brief Clone an identical FPToSIInst - virtual CastInst *clone() const; + virtual CastInst *clone(LLVMContext &Context) const; /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const FPToSIInst *) { return true; } @@ -2224,7 +2973,7 @@ public: IntToPtrInst( Value *S, ///< The value to be converted const Type *Ty, ///< The type to convert to - const std::string &Name = "", ///< A name for the new instruction + const std::string &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); @@ -2232,12 +2981,12 @@ public: IntToPtrInst( Value *S, ///< The value to be converted const Type *Ty, ///< The type to convert to - const std::string &Name, ///< A name for the new instruction + const std::string &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); /// @brief Clone an identical IntToPtrInst - virtual CastInst *clone() const; + virtual CastInst *clone(LLVMContext &Context) const; // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const IntToPtrInst *) { return true; } @@ -2263,7 +3012,7 @@ public: PtrToIntInst( Value *S, ///< The value to be converted const Type *Ty, ///< The type to convert to - const std::string &Name = "", ///< A name for the new instruction + const std::string &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); @@ -2271,12 +3020,12 @@ public: PtrToIntInst( Value *S, ///< The value to be converted const Type *Ty, ///< The type to convert to - const std::string &Name, ///< A name for the new instruction + const std::string &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); /// @brief Clone an identical PtrToIntInst - virtual CastInst *clone() const; + virtual CastInst *clone(LLVMContext &Context) const; // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const PtrToIntInst *) { return true; } @@ -2302,7 +3051,7 @@ public: BitCastInst( Value *S, ///< The value to be casted const Type *Ty, ///< The type to casted to - const std::string &Name = "", ///< A name for the new instruction + const std::string &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); @@ -2310,12 +3059,12 @@ public: BitCastInst( Value *S, ///< The value to be casted const Type *Ty, ///< The type to casted to - const std::string &Name, ///< A name for the new instruction + const std::string &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); /// @brief Clone an identical BitCastInst - virtual CastInst *clone() const; + virtual CastInst *clone(LLVMContext &Context) const; // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const BitCastInst *) { return true; }