[llvm-commits] CVS: llvm/include/llvm/InstrTypes.h Instruction.def Instructions.h

Reid Spencer reid at x10sys.com
Sun Nov 19 17:22:56 PST 2006



Changes in directory llvm/include/llvm:

InstrTypes.h updated: 1.47 -> 1.48
Instruction.def updated: 1.24 -> 1.25
Instructions.h updated: 1.45 -> 1.46
---
Log message:

For PR950: http://llvm.org/PR950 :
First in a series of patches to convert SetCondInst into ICmpInst and 
FCmpInst using only two opcodes and having the instructions contain their
predicate value. Nothing uses these classes yet. More patches to follow.


---
Diffs of the changes:  (+334 -14)

 InstrTypes.h    |   85 ++++++++++++++++++++
 Instruction.def |   30 +++----
 Instructions.h  |  233 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 334 insertions(+), 14 deletions(-)


Index: llvm/include/llvm/InstrTypes.h
diff -u llvm/include/llvm/InstrTypes.h:1.47 llvm/include/llvm/InstrTypes.h:1.48
--- llvm/include/llvm/InstrTypes.h:1.47	Sun Sep 17 14:29:56 2006
+++ llvm/include/llvm/InstrTypes.h	Sun Nov 19 19:22:35 2006
@@ -243,6 +243,91 @@
   }
 };
 
+//===----------------------------------------------------------------------===//
+//                               CmpInst Class
+//===----------------------------------------------------------------------===//
+
+/// This class is the base class for the comparison instructions. 
+/// @brief Abstract base class of comparison instructions.
+class CmpInst: public Instruction {
+  CmpInst(); // do not implement
+protected:
+  CmpInst(Instruction::OtherOps op, unsigned short pred, Value *LHS, Value *RHS,
+          const std::string &Name = "", Instruction *InsertBefore = 0);
+  
+  CmpInst(Instruction::OtherOps op, unsigned short pred, Value *LHS, Value *RHS,
+          const std::string &Name, BasicBlock *InsertAtEnd);
+
+  Use Ops[2]; // CmpInst instructions always have 2 operands, optimize
+
+public:
+  /// 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 = "",
+                         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 
+  /// 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);
+
+  /// @brief Implement superclass method.
+  virtual CmpInst *clone() const;
+
+  /// 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;
+  }
+
+  /// @brief Provide more efficient getOperand methods.
+  Value *getOperand(unsigned i) const {
+    assert(i < 2 && "getOperand() out of range!");
+    return Ops[i];
+  }
+  void setOperand(unsigned i, Value *Val) {
+    assert(i < 2 && "setOperand() out of range!");
+    Ops[i] = Val;
+  }
+
+  /// @brief CmpInst instructions always have 2 operands.
+  unsigned getNumOperands() const { return 2; }
+
+  /// This is just a convenience that dispatches to the subclasses.
+  /// @brief Swap the operands.
+  void swapOperands();
+
+  /// This is just a convenience that dispatches to the subclasses.
+  /// @brief Determine if this CmpInst is commutative.
+  bool isCommutative();
+
+  /// This is just a convenience that dispatches to the subclasses.
+  /// @brief Determine if this is an equals/not equals predicate.
+  bool isEquality();
+
+  /// @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;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
 } // End llvm namespace
 
 #endif


Index: llvm/include/llvm/Instruction.def
diff -u llvm/include/llvm/Instruction.def:1.24 llvm/include/llvm/Instruction.def:1.25
--- llvm/include/llvm/Instruction.def:1.24	Sat Nov 11 17:06:47 2006
+++ llvm/include/llvm/Instruction.def	Sun Nov 19 19:22:35 2006
@@ -126,20 +126,22 @@
 
 // Other operators...
  FIRST_OTHER_INST(31)
