merge of use-diet branch to trunk
[oota-llvm.git] / include / llvm / InstrTypes.h
index f7644e3dfa6ae96c9cab9be19f710fba954e550d..a68b5622127fb4cc7d76afc1c06e72d6a5ad7ad9 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     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 is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
@@ -17,6 +17,7 @@
 #define LLVM_INSTRUCTION_TYPES_H
 
 #include "llvm/Instruction.h"
+#include "llvm/OperandTraits.h"
 
 namespace llvm {
 
@@ -78,41 +79,62 @@ public:
   }
 };
 
+
 //===----------------------------------------------------------------------===//
 //                          UnaryInstruction Class
 //===----------------------------------------------------------------------===//
 
 class UnaryInstruction : public Instruction {
-  Use Op;
+  void *operator new(size_t, unsigned); // Do not implement
+  
 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
+  void *operator new(size_t s) {
+    return User::operator new(s, 1);
+  }
+
   // 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;
+  /// 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 ||
+           I->getOpcode() == Instruction::Load ||
+           I->getOpcode() == Instruction::VAArg ||
+           (I->getOpcode() >= CastOpsBegin && I->getOpcode() < CastOpsEnd);
   }
-  void setOperand(unsigned i, Value *Val) {
-    assert(i == 0 && "setOperand() out of range!");
-    Op = Val;
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
   }
-  unsigned getNumOperands() const { return 1; }
 };
 
+template <>
+struct OperandTraits<UnaryInstruction> : FixedNumOperandTraits<1> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryInstruction, Value)
+
 //===----------------------------------------------------------------------===//
 //                           BinaryOperator Class
 //===----------------------------------------------------------------------===//
 
 class BinaryOperator : public Instruction {
-  Use Ops[2];
+  void *operator new(size_t, unsigned); // Do not implement
 protected:
   void init(BinaryOps iType);
   BinaryOperator(BinaryOps iType, Value *S1, Value *S2, const Type *Ty,
@@ -120,17 +142,13 @@ protected:
   BinaryOperator(BinaryOps iType, Value *S1, Value *S2, const Type *Ty,
                  const std::string &Name, BasicBlock *InsertAtEnd);
 public:
+  // allocate space for exactly two operands
+  void *operator new(size_t s) {
+    return User::operator new(s, 2);
+  }
 
   /// 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
@@ -208,10 +226,8 @@ public:
 
   /// 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 is order dependent (SetLT f.e.) the opcode is
-  /// changed.  If the instruction cannot be reversed (ie, it's a Div),
-  /// then return true.
+  /// does not modify the semantics of the instruction.  If the instruction
+  /// cannot be reversed (ie, it's a Div), then return true.
   ///
   bool swapOperands();
 
@@ -225,6 +241,12 @@ public:
   }
 };
 
+template <>
+struct OperandTraits<BinaryOperator> : FixedNumOperandTraits<2> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryOperator, Value)
+
 //===----------------------------------------------------------------------===//
 //                               CastInst Class
 //===----------------------------------------------------------------------===//
@@ -381,8 +403,14 @@ public:
     BasicBlock *InsertAtEnd  ///< The block to insert the instruction into
   );
 
+  /// @brief Check whether it is valid to call getCastOpcode for these types.
+  static bool isCastable(
+    const Type *SrcTy, ///< The Type from which the value should be cast.
+    const Type *DestTy ///< The Type to which the value should be cast.
+  );
+
   /// Returns the opcode necessary to cast Val into Ty using usual casting
-  /// rules. 
+  /// rules.
   /// @brief Infer the opcode for cast operand and type
   static Instruction::CastOps getCastOpcode(
     const Value *Val, ///< The value to cast
@@ -465,7 +493,9 @@ 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
 protected:
   CmpInst(Instruction::OtherOps op, unsigned short pred, Value *LHS, Value *RHS,
@@ -474,9 +504,11 @@ 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) {
+    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.  
@@ -511,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
@@ -561,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