diff options
-rw-r--r-- | CREDITS.TXT | 4 | ||||
-rw-r--r-- | include/llvm/Constants.h | 42 | ||||
-rw-r--r-- | include/llvm/GlobalAlias.h | 15 | ||||
-rw-r--r-- | include/llvm/GlobalVariable.h | 35 | ||||
-rw-r--r-- | include/llvm/InstrTypes.h | 71 | ||||
-rw-r--r-- | include/llvm/Instruction.h | 1 | ||||
-rw-r--r-- | include/llvm/Instructions.h | 591 | ||||
-rw-r--r-- | include/llvm/OperandTraits.h | 163 | ||||
-rw-r--r-- | include/llvm/Use.h | 81 | ||||
-rw-r--r-- | include/llvm/User.h | 242 | ||||
-rw-r--r-- | include/llvm/Value.h | 7 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 51 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.h | 50 | ||||
-rw-r--r-- | lib/VMCore/ConstantFold.cpp | 16 | ||||
-rw-r--r-- | lib/VMCore/Constants.cpp | 182 | ||||
-rw-r--r-- | lib/VMCore/Globals.cpp | 18 | ||||
-rw-r--r-- | lib/VMCore/Instructions.cpp | 412 | ||||
-rw-r--r-- | lib/VMCore/Use.cpp | 131 |
18 files changed, 1528 insertions, 584 deletions
diff --git a/CREDITS.TXT b/CREDITS.TXT index 84f7e5ad16..83d1cd39ff 100644 --- a/CREDITS.TXT +++ b/CREDITS.TXT @@ -110,6 +110,10 @@ E: greened@obbligato.org D: Miscellaneous bug fixes D: Register allocation refactoring +N: Gabor Greif +E: ggreif@gmail.com +D: Improvements for space efficiency + N: Gordon Henriksen E: gordonhenriksen@mac.com D: Pluggable GC support diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index c69a381a69..a55c19a86b 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -22,6 +22,7 @@ #include "llvm/Constant.h" #include "llvm/Type.h" +#include "llvm/OperandTraits.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/APFloat.h" @@ -318,7 +319,6 @@ class ConstantArray : public Constant { ConstantArray(const ConstantArray &); // DO NOT IMPLEMENT protected: ConstantArray(const ArrayType *T, const std::vector<Constant*> &Val); - ~ConstantArray(); public: /// get() - Static factory methods - Return objects of the specified value static Constant *get(const ArrayType *T, const std::vector<Constant*> &); @@ -336,6 +336,9 @@ public: /// null termination. static Constant *get(const std::string &Initializer, bool AddNull = true); + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); + /// getType - Specialize the getType() method to always return an ArrayType, /// which reduces the amount of casting needed in parts of the compiler. /// @@ -374,6 +377,11 @@ public: } }; +template <> +struct OperandTraits<ConstantArray> : VariadicOperandTraits<> { +}; + +DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantArray, Constant) //===----------------------------------------------------------------------===// // ConstantStruct - Constant Struct Declarations @@ -384,7 +392,6 @@ class ConstantStruct : public Constant { ConstantStruct(const ConstantStruct &); // DO NOT IMPLEMENT protected: ConstantStruct(const StructType *T, const std::vector<Constant*> &Val); - ~ConstantStruct(); public: /// get() - Static factory methods - Return objects of the specified value /// @@ -396,6 +403,9 @@ public: return get(std::vector<Constant*>(Vals, Vals+NumVals), Packed); } + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); + /// getType() specialization - Reduce amount of casting... /// inline const StructType *getType() const { @@ -419,6 +429,12 @@ public: } }; +template <> +struct OperandTraits<ConstantStruct> : VariadicOperandTraits<> { +}; + +DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantStruct, Constant) + //===----------------------------------------------------------------------===// /// ConstantVector - Constant Vector Declarations /// @@ -428,7 +444,6 @@ class ConstantVector : public Constant { ConstantVector(const ConstantVector &); // DO NOT IMPLEMENT protected: ConstantVector(const VectorType *T, const std::vector<Constant*> &Val); - ~ConstantVector(); public: /// get() - Static factory methods - Return objects of the specified value static Constant *get(const VectorType *T, const std::vector<Constant*> &); @@ -438,6 +453,9 @@ public: return get(std::vector<Constant*>(Vals, Vals+NumVals)); } + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); + /// getType - Specialize the getType() method to always return a VectorType, /// which reduces the amount of casting needed in parts of the compiler. /// @@ -475,6 +493,12 @@ public: } }; +template <> +struct OperandTraits<ConstantVector> : VariadicOperandTraits<> { +}; + +DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantVector, Constant) + //===----------------------------------------------------------------------===// /// ConstantPointerNull - a constant pointer value that points to null /// @@ -573,6 +597,9 @@ public: static Constant *getIntToPtr(Constant *C, const Type *Ty); static Constant *getBitCast (Constant *C, const Type *Ty); + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); + // @brief Convenience function for getting one of the casting operations // using a CastOps opcode. static Constant *getCast( @@ -709,13 +736,13 @@ public: virtual void destroyConstant(); virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); - /// Override methods to provide more type information... +/* /// Override methods to provide more type information... inline Constant *getOperand(unsigned i) { return cast<Constant>(User::getOperand(i)); } inline Constant *getOperand(unsigned i) const { return const_cast<Constant*>(cast<Constant>(User::getOperand(i))); - } + }*/ /// Methods for support type inquiry through isa, cast, and dyn_cast: @@ -725,6 +752,11 @@ public: } }; +template <> +struct OperandTraits<ConstantExpr> : VariadicOperandTraits<1> { +}; + +DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantExpr, Constant) //===----------------------------------------------------------------------===// /// UndefValue - 'undef' values are things that do not have specified contents. diff --git a/include/llvm/GlobalAlias.h b/include/llvm/GlobalAlias.h index b59537c9af..7c147eb62a 100644 --- a/include/llvm/GlobalAlias.h +++ b/include/llvm/GlobalAlias.h @@ -16,6 +16,7 @@ #define LLVM_GLOBAL_ALIAS_H #include "llvm/GlobalValue.h" +#include "llvm/OperandTraits.h" namespace llvm { @@ -42,17 +43,19 @@ class GlobalAlias : public GlobalValue { GlobalAlias *getPrev() { return Prev; } const GlobalAlias *getPrev() const { return Prev; } - Use Aliasee; public: - // allocate space for exactly zero operands + // allocate space for exactly one operand void *operator new(size_t s) { - return User::operator new(s, 0); + return User::operator new(s, 1); } /// GlobalAlias ctor - If a parent module is specified, the alias is /// automatically inserted into the end of the specified module's alias list. GlobalAlias(const Type *Ty, LinkageTypes Linkage, const std::string &Name = "", Constant* Aliasee = 0, Module *Parent = 0); + /// Provide fast operand accessors + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + /// isDeclaration - Is this global variable lacking an initializer? If so, /// the global variable is defined in some other translation unit, and is thus /// only a declaration here. @@ -95,6 +98,12 @@ public: } }; +template <> +struct OperandTraits<GlobalAlias> : FixedNumOperandTraits<1> { +}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GlobalAlias, Value) + } // End llvm namespace #endif diff --git a/include/llvm/GlobalVariable.h b/include/llvm/GlobalVariable.h index 8c6d8030c6..5a42e78a4a 100644 --- a/include/llvm/GlobalVariable.h +++ b/include/llvm/GlobalVariable.h @@ -21,6 +21,7 @@ #define LLVM_GLOBAL_VARIABLE_H #include "llvm/GlobalValue.h" +#include "llvm/OperandTraits.h" namespace llvm { @@ -44,26 +45,32 @@ class GlobalVariable : public GlobalValue { bool isConstantGlobal : 1; // Is this a global constant? bool isThreadLocalSymbol : 1; // Is this symbol "Thread Local"? - Use Initializer; public: - // allocate space for exactly zero operands + // allocate space for exactly one operand void *operator new(size_t s) { - return User::operator new(s, 0); + return User::operator new(s, 1); } /// GlobalVariable ctor - If a parent module is specified, the global is /// automatically inserted into the end of the specified modules global list. GlobalVariable(const Type *Ty, bool isConstant, LinkageTypes Linkage, Constant *Initializer = 0, const std::string &Name = "", - Module *Parent = 0, bool ThreadLocal = false, + Module *Parent = 0, bool ThreadLocal = false, unsigned AddressSpace = 0); /// GlobalVariable ctor - This creates a global and inserts it before the /// specified other global. GlobalVariable(const Type *Ty, bool isConstant, LinkageTypes Linkage, Constant *Initializer, const std::string &Name, - GlobalVariable *InsertBefore, bool ThreadLocal = false, + GlobalVariable *InsertBefore, bool ThreadLocal = false, unsigned AddressSpace = 0); - + + ~GlobalVariable() { + NumOperands = 1; // FIXME: needed by operator delete + } + + /// Provide fast operand accessors + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + /// isDeclaration - Is this global variable lacking an initializer? If so, /// the global variable is defined in some other translation unit, and is thus /// only a declaration here. @@ -79,24 +86,24 @@ public: /// illegal to call this method if the global is external, because we cannot /// tell what the value is initialized to! /// - inline Constant *getInitializer() const { + inline /*const FIXME*/ Constant *getInitializer() const { assert(hasInitializer() && "GV doesn't have initializer!"); - return reinterpret_cast<Constant*>(Initializer.get()); + return static_cast<Constant*>(Op<0>().get()); } inline Constant *getInitializer() { assert(hasInitializer() && "GV doesn't have initializer!"); - return reinterpret_cast<Constant*>(Initializer.get()); + return static_cast<Constant*>(Op<0>().get()); } inline void setInitializer(Constant *CPV) { if (CPV == 0) { if (hasInitializer()) { - Initializer.set(0); + Op<0>().set(0); NumOperands = 0; } } else { if (!hasInitializer()) NumOperands = 1; - Initializer.set(CPV); + Op<0>().set(CPV); } } @@ -141,6 +148,12 @@ private: const GlobalVariable *getPrev() const { return Prev; } }; +template <> +struct OperandTraits<GlobalVariable> : OptionalOperandTraits<> { +}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GlobalVariable, Value) + } // End llvm namespace #endif diff --git a/include/llvm/InstrTypes.h b/include/llvm/InstrTypes.h index f735602ca8..a68b562212 100644 --- a/include/llvm/InstrTypes.h +++ b/include/llvm/InstrTypes.h @@ -17,6 +17,7 @@ #define LLVM_INSTRUCTION_TYPES_H #include "llvm/Instruction.h" +#include "llvm/OperandTraits.h" namespace llvm { @@ -78,22 +79,22 @@ public: } }; + //===----------------------------------------------------------------------===// // UnaryInstruction Class //===----------------------------------------------------------------------===// class UnaryInstruction : public Instruction { void *operator new(size_t, unsigned); // Do not implement - Use Op; - // avoiding warning: 'this' : used in base member initializer list - UnaryInstruction* this_() { return this; } protected: - UnaryInstruction(const Type *Ty, unsigned iType, Value *V, Instruction *IB =0) - : Instruction(Ty, iType, &Op, 1, IB), Op(V, this_()) { + UnaryInstruction(const Type *Ty, unsigned iType, Value *V, Instruction *IB = 0) + : Instruction(Ty, iType, &Op<0>(), 1, IB) { + Op<0>() = V; } UnaryInstruction(const Type *Ty, unsigned iType, Value *V, BasicBlock *IAE) - : Instruction(Ty, iType, &Op, 1, IAE), Op(V, this_()) { + : Instruction(Ty, iType, &Op<0>(), 1, IAE) { + Op<0>() = V; } public: // allocate space for exactly one operand @@ -104,16 +105,8 @@ public: // Out of line virtual method, so the vtable, etc has a home. ~UnaryInstruction(); - // Transparently provide more efficient getOperand methods. - Value *getOperand(unsigned i) const { - assert(i == 0 && "getOperand() out of range!"); - return Op; - } - void setOperand(unsigned i, Value *Val) { - assert(i == 0 && "setOperand() out of range!"); - Op = Val; - } - unsigned getNumOperands() const { return 1; } + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const UnaryInstruction *) { return true; } @@ -130,13 +123,18 @@ public: } }; +template <> +struct OperandTraits<UnaryInstruction> : FixedNumOperandTraits<1> { +}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryInstruction, Value) + //===----------------------------------------------------------------------===// // BinaryOperator Class //===----------------------------------------------------------------------===// class BinaryOperator : public Instruction { void *operator new(size_t, unsigned); // Do not implement - Use Ops[2]; protected: void init(BinaryOps iType); BinaryOperator(BinaryOps iType, Value *S1, Value *S2, const Type *Ty, @@ -150,15 +148,7 @@ public: } /// 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); /// create() - Construct a binary instruction, given the opcode and the two /// operands. Optionally (if InstBefore is specified) insert the instruction @@ -251,6 +241,12 @@ public: } }; +template <> +struct OperandTraits<BinaryOperator> : FixedNumOperandTraits<2> { +}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryOperator, Value) + //===----------------------------------------------------------------------===// // CastInst Class //===----------------------------------------------------------------------===// @@ -497,6 +493,7 @@ public: /// This class is the base class for the comparison instructions. /// @brief Abstract base class of comparison instructions. +// FIXME: why not derive from BinaryOperator? class CmpInst: public Instruction { void *operator new(size_t, unsigned); // DO NOT IMPLEMENT CmpInst(); // do not implement @@ -507,8 +504,6 @@ protected: CmpInst(Instruction::OtherOps op, unsigned short pred, Value *LHS, Value *RHS, const std::string &Name, BasicBlock *InsertAtEnd); - Use Ops[2]; // CmpInst instructions always have 2 operands, optimize - public: // allocate space for exactly two operands void *operator new(size_t s) { @@ -548,17 +543,7 @@ public: } /// @brief 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; - } - - /// @brief CmpInst instructions always have 2 operands. - unsigned getNumOperands() const { return 2; } + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); /// This is just a convenience that dispatches to the subclasses. /// @brief Swap the operands and adjust predicate accordingly to retain @@ -598,6 +583,14 @@ public: } }; + +// FIXME: these are redundant if CmpInst < BinaryOperator +template <> +struct OperandTraits<CmpInst> : FixedNumOperandTraits<2> { +}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CmpInst, Value) + } // End llvm namespace #endif diff --git a/include/llvm/Instruction.h b/include/llvm/Instruction.h index 29ae5c3cfb..40d83059fe 100644 --- a/include/llvm/Instruction.h +++ b/include/llvm/Instruction.h @@ -20,7 +20,6 @@ namespace llvm { struct AssemblyAnnotationWriter; -class BinaryOperator; template<typename ValueSubClass, typename ItemParentClass> class SymbolTableListTraits; diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index f292a3173f..86bc3f5793 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -21,10 +21,10 @@ #include "llvm/InstrTypes.h" #include "llvm/DerivedTypes.h" #include "llvm/ParameterAttributes.h" +#include "llvm/BasicBlock.h" namespace llvm { -class BasicBlock; class ConstantInt; class PointerType; class VectorType; @@ -288,11 +288,11 @@ public: /// class StoreInst : public Instruction { void *operator new(size_t, unsigned); // DO NOT IMPLEMENT - 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); + StoreInst(const StoreInst &SI) : Instruction(SI.getType(), Store, + &Op<0>(), 2) { + Op<0>().init(SI.Op<0>(), this); + Op<1>().init(SI.Op<1>(), this); setVolatile(SI.isVolatile()); setAlignment(SI.getAlignment()); @@ -329,15 +329,7 @@ public: } /// 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 /// @@ -363,6 +355,11 @@ public: } }; +template <> +struct OperandTraits<StoreInst> : FixedNumOperandTraits<2> { +}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(StoreInst, Value) //===----------------------------------------------------------------------===// // GetElementPtrInst Class @@ -380,14 +377,7 @@ 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<const Type*>(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); - } + GetElementPtrInst(const GetElementPtrInst &GEPI); void init(Value *Ptr, Value* const *Idx, unsigned NumIdx); void init(Value *Ptr, Value *Idx); @@ -400,8 +390,9 @@ class GetElementPtrInst : public Instruction { unsigned NumIdx = static_cast<unsigned>(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); // FIXME: for the general case + // we have to build an array here } else { init(Ptr, 0, NumIdx); @@ -446,34 +437,21 @@ class GetElementPtrInst : public Instruction { /// instruction, the second appends the new instruction to the specified /// BasicBlock. template<typename InputIterator> - 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<PointerType>(Ptr->getType())->getAddressSpace()), - GetElementPtr, 0, 0, InsertBefore) { - init(Ptr, IdxBegin, IdxEnd, Name, - typename std::iterator_traits<InputIterator>::iterator_category()); - } + inline GetElementPtrInst(Value *Ptr, InputIterator IdxBegin, + InputIterator IdxEnd, + unsigned Values, + const std::string &Name, + Instruction *InsertBefore); template<typename InputIterator> - GetElementPtrInst(Value *Ptr, InputIterator IdxBegin, InputIterator IdxEnd, - const std::string &Name, BasicBlock *InsertAtEnd) - : Instruction(PointerType::get( - checkType(getIndexedType(Ptr->getType(), - IdxBegin, IdxEnd, true)), - cast<PointerType>(Ptr->getType())->getAddressSpace()), - GetElementPtr, 0, 0, InsertAtEnd) { - init(Ptr, IdxBegin, IdxEnd, Name, - typename std::iterator_traits<InputIterator>::iterator_category()); - } + inline GetElementPtrInst(Value *Ptr, + InputIterator IdxBegin, InputIterator IdxEnd, + unsigned Values, + const std::string &Name, 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 &Name = "", 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); public: @@ -482,28 +460,40 @@ public: InputIterator IdxEnd, const std::string &Name = "", Instruction *InsertBefore = 0) { - return new(0/*FIXME*/) GetElementPtrInst(Ptr, IdxBegin, IdxEnd, Name, InsertBefore); + typename std::iterator_traits<InputIterator>::difference_type Values = + 1 + std::distance(IdxBegin, IdxEnd); + return new(Values) + GetElementPtrInst(Ptr, IdxBegin, IdxEnd, Values, Name, InsertBefore); } template<typename InputIterator> - static GetElementPtrInst *Create(Value *Ptr, InputIterator IdxBegin, InputIterator IdxEnd, - const std::string &Name, BasicBlock *InsertAtEnd) { - return new(0/*FIXME*/) GetElementPtrInst(Ptr, IdxBegin, IdxEnd, Name, InsertAtEnd); + static GetElementPtrInst *Create(Value *Ptr, + InputIterator IdxBegin, InputIterator IdxEnd, + const std::string &Name, + BasicBlock *InsertAtEnd) { + typename std::iterator_traits<InputIterator>::difference_type Values = + 1 + std::distance(IdxBegin, IdxEnd); + return new(Values) + GetElementPtrInst(Ptr, IdxBegin, IdxEnd, Values, Name, InsertAtEnd); } - /// Constructors - These two constructors are convenience methods because one - /// and two index getelementptr instructions are so common. + /// 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 &Name = "", Instruction *InsertBefore = 0) { - return new(2/*FIXME*/) GetElementPtrInst(Ptr, Idx, Name, InsertBefore); + const std::string &Name = "", + Instruction *InsertBefore = 0) { + return new(2) GetElementPtrInst(Ptr, Idx, Name, InsertBefore); } static GetElementPtrInst *Create(Value *Ptr, Value *Idx, - const std::string &Name, BasicBlock *InsertAtEnd) { - return new(2/*FIXME*/) GetElementPtrInst(Ptr, Idx, Name, InsertAtEnd); + const std::string &Name, + BasicBlock *InsertAtEnd) { + return new(2) GetElementPtrInst(Ptr, Idx, Name, InsertAtEnd); } - ~GetElementPtrInst(); virtual GetElementPtrInst *clone() const; + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + // getType - Overload to return most specific pointer type... const PointerType *getType() const { return reinterpret_cast<const PointerType*>(Instruction::getType()); @@ -570,6 +560,51 @@ public: } }; +template <> +struct OperandTraits<GetElementPtrInst> : VariadicOperandTraits<1> { +}; + +template<typename InputIterator> +GetElementPtrInst::GetElementPtrInst(Value *Ptr, + InputIterator IdxBegin, + InputIterator IdxEnd, + unsigned Values, + const std::string &Name, + Instruction *InsertBefore) + : Instruction(PointerType::get(checkType( + getIndexedType(Ptr->getType(), + IdxBegin, IdxEnd, true)), + cast<PointerType>(Ptr->getType()) + ->getAddressSpace()), + GetElementPtr, + OperandTraits<GetElementPtrInst>::op_end(this) - Values, + Values, InsertBefore) { + init(Ptr, IdxBegin, IdxEnd, Name, + typename std::iterator_traits<InputIterator>::iterator_category()); +} +template<typename InputIterator> +GetElementPtrInst::GetElementPtrInst(Value *Ptr, + InputIterator IdxBegin, + InputIterator IdxEnd, + unsigned Values, + const std::string &Name, + BasicBlock *InsertAtEnd) + : Instruction(PointerType::get(checkType( + getIndexedType(Ptr->getType(), + IdxBegin, IdxEnd, true)), + cast<PointerType>(Ptr->getType()) + ->getAddressSpace()), + GetElementPtr, + OperandTraits<GetElementPtrInst>::op_end(this) - Values, + Values, InsertAtEnd) { + init(Ptr, IdxBegin, IdxEnd, Name, + typename std::iterator_traits<InputIterator>::iterator_category()); +} + + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrInst, Value) + + //===----------------------------------------------------------------------===// // ICmpInst Class //===----------------------------------------------------------------------===// @@ -723,7 +758,7 @@ public: /// @brief Swap operands and adjust predicate. void swapOperands() { SubclassData = getSwappedPredicate(); - std::swap(Ops[0], Ops[1]); + std::swap(Op<0>(), Op<1>()); } virtual ICmpInst *clone() const; @@ -847,7 +882,7 @@ public: /// @brief Swap operands and adjust predicate. void swapOperands() { SubclassData = getSwappedPredicate(); - std::swap(Ops[0], Ops[1]); + std::swap(Op<0>(), Op<1>()); } virtual FCmpInst *clone() const; @@ -900,13 +935,7 @@ class CallInst : public Instruction { /// @brief Construct a CallInst from a range of arguments template<typename InputIterator> CallInst(Value *Func, InputIterator ArgBegin, InputIterator ArgEnd, - const std::string &Name = "", Instruction *InsertBefore = 0) - : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType()) - ->getElementType())->getReturnType(), - Instruction::Call, 0, 0, InsertBefore) { - init(Func, ArgBegin, ArgEnd, Name, - typename std::iterator_traits<InputIterator>::iterator_category()); - } + const std::string &Name, Instruction *InsertBefore); /// Construct a CallInst given a range of arguments. InputIterator /// must be a random-access iterator pointing to contiguous storage @@ -915,35 +944,29 @@ class CallInst : public Instruction { /// incur runtime overhead. /// @brief Construct a CallInst from a range of arguments template<typename InputIterator> - CallInst(Value *Func, InputIterator ArgBegin, InputIterator ArgEnd, - const std::string &Name, BasicBlock *InsertAtEnd) - : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType()) - ->getElementType())->getReturnType(), - Instruction::Call, 0, 0, InsertAtEnd) { - init(Func, ArgBegin, ArgEnd, Name, - typename std::iterator_traits<InputIterator>::iterator_category()); - } + inline CallInst(Value *Func, InputIterator ArgBegin, InputIterator ArgEnd, + const std::string &Name, BasicBlock *InsertAtEnd); - CallInst(Value *F, Value *Actual, const std::string& Name = "", - Instruction *InsertBefore = 0); + CallInst(Value *F, Value *Actual, const std::string& Name, + Instruction *InsertBefore); CallInst(Value *F, Value *Actual, const std::string& Name, BasicBlock *InsertAtEnd); - explicit CallInst(Value *F, const std::string &Name = "", - Instruction *InsertBefore = 0); + explicit CallInst(Value *F, const std::string &Name, + Instruction *InsertBefore); CallInst(Value *F, const std::string &Name, BasicBlock *InsertAtEnd); public: template<typename InputIterator> - static CallInst *Create(Value *Func, InputIterator ArgBegin, - InputIterator ArgEnd, + static CallInst *Create(Value *Func, + InputIterator ArgBegin, InputIterator ArgEnd, const std::string &Name = "", Instruction *InsertBefore = 0) { return new(ArgEnd - ArgBegin + 1) CallInst(Func, ArgBegin, ArgEnd, Name, InsertBefore); } template<typename InputIterator> - static CallInst *Create(Value *Func, InputIterator ArgBegin, - InputIterator ArgEnd, const std::string &Name, - BasicBlock *InsertAtEnd) { + static CallInst *Create(Value *Func, + InputIterator ArgBegin, InputIterator ArgEnd, + const std::string &Name, BasicBlock *InsertAtEnd) { return new(ArgEnd - ArgBegin + 1) CallInst(Func, ArgBegin, ArgEnd, Name, InsertAtEnd); } @@ -967,6 +990,9 @@ public: ~CallInst(); virtual CallInst *clone() const; + + /// Provide fast operand accessors + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); bool isTailCall() const { return SubclassData & 1; } void setTailCall(bool isTailCall = true) { @@ -1050,6 +1076,36 @@ public: } }; +template <> +struct OperandTraits<CallInst> : VariadicOperandTraits<1> { +}; + +template<typename InputIterator> +CallInst::CallInst(Value *Func, InputIterator ArgBegin, InputIterator ArgEnd, + const std::string &Name, BasicBlock *InsertAtEnd) + : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType()) + ->getElementType())->getReturnType(), + Instruction::Call, + OperandTraits<CallInst>::op_end(this) - (ArgEnd - ArgBegin + 1), + ArgEnd - ArgBegin + 1, InsertAtEnd) { + init(Func, ArgBegin, ArgEnd, Name, + typename std::iterator_traits<InputIterator>::iterator_category()); +} + +template<typename InputIterator> +CallInst::CallInst(Value *Func, InputIterator ArgBegin, InputIterator ArgEnd, + const std::string &Name, Instruction *InsertBefore) + : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType()) + ->getElementType())->getReturnType(), + Instruction::Call, + OperandTraits<CallInst>::op_end(this) - (ArgEnd - ArgBegin + 1), + ArgEnd - ArgBegin + 1, InsertBefore) { + init(Func, ArgBegin, ArgEnd, Name, + typename std::iterator_traits<InputIterator>::iterator_category()); +} + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CallInst, Value) + //===----------------------------------------------------------------------===// // SelectInst Class //===----------------------------------------------------------------------===// @@ -1057,27 +1113,27 @@ 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); + Op<0>() = C; + Op<1>() = S1; + Op<2>() = S2; } SelectInst(const SelectInst &SI) - : Instruct |