X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FInstructions.h;h=259b5aa16570cd0fe092fc7618db328a0f849fd6;hb=443b570149f5756b298de6b63d13bbbf66b4f6fc;hp=62e6022ce1a9066377aa2345ed39d412d9e30f42;hpb=a05ec71f45dfc9b8ce34718cd24c1209e2924b60;p=oota-llvm.git diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index 62e6022ce1a..259b5aa1657 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -1,10 +1,10 @@ //===-- llvm/Instructions.h - Instruction subclass definitions --*- C++ -*-===// -// +// // The LLVM Compiler Infrastructure // // This file was developed by the LLVM research group and is distributed under // the University of Illinois Open Source License. See LICENSE.TXT for details. -// +// //===----------------------------------------------------------------------===// // // This file exposes the class definitions of all of the subclasses of the @@ -16,13 +16,14 @@ #ifndef LLVM_INSTRUCTIONS_H #define LLVM_INSTRUCTIONS_H -#include "llvm/Instruction.h" #include "llvm/InstrTypes.h" namespace llvm { class BasicBlock; +class ConstantInt; class PointerType; +class VectorType; //===----------------------------------------------------------------------===// // AllocationInst Class @@ -31,15 +32,16 @@ class PointerType; /// AllocationInst - This class is the common base class of MallocInst and /// AllocaInst. /// -class AllocationInst : public Instruction { +class AllocationInst : public UnaryInstruction { + unsigned Alignment; protected: - void init(const Type *Ty, Value *ArraySize, unsigned iTy); - AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, - const std::string &Name = "", Instruction *InsertBefore = 0); - AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, - 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. + virtual ~AllocationInst(); /// isArrayAllocation - Return true if there is an allocation size parameter /// to the allocation instruction that is not 1. @@ -49,13 +51,13 @@ public: /// getArraySize - Get the number of element allocated, for a simple /// allocation of a single element, this will return a constant 1 value. /// - inline const Value *getArraySize() const { return Operands[0]; } - inline Value *getArraySize() { return Operands[0]; } + inline const Value *getArraySize() const { return getOperand(0); } + inline Value *getArraySize() { return getOperand(0); } /// getType - Overload to return most specific pointer type /// inline const PointerType *getType() const { - return reinterpret_cast(Instruction::getType()); + return reinterpret_cast(Instruction::getType()); } /// getAllocatedType - Return the type that is being allocated by the @@ -63,6 +65,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 +100,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 +144,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; @@ -143,17 +181,14 @@ public: /// FreeInst - an instruction to deallocate memory /// -class FreeInst : public Instruction { - void init(Value *Ptr); - +class FreeInst : public UnaryInstruction { + void AssertOK(); public: explicit FreeInst(Value *Ptr, Instruction *InsertBefore = 0); FreeInst(Value *Ptr, BasicBlock *InsertAfter); 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) { @@ -169,36 +204,45 @@ public: // LoadInst Class //===----------------------------------------------------------------------===// -/// LoadInst - an instruction for reading from memory +/// LoadInst - an instruction for reading from memory. This uses the +/// SubclassData field in Value to store whether or not the load is volatile. /// -class LoadInst : public Instruction { - LoadInst(const LoadInst &LI) : Instruction(LI.getType(), Load) { - Volatile = LI.isVolatile(); - init(LI.Operands[0]); +class LoadInst : public UnaryInstruction { + LoadInst(const LoadInst &LI) + : UnaryInstruction(LI.getType(), Load, LI.getOperand(0)) { + setVolatile(LI.isVolatile()); + +#ifndef NDEBUG + AssertOK(); +#endif } - bool Volatile; // True if this is a volatile load - void init(Value *Ptr); + 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, + 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. /// - bool isVolatile() const { return Volatile; } + bool isVolatile() const { return SubclassData; } /// setVolatile - Specify whether this is a volatile load or not. /// - void setVolatile(bool V) { Volatile = V; } + void setVolatile(bool V) { SubclassData = V; } 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; } @@ -218,15 +262,19 @@ public: // StoreInst Class //===----------------------------------------------------------------------===// -/// StoreInst - an instruction for storing to memory +/// StoreInst - an instruction for storing to memory /// class StoreInst : public Instruction { - StoreInst(const StoreInst &SI) : Instruction(SI.getType(), Store) { - Volatile = SI.isVolatile(); - init(SI.Operands[0], SI.Operands[1]); + 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); + setVolatile(SI.isVolatile()); +#ifndef NDEBUG + AssertOK(); +#endif } - bool Volatile; // True if this is a volatile store - void init(Value *Val, Value *Ptr); + void AssertOK(); public: StoreInst(Value *Val, Value *Ptr, Instruction *InsertBefore); StoreInst(Value *Val, Value *Ptr, BasicBlock *InsertAtEnd); @@ -238,15 +286,25 @@ public: /// isVolatile - Return true if this is a load from a volatile memory /// location. /// - bool isVolatile() const { return Volatile; } + bool isVolatile() const { return SubclassData; } /// setVolatile - Specify whether this is a volatile load or not. /// - void setVolatile(bool V) { Volatile = V; } + void setVolatile(bool V) { SubclassData = V; } + + /// 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 StoreInst *clone() const; - virtual bool mayWriteToMemory() const { return true; } + virtual StoreInst *clone() const; Value *getPointerOperand() { return getOperand(1); } const Value *getPointerOperand() const { return getOperand(1); } @@ -271,34 +329,41 @@ public: /// access elements of arrays and structs /// class GetElementPtrInst : public Instruction { - GetElementPtrInst(const GetElementPtrInst &EPI) - : Instruction((static_cast(&EPI)->getType()), - GetElementPtr) { - Operands.reserve(EPI.Operands.size()); - for (unsigned i = 0, E = (unsigned)EPI.Operands.size(); i != E; ++i) - Operands.push_back(Use(EPI.Operands[i], this)); - } - void init(Value *Ptr, const std::vector &Idx); + 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 *Idx0, Value *Idx1); + void init(Value *Ptr, Value *Idx); 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. - GetElementPtrInst(Value *Ptr, const std::vector &Idx, - const std::string &Name = "", Instruction *InsertBefore =0); - GetElementPtrInst(Value *Ptr, const std::vector &Idx, - const std::string &Name, BasicBlock *InsertAtEnd); - - /// Constructors - These two constructors are convenience methods because two - /// index getelementptr instructions are so common. + GetElementPtrInst(Value *Ptr, Value* const *Idx, unsigned NumIdx, + const std::string &Name = "", Instruction *InsertBefore =0); + 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, + const std::string &Name = "", Instruction *InsertBefore =0); + GetElementPtrInst(Value *Ptr, Value *Idx, + const std::string &Name, BasicBlock *InsertAtEnd); GetElementPtrInst(Value *Ptr, Value *Idx0, Value *Idx1, - const std::string &Name = "", Instruction *InsertBefore =0); + const std::string &Name = "", Instruction *InsertBefore =0); GetElementPtrInst(Value *Ptr, Value *Idx0, Value *Idx1, - const std::string &Name, BasicBlock *InsertAtEnd); + const std::string &Name, BasicBlock *InsertAtEnd); + ~GetElementPtrInst(); virtual GetElementPtrInst *clone() const; - + // getType - Overload to return most specific pointer type... inline const PointerType *getType() const { return reinterpret_cast(Instruction::getType()); @@ -307,15 +372,17 @@ public: /// 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 + /// A null type is returned if the indices are invalid for the specified /// pointer type. /// - static const Type *getIndexedType(const Type *Ptr, - const std::vector &Indices, - 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* 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); + inline op_iterator idx_begin() { return op_begin()+1; } inline const_op_iterator idx_begin() const { return op_begin()+1; } inline op_iterator idx_end() { return op_end(); } @@ -334,7 +401,7 @@ public: inline unsigned getNumIndices() const { // Note: always non-negative return getNumOperands() - 1; } - + inline bool hasIndices() const { return getNumOperands() > 1; } @@ -350,51 +417,139 @@ 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); + /// 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()); + } - /// getInverseCondition - Return the inverse of the current condition opcode. - /// For example seteq -> setne, setgt -> setle, setlt -> setge, etc... - /// - BinaryOps getInverseCondition() const { - return getInverseCondition(getOpcode()); + /// 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()); } - /// getInverseCondition - Static version that you can use without an - /// instruction available. - /// - static BinaryOps getInverseCondition(BinaryOps Opcode); + /// 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); - /// 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()); + /// 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()); } - /// getSwappedCondition - Static version that you can use without an - /// instruction available. - /// - static BinaryOps getSwappedCondition(BinaryOps Opcode); + /// 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); + + /// 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]); + } // 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)); @@ -402,66 +557,149 @@ 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 Instruction { - CastInst(const CastInst &CI) : Instruction(CI.getType(), Cast) { - Operands.reserve(1); - Operands.push_back(Use(CI.Operands[0], this)); - } - void init(Value *S) { - Operands.reserve(1); - Operands.push_back(Use(S, this)); - } +/// 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) - : Instruction(Ty, Cast, Name, InsertBefore) { - init(S); - } - CastInst(Value *S, const Type *Ty, const std::string &Name, - BasicBlock *InsertAtEnd) - : Instruction(Ty, Cast, Name, InsertAtEnd) { - init(S); - } - - 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 //===----------------------------------------------------------------------===// /// CallInst - This class represents a function call, abstracting a target -/// machine's calling convention. +/// machine's calling convention. This class uses low bit of the SubClassData +/// field to indicate whether or not this is a tail call. The rest of the bits +/// hold the calling convention of the call. /// 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, @@ -472,78 +710,105 @@ public: Instruction *InsertBefore = 0); CallInst(Value *F, Value *Actual, const std::string& Name, BasicBlock *InsertAtEnd); - explicit CallInst(Value *F, const std::string &Name = "", + 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); + } + + /// getCallingConv/setCallingConv - Get or set the calling convention of this + /// function call. + unsigned getCallingConv() const { return SubclassData >> 1; } + void setCallingConv(unsigned CC) { + SubclassData = (SubclassData & 1) | (CC << 1); + } /// 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. Function *getCalledFunction() const { - return dyn_cast(Operands[0]); + return static_cast(dyn_cast(getOperand(0))); } - // getCalledValue - Get a pointer to a method that is invoked by this inst. - inline const Value *getCalledValue() const { return Operands[0]; } - inline Value *getCalledValue() { return Operands[0]; } + /// 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); } // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const CallInst *) { return true; } static inline bool classof(const Instruction *I) { - return I->getOpcode() == Instruction::Call; + return I->getOpcode() == Instruction::Call; } static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; - //===----------------------------------------------------------------------===// -// ShiftInst Class +// SelectInst Class //===----------------------------------------------------------------------===// -/// ShiftInst - This class represents left and right shift instructions. +/// SelectInst - This class represents the LLVM 'select' instruction. /// -class ShiftInst : public Instruction { - ShiftInst(const ShiftInst &SI) : Instruction(SI.getType(), SI.getOpcode()) { - Operands.reserve(2); - Operands.push_back(Use(SI.Operands[0], this)); - Operands.push_back(Use(SI.Operands[1], this)); - } - void init(OtherOps Opcode, Value *S, Value *SA) { - assert((Opcode == Shl || Opcode == Shr) && "ShiftInst Opcode invalid!"); - Operands.reserve(2); - Operands.push_back(Use(S, this)); - Operands.push_back(Use(SA, this)); +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); } + SelectInst(const SelectInst &SI) + : Instruction(SI.getType(), SI.getOpcode(), Ops, 3) { + init(SI.Ops[0], SI.Ops[1], SI.Ops[2]); + } public: - ShiftInst(OtherOps Opcode, Value *S, Value *SA, const std::string &Name = "", - Instruction *InsertBefore = 0) - : Instruction(S->getType(), Opcode, Name, InsertBefore) { - init(Opcode, S, SA); + SelectInst(Value *C, Value *S1, Value *S2, const std::string &Name = "", + Instruction *InsertBefore = 0) + : Instruction(S1->getType(), Instruction::Select, Ops, 3, + Name, InsertBefore) { + init(C, S1, S2); } - ShiftInst(OtherOps Opcode, Value *S, Value *SA, const std::string &Name, - BasicBlock *InsertAtEnd) - : Instruction(S->getType(), Opcode, Name, InsertAtEnd) { - init(Opcode, S, SA); + SelectInst(Value *C, Value *S1, Value *S2, const std::string &Name, + BasicBlock *InsertAtEnd) + : Instruction(S1->getType(), Instruction::Select, Ops, 3, + Name, InsertAtEnd) { + init(C, S1, S2); + } + + Value *getCondition() const { return Ops[0]; } + Value *getTrueValue() const { return Ops[1]; } + Value *getFalseValue() const { return Ops[2]; } + + /// 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; } OtherOps getOpcode() const { return static_cast(Instruction::getOpcode()); } - virtual ShiftInst *clone() const; + virtual SelectInst *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 SelectInst *) { return true; } static inline bool classof(const Instruction *I) { - return (I->getOpcode() == Instruction::Shr) | - (I->getOpcode() == Instruction::Shl); + return I->getOpcode() == Instruction::Select; } static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); @@ -551,144 +816,196 @@ public: }; //===----------------------------------------------------------------------===// -// SelectInst Class +// VAArgInst Class //===----------------------------------------------------------------------===// -/// SelectInst - This class represents the LLVM 'select' instruction. +/// 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 SelectInst : public Instruction { - SelectInst(const SelectInst &SI) : Instruction(SI.getType(), SI.getOpcode()) { - Operands.reserve(3); - Operands.push_back(Use(SI.Operands[0], this)); - Operands.push_back(Use(SI.Operands[1], this)); - Operands.push_back(Use(SI.Operands[2], this)); +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, 0, InsertBefore) { + setName(Name); } - void init(Value *C, Value *S1, Value *S2) { - Operands.reserve(3); - Operands.push_back(Use(C, this)); - Operands.push_back(Use(S1, this)); - Operands.push_back(Use(S2, this)); + VAArgInst(Value *List, const Type *Ty, const std::string &Name, + BasicBlock *InsertAtEnd) + : UnaryInstruction(Ty, VAArg, List, 0, InsertAtEnd) { + setName(Name); } -public: - SelectInst(Value *C, Value *S1, Value *S2, const std::string &Name = "", - Instruction *InsertBefore = 0) - : Instruction(S1->getType(), Instruction::Select, Name, InsertBefore) { - init(C, S1, S2); + 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; } - SelectInst(Value *C, Value *S1, Value *S2, const std::string &Name, - BasicBlock *InsertAtEnd) - : Instruction(S1->getType(), Instruction::Select, Name, InsertAtEnd) { - init(C, S1, S2); + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); } +}; - Value *getCondition() const { return Operands[0]; } - Value *getTrueValue() const { return Operands[1]; } - Value *getFalseValue() const { return Operands[2]; } +//===----------------------------------------------------------------------===// +// ExtractElementInst Class +//===----------------------------------------------------------------------===// - OtherOps getOpcode() const { - return static_cast(Instruction::getOpcode()); +/// ExtractElementInst - This instruction extracts a single (scalar) +/// 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); } - virtual SelectInst *clone() const; +public: + 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]; + } + void setOperand(unsigned i, Value *Val) { + assert(i < 2 && "setOperand() out of range!"); + Ops[i] = Val; + } + unsigned getNumOperands() const { return 2; } // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SelectInst *) { return true; } + static inline bool classof(const ExtractElementInst *) { return true; } static inline bool classof(const Instruction *I) { - return I->getOpcode() == Instruction::Select; + return I->getOpcode() == Instruction::ExtractElement; } static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; - //===----------------------------------------------------------------------===// -// VANextInst Class +// InsertElementInst 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. +/// InsertElementInst - This instruction inserts a single (scalar) +/// element into a VectorType value /// -class VANextInst : public Instruction { - PATypeHolder ArgTy; - void init(Value *List) { - Operands.reserve(1); - Operands.push_back(Use(List, this)); - } - VANextInst(const VANextInst &VAN) - : Instruction(VAN.getType(), VANext), ArgTy(VAN.getArgType()) { - init(VAN.Operands[0]); +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()); } -public: - VANextInst(Value *List, const Type *Ty, const std::string &Name = "", - Instruction *InsertBefore = 0) - : Instruction(List->getType(), VANext, Name, InsertBefore), ArgTy(Ty) { - init(List); + /// Transparently provide more efficient getOperand methods. + Value *getOperand(unsigned i) const { + assert(i < 3 && "getOperand() out of range!"); + return Ops[i]; } - VANextInst(Value *List, const Type *Ty, const std::string &Name, - BasicBlock *InsertAtEnd) - : Instruction(List->getType(), VANext, Name, InsertAtEnd), ArgTy(Ty) { - init(List); + void setOperand(unsigned i, Value *Val) { + assert(i < 3 && "setOperand() out of range!"); + Ops[i] = Val; } - - const Type *getArgType() const { return ArgTy; } - - virtual VANextInst *clone() const; + 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 Instruction { - void init(Value* List) { - Operands.reserve(1); - Operands.push_back(Use(List, this)); - } - VAArgInst(const VAArgInst &VAA) - : Instruction(VAA.getType(), VAArg) { - init(VAA.Operands[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) - : Instruction(Ty, VAArg, Name, InsertBefore) { - init(List); - } - VAArgInst(Value *List, const Type *Ty, const std::string &Name, - BasicBlock *InsertAtEnd) - : Instruction(Ty, VAArg, Name, InsertAtEnd) { - init(List); + 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 //===----------------------------------------------------------------------===// @@ -698,46 +1015,59 @@ public: // scientist's overactive imagination. // class PHINode : public Instruction { + /// ReservedSpace - The number of operands actually allocated. NumOperands is + /// the number actually in use. + unsigned ReservedSpace; PHINode(const PHINode &PN); public: - PHINode(const Type *Ty, const std::string &Name = "", - Instruction *InsertBefore = 0) - : Instruction(Ty, Instruction::PHI, Name, InsertBefore) { + explicit PHINode(const Type *Ty, const std::string &Name = "", + Instruction *InsertBefore = 0) + : Instruction(Ty, Instruction::PHI, 0, 0, Name, InsertBefore), + ReservedSpace(0) { } PHINode(const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd) - : Instruction(Ty, Instruction::PHI, Name, InsertAtEnd) { + : Instruction(Ty, Instruction::PHI, 0, 0, Name, InsertAtEnd), + ReservedSpace(0) { + } + + ~PHINode(); + + /// reserveOperandSpace - This method can be used to avoid repeated + /// reallocation of PHI operand lists by reserving space for the correct + /// number of operands before adding them. Unlike normal vector reserves, + /// this method can also be used to trim the operand space. + void reserveOperandSpace(unsigned NumValues) { + resizeOperands(NumValues*2); } virtual PHINode *clone() const; /// getNumIncomingValues - Return the number of incoming edges /// - unsigned getNumIncomingValues() const { return (unsigned)Operands.size()/2; } + 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 < Operands.size() && "Invalid value number!"); - return Operands[i*2]; + assert(i*2 < getNumOperands() && "Invalid value number!"); + return getOperand(i*2); } void setIncomingValue(unsigned i, Value *V) { - assert(i*2 < Operands.size() && "Invalid value number!"); - Operands[i*2] = V; + assert(i*2 < getNumOperands() && "Invalid value number!"); + setOperand(i*2, V); } - inline unsigned getOperandNumForIncomingValue(unsigned i) { + unsigned getOperandNumForIncomingValue(unsigned i) { return i*2; } - /// getIncomingBlock - Return incoming basic block #x + /// getIncomingBlock - Return incoming basic block number x /// - BasicBlock *getIncomingBlock(unsigned i) const { - assert(i*2+1 < Operands.size() && "Invalid value number!"); - return reinterpret_cast(Operands[i*2+1].get()); + BasicBlock *getIncomingBlock(unsigned i) const { + return reinterpret_cast(getOperand(i*2+1)); } void setIncomingBlock(unsigned i, BasicBlock *BB) { - assert(i*2+1 < Operands.size() && "Invalid value number!"); - Operands[i*2+1] = reinterpret_cast(BB); + setOperand(i*2+1, reinterpret_cast(BB)); } unsigned getOperandNumForIncomingBlock(unsigned i) { return i*2+1; @@ -748,10 +1078,15 @@ public: void addIncoming(Value *V, BasicBlock *BB) { assert(getType() == V->getType() && "All operands to PHI node must be the same type as the PHI node!"); - Operands.push_back(Use(V, this)); - Operands.push_back(Use(reinterpret_cast(BB), this)); + unsigned OpNo = NumOperands; + if (OpNo+2 > ReservedSpace) + 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); } - + /// removeIncomingValue - Remove an incoming value. This is useful if a /// predecessor basic block is deleted. The value removed is returned. /// @@ -768,12 +1103,13 @@ public: return removeIncomingValue(Idx, DeletePHIIfEmpty); } - /// getBasicBlockIndex - Return the first index of the specified basic + /// getBasicBlockIndex - Return the first index of the specified basic /// block in the value list for this PHI. Returns -1 if no instance. /// int getBasicBlockIndex(const BasicBlock *BB) const { - for (unsigned i = 0; i < Operands.size()/2; ++i) - if (getIncomingBlock(i) == BB) return i; + Use *OL = OperandList; + for (unsigned i = 0, e = getNumOperands(); i != e; i += 2) + if (OL[i+1] == reinterpret_cast(BB)) return i/2; return -1; } @@ -781,14 +1117,21 @@ 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) { - return I->getOpcode() == Instruction::PHI; + return I->getOpcode() == Instruction::PHI; } static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + private: + void resizeOperands(unsigned NumOperands); }; //===----------------------------------------------------------------------===// @@ -800,12 +1143,11 @@ public: /// does not continue in this function any longer. /// class ReturnInst : public TerminatorInst { - ReturnInst(const ReturnInst &RI) : TerminatorInst(Instruction::Ret) { - if (RI.Operands.size()) { - assert(RI.Operands.size() == 1 && "Return insn can only have 1 operand!"); - Operands.reserve(1); - Operands.push_back(Use(RI.Operands[0], this)); - } + Use RetVal; // Possibly null retval. + ReturnInst(const ReturnInst &RI) : TerminatorInst(Instruction::Ret, &RetVal, + RI.getNumOperands()) { + if (RI.getNumOperands()) + RetVal.init(RI.RetVal, this); } void init(Value *RetVal); @@ -822,34 +1164,33 @@ 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, InsertBefore) { - init(RetVal); + explicit ReturnInst(Value *retVal = 0, Instruction *InsertBefore = 0) + : TerminatorInst(Instruction::Ret, &RetVal, 0, InsertBefore) { + init(retVal); } - ReturnInst(Value *RetVal, BasicBlock *InsertAtEnd) - : TerminatorInst(Instruction::Ret, InsertAtEnd) { - init(RetVal); + ReturnInst(Value *retVal, BasicBlock *InsertAtEnd) + : TerminatorInst(Instruction::Ret, &RetVal, 0, InsertAtEnd) { + init(retVal); } - ReturnInst(BasicBlock *InsertAtEnd) - : TerminatorInst(Instruction::Ret, InsertAtEnd) { + explicit ReturnInst(BasicBlock *InsertAtEnd) + : TerminatorInst(Instruction::Ret, &RetVal, 0, InsertAtEnd) { } virtual ReturnInst *clone() const; - inline const Value *getReturnValue() const { - return Operands.size() ? Operands[0].get() : 0; + // Transparently provide more efficient getOperand methods. + Value *getOperand(unsigned i) const { + assert(i < getNumOperands() && "getOperand() out of range!"); + return RetVal; } - inline Value *getReturnValue() { - return Operands.size() ? Operands[0].get() : 0; + void setOperand(unsigned i, Value *Val) { + assert(i < getNumOperands() && "setOperand() out of range!"); + RetVal = Val; } - virtual const BasicBlock *getSuccessor(unsigned idx) const { - assert(0 && "ReturnInst has no successors!"); - abort(); - return 0; - } - virtual void setSuccessor(unsigned idx, BasicBlock *NewSucc); - virtual unsigned getNumSuccessors() const { return 0; } + Value *getReturnValue() const { return RetVal; } + + unsigned getNumSuccessors() const { return 0; } // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const ReturnInst *) { return true; } @@ -859,6 +1200,10 @@ public: static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + private: + virtual BasicBlock *getSuccessorV(unsigned idx) const; + virtual unsigned getNumSuccessorsV() const; + virtual void setSuccessorV(unsigned idx, BasicBlock *B); }; //===----------------------------------------------------------------------===// @@ -869,9 +1214,12 @@ public: /// BranchInst - Conditional or Unconditional Branch instruction. /// 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]; BranchInst(const BranchInst &BI); - void init(BasicBlock *IfTrue); - void init(BasicBlock *True, BasicBlock *False, Value *Cond); + void AssertOK(); public: // BranchInst constructors (where {B, T, F} are blocks, and C is a condition): // BranchInst(BB *B) - 'br B' @@ -880,35 +1228,58 @@ 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, InsertBefore) { - init(IfTrue); + explicit 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); } BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond, Instruction *InsertBefore = 0) - : TerminatorInst(Instruction::Br, InsertBefore) { - init(IfTrue, IfFalse, Cond); + : 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, InsertAtEnd) { - init(IfTrue); + : TerminatorInst(Instruction::Br, Ops, 1, InsertAtEnd) { + assert(IfTrue != 0 && "Branch destination may not be null!"); + Ops[0].init(reinterpret_cast(IfTrue), this); } BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond, BasicBlock *InsertAtEnd) - : TerminatorInst(Instruction::Br, InsertAtEnd) { - init(IfTrue, IfFalse, Cond); + : 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 + } + + + /// Transparently provide more efficient getOperand methods. + Value *getOperand(unsigned i) const { + assert(i < getNumOperands() && "getOperand() out of range!"); + return Ops[i]; + } + void setOperand(unsigned i, Value *Val) { + assert(i < getNumOperands() && "setOperand() out of range!"); + Ops[i] = Val; } virtual BranchInst *clone() const; - inline bool isUnconditional() const { return Operands.size() == 1; } - inline bool isConditional() const { return Operands.size() == 3; } + inline bool isUnconditional() const { return getNumOperands() == 1; } + inline bool isConditional() const { return getNumOperands() == 3; } inline Value *getCondition() const { assert(isConditional() && "Cannot get condition of an uncond branch!"); - return Operands[2].get(); + return getOperand(2); } void setCondition(Value *V) { @@ -918,29 +1289,29 @@ public: // setUnconditionalDest - Change the current branch to an unconditional branch // targeting the specified block. - // + // FIXME: Eliminate this ugly method. void setUnconditionalDest(BasicBlock *Dest) { - if (isConditional()) Operands.erase(Operands.begin()+1, Operands.end()); - Operands[0] = reinterpret_cast(Dest); + if (isConditional()) { // Convert this to an uncond branch. + NumOperands = 1; + Ops[1].set(0); + Ops[2].set(0); + } + setOperand(0, reinterpret_cast(Dest)); } - virtual const BasicBlock *getSuccessor(unsigned i) const { + unsigned getNumSuccessors() const { return 1+isConditional(); } + + BasicBlock *getSuccessor(unsigned i) const { assert(i < getNumSuccessors() && "Successor # out of range for Branch!"); - return (i == 0) ? cast(Operands[0].get()) : - cast(Operands[1].get()); - } - inline BasicBlock *getSuccessor(unsigned idx) { - const BranchInst *BI = this; - return const_cast(BI->getSuccessor(idx)); + return (i == 0) ? cast(getOperand(0)) : + cast(getOperand(1)); } - virtual void setSuccessor(unsigned idx, BasicBlock *NewSucc) { + void setSuccessor(unsigned idx, BasicBlock *NewSucc) { assert(idx < getNumSuccessors() && "Successor # out of range for Branch!"); - Operands[idx] = reinterpret_cast(NewSucc); + setOperand(idx, reinterpret_cast(NewSucc)); } - virtual unsigned getNumSuccessors() const { return 1+isConditional(); } - // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const BranchInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -949,6 +1320,10 @@ public: static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } +private: + virtual BasicBlock *getSuccessorV(unsigned idx) const; + virtual unsigned getNumSuccessorsV() const; + virtual void setSuccessorV(unsigned idx, BasicBlock *B); }; //===----------------------------------------------------------------------===// @@ -959,52 +1334,61 @@ public: /// SwitchInst - Multiway switch /// class SwitchInst : public TerminatorInst { + unsigned ReservedSpace; // Operand[0] = Value to switch on // Operand[1] = Default basic block destination // Operand[2n ] = Value to match // Operand[2n+1] = BasicBlock to go to on match SwitchInst(const SwitchInst &RI); - void init(Value *Value, BasicBlock *Default); - + void init(Value *Value, BasicBlock *Default, unsigned NumCases); + void resizeOperands(unsigned No); public: - SwitchInst(Value *Value, BasicBlock *Default, Instruction *InsertBefore = 0) - : TerminatorInst(Instruction::Switch, InsertBefore) { - init(Value, Default); + /// 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) + : TerminatorInst(Instruction::Switch, 0, 0, InsertBefore) { + init(Value, Default, NumCases); } - SwitchInst(Value *Value, BasicBlock *Default, BasicBlock *InsertAtEnd) - : TerminatorInst(Instruction::Switch, InsertAtEnd) { - init(Value, Default); + + /// 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); } + ~SwitchInst(); - virtual SwitchInst *clone() const; // Accessor Methods for Switch stmt - // - inline const Value *getCondition() const { return Operands[0]; } - inline Value *getCondition() { return Operands[0]; } - inline const BasicBlock *getDefaultDest() const { - return cast(Operands[1].get()); - } - inline BasicBlock *getDefaultDest() { - return cast(Operands[1].get()); + inline Value *getCondition() const { return getOperand(0); } + void setCondition(Value *V) { setOperand(0, V); } + + inline BasicBlock *getDefaultDest() const { + return cast(getOperand(1)); } /// getNumCases - return the number of 'cases' in this switch instruction. /// Note that case #0 is always the default case. unsigned getNumCases() const { - return (unsigned)Operands.size()/2; + return getNumOperands()/2; } /// getCaseValue - Return the specified case value. Note that case #0, the /// default destination, does not have a case value. - Constant *getCaseValue(unsigned i) { + ConstantInt *getCaseValue(unsigned i) { assert(i && i < getNumCases() && "Illegal case value to get!"); return getSuccessorValue(i); } /// getCaseValue - Return the specified case value. Note that case #0, the /// default destination, does not have a case value. - const Constant *getCaseValue(unsigned i) const { + const ConstantInt *getCaseValue(unsigned i) const { assert(i && i < getNumCases() && "Illegal case value to get!"); return getSuccessorValue(i); } @@ -1012,16 +1396,31 @@ public: /// findCaseValue - Search all of the case values for the specified constant. /// If it is explicitly handled, return the case number of it, otherwise /// return 0 to indicate that it is handled by the default handler. - unsigned findCaseValue(const Constant *C) const { + unsigned findCaseValue(const ConstantInt *C) const { for (unsigned i = 1, e = getNumCases(); i != e; ++i) if (getCaseValue(i) == C) return i; 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(Constant *OnVal, BasicBlock *Dest); + void addCase(ConstantInt *OnVal, BasicBlock *Dest); /// removeCase - This method removes the specified successor from the switch /// instruction. Note that this cannot be used to remove the default @@ -1029,40 +1428,37 @@ public: /// void removeCase(unsigned idx); - virtual const BasicBlock *getSuccessor(unsigned idx) const { - assert(idx < getNumSuccessors() &&"Successor idx out of range for switch!"); - return cast(Operands[idx*2+1].get()); - } - inline BasicBlock *getSuccessor(unsigned idx) { + virtual SwitchInst *clone() const; + + unsigned getNumSuccessors() const { return getNumOperands()/2; } + BasicBlock *getSuccessor(unsigned idx) const { assert(idx < getNumSuccessors() &&"Successor idx out of range for switch!"); - return cast(Operands[idx*2+1].get()); + return cast(getOperand(idx*2+1)); } - - virtual void setSuccessor(unsigned idx, BasicBlock *NewSucc) { + void setSuccessor(unsigned idx, BasicBlock *NewSucc) { assert(idx < getNumSuccessors() && "Successor # out of range for switch!"); - Operands[idx*2+1] = reinterpret_cast(NewSucc); + setOperand(idx*2+1, reinterpret_cast(NewSucc)); } // getSuccessorValue - Return the value associated with the specified // successor. - inline const Constant *getSuccessorValue(unsigned idx) const { - assert(idx < getNumSuccessors() && "Successor # out of range!"); - return cast(Operands[idx*2].get()); - } - inline Constant *getSuccessorValue(unsigned idx) { + inline ConstantInt *getSuccessorValue(unsigned idx) const { assert(idx < getNumSuccessors() && "Successor # out of range!"); - return cast(Operands[idx*2].get()); + return reinterpret_cast(getOperand(idx*2)); } - virtual unsigned getNumSuccessors() const { return (unsigned)Operands.size()/2; } // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const SwitchInst *) { return true; } static inline bool classof(const Instruction *I) { - return (I->getOpcode() == Instruction::Switch); + return I->getOpcode() == Instruction::Switch; } static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } +private: + virtual BasicBlock *getSuccessorV(unsigned idx) const; + virtual unsigned getNumSuccessorsV() const; + virtual void setSuccessorV(unsigned idx, BasicBlock *B); }; //===----------------------------------------------------------------------===// @@ -1070,72 +1466,68 @@ public: //===----------------------------------------------------------------------===// //===--------------------------------------------------------------------------- -/// InvokeInst - Invoke instruction + +/// InvokeInst - Invoke instruction. The SubclassData field is used to hold the +/// calling convention of the call. /// 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; } + void setCallingConv(unsigned CC) { + SubclassData = CC; + } /// getCalledFunction - Return the function called, or null if this is an /// indirect function invocation. /// Function *getCalledFunction() const { - return dyn_cast(Operands[0]); + return dyn_cast(getOperand(0)); } // getCalledValue - Get a pointer to a function that is invoked by this inst. - inline const Value *getCalledValue() const { return Operands[0]; } - inline Value *getCalledValue() { return Operands[0]; } + inline Value *getCalledValue() const { return getOperand(0); } // get*Dest - Return the destination basic blocks... - inline const BasicBlock *getNormalDest() const { - return cast(Operands[1].get()); - } - inline BasicBlock *getNormalDest() { - return cast(Operands[1].get()); + BasicBlock *getNormalDest() const { + return cast(getOperand(1)); } - inline const BasicBlock *getUnwindDest() const { - return cast(Operands[2].get()); + BasicBlock *getUnwindDest() const { + return cast(getOperand(2)); } - inline BasicBlock *getUnwindDest() { - return cast(Operands[2].get()); + void setNormalDest(BasicBlock *B) { + setOperand(1, reinterpret_cast(B)); } - inline void setNormalDest(BasicBlock *B){ - Operands[1] = reinterpret_cast(B); + void setUnwindDest(BasicBlock *B) { + setOperand(2, reinterpret_cast(B)); } - inline void setUnwindDest(BasicBlock *B){ - Operands[2] = reinterpret_cast(B); - } - - virtual const BasicBlock *getSuccessor(unsigned i) const { - assert(i < 2 && "Successor # out of range for invoke!"); - return i == 0 ? getNormalDest() : getUnwindDest(); - } - inline BasicBlock *getSuccessor(unsigned i) { + inline BasicBlock *getSuccessor(unsigned i) const { assert(i < 2 && "Successor # out of range for invoke!"); return i == 0 ? getNormalDest() : getUnwindDest(); } - virtual void setSuccessor(unsigned idx, BasicBlock *NewSucc) { + void setSuccessor(unsigned idx, BasicBlock *NewSucc) { assert(idx < 2 && "Successor # out of range for invoke!"); - Operands[idx+1] = reinterpret_cast(NewSucc); + setOperand(idx+1, reinterpret_cast(NewSucc)); } - virtual unsigned getNumSuccessors() const { return 2; } + unsigned getNumSuccessors() const { return 2; } // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const InvokeInst *) { return true; } @@ -1145,6 +1537,10 @@ public: static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } +private: + virtual BasicBlock *getSuccessorV(unsigned idx) const; + virtual unsigned getNumSuccessorsV() const; + virtual void setSuccessorV(unsigned idx, BasicBlock *B); }; @@ -1158,22 +1554,16 @@ public: /// class UnwindInst : public TerminatorInst { public: - UnwindInst(Instruction *InsertBefore = 0) - : TerminatorInst(Instruction::Unwind, InsertBefore) { + explicit UnwindInst(Instruction *InsertBefore = 0) + : TerminatorInst(Instruction::Unwind, 0, 0, InsertBefore) { } - UnwindInst(BasicBlock *InsertAtEnd) - : TerminatorInst(Instruction::Unwind, InsertAtEnd) { + explicit UnwindInst(BasicBlock *InsertAtEnd) + : TerminatorInst(Instruction::Unwind, 0, 0, InsertAtEnd) { } virtual UnwindInst *clone() const; - virtual const BasicBlock *getSuccessor(unsigned idx) const { - assert(0 && "UnwindInst has no successors!"); - abort(); - return 0; - } - virtual void setSuccessor(unsigned idx, BasicBlock *NewSucc); - virtual unsigned getNumSuccessors() const { return 0; } + unsigned getNumSuccessors() const { return 0; } // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const UnwindInst *) { return true; } @@ -1183,6 +1573,10 @@ public: static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } +private: + virtual BasicBlock *getSuccessorV(unsigned idx) const; + virtual unsigned getNumSuccessorsV() const; + virtual void setSuccessorV(unsigned idx, BasicBlock *B); }; //===----------------------------------------------------------------------===// @@ -1196,22 +1590,16 @@ public: /// class UnreachableInst : public TerminatorInst { public: - UnreachableInst(Instruction *InsertBefore = 0) - : TerminatorInst(Instruction::Unreachable, InsertBefore) { + explicit UnreachableInst(Instruction *InsertBefore = 0) + : TerminatorInst(Instruction::Unreachable, 0, 0, InsertBefore) { } - UnreachableInst(BasicBlock *InsertAtEnd) - : TerminatorInst(Instruction::Unreachable, InsertAtEnd) { + explicit UnreachableInst(BasicBlock *InsertAtEnd) + : TerminatorInst(Instruction::Unreachable, 0, 0, InsertAtEnd) { } virtual UnreachableInst *clone() const; - virtual const BasicBlock *getSuccessor(unsigned idx) const { - assert(0 && "UnreachableInst has no successors!"); - abort(); - return 0; - } - virtual void setSuccessor(unsigned idx, BasicBlock *NewSucc); - virtual unsigned getNumSuccessors() const { return 0; } + unsigned getNumSuccessors() const { return 0; } // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const UnreachableInst *) { return true; } @@ -1221,6 +1609,481 @@ public: static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } +private: + virtual BasicBlock *getSuccessorV(unsigned idx) const; + virtual unsigned getNumSuccessorsV() const; + 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