operator== returns false when two bitvectors have different sizes.
[oota-llvm.git] / include / llvm / Instruction.h
index d9cb5859211513b2b5022046a3a36d8d184a0959..7f7bcc881cc0831511c19a9979b4f5a45a3ad9c5 100644 (file)
@@ -27,6 +27,9 @@ template<typename ValueSubClass, typename ItemParentClass, typename SymTabClass,
          typename SubClass> class SymbolTableListTraits;
 
 class Instruction : public User {
+  void operator=(const Instruction &);     // Do not implement
+  Instruction(const Instruction &);        // Do not implement
+
   BasicBlock *Parent;
   Instruction *Prev, *Next; // Next and Prev links for our intrusive linked list
 
@@ -36,24 +39,19 @@ class Instruction : public User {
   friend class SymbolTableListTraits<Instruction, BasicBlock, Function,
                                      ilist_traits<Instruction> >;
   void setParent(BasicBlock *P);
-
-private:
-  // FIXME: This is a dirty hack.  Setcc instructions shouldn't encode the CC
-  // into the opcode field.  When they don't, this will be unneeded.
-  void setOpcode(unsigned NewOpcode);
-  friend class BinaryOperator;
 protected:
   Instruction(const Type *Ty, unsigned iType, Use *Ops, unsigned NumOps,
-              const std::string &Name = "",
-              Instruction *InsertBefore = 0);
+              const std::string &Name, Instruction *InsertBefore = 0);
   Instruction(const Type *Ty, unsigned iType, Use *Ops, unsigned NumOps,
               const std::string &Name, BasicBlock *InsertAtEnd);
+  Instruction(const Type *Ty, unsigned iType, Use *Ops, unsigned NumOps,
+              const char *Name = 0, Instruction *InsertBefore = 0);
+  Instruction(const Type *Ty, unsigned iType, Use *Ops, unsigned NumOps,
+              const char *Name, BasicBlock *InsertAtEnd);
 public:
-
-  ~Instruction() {
-    assert(Parent == 0 && "Instruction still linked in the program!");
-  }
-
+  // Out of line virtual method, so the vtable, etc has a home.
+  ~Instruction();
+  
   /// mayWriteToMemory - Return true if this instruction may modify memory.
   ///
   virtual bool mayWriteToMemory() const { return false; }
@@ -70,7 +68,21 @@ public:
   /// extra information (e.g. load is volatile) agree.
   bool isIdenticalTo(Instruction *I) const;
 
-
+  /// This function determines if the specified instruction executes the same
+  /// operation as the current one. This means that the opcodes, type, operand
+  /// types and any other factors affecting the operation must be the same. This
+  /// is similar to isIdenticalTo except the operands themselves don't have to
+  /// be identical.
+  /// @returns true if the specified instruction is the same operation as
+  /// the current one.
+  /// @brief Determine if one instruction is the same operation as another.
+  bool isSameOperationAs(Instruction *I) const;
+
+  /// use_back - Specialize the methods defined in Value, as we know that an
+  /// instruction can only be used by other instructions.
+  Instruction       *use_back()       { return cast<Instruction>(*use_begin());}
+  const Instruction *use_back() const { return cast<Instruction>(*use_begin());}
+  
   // Accessor methods...
   //
   inline const BasicBlock *getParent() const { return Parent; }
@@ -103,7 +115,7 @@ public:
   /// one of the enums that is coming soon (down below)...
   ///
   unsigned getOpcode() const { return getValueType() - InstructionVal; }
-  virtual const char *getOpcodeName() const {
+  const char *getOpcodeName() const {
     return getOpcodeName(getOpcode());
   }
   static const char* getOpcodeName(unsigned OpCode);
@@ -120,6 +132,37 @@ public:
     return getOpcode() >= BinaryOpsBegin && getOpcode() < BinaryOpsEnd;
   }
 
+  /// @brief Determine if the Opcode is one of the shift instructions.
+  static inline bool isShift(unsigned Opcode) {
+    return Opcode >= Shl && Opcode <= AShr;
+  }
+
+  /// @brief Determine if the instruction's opcode is one of the shift 
+  /// instructions.
+  inline bool isShift() { return isShift(getOpcode()); }
+
+  /// isLogicalShift - Return true if this is a logical shift left or a logical
+  /// shift right.
+  inline bool isLogicalShift() {
+    return getOpcode() == Shl || getOpcode() == LShr;
+  }
+
+  /// isLogicalShift - Return true if this is a logical shift left or a logical
+  /// shift right.
+  inline bool isArithmeticShift() {
+    return getOpcode() == AShr;
+  }
+
+  /// @brief Determine if the OpCode is one of the CastInst instructions.
+  static inline bool isCast(unsigned OpCode) {
+    return OpCode >= CastOpsBegin && OpCode < CastOpsEnd;
+  }
+
+  /// @brief Determine if this is one of the CastInst instructions.
+  inline bool isCast() const {
+    return isCast(getOpcode());
+  }
+
   /// isAssociative - Return true if the instruction is associative:
   ///
   ///   Associative operators satisfy:  x op (y op z) === (x op y) op z
@@ -140,12 +183,6 @@ public:
   bool isCommutative() const { return isCommutative(getOpcode()); }
   static bool isCommutative(unsigned op);
 
-  /// isRelational - Return true if the instruction is a Set* instruction:
-  ///
-  bool isRelational() const { return isRelational(getOpcode()); }
-  static bool isRelational(unsigned op);
-
-
   /// isTrappingInstruction - Return true if the instruction may trap.
   ///
   bool isTrapping() const {
@@ -154,6 +191,7 @@ public:
   static bool isTrapping(unsigned op);
 
   virtual void print(std::ostream &OS) const { print(OS, 0); }
+  void print(std::ostream *OS) const { if (OS) print(*OS); }
   void print(std::ostream &OS, AssemblyAnnotationWriter *AAW) const;
 
   /// Methods for support type inquiry through isa, cast, and dyn_cast:
@@ -186,6 +224,13 @@ public:
 #include "llvm/Instruction.def"
   };
 
+  enum CastOps {
+#define  FIRST_CAST_INST(N)             CastOpsBegin = N,
+#define HANDLE_CAST_INST(N, OPC, CLASS) OPC = N,
+#define   LAST_CAST_INST(N)             CastOpsEnd = N+1
+#include "llvm/Instruction.def"
+  };
+
   enum OtherOps {
 #define  FIRST_OTHER_INST(N)             OtherOpsBegin = N,
 #define HANDLE_OTHER_INST(N, OPC, CLASS) OPC = N,