merge of use-diet branch to trunk
[oota-llvm.git] / include / llvm / InstrTypes.h
index f735602ca8ce56a3e76574562b7931bdf06179c3..a68b5622127fb4cc7d76afc1c06e72d6a5ad7ad9 100644 (file)
@@ -17,6 +17,7 @@
 #define LLVM_INSTRUCTION_TYPES_H
 
 #include "llvm/Instruction.h"
+#include "llvm/OperandTraits.h"
 
 namespace llvm {
 
@@ -78,22 +79,22 @@ public:
   }
 };
 
+
 //===----------------------------------------------------------------------===//
 //                          UnaryInstruction Class
 //===----------------------------------------------------------------------===//
 
 class UnaryInstruction : public Instruction {
   void *operator new(size_t, unsigned); // Do not implement
-  Use Op;
   
-  // avoiding warning: 'this' : used in base member initializer list
-  UnaryInstruction* this_() { return this; }
 protected:
-  UnaryInstruction(const Type *Ty, unsigned iType, Value *V, Instruction *IB =0)
-    : Instruction(Ty, iType, &Op, 1, IB), Op(V, this_()) {
+  UnaryInstruction(const Type *Ty, unsigned iType, Value *V, Instruction *IB = 0)
+    : Instruction(Ty, iType, &Op<0>(), 1, IB) {
+    Op<0>() = V;
   }
   UnaryInstruction(const Type *Ty, unsigned iType, Value *V, BasicBlock *IAE)
-    : Instruction(Ty, iType, &Op, 1, IAE), Op(V, this_()) {
+    : Instruction(Ty, iType, &Op<0>(), 1, IAE) {
+    Op<0>() = V;
   }
 public:
   // allocate space for exactly one operand
@@ -104,16 +105,8 @@ public:
   // Out of line virtual method, so the vtable, etc has a home.
   ~UnaryInstruction();
 
-  // Transparently provide more efficient getOperand methods.
-  Value *getOperand(unsigned i) const {
-    assert(i == 0 && "getOperand() out of range!");
-    return Op;
-  }
-  void setOperand(unsigned i, Value *Val) {
-    assert(i == 0 && "setOperand() out of range!");
-    Op = Val;
-  }
-  unsigned getNumOperands() const { return 1; }
+  /// Transparently provide more efficient getOperand methods.
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
   
   // Methods for support type inquiry through isa, cast, and dyn_cast:
   static inline bool classof(const UnaryInstruction *) { return true; }
@@ -130,13 +123,18 @@ public:
   }
 };
 
+template <>
+struct OperandTraits<UnaryInstruction> : FixedNumOperandTraits<1> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryInstruction, Value)
+
 //===----------------------------------------------------------------------===//
 //                           BinaryOperator Class
 //===----------------------------------------------------------------------===//
 
 class BinaryOperator : public Instruction {
   void *operator new(size_t, unsigned); // Do not implement
-  Use Ops[2];
 protected:
   void init(BinaryOps iType);
   BinaryOperator(BinaryOps iType, Value *S1, Value *S2, const Type *Ty,
@@ -150,15 +148,7 @@ public:
   }
 
   /// Transparently provide more efficient getOperand methods.
-  Value *getOperand(unsigned i) const {
-    assert(i < 2 && "getOperand() out of range!");
-    return Ops[i];
-  }
-  void setOperand(unsigned i, Value *Val) {
-    assert(i < 2 && "setOperand() out of range!");
-    Ops[i] = Val;
-  }
-  unsigned getNumOperands() const { return 2; }
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
 
   /// create() - Construct a binary instruction, given the opcode and the two
   /// operands.  Optionally (if InstBefore is specified) insert the instruction
@@ -251,6 +241,12 @@ public:
   }
 };
 
+template <>
+struct OperandTraits<BinaryOperator> : FixedNumOperandTraits<2> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryOperator, Value)
+
 //===----------------------------------------------------------------------===//
 //                               CastInst Class
 //===----------------------------------------------------------------------===//
@@ -497,6 +493,7 @@ public:
 
 /// This class is the base class for the comparison instructions. 
 /// @brief Abstract base class of comparison instructions.
+// FIXME: why not derive from BinaryOperator?
 class CmpInst: public Instruction {
   void *operator new(size_t, unsigned);  // DO NOT IMPLEMENT
   CmpInst(); // do not implement
@@ -507,8 +504,6 @@ protected:
   CmpInst(Instruction::OtherOps op, unsigned short pred, Value *LHS, Value *RHS,
           const std::string &Name, BasicBlock *InsertAtEnd);
 
-  Use Ops[2]; // CmpInst instructions always have 2 operands, optimize
-
 public:
   // allocate space for exactly two operands
   void *operator new(size_t s) {
@@ -548,17 +543,7 @@ public:
   }
 
   /// @brief Provide more efficient getOperand methods.
-  Value *getOperand(unsigned i) const {
-    assert(i < 2 && "getOperand() out of range!");
-    return Ops[i];
-  }
-  void setOperand(unsigned i, Value *Val) {
-    assert(i < 2 && "setOperand() out of range!");
-    Ops[i] = Val;
-  }
-
-  /// @brief CmpInst instructions always have 2 operands.
-  unsigned getNumOperands() const { return 2; }
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
 
   /// This is just a convenience that dispatches to the subclasses.
   /// @brief Swap the operands and adjust predicate accordingly to retain
@@ -598,6 +583,14 @@ public:
   }
 };
 
+
+// FIXME: these are redundant if CmpInst < BinaryOperator
+template <>
+struct OperandTraits<CmpInst> : FixedNumOperandTraits<2> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CmpInst, Value)
+
 } // End llvm namespace
 
 #endif