-HANDLE_OTHER_INST(31, PHI    , PHINode    )  // PHI node instruction
-HANDLE_OTHER_INST(32, Cast   , CastInst   )  // Type cast
-HANDLE_OTHER_INST(33, Call   , CallInst   )  // Call a function
-HANDLE_OTHER_INST(34, Shl    , ShiftInst  )  // Shift Left operations (logical)
-HANDLE_OTHER_INST(35, LShr   , ShiftInst  )  // Logical Shift right (unsigned) 
-HANDLE_OTHER_INST(36, AShr   , ShiftInst  )  // Arithmetic shift right (signed)
-HANDLE_OTHER_INST(37, Select , SelectInst )  // select instruction
-HANDLE_OTHER_INST(38, UserOp1, Instruction)  // May be used internally in a pass
-HANDLE_OTHER_INST(39, UserOp2, Instruction)  // Internal to passes only
-HANDLE_OTHER_INST(40, VAArg  , VAArgInst  )  // vaarg instruction
-HANDLE_OTHER_INST(41, ExtractElement, ExtractElementInst)// extract from vector.
-HANDLE_OTHER_INST(42, InsertElement, InsertElementInst)  // insert into vector
-HANDLE_OTHER_INST(43, ShuffleVector, ShuffleVectorInst)  // shuffle two vectors.
-  LAST_OTHER_INST(43)
+HANDLE_OTHER_INST(31, ICmp   , ICmpInst   )  // Integer comparison instruction
+HANDLE_OTHER_INST(32, FCmp   , FCmpInst   )  // Floating point comparison instr.
+HANDLE_OTHER_INST(33, PHI    , PHINode    )  // PHI node instruction
+HANDLE_OTHER_INST(34, Cast   , CastInst   )  // Type cast
+HANDLE_OTHER_INST(35, Call   , CallInst   )  // Call a function
+HANDLE_OTHER_INST(36, Shl    , ShiftInst  )  // Shift Left operations (logical)
+HANDLE_OTHER_INST(37, LShr   , ShiftInst  )  // Logical Shift right (unsigned) 
+HANDLE_OTHER_INST(38, AShr   , ShiftInst  )  // Arithmetic shift right (signed)
+HANDLE_OTHER_INST(39, Select , SelectInst )  // select instruction
+HANDLE_OTHER_INST(40, UserOp1, Instruction)  // May be used internally in a pass
+HANDLE_OTHER_INST(41, UserOp2, Instruction)  // Internal to passes only
+HANDLE_OTHER_INST(42, VAArg  , VAArgInst  )  // vaarg instruction
+HANDLE_OTHER_INST(43, ExtractElement, ExtractElementInst)// extract from vector.
+HANDLE_OTHER_INST(44, InsertElement, InsertElementInst)  // insert into vector
+HANDLE_OTHER_INST(45, ShuffleVector, ShuffleVectorInst)  // shuffle two vectors.
+  LAST_OTHER_INST(45)
 
 #undef  FIRST_TERM_INST
 #undef HANDLE_TERM_INST


Index: llvm/include/llvm/Instructions.h
diff -u llvm/include/llvm/Instructions.h:1.45 llvm/include/llvm/Instructions.h:1.46
--- llvm/include/llvm/Instructions.h:1.45	Wed Nov  8 00:47:32 2006
+++ llvm/include/llvm/Instructions.h	Sun Nov 19 19:22:35 2006
@@ -415,6 +415,239 @@
 };
 
 //===----------------------------------------------------------------------===//
+//                               ICmpInst Class
+//===----------------------------------------------------------------------===//
+
+/// This instruction compares its operands according to the predicate given
+/// to the constructor. It only operates on integers, pointers, or packed 
+/// vectors of integrals. The two operands must be the same type.
+/// @brief Represent an integer comparison operator.
+class ICmpInst: public CmpInst {
+public:
+  /// This enumeration lists the possible predicates for the ICmpInst. The
+  /// values in the range 0-31 are reserved for FCmpInst while values in the
+  /// range 32-64 are reserved for ICmpInst. This is necessary to ensure the
+  /// predicate values are not overlapping between the classes.
+  enum Predicate {
+    ICMP_EQ  = 32,    ///< equal
+    ICMP_NE  = 33,    ///< not equal
+    ICMP_UGT = 34,    ///< unsigned greater than
+    ICMP_UGE = 35,    ///< unsigned greater or equal
+    ICMP_ULT = 36,    ///< unsigned less than
+    ICMP_ULE = 37,    ///< unsigned less or equal
+    ICMP_SGT = 38,    ///< signed greater than
+    ICMP_SGE = 39,    ///< signed greater or equal
+    ICMP_SLT = 40,    ///< signed less than
+    ICMP_SLE = 41,    ///< signed less or equal
+    FIRST_ICMP_PREDICATE = ICMP_EQ,
+    LAST_ICMP_PREDICATE = ICMP_SLE
+  };
+
+  /// @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); }
+
+  /// For example, EQ -> NE, UGT -> ULE, SLT -> SGE, etc.
+  /// @returns the inverse predicate for the instruction's current predicate. 
+  /// @brief Return the inverse of the instruction's predicate.
+  Predicate getInversePredicate() const {
+    return getInversePredicate(getPredicate());
+  }
+
+  /// For example, EQ -> NE, UGT -> ULE, SLT -> SGE, etc.
+  /// @returns the inverse predicate for predicate provided in \p pred. 
+  /// @brief Return the inverse of a given predicate
+  static Predicate getInversePredicate(Predicate pred);
+
+  /// For example, EQ->EQ, SLE->SGE, ULT->UGT, etc.
+  /// @returns the predicate that would be the result of exchanging the two 
+  /// operands of the ICmpInst instruction without changing the result 
+  /// produced.  
+  /// @brief Return the predicate as if the operands were swapped
+  Predicate getSwappedPredicate() const {
+    return getSwappedPredicate(getPredicate());
+  }
+
+  /// This is a static version that you can use without an instruction 
+  /// available.
+  /// @brief Return the predicate as if the operands were swapped.
+  static Predicate getSwappedPredicate(Predicate 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 == ICMP_EQ || SubclassData == ICMP_NE;
+  }
+  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]);
+  }
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const ICmpInst *) { return true; }
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == Instruction::ICmp;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+//===----------------------------------------------------------------------===//
+//                               FCmpInst Class
+//===----------------------------------------------------------------------===//
+
+/// 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:
+  /// 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
+  };
+
+  /// @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); }
+
+  /// 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() == Instruction::FCmp;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+
+//===----------------------------------------------------------------------===//
 //                            SetCondInst Class
 //===----------------------------------------------------------------------===//
 






More information about the llvm-commits mailing list