EXTRACT_SUBREG coalescing support. The coalescer now treats EXTRACT_SUBREG like
[oota-llvm.git] / include / llvm / CodeGen / MachineInstr.h
index e98caa56afa0331cea16829cc813c24da5878b03..beba6923ee7832749f0569aeccb875b61cfb7dd3 100644 (file)
 
 #include "llvm/ADT/iterator"
 #include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Streams.h"
 #include <vector>
 #include <cassert>
+#include <iosfwd>
 
 namespace llvm {
 
 class Value;
 class Function;
 class MachineBasicBlock;
+class TargetInstrDescriptor;
 class TargetMachine;
 class GlobalValue;
 
 template <typename T> struct ilist_traits;
 template <typename T> struct ilist;
 
-typedef short MachineOpCode;
-
 //===----------------------------------------------------------------------===//
 // class MachineOperand
 //
-// Purpose:
 //   Representation of each machine instruction operand.
-//   This class is designed so that you can allocate a vector of operands
-//   first and initialize each one later.
-//
-//   E.g, for this VM instruction:
-//     ptr = alloca type, numElements
-//   we generate 2 machine instructions on the SPARC:
-//
-//    mul Constant, Numelements -> Reg
-//    add %sp, Reg -> Ptr
-//
-//   Each instruction has 3 operands, listed above.  Of those:
-//   - Reg, NumElements, and Ptr are of operand type MO_Register.
-//   - Constant is of operand type MO_SignExtendedImmed on the SPARC.
-//
-//   For the register operands, the virtual register type is as follows:
-//
-//   - Reg will be of virtual register type MO_MInstrVirtualReg.  The field
-//     MachineInstr* minstr will point to the instruction that computes reg.
 //
-//   - %sp will be of virtual register type MO_MachineReg.
-//     The field regNum identifies the machine register.
-//
-//   - NumElements will be of virtual register type MO_VirtualReg.
-//     The field Value* value identifies the value.
-//
-//   - Ptr will also be of virtual register type MO_VirtualReg.
-//     Again, the field Value* value identifies the value.
-//
-//===----------------------------------------------------------------------===//
-
 struct MachineOperand {
-private:
-  // Bit fields of the flags variable used for different operand properties
-  enum {
-    DEFFLAG     = 0x01,       // this is a def of the operand
-    USEFLAG     = 0x02,       // this is a use of the operand
-    HIFLAG32    = 0x04,       // operand is %hi32(value_or_immedVal)
-    LOFLAG32    = 0x08,       // operand is %lo32(value_or_immedVal)
-    HIFLAG64    = 0x10,       // operand is %hi64(value_or_immedVal)
-    LOFLAG64    = 0x20,       // operand is %lo64(value_or_immedVal)
-    PCRELATIVE  = 0x40        // Operand is relative to PC, not a global address
-  };
-
-public:
-  // UseType - This enum describes how the machine operand is used by
-  // the instruction. Note that the MachineInstr/Operator class
-  // currently uses bool arguments to represent this information
-  // instead of an enum.  Eventually this should change over to use
-  // this _easier to read_ representation instead.
-  //
-  enum UseType {
-    Use = USEFLAG,        /// only read
-    Def = DEFFLAG,        /// only written
-    UseAndDef = Use | Def /// read AND written
-  };
-
   enum MachineOperandType {
-    MO_VirtualRegister,         // virtual register for *value
-    MO_MachineRegister,         // pre-assigned machine register `regNum'
-    MO_CCRegister,
-    MO_SignExtendedImmed,
-    MO_UnextendedImmed,
-    MO_PCRelativeDisp,
+    MO_Register,                // Register operand.
+    MO_Immediate,               // Immediate Operand
     MO_MachineBasicBlock,       // MachineBasicBlock reference
     MO_FrameIndex,              // Abstract Stack Frame Index
     MO_ConstantPoolIndex,       // Address of indexed Constant in Constant Pool
+    MO_JumpTableIndex,          // Address of indexed Jump Table for switch
     MO_ExternalSymbol,          // Name of external global symbol
     MO_GlobalAddress            // Address of a global value
   };
 
 private:
   union {
-    Value*  value;      // BasicBlockVal for a label operand.
-                        // ConstantVal for a non-address immediate.
-                        // Virtual register for an SSA operand,
-                        //   including hidden operands required for
-                        //   the generated machine code.
-                        // LLVM global for MO_GlobalAddress.
-
-    int64_t immedVal;   // Constant value for an explicit constant
-
-    MachineBasicBlock *MBB;     // For MO_MachineBasicBlock type
-    const char *SymbolName;     // For MO_ExternalSymbol type
+    GlobalValue *GV;          // For MO_GlobalAddress.
+    MachineBasicBlock *MBB;   // For MO_MachineBasicBlock.
+    const char *SymbolName;   // For MO_ExternalSymbol.
+    unsigned RegNo;           // For MO_Register.
+    int64_t immedVal;         // For MO_Immediate and MO_*Index.
   } contents;
 
-  char flags;                   // see bit field definitions above
-  MachineOperandType opType:8;  // Pack into 8 bits efficiently after flags.
-  union {
-    int regNum;                 // register number for an explicit register
-                                // will be set for a value after reg allocation
-
-    int offset;                 // Offset to address of global or external, only
-                                // valid for MO_GlobalAddress, MO_ExternalSym
-                                // and MO_ConstantPoolIndex
-  } extra;
+  MachineOperandType opType:8; // Discriminate the union.
+  bool IsDef : 1;              // True if this is a def, false if this is a use.
+  bool IsImp : 1;              // True if this is an implicit def or use.
 
-  void zeroContents () {
-    memset (&contents, 0, sizeof (contents));
-    memset (&extra, 0, sizeof (extra));
-  }
-
-  MachineOperand(int64_t ImmVal = 0,
-        MachineOperandType OpTy = MO_VirtualRegister, int Offset = 0)
-    : flags(0), opType(OpTy) {
-    zeroContents ();
-    contents.immedVal = ImmVal;
-    if (OpTy == MachineOperand::MO_ConstantPoolIndex)
-      extra.offset = Offset;
-    else
-      extra.regNum = -1;
-  }
-
-  MachineOperand(int Reg, MachineOperandType OpTy, UseType UseTy)
-    : flags(UseTy), opType(OpTy) {
-    zeroContents ();
-    extra.regNum = Reg;
-  }
-
-  MachineOperand(Value *V, MachineOperandType OpTy, UseType UseTy,
-                 bool isPCRelative = false)
-    : flags(UseTy | (isPCRelative?PCRELATIVE:0)), opType(OpTy) {
-    assert(OpTy != MachineOperand::MO_GlobalAddress);
-    zeroContents();
-    contents.value = V;
-    extra.regNum = -1;
-  }
-
-  MachineOperand(GlobalValue *V, MachineOperandType OpTy, UseType UseTy,
-                 bool isPCRelative = false, int Offset = 0)
-    : flags(UseTy | (isPCRelative?PCRELATIVE:0)), opType(OpTy) {
-    assert(OpTy == MachineOperand::MO_GlobalAddress);
-    zeroContents ();
-    contents.value = (Value*)V;
-    extra.offset = Offset;
-  }
-
-  MachineOperand(MachineBasicBlock *mbb)
-    : flags(0), opType(MO_MachineBasicBlock) {
-    zeroContents ();
-    contents.MBB = mbb;
-    extra.regNum = -1;
-  }
+  bool IsKill : 1;             // True if this is a reg use and the reg is dead
+                               // immediately after the read.
+  bool IsDead : 1;             // True if this is a reg def and the reg is dead
+                               // immediately after the write. i.e. A register
+                               // that is defined but never used.
+  
+  /// auxInfo - auxiliary information used by the MachineOperand
+  union {
+    /// offset - Offset to address of global or external, only valid for
+    /// MO_GlobalAddress, MO_ExternalSym and MO_ConstantPoolIndex
+    int offset;
+  } auxInfo;
+  
+  MachineOperand() {}
 
-  MachineOperand(const char *SymName, bool isPCRelative, int Offset)
-    : flags(isPCRelative?PCRELATIVE:0), opType(MO_ExternalSymbol) {
-    zeroContents ();
-    contents.SymbolName = SymName;
-    extra.offset = Offset;
-  }
+  void print(std::ostream &os) const;
+  void print(std::ostream *os) const { if (os) print(*os); }
 
 public:
-  MachineOperand(const MachineOperand &M)
-    : flags(M.flags), opType(M.opType) {
-    zeroContents ();
-    contents = M.contents;
-    extra = M.extra;
+  MachineOperand(const MachineOperand &M) {
+    *this = M;
   }
-
-
+  
   ~MachineOperand() {}
+  
+  static MachineOperand CreateImm(int64_t Val) {
+    MachineOperand Op;
+    Op.opType = MachineOperand::MO_Immediate;
+    Op.contents.immedVal = Val;
+    Op.IsDef = false;
+    Op.IsImp = false;
+    Op.IsKill = false;
+    Op.IsDead = false;
+    Op.auxInfo.offset = 0;
+    return Op;
+  }
+  
+  static MachineOperand CreateFrameIndex(unsigned Idx) {
+    MachineOperand Op;
+    Op.opType = MachineOperand::MO_FrameIndex;
+    Op.contents.immedVal = Idx;
+    Op.IsDef = false;
+    Op.IsImp = false;
+    Op.IsKill = false;
+    Op.IsDead = false;
+    Op.auxInfo.offset = 0;
+    return Op;
+  }
 
   const MachineOperand &operator=(const MachineOperand &MO) {
     contents = MO.contents;
-    flags    = MO.flags;
+    IsDef    = MO.IsDef;
+    IsImp    = MO.IsImp;
+    IsKill   = MO.IsKill;
+    IsDead   = MO.IsDead;
     opType   = MO.opType;
-    extra    = MO.extra;
+    auxInfo  = MO.auxInfo;
     return *this;
   }
 
@@ -212,63 +129,30 @@ public:
   ///
   MachineOperandType getType() const { return opType; }
 
-  /// getUseType - Returns the MachineOperandUseType of this operand.
-  ///
-  UseType getUseType() const { return UseType(flags & (USEFLAG|DEFFLAG)); }
-
-  /// isPCRelative - This returns the value of the PCRELATIVE flag, which
-  /// indicates whether this operand should be emitted as a PC relative value
-  /// instead of a global address.  This is used for operands of the forms:
-  /// MachineBasicBlock, GlobalAddress, ExternalSymbol
-  ///
-  bool isPCRelative() const { return (flags & PCRELATIVE) != 0; }
-
-  /// isRegister - Return true if this operand is a register operand.  The X86
-  /// backend currently can't decide whether to use MO_MR or MO_VR to represent
-  /// them, so we accept both.
-  ///
-  /// Note: The sparc backend should not use this method.
-  ///
-  bool isRegister() const {
-    return opType == MO_MachineRegister || opType == MO_VirtualRegister;
-  }
-
   /// Accessors that tell you what kind of MachineOperand you're looking at.
   ///
+  bool isRegister() const { return opType == MO_Register; }
+  bool isImmediate() const { return opType == MO_Immediate; }
   bool isMachineBasicBlock() const { return opType == MO_MachineBasicBlock; }
-  bool isPCRelativeDisp() const { return opType == MO_PCRelativeDisp; }
-  bool isImmediate() const {
-    return opType == MO_SignExtendedImmed || opType == MO_UnextendedImmed;
-  }
   bool isFrameIndex() const { return opType == MO_FrameIndex; }
   bool isConstantPoolIndex() const { return opType == MO_ConstantPoolIndex; }
+  bool isJumpTableIndex() const { return opType == MO_JumpTableIndex; }
   bool isGlobalAddress() const { return opType == MO_GlobalAddress; }
   bool isExternalSymbol() const { return opType == MO_ExternalSymbol; }
 
-  /// getVRegValueOrNull - Get the Value* out of a MachineOperand if it
-  /// has one. This is deprecated and only used by the SPARC v9 backend.
-  ///
-  Value* getVRegValueOrNull() const {
-    return (opType == MO_VirtualRegister || opType == MO_CCRegister ||
-            isPCRelativeDisp()) ? contents.value : NULL;
-  }
-
-  /// MachineOperand accessors that only work on certain types of
-  /// MachineOperand...
-  ///
-  Value* getVRegValue() const {
-    assert ((opType == MO_VirtualRegister || opType == MO_CCRegister
-             || isPCRelativeDisp()) && "Wrong MachineOperand accessor");
-    return contents.value;
-  }
-  int getMachineRegNum() const {
-    assert(opType == MO_MachineRegister && "Wrong MachineOperand accessor");
-    return extra.regNum;
+  int64_t getImm() const {
+    assert(isImmediate() && "Wrong MachineOperand accessor");
+    return contents.immedVal;
   }
+  
   int64_t getImmedValue() const {
     assert(isImmediate() && "Wrong MachineOperand accessor");
     return contents.immedVal;
   }
+  MachineBasicBlock *getMBB() const {
+    assert(isMachineBasicBlock() && "Wrong MachineOperand accessor");
+    return contents.MBB;
+  }
   MachineBasicBlock *getMachineBasicBlock() const {
     assert(isMachineBasicBlock() && "Wrong MachineOperand accessor");
     return contents.MBB;
@@ -285,93 +169,141 @@ public:
     assert(isConstantPoolIndex() && "Wrong MachineOperand accessor");
     return (unsigned)contents.immedVal;
   }
+  unsigned getJumpTableIndex() const {
+    assert(isJumpTableIndex() && "Wrong MachineOperand accessor");
+    return (unsigned)contents.immedVal;
+  }
   GlobalValue *getGlobal() const {
     assert(isGlobalAddress() && "Wrong MachineOperand accessor");
-    return (GlobalValue*)contents.value;
+    return contents.GV;
   }
   int getOffset() const {
     assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex()) &&
         "Wrong MachineOperand accessor");
-    return extra.offset;
+    return auxInfo.offset;
   }
   const char *getSymbolName() const {
     assert(isExternalSymbol() && "Wrong MachineOperand accessor");
     return contents.SymbolName;
   }
 
-  /// MachineOperand methods for testing that work on any kind of
-  /// MachineOperand...
-  ///
-  bool            isUse           () const { return flags & USEFLAG; }
-  MachineOperand& setUse          ()       { flags |= USEFLAG; return *this; }
-  bool            isDef           () const { return flags & DEFFLAG; }
-  MachineOperand& setDef          ()       { flags |= DEFFLAG; return *this; }
-  bool            isHiBits32      () const { return flags & HIFLAG32; }
-  bool            isLoBits32      () const { return flags & LOFLAG32; }
-  bool            isHiBits64      () const { return flags & HIFLAG64; }
-  bool            isLoBits64      () const { return flags & LOFLAG64; }
-
-  /// hasAllocatedReg - Returns true iff a machine register has been
-  /// allocated to this operand.
-  ///
-  bool hasAllocatedReg() const {
-    return (extra.regNum >= 0 &&
-            (opType == MO_VirtualRegister || opType == MO_CCRegister ||
-             opType == MO_MachineRegister));
+  bool isUse() const { 
+    assert(isRegister() && "Wrong MachineOperand accessor");
+    return !IsDef;
+  }
+  bool isDef() const {
+    assert(isRegister() && "Wrong MachineOperand accessor");
+    return IsDef;
+  }
+  void setIsUse() {
+    assert(isRegister() && "Wrong MachineOperand accessor");
+    IsDef = false;
+  }
+  void setIsDef() {
+    assert(isRegister() && "Wrong MachineOperand accessor");
+    IsDef = true;
   }
 
-  /// getReg - Returns the register number. It is a runtime error to call this
-  /// if a register is not allocated.
+  bool isImplicit() const { 
+    assert(isRegister() && "Wrong MachineOperand accessor");
+    return IsImp;
+  }
+  void setImplicit() { 
+    assert(isRegister() && "Wrong MachineOperand accessor");
+    IsImp = true;
+  }
+
+  bool isKill() const {
+    assert(isRegister() && "Wrong MachineOperand accessor");
+    return IsKill;
+  }
+  bool isDead() const {
+    assert(isRegister() && "Wrong MachineOperand accessor");
+    return IsDead;
+  }
+  void setIsKill() {
+    assert(isRegister() && !IsDef && "Wrong MachineOperand accessor");
+    IsKill = true;
+  }
+  void setIsDead() {
+    assert(isRegister() && IsDef && "Wrong MachineOperand accessor");
+    IsDead = true;
+  }
+  void unsetIsKill() {
+    assert(isRegister() && !IsDef && "Wrong MachineOperand accessor");
+    IsKill = false;
+  }
+  void unsetIsDead() {
+    assert(isRegister() && IsDef && "Wrong MachineOperand accessor");
+    IsDead = false;
+  }
+
+  /// getReg - Returns the register number.
   ///
   unsigned getReg() const {
-    assert(hasAllocatedReg());
-    return extra.regNum;
+    assert(isRegister() && "This is not a register operand!");
+    return contents.RegNo;
   }
 
-  /// MachineOperand mutators...
+  /// MachineOperand mutators.
   ///
   void setReg(unsigned Reg) {
-    // This method's comment used to say: 'TODO: get rid of this duplicate
-    // code.' It's not clear where the duplication is.
-    assert(hasAllocatedReg() && "This operand cannot have a register number!");
-    extra.regNum = Reg;
+    assert(isRegister() && "This is not a register operand!");
+    contents.RegNo = Reg;
   }
 
-  void setValueReg(Value *val) {
-    assert(getVRegValueOrNull() != 0 && "Original operand must of type Value*");
-    contents.value = val;
+  void setImmedValue(int64_t immVal) {
+    assert(isImmediate() && "Wrong MachineOperand mutator");
+    contents.immedVal = immVal;
   }
-
-  void setImmedValue(int immVal) {
+  void setImm(int64_t immVal) {
     assert(isImmediate() && "Wrong MachineOperand mutator");
     contents.immedVal = immVal;
   }
 
   void setOffset(int Offset) {
-    assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex()) &&
+    assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex() ||
+            isJumpTableIndex()) &&
         "Wrong MachineOperand accessor");
-    extra.offset = Offset;
+    auxInfo.offset = Offset;
+  }
+  void setConstantPoolIndex(unsigned Idx) {
+    assert(isConstantPoolIndex() && "Wrong MachineOperand accessor");
+    contents.immedVal = Idx;
+  }
+  void setJumpTableIndex(unsigned Idx) {
+    assert(isJumpTableIndex() && "Wrong MachineOperand accessor");
+    contents.immedVal = Idx;
+  }
+  
+  /// isIdenticalTo - Return true if this operand is identical to the specified
+  /// operand. Note: This method ignores isKill and isDead properties.
+  bool isIdenticalTo(const MachineOperand &Other) const;
+  
+  /// ChangeToImmediate - Replace this operand with a new immediate operand of
+  /// the specified value.  If an operand is known to be an immediate already,
+  /// the setImmedValue method should be used.
+  void ChangeToImmediate(int64_t ImmVal) {
+    opType = MO_Immediate;
+    contents.immedVal = ImmVal;
   }
 
-  friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop);
-
-  /// markHi32, markLo32, etc. - These methods are deprecated and only used by
-  /// the SPARC v9 back-end.
-  ///
-  void markHi32()      { flags |= HIFLAG32; }
-  void markLo32()      { flags |= LOFLAG32; }
-  void markHi64()      { flags |= HIFLAG64; }
-  void markLo64()      { flags |= LOFLAG64; }
+  /// ChangeToRegister - Replace this operand with a new register operand of
+  /// the specified value.  If an operand is known to be an register already,
+  /// the setReg method should be used.
+  void ChangeToRegister(unsigned Reg, bool isDef, bool isImp = false,
+                        bool isKill = false, bool isDead = false) {
+    opType = MO_Register;
+    contents.RegNo = Reg;
+    IsDef = isDef;
+    IsImp = isImp;
+    IsKill = isKill;
+    IsDead = isDead;
+  }
 
-private:
-  /// setRegForValue - Replaces the Value with its corresponding physical
-  /// register after register allocation is complete. This is deprecated
-  /// and only used by the SPARC v9 back-end.
-  ///
-  void setRegForValue(int reg) {
-    assert(opType == MO_VirtualRegister || opType == MO_CCRegister ||
-           opType == MO_MachineRegister);
-    extra.regNum = reg;
+  friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop) {
+    mop.print(os);
+    return os;
   }
 
   friend class MachineInstr;
@@ -379,35 +311,21 @@ private:
 
 
 //===----------------------------------------------------------------------===//
-// class MachineInstr
-//
-// Purpose:
-//   Representation of each machine instruction.
-//
-//   MachineOpCode must be an enum, defined separately for each target.
-//   E.g., It is defined in SparcInstructionSelection.h for the SPARC.
-//
-//  There are 2 kinds of operands:
-//
-//  (1) Explicit operands of the machine instruction in vector operands[]
-//
-//  (2) "Implicit operands" are values implicitly used or defined by the
-//      machine instruction, such as arguments to a CALL, return value of
-//      a CALL (if any), and return value of a RETURN.
-//===----------------------------------------------------------------------===//
-
+/// MachineInstr - Representation of each machine instruction.
+///
 class MachineInstr {
-  short Opcode;                         // the opcode
-  std::vector<MachineOperand> operands; // the operands
+  const TargetInstrDescriptor *TID;     // Instruction descriptor.
+  unsigned short NumImplicitOps;        // Number of implicit operands (which
+                                        // are determined at construction time).
+
+  std::vector<MachineOperand> Operands; // the operands
   MachineInstr* prev, *next;            // links for our intrusive list
   MachineBasicBlock* parent;            // pointer to the owning basic block
 
   // OperandComplete - Return true if it's illegal to add a new operand
   bool OperandsComplete() const;
 
-  //Constructor used by clone() method
   MachineInstr(const MachineInstr&);
-
   void operator=(const MachineInstr&); // DO NOT IMPLEMENT
 
   // Intrusive list support
@@ -415,47 +333,66 @@ class MachineInstr {
   friend struct ilist_traits<MachineInstr>;
 
 public:
-  MachineInstr(short Opcode, unsigned numOperands);
+  /// MachineInstr ctor - This constructor creates a dummy MachineInstr with
+  /// TID NULL and no operands.
+  MachineInstr();
 
-  /// MachineInstr ctor - This constructor only does a _reserve_ of the
-  /// operands, not a resize for them.  It is expected that if you use this that
-  /// you call add* methods below to fill up the operands, instead of the Set
-  /// methods.  Eventually, the "resizing" ctors will be phased out.
-  ///
-  MachineInstr(short Opcode, unsigned numOperands, bool XX, bool YY);
+  /// MachineInstr ctor - This constructor create a MachineInstr and add the
+  /// implicit operands. It reserves space for number of operands specified by
+  /// TargetInstrDescriptor.
+  explicit MachineInstr(const TargetInstrDescriptor &TID);
 
   /// MachineInstr ctor - Work exactly the same as the ctor above, except that
   /// the MachineInstr is created and added to the end of the specified basic
   /// block.
   ///
-  MachineInstr(MachineBasicBlock *MBB, short Opcode, unsigned numOps);
+  MachineInstr(MachineBasicBlock *MBB, const TargetInstrDescriptor &TID);
 
   ~MachineInstr();
 
   const MachineBasicBlock* getParent() const { return parent; }
   MachineBasicBlock* getParent() { return parent; }
+  
+  /// getInstrDescriptor - Returns the target instruction descriptor of this
+  /// MachineInstr.
+  const TargetInstrDescriptor *getInstrDescriptor() const { return TID; }
 
   /// getOpcode - Returns the opcode of this MachineInstr.
   ///
-  const int getOpcode() const { return Opcode; }
+  int getOpcode() const;
 
   /// Access to explicit operands of the instruction.
   ///
-  unsigned getNumOperands() const { return operands.size(); }
+  unsigned getNumOperands() const { return Operands.size(); }
 
   const MachineOperand& getOperand(unsigned i) const {
     assert(i < getNumOperands() && "getOperand() out of range!");
-    return operands[i];
+    return Operands[i];
   }
   MachineOperand& getOperand(unsigned i) {
     assert(i < getNumOperands() && "getOperand() out of range!");
-    return operands[i];
+    return Operands[i];
   }
 
+  /// getNumExplicitOperands - Returns the number of non-implicit operands.
+  ///
+  unsigned getNumExplicitOperands() const;
+  
+  /// isIdenticalTo - Return true if this instruction is identical to (same
+  /// opcode and same operands as) the specified instruction.
+  bool isIdenticalTo(const MachineInstr *Other) const {
+    if (Other->getOpcode() != getOpcode() ||
+        Other->getNumOperands() != getNumOperands())
+      return false;
+    for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
+      if (!getOperand(i).isIdenticalTo(Other->getOperand(i)))
+        return false;
+    return true;
+  }
 
   /// clone - Create a copy of 'this' instruction that is identical in
   /// all ways except the the instruction has no parent, prev, or next.
-  MachineInstr* clone() const;
+  MachineInstr* clone() const { return new MachineInstr(*this); }
   
   /// removeFromParent - This method unlinks 'this' from the containing basic
   /// block, and returns it, but does not delete it.
@@ -467,191 +404,155 @@ public:
     delete removeFromParent();
   }
 
+  /// findRegisterUseOperandIdx() - Returns the operand index that is a use of
+  /// the specific register or -1 if it is not found. It further tightening
+  /// the search criteria to a use that kills the register if isKill is true.
+  int findRegisterUseOperandIdx(unsigned Reg, bool isKill = false) const;
+  
+  /// findRegisterDefOperand() - Returns the MachineOperand that is a def of
+  /// the specific register or NULL if it is not found.
+  MachineOperand *findRegisterDefOperand(unsigned Reg);
+
+  /// findFirstPredOperandIdx() - Find the index of the first operand in the
+  /// operand list that is used to represent the predicate. It returns -1 if
+  /// none is found.
+  int findFirstPredOperandIdx() const;
+  
+  /// isRegReDefinedByTwoAddr - Returns true if the Reg re-definition is due
+  /// to two addr elimination.
+  bool isRegReDefinedByTwoAddr(unsigned Reg) const;
+
+  /// copyKillDeadInfo - Copies kill / dead operand properties from MI.
+  ///
+  void copyKillDeadInfo(const MachineInstr *MI);
+
+  /// copyPredicates - Copies predicate operand(s) from MI.
+  void copyPredicates(const MachineInstr *MI);
+
   //
   // Debugging support
   //
+  void print(std::ostream *OS, const TargetMachine *TM) const {
+    if (OS) print(*OS, TM);
+  }
   void print(std::ostream &OS, const TargetMachine *TM) const;
+  void print(std::ostream &OS) const;
+  void print(std::ostream *OS) const { if (OS) print(*OS); }
   void dump() const;
-  friend std::ostream& operator<<(std::ostream& os, const MachineInstr& minstr);
+  friend std::ostream& operator<<(std::ostream& os, const MachineInstr& minstr){
+    minstr.print(os);
+    return os;
+  }
 
   //===--------------------------------------------------------------------===//
-  // Accessors to add operands when building up machine instructions
+  // Accessors to add operands when building up machine instructions.
   //
 
-  /// addRegOperand - Add a MO_VirtualRegister operand to the end of the
-  /// operands list...
-  ///
-  void addRegOperand(Value *V, bool isDef, bool isDefAndUse=false) {
-    assert(!OperandsComplete() &&
-           "Trying to add an operand to a machine instr that is already done!");
-    operands.push_back(
-      MachineOperand(V, MachineOperand::MO_VirtualRegister,
-                     !isDef ? MachineOperand::Use :
-                     (isDefAndUse ? MachineOperand::UseAndDef :
-                      MachineOperand::Def)));
-  }
-
-  void addRegOperand(Value *V,
-                     MachineOperand::UseType UTy = MachineOperand::Use,
-                     bool isPCRelative = false) {
-    assert(!OperandsComplete() &&
-           "Trying to add an operand to a machine instr that is already done!");
-    operands.push_back(MachineOperand(V, MachineOperand::MO_VirtualRegister,
-                                      UTy, isPCRelative));
-  }
-
-  void addCCRegOperand(Value *V,
-                       MachineOperand::UseType UTy = MachineOperand::Use) {
-    assert(!OperandsComplete() &&
-           "Trying to add an operand to a machine instr that is already done!");
-    operands.push_back(MachineOperand(V, MachineOperand::MO_CCRegister, UTy,
-                                      false));
-  }
-
-
-  /// addRegOperand - Add a symbolic virtual register reference...
-  ///
-  void addRegOperand(int reg, bool isDef) {
-    assert(!OperandsComplete() &&
-           "Trying to add an operand to a machine instr that is already done!");
-    operands.push_back(
-      MachineOperand(reg, MachineOperand::MO_VirtualRegister,
-                     isDef ? MachineOperand::Def : MachineOperand::Use));
-  }
-
-  /// addRegOperand - Add a symbolic virtual register reference...
-  ///
-  void addRegOperand(int reg,
-                     MachineOperand::UseType UTy = MachineOperand::Use) {
-    assert(!OperandsComplete() &&
-           "Trying to add an operand to a machine instr that is already done!");
-    operands.push_back(
-      MachineOperand(reg, MachineOperand::MO_VirtualRegister, UTy));
-  }
-
-  /// addPCDispOperand - Add a PC relative displacement operand to the MI
-  ///
-  void addPCDispOperand(Value *V) {
-    assert(!OperandsComplete() &&
-           "Trying to add an operand to a machine instr that is already done!");
-    operands.push_back(
-      MachineOperand(V, MachineOperand::MO_PCRelativeDisp,MachineOperand::Use));
-  }
-
-  /// addMachineRegOperand - Add a virtual register operand to this MachineInstr
+  /// addRegOperand - Add a register operand.
   ///
-  void addMachineRegOperand(int reg, bool isDef) {
-    assert(!OperandsComplete() &&
-           "Trying to add an operand to a machine instr that is already done!");
-    operands.push_back(
-      MachineOperand(reg, MachineOperand::MO_MachineRegister,
-                     isDef ? MachineOperand::Def : MachineOperand::Use));
+  void addRegOperand(unsigned Reg, bool IsDef, bool IsImp = false,
+                     bool IsKill = false, bool IsDead = false) {
+    MachineOperand &Op = AddNewOperand(IsImp);
+    Op.opType = MachineOperand::MO_Register;
+    Op.IsDef = IsDef;
+    Op.IsImp = IsImp;
+    Op.IsKill = IsKill;
+    Op.IsDead = IsDead;
+    Op.contents.RegNo = Reg;
   }
 
-  /// addMachineRegOperand - Add a virtual register operand to this MachineInstr
-  ///
-  void addMachineRegOperand(int reg,
-                            MachineOperand::UseType UTy = MachineOperand::Use) {
-    assert(!OperandsComplete() &&
-           "Trying to add an operand to a machine instr that is already done!");
-    operands.push_back(
-      MachineOperand(reg, MachineOperand::MO_MachineRegister, UTy));
-  }
-
-  /// addZeroExtImmOperand - Add a zero extended constant argument to the
+  /// addImmOperand - Add a zero extended constant argument to the
   /// machine instruction.
   ///
-  void addZeroExtImmOperand(int intValue) {
-    assert(!OperandsComplete() &&
-           "Trying to add an operand to a machine instr that is already done!");
-    operands.push_back(
-      MachineOperand(intValue, MachineOperand::MO_UnextendedImmed));
-  }
-
-  /// addZeroExtImm64Operand - Add a zero extended 64-bit constant argument
-  /// to the machine instruction.
-  ///
-  void addZeroExtImm64Operand(uint64_t intValue) {
-    assert(!OperandsComplete() &&
-           "Trying to add an operand to a machine instr that is already done!");
-    operands.push_back(
-      MachineOperand(intValue, MachineOperand::MO_UnextendedImmed));
-  }
-
-  /// addSignExtImmOperand - Add a zero extended constant argument to the
-  /// machine instruction.
-  ///
-  void addSignExtImmOperand(int intValue) {
-    assert(!OperandsComplete() &&
-           "Trying to add an operand to a machine instr that is already done!");
-    operands.push_back(
-      MachineOperand(intValue, MachineOperand::MO_SignExtendedImmed));
+  void addImmOperand(int64_t Val) {
+    MachineOperand &Op = AddNewOperand();
+    Op.opType = MachineOperand::MO_Immediate;
+    Op.contents.immedVal = Val;
+    Op.auxInfo.offset = 0;
   }
 
   void addMachineBasicBlockOperand(MachineBasicBlock *MBB) {
-    assert(!OperandsComplete() &&
-           "Trying to add an operand to a machine instr that is already done!");
-    operands.push_back(MachineOperand(MBB));
+    MachineOperand &Op = AddNewOperand();
+    Op.opType = MachineOperand::MO_MachineBasicBlock;
+    Op.contents.MBB = MBB;
+    Op.auxInfo.offset = 0;
   }
 
   /// addFrameIndexOperand - Add an abstract frame index to the instruction
   ///
   void addFrameIndexOperand(unsigned Idx) {
-    assert(!OperandsComplete() &&
-           "Trying to add an operand to a machine instr that is already done!");
-    operands.push_back(MachineOperand(Idx, MachineOperand::MO_FrameIndex));
+    MachineOperand &Op = AddNewOperand();
+    Op.opType = MachineOperand::MO_FrameIndex;
+    Op.contents.immedVal = Idx;
+    Op.auxInfo.offset = 0;
   }
 
   /// addConstantPoolndexOperand - Add a constant pool object index to the
   /// instruction.
   ///
-  void addConstantPoolIndexOperand(unsigned I, int Offset=0) {
-    assert(!OperandsComplete() &&
-           "Trying to add an operand to a machine instr that is already done!");
-    operands.push_back(MachineOperand(I, MachineOperand::MO_ConstantPoolIndex));
+  void addConstantPoolIndexOperand(unsigned Idx, int Offset) {
+    MachineOperand &Op = AddNewOperand();
+    Op.opType = MachineOperand::MO_ConstantPoolIndex;
+    Op.contents.immedVal = Idx;
+    Op.auxInfo.offset = Offset;
   }
 
-  void addGlobalAddressOperand(GlobalValue *GV, bool isPCRelative, int Offset) {
-    assert(!OperandsComplete() &&
-           "Trying to add an operand to a machine instr that is already done!");
-    operands.push_back(
-      MachineOperand(GV, MachineOperand::MO_GlobalAddress,
-                     MachineOperand::Use, isPCRelative, Offset));
+  /// addJumpTableIndexOperand - Add a jump table object index to the
+  /// instruction.
+  ///
+  void addJumpTableIndexOperand(unsigned Idx) {
+    MachineOperand &Op = AddNewOperand();
+    Op.opType = MachineOperand::MO_JumpTableIndex;
+    Op.contents.immedVal = Idx;
+    Op.auxInfo.offset = 0;
+  }
+  
+  void addGlobalAddressOperand(GlobalValue *GV, int Offset) {
+    MachineOperand &Op = AddNewOperand();
+    Op.opType = MachineOperand::MO_GlobalAddress;
+    Op.contents.GV = GV;
+    Op.auxInfo.offset = Offset;
   }
 
   /// addExternalSymbolOperand - Add an external symbol operand to this instr
   ///
-  void addExternalSymbolOperand(const char *SymName, bool isPCRelative) {
-    operands.push_back(MachineOperand(SymName, isPCRelative, 0));
+  void addExternalSymbolOperand(const char *SymName) {
+    MachineOperand &Op = AddNewOperand();
+    Op.opType = MachineOperand::MO_ExternalSymbol;
+    Op.contents.SymbolName = SymName;
+    Op.auxInfo.offset = 0;
   }
 
   //===--------------------------------------------------------------------===//
   // Accessors used to modify instructions in place.
   //
-  // FIXME: Move this stuff to MachineOperand itself!
 
-  /// setOpcode - Replace the opcode of the current instruction with a new one.
+  /// setInstrDescriptor - Replace the instruction descriptor (thus opcode) of
+  /// the current instruction with a new one.
   ///
-  void setOpcode(unsigned Op) { Opcode = Op; }
+  void setInstrDescriptor(const TargetInstrDescriptor &tid) { TID = &tid; }
 
   /// RemoveOperand - Erase an operand  from an instruction, leaving it with one
   /// fewer operand than it started with.
   ///
   void RemoveOperand(unsigned i) {
-    operands.erase(operands.begin()+i);
+    Operands.erase(Operands.begin()+i);
+  }
+private:
+  MachineOperand &AddNewOperand(bool IsImp = false) {
+    assert((IsImp || !OperandsComplete()) &&
+           "Trying to add an operand to a machine instr that is already done!");
+    if (IsImp || NumImplicitOps == 0) { // This is true most of the time.
+      Operands.push_back(MachineOperand());
+      return Operands.back();
+    }
+    return *Operands.insert(Operands.begin()+Operands.size()-NumImplicitOps,
+                            MachineOperand());
   }
 
-  // Access to set the operands when building the machine instruction
-  //
-  void SetMachineOperandVal(unsigned i,
-                            MachineOperand::MachineOperandType operandType,
-                            Value* V);
-
-  void SetMachineOperandConst(unsigned i,
-                              MachineOperand::MachineOperandType operandType,
-                              int intValue);
-
-  void SetMachineOperandReg(unsigned i, int regNum);
+  /// addImplicitDefUseOperands - Add all implicit def and use operands to
+  /// this instruction.
+  void addImplicitDefUseOperands();
 };
 
 //===----------------------------------------------------------------------===//