X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FInstructions.h;h=337ae2a463b78b07fb58c52a302935b114db8699;hb=3a84b9baf67c938454840d10d9e53269c755cd3e;hp=904ca8f3784ef96f7782d0c0de05b828d32bdaf1;hpb=edd5d9ece15f73ec1a31423a4ae39774aa6c521c;p=oota-llvm.git diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index 904ca8f3784..337ae2a463b 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -16,7 +16,6 @@ #ifndef LLVM_INSTRUCTIONS_H #define LLVM_INSTRUCTIONS_H -#include "llvm/Instruction.h" #include "llvm/InstrTypes.h" namespace llvm { @@ -24,6 +23,9 @@ namespace llvm { class BasicBlock; class ConstantInt; class PointerType; +class VectorType; +class ConstantRange; +class APInt; //===----------------------------------------------------------------------===// // AllocationInst Class @@ -33,13 +35,15 @@ class PointerType; /// AllocaInst. /// class AllocationInst : public UnaryInstruction { + unsigned Alignment; protected: - AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, + 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, + 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. + virtual ~AllocationInst(); /// isArrayAllocation - Return true if there is an allocation size parameter /// to the allocation instruction that is not 1. @@ -63,6 +67,15 @@ public: /// const Type *getAllocatedType() const; + /// 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; + } + virtual Instruction *clone() const = 0; // Methods for support type inquiry through isa, cast, and dyn_cast: @@ -89,10 +102,24 @@ public: explicit MallocInst(const Type *Ty, Value *ArraySize = 0, const std::string &Name = "", Instruction *InsertBefore = 0) - : AllocationInst(Ty, ArraySize, Malloc, Name, InsertBefore) {} + : AllocationInst(Ty, ArraySize, Malloc, 0, Name, InsertBefore) {} MallocInst(const Type *Ty, Value *ArraySize, const std::string &Name, BasicBlock *InsertAtEnd) - : AllocationInst(Ty, ArraySize, Malloc, Name, InsertAtEnd) {} + : AllocationInst(Ty, ArraySize, Malloc, 0, Name, InsertAtEnd) {} + + MallocInst(const Type *Ty, const std::string &Name, + 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) {} virtual MallocInst *clone() const; @@ -119,10 +146,23 @@ public: explicit AllocaInst(const Type *Ty, Value *ArraySize = 0, const std::string &Name = "", Instruction *InsertBefore = 0) - : AllocationInst(Ty, ArraySize, Alloca, Name, InsertBefore) {} + : AllocationInst(Ty, ArraySize, Alloca, 0, Name, InsertBefore) {} AllocaInst(const Type *Ty, Value *ArraySize, const std::string &Name, BasicBlock *InsertAtEnd) - : AllocationInst(Ty, ArraySize, Alloca, Name, InsertAtEnd) {} + : AllocationInst(Ty, ArraySize, Alloca, 0, Name, InsertAtEnd) {} + + AllocaInst(const Type *Ty, const std::string &Name, + 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) {} + + 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) {} virtual AllocaInst *clone() const; @@ -151,8 +191,6 @@ public: virtual FreeInst *clone() const; - virtual bool mayWriteToMemory() const { return true; } - // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const FreeInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -184,11 +222,18 @@ class LoadInst : public UnaryInstruction { 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, + LoadInst(Value *Ptr, const std::string &Name, bool isVolatile = false, Instruction *InsertBefore = 0); LoadInst(Value *Ptr, const std::string &Name, 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. /// @@ -200,8 +245,6 @@ public: virtual LoadInst *clone() const; - virtual bool mayWriteToMemory() const { return isVolatile(); } - Value *getPointerOperand() { return getOperand(0); } const Value *getPointerOperand() const { return getOperand(0); } static unsigned getPointerOperandIndex() { return 0U; } @@ -265,8 +308,6 @@ public: virtual StoreInst *clone() const; - virtual bool mayWriteToMemory() const { return true; } - Value *getPointerOperand() { return getOperand(1); } const Value *getPointerOperand() const { return getOperand(1); } static unsigned getPointerOperandIndex() { return 1U; } @@ -298,7 +339,7 @@ class GetElementPtrInst : public Instruction { for (unsigned i = 0, E = NumOperands; i != E; ++i) OL[i].init(GEPIOL[i], this); } - void init(Value *Ptr, const std::vector &Idx); + void init(Value *Ptr, Value* const *Idx, unsigned NumIdx); void init(Value *Ptr, Value *Idx0, Value *Idx1); void init(Value *Ptr, Value *Idx); public: @@ -306,11 +347,11 @@ public: /// list of indices. The first ctor can optionally insert before an existing /// instruction, the second appends the new instruction to the specified /// BasicBlock. - GetElementPtrInst(Value *Ptr, const std::vector &Idx, + GetElementPtrInst(Value *Ptr, Value* const *Idx, unsigned NumIdx, const std::string &Name = "", Instruction *InsertBefore =0); - GetElementPtrInst(Value *Ptr, const std::vector &Idx, + GetElementPtrInst(Value *Ptr, Value* const *Idx, unsigned NumIdx, 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, @@ -337,8 +378,9 @@ public: /// pointer type. /// static const Type *getIndexedType(const Type *Ptr, - const std::vector &Indices, + Value* const *Idx, unsigned NumIdx, bool AllowStructLeaf = false); + static const Type *getIndexedType(const Type *Ptr, Value *Idx0, Value *Idx1, bool AllowStructLeaf = false); static const Type *getIndexedType(const Type *Ptr, Value *Idx); @@ -377,51 +419,143 @@ public: }; //===----------------------------------------------------------------------===// -// SetCondInst Class +// ICmpInst Class //===----------------------------------------------------------------------===// -/// SetCondInst class - Represent a setCC operator, where CC is eq, ne, lt, gt, -/// le, or ge. -/// -class SetCondInst : public BinaryOperator { +/// 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. +/// @brief Represent an integer comparison operator. +class ICmpInst: public CmpInst { public: - SetCondInst(BinaryOps Opcode, Value *LHS, Value *RHS, - const std::string &Name = "", Instruction *InsertBefore = 0); - SetCondInst(BinaryOps Opcode, Value *LHS, Value *RHS, - const std::string &Name, BasicBlock *InsertAtEnd); - - /// getInverseCondition - Return the inverse of the current condition opcode. - /// For example seteq -> setne, setgt -> setle, setlt -> setge, etc... - /// - BinaryOps getInverseCondition() const { - return getInverseCondition(getOpcode()); - } - - /// getInverseCondition - Static version that you can use without an - /// instruction available. - /// - static BinaryOps getInverseCondition(BinaryOps Opcode); - - /// getSwappedCondition - Return the condition opcode that would be the result - /// of exchanging the two operands of the setcc instruction without changing - /// the result produced. Thus, seteq->seteq, setle->setge, setlt->setgt, etc. - /// - BinaryOps getSwappedCondition() const { - return getSwappedCondition(getOpcode()); + /// 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( + 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) { + } + + /// @brief Constructor with insert-at-block-end semantics. + ICmpInst( + 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()); + } + + /// 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. + /// @brief Return the signed version of the predicate + Predicate getSignedPredicate() const { + return getSignedPredicate(getPredicate()); + } + + /// This is a static version that you can use without an instruction. + /// @brief Return the signed version of the predicate. + static Predicate getSignedPredicate(Predicate pred); + + /// This also tests for commutativity. If isEquality() returns true then + /// the predicate is also 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 == ICMP_EQ || SubclassData == ICMP_NE; + } + + /// @returns true if the predicate of this ICmpInst is commutative + /// @brief Determine if this relation is commutative. + bool isCommutative() const { return isEquality(); } + + /// @returns true if the predicate is relational (not EQ or NE). + /// @brief Determine if this a relational predicate. + bool isRelational() const { + return !isEquality(); + } + + /// @returns true if the predicate of this ICmpInst is signed, false otherwise + /// @brief Determine if this instruction's predicate is signed. + bool isSignedPredicate() { return isSignedPredicate(getPredicate()); } + + /// @returns true if the predicate provided is signed, false otherwise + /// @brief Determine if the predicate is signed. + static bool isSignedPredicate(Predicate pred); + + /// 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). + /// @brief Swap operands and adjust predicate. + void swapOperands() { + SubclassData = getSwappedPredicate(); + std::swap(Ops[0], Ops[1]); } - /// getSwappedCondition - Static version that you can use without an - /// instruction available. - /// - static BinaryOps getSwappedCondition(BinaryOps Opcode); - - // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SetCondInst *) { return true; } + static inline bool classof(const ICmpInst *) { return true; } static inline bool classof(const Instruction *I) { - return I->getOpcode() == SetEQ || I->getOpcode() == SetNE || - I->getOpcode() == SetLE || I->getOpcode() == SetGE || - I->getOpcode() == SetLT || I->getOpcode() == SetGT; + return I->getOpcode() == Instruction::ICmp; } static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); @@ -429,39 +563,127 @@ public: }; //===----------------------------------------------------------------------===// -// CastInst Class +// FCmpInst Class //===----------------------------------------------------------------------===// -/// CastInst - This class represents a cast from Operand[0] to the type of -/// the instruction (i->getType()). -/// -class CastInst : public UnaryInstruction { - CastInst(const CastInst &CI) - : UnaryInstruction(CI.getType(), Cast, CI.getOperand(0)) { - } +/// This instruction compares its operands according to the predicate given +/// 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: - CastInst(Value *S, const Type *Ty, const std::string &Name = "", - Instruction *InsertBefore = 0) - : UnaryInstruction(Ty, Cast, S, Name, InsertBefore) { - } - CastInst(Value *S, const Type *Ty, const std::string &Name, - BasicBlock *InsertAtEnd) - : UnaryInstruction(Ty, Cast, S, Name, InsertAtEnd) { - } - - virtual CastInst *clone() const; - - // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const CastInst *) { return true; } + /// 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( + 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) { + } + + /// @brief Constructor with insert-at-block-end semantics. + FCmpInst( + 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()); + } + + /// 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). + /// @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). + /// @brief Swap operands and adjust predicate. + void swapOperands() { + SubclassData = getSwappedPredicate(); + std::swap(Ops[0], Ops[1]); + } + + /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const FCmpInst *) { return true; } static inline bool classof(const Instruction *I) { - return I->getOpcode() == Cast; + return I->getOpcode() == Instruction::FCmp; } static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; - //===----------------------------------------------------------------------===// // CallInst Class //===----------------------------------------------------------------------===// @@ -473,17 +695,17 @@ public: /// class CallInst : public Instruction { CallInst(const CallInst &CI); - void init(Value *Func, const std::vector &Params); + void init(Value *Func, Value* const *Params, unsigned NumParams); void init(Value *Func, Value *Actual1, Value *Actual2); void init(Value *Func, Value *Actual); void init(Value *Func); public: - CallInst(Value *F, const std::vector &Par, + CallInst(Value *F, Value* const *Args, unsigned NumArgs, const std::string &Name = "", Instruction *InsertBefore = 0); - CallInst(Value *F, const std::vector &Par, + CallInst(Value *F, Value *const *Args, unsigned NumArgs, const std::string &Name, BasicBlock *InsertAtEnd); - + // Alternate CallInst ctors w/ two actuals, w/ one actual and no // actuals, respectively. CallInst(Value *F, Value *Actual1, Value *Actual2, @@ -496,13 +718,11 @@ public: BasicBlock *InsertAtEnd); explicit CallInst(Value *F, const std::string &Name = "", Instruction *InsertBefore = 0); - explicit CallInst(Value *F, const std::string &Name, - BasicBlock *InsertAtEnd); + CallInst(Value *F, const std::string &Name, BasicBlock *InsertAtEnd); ~CallInst(); virtual CallInst *clone() const; - bool mayWriteToMemory() const { return true; } - + bool isTailCall() const { return SubclassData & 1; } void setTailCall(bool isTailCall = true) { SubclassData = (SubclassData & ~1) | unsigned(isTailCall); @@ -522,7 +742,8 @@ public: return static_cast(dyn_cast(getOperand(0))); } - // getCalledValue - Get a pointer to a method that is invoked by this inst. + /// 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); } @@ -536,66 +757,6 @@ public: } }; - -//===----------------------------------------------------------------------===// -// ShiftInst Class -//===----------------------------------------------------------------------===// - -/// ShiftInst - This class represents left and right shift instructions. -/// -class ShiftInst : public Instruction { - Use Ops[2]; - ShiftInst(const ShiftInst &SI) - : Instruction(SI.getType(), SI.getOpcode(), Ops, 2) { - Ops[0].init(SI.Ops[0], this); - Ops[1].init(SI.Ops[1], this); - } - void init(OtherOps Opcode, Value *S, Value *SA) { - assert((Opcode == Shl || Opcode == Shr) && "ShiftInst Opcode invalid!"); - Ops[0].init(S, this); - Ops[1].init(SA, this); - } - -public: - ShiftInst(OtherOps Opcode, Value *S, Value *SA, const std::string &Name = "", - Instruction *InsertBefore = 0) - : Instruction(S->getType(), Opcode, Ops, 2, Name, InsertBefore) { - init(Opcode, S, SA); - } - ShiftInst(OtherOps Opcode, Value *S, Value *SA, const std::string &Name, - BasicBlock *InsertAtEnd) - : Instruction(S->getType(), Opcode, Ops, 2, Name, InsertAtEnd) { - init(Opcode, S, SA); - } - - OtherOps getOpcode() const { - return static_cast(Instruction::getOpcode()); - } - - /// 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; } - - virtual ShiftInst *clone() const; - - // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const ShiftInst *) { return true; } - static inline bool classof(const Instruction *I) { - return (I->getOpcode() == Instruction::Shr) | - (I->getOpcode() == Instruction::Shl); - } - static inline bool classof(const Value *V) { - return isa(V) && classof(cast(V)); - } -}; - //===----------------------------------------------------------------------===// // SelectInst Class //===----------------------------------------------------------------------===// @@ -618,15 +779,15 @@ class SelectInst : public Instruction { public: SelectInst(Value *C, Value *S1, Value *S2, const std::string &Name = "", Instruction *InsertBefore = 0) - : Instruction(S1->getType(), Instruction::Select, Ops, 3, - Name, InsertBefore) { + : Instruction(S1->getType(), Instruction::Select, Ops, 3, InsertBefore) { init(C, S1, S2); + setName(Name); } SelectInst(Value *C, Value *S1, Value *S2, const std::string &Name, BasicBlock *InsertAtEnd) - : Instruction(S1->getType(), Instruction::Select, Ops, 3, - Name, InsertAtEnd) { + : Instruction(S1->getType(), Instruction::Select, Ops, 3, InsertAtEnd) { init(C, S1, S2); + setName(Name); } Value *getCondition() const { return Ops[0]; } @@ -660,81 +821,197 @@ public: } }; +//===----------------------------------------------------------------------===// +// VAArgInst Class +//===----------------------------------------------------------------------===// + +/// VAArgInst - This class represents the va_arg llvm instruction, which returns +/// an argument of the specified type given a va_list and increments that list +/// +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 = "", + Instruction *InsertBefore = 0) + : UnaryInstruction(Ty, VAArg, List, InsertBefore) { + setName(Name); + } + VAArgInst(Value *List, const Type *Ty, const std::string &Name, + BasicBlock *InsertAtEnd) + : UnaryInstruction(Ty, VAArg, List, InsertAtEnd) { + setName(Name); + } + + virtual VAArgInst *clone() const; + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const VAArgInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == VAArg; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +}; //===----------------------------------------------------------------------===// -// VANextInst Class +// ExtractElementInst Class //===----------------------------------------------------------------------===// -/// VANextInst - This class represents the va_next llvm instruction, which -/// advances a vararg list passed an argument of the specified type, returning -/// the resultant list. +/// ExtractElementInst - This instruction extracts a single (scalar) +/// element from a VectorType value /// -class VANextInst : public UnaryInstruction { - PATypeHolder ArgTy; - VANextInst(const VANextInst &VAN) - : UnaryInstruction(VAN.getType(), VANext, VAN.getOperand(0)), - ArgTy(VAN.getArgType()) { +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); } public: - VANextInst(Value *List, const Type *Ty, const std::string &Name = "", - Instruction *InsertBefore = 0) - : UnaryInstruction(List->getType(), VANext, List, Name, InsertBefore), - ArgTy(Ty) { + ExtractElementInst(Value *Vec, Value *Idx, const std::string &Name = "", + Instruction *InsertBefore = 0); + ExtractElementInst(Value *Vec, unsigned Idx, const std::string &Name = "", + Instruction *InsertBefore = 0); + ExtractElementInst(Value *Vec, Value *Idx, const std::string &Name, + BasicBlock *InsertAtEnd); + ExtractElementInst(Value *Vec, unsigned Idx, const std::string &Name, + 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; + + /// Transparently provide more efficient getOperand methods. + Value *getOperand(unsigned i) const { + assert(i < 2 && "getOperand() out of range!"); + return Ops[i]; } - VANextInst(Value *List, const Type *Ty, const std::string &Name, - BasicBlock *InsertAtEnd) - : UnaryInstruction(List->getType(), VANext, List, Name, InsertAtEnd), - ArgTy(Ty) { + void setOperand(unsigned i, Value *Val) { + assert(i < 2 && "setOperand() out of range!"); + Ops[i] = Val; } + unsigned getNumOperands() const { return 2; } - const Type *getArgType() const { return ArgTy; } + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const ExtractElementInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == Instruction::ExtractElement; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +}; + +//===----------------------------------------------------------------------===// +// InsertElementInst Class +//===----------------------------------------------------------------------===// + +/// InsertElementInst - This instruction inserts a single (scalar) +/// 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); + 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); + + /// 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; + + /// getType - Overload to return most specific vector type. + /// + inline const VectorType *getType() const { + return reinterpret_cast(Instruction::getType()); + } - virtual VANextInst *clone() const; + /// 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; } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const VANextInst *) { return true; } + static inline bool classof(const InsertElementInst *) { return true; } static inline bool classof(const Instruction *I) { - return I->getOpcode() == VANext; + return I->getOpcode() == Instruction::InsertElement; } static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; - //===----------------------------------------------------------------------===// -// VAArgInst Class +// ShuffleVectorInst Class //===----------------------------------------------------------------------===// -/// VAArgInst - This class represents the va_arg llvm instruction, which returns -/// an argument of the specified type given a va_list. +/// ShuffleVectorInst - This instruction constructs a fixed permutation of two +/// input vectors. /// -class VAArgInst : public UnaryInstruction { - VAArgInst(const VAArgInst &VAA) - : UnaryInstruction(VAA.getType(), VAArg, VAA.getOperand(0)) {} +class ShuffleVectorInst : public Instruction { + Use Ops[3]; + ShuffleVectorInst(const ShuffleVectorInst &IE); public: - VAArgInst(Value *List, const Type *Ty, const std::string &Name = "", - Instruction *InsertBefore = 0) - : UnaryInstruction(Ty, VAArg, List, Name, InsertBefore) { - } - VAArgInst(Value *List, const Type *Ty, const std::string &Name, - BasicBlock *InsertAtEnd) - : UnaryInstruction(Ty, VAArg, List, Name, InsertAtEnd) { + ShuffleVectorInst(Value *V1, Value *V2, Value *Mask, + const std::string &Name = "", Instruction *InsertBefor = 0); + ShuffleVectorInst(Value *V1, Value *V2, Value *Mask, + const std::string &Name, 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; + + /// getType - Overload to return most specific vector type. + /// + inline const VectorType *getType() const { + return reinterpret_cast(Instruction::getType()); } - virtual VAArgInst *clone() const; + /// 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; } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const VAArgInst *) { return true; } + static inline bool classof(const ShuffleVectorInst *) { return true; } static inline bool classof(const Instruction *I) { - return I->getOpcode() == VAArg; + return I->getOpcode() == Instruction::ShuffleVector; } static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; + //===----------------------------------------------------------------------===// // PHINode Class //===----------------------------------------------------------------------===// @@ -749,15 +1026,17 @@ class PHINode : public Instruction { unsigned ReservedSpace; PHINode(const PHINode &PN); public: - PHINode(const Type *Ty, const std::string &Name = "", - Instruction *InsertBefore = 0) - : Instruction(Ty, Instruction::PHI, 0, 0, Name, InsertBefore), + explicit PHINode(const Type *Ty, const std::string &Name = "", + Instruction *InsertBefore = 0) + : Instruction(Ty, Instruction::PHI, 0, 0, InsertBefore), ReservedSpace(0) { + setName(Name); } PHINode(const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd) - : Instruction(Ty, Instruction::PHI, 0, 0, Name, InsertAtEnd), + : Instruction(Ty, Instruction::PHI, 0, 0, InsertAtEnd), ReservedSpace(0) { + setName(Name); } ~PHINode(); @@ -776,7 +1055,7 @@ public: /// unsigned getNumIncomingValues() const { return getNumOperands()/2; } - /// getIncomingValue - Return incoming value #x + /// getIncomingValue - Return incoming value number x /// Value *getIncomingValue(unsigned i) const { assert(i*2 < getNumOperands() && "Invalid value number!"); @@ -790,7 +1069,7 @@ public: return i*2; } - /// getIncomingBlock - Return incoming basic block #x + /// getIncomingBlock - Return incoming basic block number x /// BasicBlock *getIncomingBlock(unsigned i) const { return reinterpret_cast(getOperand(i*2+1)); @@ -846,6 +1125,11 @@ public: return getIncomingValue(getBasicBlockIndex(BB)); } + /// hasConstantValue - If the specified PHI node always merges together the + /// same value, return the value, otherwise return null. + /// + Value *hasConstantValue(bool AllowNonDominatingInstruction = false) const; + /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const PHINode *) { return true; } static inline bool classof(const Instruction *I) { @@ -867,13 +1151,8 @@ public: /// does not continue in this function any longer. /// class ReturnInst : public TerminatorInst { - Use RetVal; // Possibly null retval. - ReturnInst(const ReturnInst &RI) : TerminatorInst(Instruction::Ret, &RetVal, - RI.getNumOperands()) { - if (RI.getNumOperands()) - RetVal.init(RI.RetVal, this); - } - + Use RetVal; // Return Value: null if 'void'. + ReturnInst(const ReturnInst &RI); void init(Value *RetVal); public: @@ -888,17 +1167,9 @@ public: // // NOTE: If the Value* passed is of type void then the constructor behaves as // if it was passed NULL. - ReturnInst(Value *retVal = 0, Instruction *InsertBefore = 0) - : TerminatorInst(Instruction::Ret, &RetVal, 0, InsertBefore) { - init(retVal); - } - ReturnInst(Value *retVal, BasicBlock *InsertAtEnd) - : TerminatorInst(Instruction::Ret, &RetVal, 0, InsertAtEnd) { - init(retVal); - } - ReturnInst(BasicBlock *InsertAtEnd) - : TerminatorInst(Instruction::Ret, &RetVal, 0, InsertAtEnd) { - } + explicit ReturnInst(Value *retVal = 0, Instruction *InsertBefore = 0); + ReturnInst(Value *retVal, BasicBlock *InsertAtEnd); + explicit ReturnInst(BasicBlock *InsertAtEnd); virtual ReturnInst *clone() const; @@ -952,39 +1223,12 @@ public: // BranchInst(BB* T, BB *F, Value *C, Inst *I) - 'br C, T, F', insert before I // BranchInst(BB* B, BB *I) - 'br B' insert at end // BranchInst(BB* T, BB *F, Value *C, BB *I) - 'br C, T, F', insert at end - BranchInst(BasicBlock *IfTrue, Instruction *InsertBefore = 0) - : TerminatorInst(Instruction::Br, Ops, 1, InsertBefore) { - assert(IfTrue != 0 && "Branch destination may not be null!"); - Ops[0].init(reinterpret_cast(IfTrue), this); - } + explicit BranchInst(BasicBlock *IfTrue, Instruction *InsertBefore = 0); BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond, - Instruction *InsertBefore = 0) - : TerminatorInst(Instruction::Br, Ops, 3, InsertBefore) { - Ops[0].init(reinterpret_cast(IfTrue), this); - Ops[1].init(reinterpret_cast(IfFalse), this); - Ops[2].init(Cond, this); -#ifndef NDEBUG - AssertOK(); -#endif - } - - BranchInst(BasicBlock *IfTrue, BasicBlock *InsertAtEnd) - : TerminatorInst(Instruction::Br, Ops, 1, InsertAtEnd) { - assert(IfTrue != 0 && "Branch destination may not be null!"); - Ops[0].init(reinterpret_cast(IfTrue), this); - } - + Instruction *InsertBefore = 0); + BranchInst(BasicBlock *IfTrue, BasicBlock *InsertAtEnd); BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond, - BasicBlock *InsertAtEnd) - : TerminatorInst(Instruction::Br, Ops, 3, InsertAtEnd) { - Ops[0].init(reinterpret_cast(IfTrue), this); - Ops[1].init(reinterpret_cast(IfFalse), this); - Ops[2].init(Cond, this); -#ifndef NDEBUG - AssertOK(); -#endif - } - + BasicBlock *InsertAtEnd); /// Transparently provide more efficient getOperand methods. Value *getOperand(unsigned i) const { @@ -1072,20 +1316,14 @@ public: /// 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) - : TerminatorInst(Instruction::Switch, 0, 0, InsertBefore) { - init(Value, Default, 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) - : TerminatorInst(Instruction::Switch, 0, 0, InsertAtEnd) { - init(Value, Default, NumCases); - } + BasicBlock *InsertAtEnd); ~SwitchInst(); @@ -1127,6 +1365,21 @@ public: return 0; } + /// findCaseDest - Finds the unique case value for a given successor. Returns + /// null if the successor is not found, not unique, or is the default case. + ConstantInt *findCaseDest(BasicBlock *BB) { + if (BB == getDefaultDest()) return NULL; + + ConstantInt *CI = NULL; + for (unsigned i = 1, e = getNumCases(); i != e; ++i) { + if (getSuccessor(i) == BB) { + if (CI) return NULL; // Multiple cases lead to BB. + else CI = getCaseValue(i); + } + } + return CI; + } + /// addCase - Add an entry to the switch instruction... /// void addCase(ConstantInt *OnVal, BasicBlock *Dest); @@ -1182,20 +1435,18 @@ private: class InvokeInst : public TerminatorInst { InvokeInst(const InvokeInst &BI); void init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException, - const std::vector &Params); + Value* const *Args, unsigned NumArgs); public: InvokeInst(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException, - const std::vector &Params, const std::string &Name = "", + Value* const* Args, unsigned NumArgs, const std::string &Name = "", Instruction *InsertBefore = 0); InvokeInst(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException, - const std::vector &Params, const std::string &Name, + Value* const* Args, unsigned NumArgs, const std::string &Name, BasicBlock *InsertAtEnd); ~InvokeInst(); virtual InvokeInst *clone() const; - bool mayWriteToMemory() const { return true; } - /// getCallingConv/setCallingConv - Get or set the calling convention of this /// function call. unsigned getCallingConv() const { return SubclassData; } @@ -1265,12 +1516,8 @@ private: /// class UnwindInst : public TerminatorInst { public: - UnwindInst(Instruction *InsertBefore = 0) - : TerminatorInst(Instruction::Unwind, 0, 0, InsertBefore) { - } - UnwindInst(BasicBlock *InsertAtEnd) - : TerminatorInst(Instruction::Unwind, 0, 0, InsertAtEnd) { - } + explicit UnwindInst(Instruction *InsertBefore = 0); + explicit UnwindInst(BasicBlock *InsertAtEnd); virtual UnwindInst *clone() const; @@ -1301,12 +1548,8 @@ private: /// class UnreachableInst : public TerminatorInst { public: - UnreachableInst(Instruction *InsertBefore = 0) - : TerminatorInst(Instruction::Unreachable, 0, 0, InsertBefore) { - } - UnreachableInst(BasicBlock *InsertAtEnd) - : TerminatorInst(Instruction::Unreachable, 0, 0, InsertAtEnd) { - } + explicit UnreachableInst(Instruction *InsertBefore = 0); + explicit UnreachableInst(BasicBlock *InsertAtEnd); virtual UnreachableInst *clone() const; @@ -1326,6 +1569,477 @@ private: virtual void setSuccessorV(unsigned idx, BasicBlock *B); }; +//===----------------------------------------------------------------------===// +// TruncInst Class +//===----------------------------------------------------------------------===// + +/// @brief This class represents a truncation of integer types. +class TruncInst : public CastInst { + /// Private copy constructor + TruncInst(const TruncInst &CI) + : CastInst(CI.getType(), Trunc, CI.getOperand(0)) { + } +public: + /// @brief Constructor with insert-before-instruction semantics + 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 + Instruction *InsertBefore = 0 ///< Where to insert the new instruction + ); + + /// @brief Constructor with insert-at-end-of-block semantics + 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 + BasicBlock *InsertAtEnd ///< The block to insert the instruction into + ); + + /// @brief Clone an identical TruncInst + virtual CastInst *clone() const; + + /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const TruncInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == Trunc; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +}; + +//===----------------------------------------------------------------------===// +// ZExtInst Class +//===----------------------------------------------------------------------===// + +/// @brief This class represents zero extension of integer types. +class ZExtInst : public CastInst { + /// @brief Private copy constructor + ZExtInst(const ZExtInst &CI) + : CastInst(CI.getType(), ZExt, CI.getOperand(0)) { + } +public: + /// @brief Constructor with insert-before-instruction semantics + 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 + Instruction *InsertBefore = 0 ///< Where to insert the new instruction + ); + + /// @brief Constructor with insert-at-end semantics. + 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 + BasicBlock *InsertAtEnd ///< The block to insert the instruction into + ); + + /// @brief Clone an identical ZExtInst + virtual CastInst *clone() const; + + /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const ZExtInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == ZExt; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +}; + +//===----------------------------------------------------------------------===// +// SExtInst Class +//===----------------------------------------------------------------------===// + +/// @brief This class represents a sign extension of integer types. +class SExtInst : public CastInst { + /// @brief Private copy constructor + SExtInst(const SExtInst &CI) + : CastInst(CI.getType(), SExt, CI.getOperand(0)) { + } +public: + /// @brief Constructor with insert-before-instruction semantics + 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 + Instruction *InsertBefore = 0 ///< Where to insert the new instruction + ); + + /// @brief Constructor with insert-at-end-of-block semantics + 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 + BasicBlock *InsertAtEnd ///< The block to insert the instruction into + ); + + /// @brief Clone an identical SExtInst + virtual CastInst *clone() const; + + /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const SExtInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == SExt; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +}; + +//===----------------------------------------------------------------------===// +// FPTruncInst Class +//===----------------------------------------------------------------------===// + +/// @brief This class represents a truncation of floating point types. +class FPTruncInst : public CastInst { + FPTruncInst(const FPTruncInst &CI) + : CastInst(CI.getType(), FPTrunc, CI.getOperand(0)) { + } +public: + /// @brief Constructor with insert-before-instruction semantics + 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 + Instruction *InsertBefore = 0 ///< Where to insert the new instruction + ); + + /// @brief Constructor with insert-before-instruction semantics + 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 + BasicBlock *InsertAtEnd ///< The block to insert the instruction into + ); + + /// @brief Clone an identical FPTruncInst + virtual CastInst *clone() const; + + /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const FPTruncInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == FPTrunc; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +}; + +//===----------------------------------------------------------------------===// +// FPExtInst Class +//===----------------------------------------------------------------------===// + +/// @brief This class represents an extension of floating point types. +class FPExtInst : public CastInst { + FPExtInst(const FPExtInst &CI) + : CastInst(CI.getType(), FPExt, CI.getOperand(0)) { + } +public: + /// @brief Constructor with insert-before-instruction semantics + 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 + Instruction *InsertBefore = 0 ///< Where to insert the new instruction + ); + + /// @brief Constructor with insert-at-end-of-block semantics + 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 + BasicBlock *InsertAtEnd ///< The block to insert the instruction into + ); + + /// @brief Clone an identical FPExtInst + virtual CastInst *clone() const; + + /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const FPExtInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == FPExt; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +}; + +//===----------------------------------------------------------------------===// +// UIToFPInst Class +//===----------------------------------------------------------------------===// + +/// @brief This class represents a cast unsigned integer to floating point. +class UIToFPInst : public CastInst { + UIToFPInst(const UIToFPInst &CI) + : CastInst(CI.getType(), UIToFP, CI.getOperand(0)) { + } +public: + /// @brief Constructor with insert-before-instruction semantics + 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 + Instruction *InsertBefore = 0 ///< Where to insert the new instruction + ); + + /// @brief Constructor with insert-at-end-of-block semantics + 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 + BasicBlock *InsertAtEnd ///< The block to insert the instruction into + ); + + /// @brief Clone an identical UIToFPInst + virtual CastInst *clone() const; + + /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const UIToFPInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == UIToFP; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +}; + +//===----------------------------------------------------------------------===// +// SIToFPInst Class +//===----------------------------------------------------------------------===// + +/// @brief This class represents a cast from signed integer to floating point. +class SIToFPInst : public CastInst { + SIToFPInst(const SIToFPInst &CI) + : CastInst(CI.getType(), SIToFP, CI.getOperand(0)) { + } +public: + /// @brief Constructor with insert-before-instruction semantics + 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 + Instruction *InsertBefore = 0 ///< Where to insert the new instruction + ); + + /// @brief Constructor with insert-at-end-of-block semantics + 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 + BasicBlock *InsertAtEnd ///< The block to insert the instruction into + ); + + /// @brief Clone an identical SIToFPInst + virtual CastInst *clone() const; + + /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const SIToFPInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == SIToFP; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +}; + +//===----------------------------------------------------------------------===// +// FPToUIInst Class +//===----------------------------------------------------------------------===// + +/// @brief This class represents a cast from floating point to unsigned integer +class FPToUIInst : public CastInst { + FPToUIInst(const FPToUIInst &CI) + : CastInst(CI.getType(), FPToUI, CI.getOperand(0)) { + } +public: + /// @brief Constructor with insert-before-instruction semantics + 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 + Instruction *InsertBefore = 0 ///< Where to insert the new instruction + ); + + /// @brief Constructor with insert-at-end-of-block semantics + 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 + BasicBlock *InsertAtEnd ///< Where to insert the new instruction + ); + + /// @brief Clone an identical FPToUIInst + virtual CastInst *clone() const; + + /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const FPToUIInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == FPToUI; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +}; + +//===----------------------------------------------------------------------===// +// FPToSIInst Class +//===----------------------------------------------------------------------===// + +/// @brief This class represents a cast from floating point to signed integer. +class FPToSIInst : public CastInst { + FPToSIInst(const FPToSIInst &CI) + : CastInst(CI.getType(), FPToSI, CI.getOperand(0)) { + } +public: + /// @brief Constructor with insert-before-instruction semantics + 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 + Instruction *InsertBefore = 0 ///< Where to insert the new instruction + ); + + /// @brief Constructor with insert-at-end-of-block semantics + 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 + BasicBlock *InsertAtEnd ///< The block to insert the instruction into + ); + + /// @brief Clone an identical FPToSIInst + virtual CastInst *clone() const; + + /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const FPToSIInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == FPToSI; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +}; + +//===----------------------------------------------------------------------===// +// IntToPtrInst Class +//===----------------------------------------------------------------------===// + +/// @brief This class represents a cast from an integer to a pointer. +class IntToPtrInst : public CastInst { + IntToPtrInst(const IntToPtrInst &CI) + : CastInst(CI.getType(), IntToPtr, CI.getOperand(0)) { + } +public: + /// @brief Constructor with insert-before-instruction semantics + 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 + Instruction *InsertBefore = 0 ///< Where to insert the new instruction + ); + + /// @brief Constructor with insert-at-end-of-block semantics + 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 + BasicBlock *InsertAtEnd ///< The block to insert the instruction into + ); + + /// @brief Clone an identical IntToPtrInst + virtual CastInst *clone() const; + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const IntToPtrInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == IntToPtr; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +}; + +//===----------------------------------------------------------------------===// +// PtrToIntInst Class +//===----------------------------------------------------------------------===// + +/// @brief This class represents a cast from a pointer to an integer +class PtrToIntInst : public CastInst { + PtrToIntInst(const PtrToIntInst &CI) + : CastInst(CI.getType(), PtrToInt, CI.getOperand(0)) { + } +public: + /// @brief Constructor with insert-before-instruction semantics + 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 + Instruction *InsertBefore = 0 ///< Where to insert the new instruction + ); + + /// @brief Constructor with insert-at-end-of-block semantics + 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 + BasicBlock *InsertAtEnd ///< The block to insert the instruction into + ); + + /// @brief Clone an identical PtrToIntInst + virtual CastInst *clone() const; + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const PtrToIntInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == PtrToInt; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +}; + +//===----------------------------------------------------------------------===// +// BitCastInst Class +//===----------------------------------------------------------------------===// + +/// @brief This class represents a no-op cast from one type to another. +class BitCastInst : public CastInst { + BitCastInst(const BitCastInst &CI) + : CastInst(CI.getType(), BitCast, CI.getOperand(0)) { + } +public: + /// @brief Constructor with insert-before-instruction semantics + 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 + Instruction *InsertBefore = 0 ///< Where to insert the new instruction + ); + + /// @brief Constructor with insert-at-end-of-block semantics + 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 + BasicBlock *InsertAtEnd ///< The block to insert the instruction into + ); + + /// @brief Clone an identical BitCastInst + virtual CastInst *clone() const; + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const BitCastInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == BitCast; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +}; + } // End llvm namespace #endif