X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FInstrTypes.h;h=b25290226bb738c49540987c562551911daca3d8;hb=bdc46c6af5ffcf3596a72df75880fe8703436060;hp=3748b0c9a56fae777383db5c3a153b70fea2fa25;hpb=7cbd8a3e92221437048b484d5ef9c0a22d0f8c58;p=oota-llvm.git diff --git a/include/llvm/InstrTypes.h b/include/llvm/InstrTypes.h index 3748b0c9a56..b25290226bb 100644 --- a/include/llvm/InstrTypes.h +++ b/include/llvm/InstrTypes.h @@ -18,9 +18,13 @@ #include "llvm/Instruction.h" #include "llvm/OperandTraits.h" +#include "llvm/Operator.h" +#include "llvm/DerivedTypes.h" namespace llvm { +class LLVMContext; + //===----------------------------------------------------------------------===// // TerminatorInst Class //===----------------------------------------------------------------------===// @@ -47,10 +51,9 @@ protected: virtual BasicBlock *getSuccessorV(unsigned idx) const = 0; virtual unsigned getNumSuccessorsV() const = 0; virtual void setSuccessorV(unsigned idx, BasicBlock *B) = 0; + virtual TerminatorInst *clone_impl() const = 0; public: - virtual Instruction *clone() const = 0; - /// getNumSuccessors - Return the number of successors that this terminator /// has. unsigned getNumSuccessors() const { @@ -72,7 +75,7 @@ public: // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const TerminatorInst *) { return true; } static inline bool classof(const Instruction *I) { - return I->getOpcode() >= TermOpsBegin && I->getOpcode() < TermOpsEnd; + return I->isTerminator(); } static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); @@ -86,10 +89,10 @@ public: class UnaryInstruction : public Instruction { void *operator new(size_t, unsigned); // Do not implement - UnaryInstruction(const UnaryInstruction&); // Do not implement protected: - UnaryInstruction(const Type *Ty, unsigned iType, Value *V, Instruction *IB = 0) + UnaryInstruction(const Type *Ty, unsigned iType, Value *V, + Instruction *IB = 0) : Instruction(Ty, iType, &Op<0>(), 1, IB) { Op<0>() = V; } @@ -108,16 +111,14 @@ public: /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); - + // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const UnaryInstruction *) { return true; } static inline bool classof(const Instruction *I) { - return I->getOpcode() == Instruction::Malloc || - I->getOpcode() == Instruction::Alloca || - I->getOpcode() == Instruction::Free || + return I->getOpcode() == Instruction::Alloca || I->getOpcode() == Instruction::Load || I->getOpcode() == Instruction::VAArg || - I->getOpcode() == Instruction::GetResult || + I->getOpcode() == Instruction::ExtractValue || (I->getOpcode() >= CastOpsBegin && I->getOpcode() < CastOpsEnd); } static inline bool classof(const Value *V) { @@ -126,7 +127,7 @@ public: }; template <> -struct OperandTraits : FixedNumOperandTraits<1> { +struct OperandTraits : public FixedNumOperandTraits<1> { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryInstruction, Value) @@ -140,9 +141,10 @@ class BinaryOperator : public Instruction { protected: void init(BinaryOps iType); BinaryOperator(BinaryOps iType, Value *S1, Value *S2, const Type *Ty, - const std::string &Name, Instruction *InsertBefore); + const Twine &Name, Instruction *InsertBefore); BinaryOperator(BinaryOps iType, Value *S1, Value *S2, const Type *Ty, - const std::string &Name, BasicBlock *InsertAtEnd); + const Twine &Name, BasicBlock *InsertAtEnd); + virtual BinaryOperator *clone_impl() const; public: // allocate space for exactly two operands void *operator new(size_t s) { @@ -158,7 +160,7 @@ public: /// Instruction is allowed to be a dereferenced end iterator. /// static BinaryOperator *Create(BinaryOps Op, Value *S1, Value *S2, - const std::string &Name = "", + const Twine &Name = "", Instruction *InsertBefore = 0); /// Create() - Construct a binary instruction, given the opcode and the two @@ -166,57 +168,174 @@ public: /// BasicBlock specified. /// static BinaryOperator *Create(BinaryOps Op, Value *S1, Value *S2, - const std::string &Name, - BasicBlock *InsertAtEnd); + const Twine &Name, BasicBlock *InsertAtEnd); - /// Create* - These methods just forward to create, and are useful when you + /// Create* - These methods just forward to Create, and are useful when you /// statically know what type of instruction you're going to create. These /// helpers just save some typing. #define HANDLE_BINARY_INST(N, OPC, CLASS) \ static BinaryOperator *Create##OPC(Value *V1, Value *V2, \ - const std::string &Name = "") {\ + const Twine &Name = "") {\ return Create(Instruction::OPC, V1, V2, Name);\ } #include "llvm/Instruction.def" #define HANDLE_BINARY_INST(N, OPC, CLASS) \ static BinaryOperator *Create##OPC(Value *V1, Value *V2, \ - const std::string &Name, BasicBlock *BB) {\ + const Twine &Name, BasicBlock *BB) {\ return Create(Instruction::OPC, V1, V2, Name, BB);\ } #include "llvm/Instruction.def" #define HANDLE_BINARY_INST(N, OPC, CLASS) \ static BinaryOperator *Create##OPC(Value *V1, Value *V2, \ - const std::string &Name, Instruction *I) {\ + const Twine &Name, Instruction *I) {\ return Create(Instruction::OPC, V1, V2, Name, I);\ } #include "llvm/Instruction.def" + /// CreateNSWAdd - Create an Add operator with the NSW flag set. + /// + static BinaryOperator *CreateNSWAdd(Value *V1, Value *V2, + const Twine &Name = "") { + BinaryOperator *BO = CreateAdd(V1, V2, Name); + BO->setHasNoSignedWrap(true); + return BO; + } + static BinaryOperator *CreateNSWAdd(Value *V1, Value *V2, + const Twine &Name, BasicBlock *BB) { + BinaryOperator *BO = CreateAdd(V1, V2, Name, BB); + BO->setHasNoSignedWrap(true); + return BO; + } + static BinaryOperator *CreateNSWAdd(Value *V1, Value *V2, + const Twine &Name, Instruction *I) { + BinaryOperator *BO = CreateAdd(V1, V2, Name, I); + BO->setHasNoSignedWrap(true); + return BO; + } + + /// CreateNUWAdd - Create an Add operator with the NUW flag set. + /// + static BinaryOperator *CreateNUWAdd(Value *V1, Value *V2, + const Twine &Name = "") { + BinaryOperator *BO = CreateAdd(V1, V2, Name); + BO->setHasNoUnsignedWrap(true); + return BO; + } + static BinaryOperator *CreateNUWAdd(Value *V1, Value *V2, + const Twine &Name, BasicBlock *BB) { + BinaryOperator *BO = CreateAdd(V1, V2, Name, BB); + BO->setHasNoUnsignedWrap(true); + return BO; + } + static BinaryOperator *CreateNUWAdd(Value *V1, Value *V2, + const Twine &Name, Instruction *I) { + BinaryOperator *BO = CreateAdd(V1, V2, Name, I); + BO->setHasNoUnsignedWrap(true); + return BO; + } + + /// CreateNSWSub - Create an Sub operator with the NSW flag set. + /// + static BinaryOperator *CreateNSWSub(Value *V1, Value *V2, + const Twine &Name = "") { + BinaryOperator *BO = CreateSub(V1, V2, Name); + BO->setHasNoSignedWrap(true); + return BO; + } + static BinaryOperator *CreateNSWSub(Value *V1, Value *V2, + const Twine &Name, BasicBlock *BB) { + BinaryOperator *BO = CreateSub(V1, V2, Name, BB); + BO->setHasNoSignedWrap(true); + return BO; + } + static BinaryOperator *CreateNSWSub(Value *V1, Value *V2, + const Twine &Name, Instruction *I) { + BinaryOperator *BO = CreateSub(V1, V2, Name, I); + BO->setHasNoSignedWrap(true); + return BO; + } + + /// CreateNUWSub - Create an Sub operator with the NUW flag set. + /// + static BinaryOperator *CreateNUWSub(Value *V1, Value *V2, + const Twine &Name = "") { + BinaryOperator *BO = CreateSub(V1, V2, Name); + BO->setHasNoUnsignedWrap(true); + return BO; + } + static BinaryOperator *CreateNUWSub(Value *V1, Value *V2, + const Twine &Name, BasicBlock *BB) { + BinaryOperator *BO = CreateSub(V1, V2, Name, BB); + BO->setHasNoUnsignedWrap(true); + return BO; + } + static BinaryOperator *CreateNUWSub(Value *V1, Value *V2, + const Twine &Name, Instruction *I) { + BinaryOperator *BO = CreateSub(V1, V2, Name, I); + BO->setHasNoUnsignedWrap(true); + return BO; + } + + /// CreateExactSDiv - Create an SDiv operator with the exact flag set. + /// + static BinaryOperator *CreateExactSDiv(Value *V1, Value *V2, + const Twine &Name = "") { + BinaryOperator *BO = CreateSDiv(V1, V2, Name); + BO->setIsExact(true); + return BO; + } + static BinaryOperator *CreateExactSDiv(Value *V1, Value *V2, + const Twine &Name, BasicBlock *BB) { + BinaryOperator *BO = CreateSDiv(V1, V2, Name, BB); + BO->setIsExact(true); + return BO; + } + static BinaryOperator *CreateExactSDiv(Value *V1, Value *V2, + const Twine &Name, Instruction *I) { + BinaryOperator *BO = CreateSDiv(V1, V2, Name, I); + BO->setIsExact(true); + return BO; + } + /// Helper functions to construct and inspect unary operations (NEG and NOT) /// via binary operators SUB and XOR: /// /// CreateNeg, CreateNot - Create the NEG and NOT /// instructions out of SUB and XOR instructions. /// - static BinaryOperator *CreateNeg(Value *Op, const std::string &Name = "", + static BinaryOperator *CreateNeg(Value *Op, const Twine &Name = "", Instruction *InsertBefore = 0); - static BinaryOperator *CreateNeg(Value *Op, const std::string &Name, + static BinaryOperator *CreateNeg(Value *Op, const Twine &Name, BasicBlock *InsertAtEnd); - static BinaryOperator *CreateNot(Value *Op, const std::string &Name = "", + static BinaryOperator *CreateNSWNeg(Value *Op, const Twine &Name = "", + Instruction *InsertBefore = 0); + static BinaryOperator *CreateNSWNeg(Value *Op, const Twine &Name, + BasicBlock *InsertAtEnd); + static BinaryOperator *CreateFNeg(Value *Op, const Twine &Name = "", + Instruction *InsertBefore = 0); + static BinaryOperator *CreateFNeg(Value *Op, const Twine &Name, + BasicBlock *InsertAtEnd); + static BinaryOperator *CreateNot(Value *Op, const Twine &Name = "", Instruction *InsertBefore = 0); - static BinaryOperator *CreateNot(Value *Op, const std::string &Name, + static BinaryOperator *CreateNot(Value *Op, const Twine &Name, BasicBlock *InsertAtEnd); - /// isNeg, isNot - Check if the given Value is a NEG or NOT instruction. + /// isNeg, isFNeg, isNot - Check if the given Value is a + /// NEG, FNeg, or NOT instruction. /// static bool isNeg(const Value *V); + static bool isFNeg(const Value *V); static bool isNot(const Value *V); /// getNegArgument, getNotArgument - Helper functions to extract the - /// unary argument of a NEG or NOT operation implemented via Sub or Xor. + /// unary argument of a NEG, FNEG or NOT operation implemented via + /// Sub, FSub, or Xor. /// static const Value *getNegArgument(const Value *BinOp); static Value *getNegArgument( Value *BinOp); + static const Value *getFNegArgument(const Value *BinOp); + static Value *getFNegArgument( Value *BinOp); static const Value *getNotArgument(const Value *BinOp); static Value *getNotArgument( Value *BinOp); @@ -224,8 +343,6 @@ public: return static_cast(Instruction::getOpcode()); } - virtual BinaryOperator *clone() const; - /// swapOperands - Exchange the two operands to this instruction. /// This instruction is safe to use on any binary instruction and /// does not modify the semantics of the instruction. If the instruction @@ -233,65 +350,42 @@ public: /// bool swapOperands(); + /// setHasNoUnsignedWrap - Set or clear the nsw flag on this instruction, + /// which must be an operator which supports this flag. See LangRef.html + /// for the meaning of this flag. + void setHasNoUnsignedWrap(bool b = true); + + /// setHasNoSignedWrap - Set or clear the nsw flag on this instruction, + /// which must be an operator which supports this flag. See LangRef.html + /// for the meaning of this flag. + void setHasNoSignedWrap(bool b = true); + + /// setIsExact - Set or clear the exact flag on this instruction, + /// which must be an operator which supports this flag. See LangRef.html + /// for the meaning of this flag. + void setIsExact(bool b = true); + + /// hasNoUnsignedWrap - Determine whether the no unsigned wrap flag is set. + bool hasNoUnsignedWrap() const; + + /// hasNoSignedWrap - Determine whether the no signed wrap flag is set. + bool hasNoSignedWrap() const; + + /// isExact - Determine whether the exact flag is set. + bool isExact() const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const BinaryOperator *) { return true; } static inline bool classof(const Instruction *I) { - return I->getOpcode() >= BinaryOpsBegin && I->getOpcode() < BinaryOpsEnd; + return I->isBinaryOp(); } static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } - - /// Backward-compatible interfaces - /// @deprecated in 2.4, do not use, will disappear soon - static BinaryOperator *create(BinaryOps Op, Value *S1, Value *S2, - const std::string &Name = "", - Instruction *InsertBefore = 0) { - return Create(Op, S1, S2, Name, InsertBefore); - } - static BinaryOperator *create(BinaryOps Op, Value *S1, Value *S2, - const std::string &Name, - BasicBlock *InsertAtEnd) { - return Create(Op, S1, S2, Name, InsertAtEnd); - } -#define HANDLE_BINARY_INST(N, OPC, CLASS) \ - static BinaryOperator *create##OPC(Value *V1, Value *V2, \ - const std::string &Name = "") {\ - return Create(Instruction::OPC, V1, V2, Name);\ - } -#include "llvm/Instruction.def" -#define HANDLE_BINARY_INST(N, OPC, CLASS) \ - static BinaryOperator *create##OPC(Value *V1, Value *V2, \ - const std::string &Name, BasicBlock *BB) {\ - return Create(Instruction::OPC, V1, V2, Name, BB);\ - } -#include "llvm/Instruction.def" -#define HANDLE_BINARY_INST(N, OPC, CLASS) \ - static BinaryOperator *create##OPC(Value *V1, Value *V2, \ - const std::string &Name, Instruction *I) {\ - return Create(Instruction::OPC, V1, V2, Name, I);\ - } -#include "llvm/Instruction.def" - static BinaryOperator *createNeg(Value *Op, const std::string &Name = "", - Instruction *InsertBefore = 0) { - return CreateNeg(Op, Name, InsertBefore); - } - static BinaryOperator *createNeg(Value *Op, const std::string &Name, - BasicBlock *InsertAtEnd) { - return CreateNeg(Op, Name, InsertAtEnd); - } - static BinaryOperator *createNot(Value *Op, const std::string &Name = "", - Instruction *InsertBefore = 0) { - return CreateNot(Op, Name, InsertBefore); - } - static BinaryOperator *createNot(Value *Op, const std::string &Name, - BasicBlock *InsertAtEnd) { - return CreateNot(Op, Name, InsertAtEnd); - } }; template <> -struct OperandTraits : FixedNumOperandTraits<2> { +struct OperandTraits : public FixedNumOperandTraits<2> { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryOperator, Value) @@ -307,27 +401,21 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryOperator, Value) /// if (isa(Instr)) { ... } /// @brief Base class of casting instructions. class CastInst : public UnaryInstruction { - /// @brief Copy constructor - CastInst(const CastInst &CI) - : UnaryInstruction(CI.getType(), CI.getOpcode(), CI.getOperand(0)) { - } - /// @brief Do not allow default construction - CastInst(); protected: /// @brief Constructor with insert-before-instruction semantics for subclasses - CastInst(const Type *Ty, unsigned iType, Value *S, - const std::string &Name = "", Instruction *InsertBefore = 0) + CastInst(const Type *Ty, unsigned iType, Value *S, + const Twine &NameStr = "", Instruction *InsertBefore = 0) : UnaryInstruction(Ty, iType, S, InsertBefore) { - setName(Name); + setName(NameStr); } /// @brief Constructor with insert-at-end-of-block semantics for subclasses - CastInst(const Type *Ty, unsigned iType, Value *S, - const std::string &Name, BasicBlock *InsertAtEnd) + CastInst(const Type *Ty, unsigned iType, Value *S, + const Twine &NameStr, BasicBlock *InsertAtEnd) : UnaryInstruction(Ty, iType, S, InsertAtEnd) { - setName(Name); + setName(NameStr); } public: - /// Provides a way to construct any of the CastInst subclasses using an + /// Provides a way to construct any of the CastInst subclasses using an /// opcode instead of the subclass's constructor. The opcode must be in the /// CastOps category (Instruction::isCast(opcode) returns true). This /// constructor has insert-before-instruction semantics to automatically @@ -337,7 +425,7 @@ public: Instruction::CastOps, ///< The opcode of the cast instruction Value *S, ///< The value to be casted (operand 0) const Type *Ty, ///< The type to which cast should be made - const std::string &Name = "", ///< Name for the instruction + const Twine &Name = "", ///< Name for the instruction Instruction *InsertBefore = 0 ///< Place to insert the instruction ); /// Provides a way to construct any of the CastInst subclasses using an @@ -350,7 +438,7 @@ public: Instruction::CastOps, ///< The opcode for the cast instruction Value *S, ///< The value to be casted (operand 0) const Type *Ty, ///< The type to which operand is casted - const std::string &Name, ///< The name for the instruction + const Twine &Name, ///< The name for the instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); @@ -358,7 +446,7 @@ public: static CastInst *CreateZExtOrBitCast( Value *S, ///< The value to be casted (operand 0) const Type *Ty, ///< The type to which cast should be made - const std::string &Name = "", ///< Name for the instruction + const Twine &Name = "", ///< Name for the instruction Instruction *InsertBefore = 0 ///< Place to insert the instruction ); @@ -366,7 +454,7 @@ public: static CastInst *CreateZExtOrBitCast( Value *S, ///< The value to be casted (operand 0) const Type *Ty, ///< The type to which operand is casted - const std::string &Name, ///< The name for the instruction + const Twine &Name, ///< The name for the instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); @@ -374,7 +462,7 @@ public: static CastInst *CreateSExtOrBitCast( Value *S, ///< The value to be casted (operand 0) const Type *Ty, ///< The type to which cast should be made - const std::string &Name = "", ///< Name for the instruction + const Twine &Name = "", ///< Name for the instruction Instruction *InsertBefore = 0 ///< Place to insert the instruction ); @@ -382,7 +470,7 @@ public: static CastInst *CreateSExtOrBitCast( Value *S, ///< The value to be casted (operand 0) const Type *Ty, ///< The type to which operand is casted - const std::string &Name, ///< The name for the instruction + const Twine &Name, ///< The name for the instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); @@ -390,7 +478,7 @@ public: static CastInst *CreatePointerCast( Value *S, ///< The pointer value to be casted (operand 0) const Type *Ty, ///< The type to which operand is casted - const std::string &Name, ///< The name for the instruction + const Twine &Name, ///< The name for the instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); @@ -398,7 +486,7 @@ public: static CastInst *CreatePointerCast( Value *S, ///< The pointer value to be casted (operand 0) const Type *Ty, ///< The type to which cast should be made - const std::string &Name = "", ///< Name for the instruction + const Twine &Name = "", ///< Name for the instruction Instruction *InsertBefore = 0 ///< Place to insert the instruction ); @@ -407,7 +495,7 @@ public: Value *S, ///< The pointer value to be casted (operand 0) const Type *Ty, ///< The type to which cast should be made bool isSigned, ///< Whether to regard S as signed or not - const std::string &Name = "", ///< Name for the instruction + const Twine &Name = "", ///< Name for the instruction Instruction *InsertBefore = 0 ///< Place to insert the instruction ); @@ -416,23 +504,23 @@ public: Value *S, ///< The integer value to be casted (operand 0) const Type *Ty, ///< The integer type to which operand is casted bool isSigned, ///< Whether to regard S as signed or not - const std::string &Name, ///< The name for the instruction + const Twine &Name, ///< The name for the instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); /// @brief Create an FPExt, BitCast, or FPTrunc for fp -> fp casts static CastInst *CreateFPCast( - Value *S, ///< The floating point value to be casted + Value *S, ///< The floating point value to be casted const Type *Ty, ///< The floating point type to cast to - const std::string &Name = "", ///< Name for the instruction + const Twine &Name = "", ///< Name for the instruction Instruction *InsertBefore = 0 ///< Place to insert the instruction ); /// @brief Create an FPExt, BitCast, or FPTrunc for fp -> fp casts static CastInst *CreateFPCast( - Value *S, ///< The floating point value to be casted + Value *S, ///< The floating point value to be casted const Type *Ty, ///< The floating point type to cast to - const std::string &Name, ///< The name for the instruction + const Twine &Name, ///< The name for the instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); @@ -440,7 +528,7 @@ public: static CastInst *CreateTruncOrBitCast( Value *S, ///< The value to be casted (operand 0) const Type *Ty, ///< The type to which cast should be made - const std::string &Name = "", ///< Name for the instruction + const Twine &Name = "", ///< Name for the instruction Instruction *InsertBefore = 0 ///< Place to insert the instruction ); @@ -448,7 +536,7 @@ public: static CastInst *CreateTruncOrBitCast( Value *S, ///< The value to be casted (operand 0) const Type *Ty, ///< The type to which operand is casted - const std::string &Name, ///< The name for the instruction + const Twine &Name, ///< The name for the instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); @@ -468,7 +556,7 @@ public: bool DstIsSigned ///< Whether to treate the dest. as signed ); - /// There are several places where we need to know if a cast instruction + /// There are several places where we need to know if a cast instruction /// only deals with integer source and destination types. To simplify that /// logic, this method is provided. /// @returns true iff the cast has only integral typed operand and dest type. @@ -477,20 +565,20 @@ public: /// A lossless cast is one that does not alter the basic value. It implies /// a no-op cast but is more stringent, preventing things like int->float, - /// long->double, int->ptr, or vector->anything. + /// long->double, int->ptr, or vector->anything. /// @returns true iff the cast is lossless. /// @brief Determine if this is a lossless cast. bool isLosslessCast() const; - /// A no-op cast is one that can be effected without changing any bits. + /// A no-op cast is one that can be effected without changing any bits. /// It implies that the source and destination types are the same size. The - /// IntPtrTy argument is used to make accurate determinations for casts + /// IntPtrTy argument is used to make accurate determinations for casts /// involving Integer and Pointer types. They are no-op casts if the integer - /// is the same size as the pointer. However, pointer size varies with + /// is the same size as the pointer. However, pointer size varies with /// platform. Generally, the result of TargetData::getIntPtrType() should be /// passed in. If that's not available, use Type::Int64Ty, which will make /// the isNoopCast call conservative. - /// @brief Determine if this cast is a no-op cast. + /// @brief Determine if this cast is a no-op cast. bool isNoopCast( const Type *IntPtrTy ///< Integer type corresponding to pointer ) const; @@ -498,7 +586,7 @@ public: /// Determine how a pair of casts can be eliminated, if they can be at all. /// This is a helper function for both CastInst and ConstantExpr. /// @returns 0 if the CastInst pair can't be eliminated - /// @returns Instruction::CastOps value for a cast that can replace + /// @returns Instruction::CastOps value for a cast that can replace /// the pair, casting SrcTy to DstTy. /// @brief Determine if a cast pair is eliminable static unsigned isEliminableCastPair( @@ -507,12 +595,12 @@ public: const Type *SrcTy, ///< SrcTy of 1st cast const Type *MidTy, ///< DstTy of 1st cast & SrcTy of 2nd cast const Type *DstTy, ///< DstTy of 2nd cast - const Type *IntPtrTy ///< Integer type corresponding to Ptr types + const Type *IntPtrTy ///< Integer type corresponding to Ptr types, or null ); /// @brief Return the opcode of this CastInst - Instruction::CastOps getOpcode() const { - return Instruction::CastOps(Instruction::getOpcode()); + Instruction::CastOps getOpcode() const { + return Instruction::CastOps(Instruction::getOpcode()); } /// @brief Return the source type, as a convenience @@ -521,7 +609,7 @@ public: const Type* getDestTy() const { return getType(); } /// This method can be used to determine if a cast from S to DstTy using - /// Opcode op is valid or not. + /// Opcode op is valid or not. /// @returns true iff the proposed cast is valid. /// @brief Determine if a cast is valid without creating one. static bool castIsValid(Instruction::CastOps op, Value *S, const Type *DstTy); @@ -529,52 +617,18 @@ public: /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const CastInst *) { return true; } static inline bool classof(const Instruction *I) { - return I->getOpcode() >= CastOpsBegin && I->getOpcode() < CastOpsEnd; + return I->isCast(); } static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } - /// Backward-compatible interfaces - /// @deprecated in 2.4, do not use, will disappear soon - static CastInst *create(Instruction::CastOps Op,Value *S,const Type *Ty, - const std::string &Name = "",Instruction *InsertBefore = 0) { - return Create(Op,S,Ty,Name,InsertBefore); - } - static CastInst *create(Instruction::CastOps Op,Value *S,const Type *Ty, - const std::string &Name,BasicBlock *InsertAtEnd) { - return Create(Op,S,Ty,Name,InsertAtEnd); - } - -#define DEFINE_CASTINST_DEPRECATED(OP) \ - static CastInst *create ## OP ## Cast(Value *S, const Type *Ty, \ - const std::string &Name = "", Instruction *InsertBefore = 0) { \ - return Create ## OP ## Cast(S, Ty, Name, InsertBefore); \ - } \ - static CastInst *create ## OP ## Cast(Value *S, const Type *Ty, \ - const std::string &Name, BasicBlock *InsertAtEnd) { \ - return Create ## OP ## Cast(S, Ty, Name, InsertAtEnd); \ - } - DEFINE_CASTINST_DEPRECATED(ZExtOrBit) - DEFINE_CASTINST_DEPRECATED(SExtOrBit) - DEFINE_CASTINST_DEPRECATED(Pointer) - DEFINE_CASTINST_DEPRECATED(FP) - DEFINE_CASTINST_DEPRECATED(TruncOrBit) -#undef DEFINE_CASTINST_DEPRECATED - static CastInst *createIntegerCast(Value *S, const Type *Ty, bool isSigned, - const std::string &Name = "", Instruction *InsertBefore = 0) { - return CreateIntegerCast(S, Ty, isSigned, Name, InsertBefore); - } - static CastInst *createIntegerCast(Value *S, const Type *Ty, bool isSigned, - const std::string &Name, BasicBlock *InsertAtEnd) { - return CreateIntegerCast(S, Ty, isSigned, Name, InsertAtEnd); - } }; //===----------------------------------------------------------------------===// // CmpInst Class //===----------------------------------------------------------------------===// -/// This class is the base class for the comparison instructions. +/// This class is the base class for the comparison instructions. /// @brief Abstract base class of comparison instructions. // FIXME: why not derive from BinaryOperator? class CmpInst: public Instruction { @@ -582,11 +636,11 @@ class CmpInst: public Instruction { CmpInst(); // do not implement protected: CmpInst(const Type *ty, Instruction::OtherOps op, unsigned short pred, - Value *LHS, Value *RHS, const std::string &Name = "", + Value *LHS, Value *RHS, const Twine &Name = "", Instruction *InsertBefore = 0); - + CmpInst(const Type *ty, Instruction::OtherOps op, unsigned short pred, - Value *LHS, Value *RHS, const std::string &Name, + Value *LHS, Value *RHS, const Twine &Name, BasicBlock *InsertAtEnd); public: @@ -634,38 +688,74 @@ public: void *operator new(size_t s) { return User::operator new(s, 2); } - /// Construct a compare instruction, given the opcode, the predicate and - /// the two operands. Optionally (if InstBefore is specified) insert the - /// instruction into a BasicBlock right before the specified instruction. + /// Construct a compare instruction, given the opcode, the predicate and + /// the two operands. Optionally (if InstBefore is specified) insert the + /// instruction into a BasicBlock right before the specified instruction. /// The specified Instruction is allowed to be a dereferenced end iterator. /// @brief Create a CmpInst - static CmpInst *Create(OtherOps Op, unsigned short predicate, Value *S1, - Value *S2, const std::string &Name = "", + static CmpInst *Create(OtherOps Op, + unsigned short predicate, Value *S1, + Value *S2, const Twine &Name = "", Instruction *InsertBefore = 0); - /// Construct a compare instruction, given the opcode, the predicate and the - /// two operands. Also automatically insert this instruction to the end of + /// Construct a compare instruction, given the opcode, the predicate and the + /// two operands. Also automatically insert this instruction to the end of /// the BasicBlock specified. /// @brief Create a CmpInst - static CmpInst *Create(OtherOps Op, unsigned short predicate, Value *S1, - Value *S2, const std::string &Name, - BasicBlock *InsertAtEnd); - + static CmpInst *Create(OtherOps Op, unsigned short predicate, Value *S1, + Value *S2, const Twine &Name, BasicBlock *InsertAtEnd); + /// @brief Get the opcode casted to the right type OtherOps getOpcode() const { return static_cast(Instruction::getOpcode()); } - /// The predicate for CmpInst is defined by the subclasses but stored in - /// the SubclassData field (see Value.h). We allow it to be fetched here - /// as the predicate but there is no enum type for it, just the raw unsigned - /// short. This facilitates comparison of CmpInst instances without delving - /// into the subclasses since predicate values are distinct between the - /// CmpInst subclasses. /// @brief Return the predicate for this instruction. - unsigned short getPredicate() const { - return SubclassData; + Predicate getPredicate() const { return Predicate(SubclassData); } + + /// @brief Set the predicate for this instruction to the specified value. + void setPredicate(Predicate P) { SubclassData = P; } + + static bool isFPPredicate(Predicate P) { + return P >= FIRST_FCMP_PREDICATE && P <= LAST_FCMP_PREDICATE; + } + + static bool isIntPredicate(Predicate P) { + return P >= FIRST_ICMP_PREDICATE && P <= LAST_ICMP_PREDICATE; } + + bool isFPPredicate() const { return isFPPredicate(getPredicate()); } + bool isIntPredicate() const { return isIntPredicate(getPredicate()); } + + + /// For example, EQ -> NE, UGT -> ULE, SLT -> SGE, + /// OEQ -> UNE, UGT -> OLE, OLT -> UGE, 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, + /// OEQ -> UNE, UGT -> OLE, OLT -> UGE, 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, + /// OEQ->OEQ, ULE->UGE, OLT->OGT, etc. + /// @returns the predicate that would be the result of exchanging the two + /// operands of the CmpInst 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); /// @brief Provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); @@ -683,6 +773,30 @@ public: /// @brief Determine if this is an equals/not equals predicate. bool isEquality(); + /// @returns true if the comparison is signed, false otherwise. + /// @brief Determine if this instruction is using a signed comparison. + bool isSigned() const { + return isSigned(getPredicate()); + } + + /// @returns true if the comparison is unsigned, false otherwise. + /// @brief Determine if this instruction is using an unsigned comparison. + bool isUnsigned() const { + return isUnsigned(getPredicate()); + } + + /// This is just a convenience. + /// @brief Determine if this is true when both operands are the same. + bool isTrueWhenEqual() const { + return isTrueWhenEqual(getPredicate()); + } + + /// This is just a convenience. + /// @brief Determine if this is false when both operands are the same. + bool isFalseWhenEqual() const { + return isFalseWhenEqual(getPredicate()); + } + /// @returns true if the predicate is unsigned, false otherwise. /// @brief Determine if the predicate is an unsigned operation. static bool isUnsigned(unsigned short predicate); @@ -697,35 +811,36 @@ public: /// @brief Determine if the predicate is an unordered operation. static bool isUnordered(unsigned short predicate); + /// Determine if the predicate is true when comparing a value with itself. + static bool isTrueWhenEqual(unsigned short predicate); + + /// Determine if the predicate is false when comparing a value with itself. + static bool isFalseWhenEqual(unsigned short predicate); + /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const CmpInst *) { return true; } static inline bool classof(const Instruction *I) { - return I->getOpcode() == Instruction::ICmp || - I->getOpcode() == Instruction::FCmp || - I->getOpcode() == Instruction::VICmp || - I->getOpcode() == Instruction::VFCmp; + return I->getOpcode() == Instruction::ICmp || + I->getOpcode() == Instruction::FCmp; } static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } - /// Backward-compatible interfaces - /// @deprecated in 2.4, do not use, will disappear soon - static CmpInst *create(OtherOps Op, unsigned short predicate, Value *S1, - Value *S2, const std::string &Name = "", - Instruction *InsertBefore = 0) { - return Create(Op, predicate, S1, S2, Name, InsertBefore); - } - static CmpInst *create(OtherOps Op, unsigned short predicate, Value *S1, - Value *S2, const std::string &Name, - BasicBlock *InsertAtEnd) { - return Create(Op, predicate, S1, S2, Name, InsertAtEnd); + + /// @brief Create a result type for fcmp/icmp + static const Type* makeCmpResultType(const Type* opnd_type) { + if (const VectorType* vt = dyn_cast(opnd_type)) { + return VectorType::get(Type::getInt1Ty(opnd_type->getContext()), + vt->getNumElements()); + } + return Type::getInt1Ty(opnd_type->getContext()); } }; // FIXME: these are redundant if CmpInst < BinaryOperator template <> -struct OperandTraits : FixedNumOperandTraits<2> { +struct OperandTraits : public FixedNumOperandTraits<2> { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CmpInst, Value)