EXTRACT_SUBREG coalescing support. The coalescer now treats EXTRACT_SUBREG like
[oota-llvm.git] / include / llvm / CodeGen / MachineInstr.h
index 907985877f035f633c791cc436d1be3af539e81b..beba6923ee7832749f0569aeccb875b61cfb7dd3 100644 (file)
@@ -18,6 +18,7 @@
 
 #include "llvm/ADT/iterator"
 #include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Streams.h"
 #include <vector>
 #include <cassert>
 #include <iosfwd>
@@ -27,7 +28,6 @@ namespace llvm {
 class Value;
 class Function;
 class MachineBasicBlock;
-class TargetInstrInfo;
 class TargetInstrDescriptor;
 class TargetMachine;
 class GlobalValue;
@@ -71,11 +71,18 @@ private:
                                // immediately after the write. i.e. A register
                                // that is defined but never used.
   
-  /// offset - Offset to address of global or external, only valid for
-  /// MO_GlobalAddress, MO_ExternalSym and MO_ConstantPoolIndex
-  int offset;
-
+  /// 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() {}
+
+  void print(std::ostream &os) const;
+  void print(std::ostream *os) const { if (os) print(*os); }
+
 public:
   MachineOperand(const MachineOperand &M) {
     *this = M;
@@ -91,10 +98,22 @@ public:
     Op.IsImp = false;
     Op.IsKill = false;
     Op.IsDead = false;
-    Op.offset = 0;
+    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;
     IsDef    = MO.IsDef;
@@ -102,7 +121,7 @@ public:
     IsKill   = MO.IsKill;
     IsDead   = MO.IsDead;
     opType   = MO.opType;
-    offset   = MO.offset;
+    auxInfo  = MO.auxInfo;
     return *this;
   }
 
@@ -112,10 +131,6 @@ public:
 
   /// Accessors that tell you what kind of MachineOperand you're looking at.
   ///
-  bool isReg() const { return opType == MO_Register; }
-  bool isImm() const { return opType == MO_Immediate; }
-  bool isMBB() const { return opType == MO_MachineBasicBlock; }
-  
   bool isRegister() const { return opType == MO_Register; }
   bool isImmediate() const { return opType == MO_Immediate; }
   bool isMachineBasicBlock() const { return opType == MO_MachineBasicBlock; }
@@ -126,12 +141,12 @@ public:
   bool isExternalSymbol() const { return opType == MO_ExternalSymbol; }
 
   int64_t getImm() const {
-    assert(isImm() && "Wrong MachineOperand accessor");
+    assert(isImmediate() && "Wrong MachineOperand accessor");
     return contents.immedVal;
   }
   
   int64_t getImmedValue() const {
-    assert(isImm() && "Wrong MachineOperand accessor");
+    assert(isImmediate() && "Wrong MachineOperand accessor");
     return contents.immedVal;
   }
   MachineBasicBlock *getMBB() const {
@@ -165,7 +180,7 @@ public:
   int getOffset() const {
     assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex()) &&
         "Wrong MachineOperand accessor");
-    return offset;
+    return auxInfo.offset;
   }
   const char *getSymbolName() const {
     assert(isExternalSymbol() && "Wrong MachineOperand accessor");
@@ -238,11 +253,11 @@ public:
   }
 
   void setImmedValue(int64_t immVal) {
-    assert(isImm() && "Wrong MachineOperand mutator");
+    assert(isImmediate() && "Wrong MachineOperand mutator");
     contents.immedVal = immVal;
   }
   void setImm(int64_t immVal) {
-    assert(isImm() && "Wrong MachineOperand mutator");
+    assert(isImmediate() && "Wrong MachineOperand mutator");
     contents.immedVal = immVal;
   }
 
@@ -250,7 +265,7 @@ public:
     assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex() ||
             isJumpTableIndex()) &&
         "Wrong MachineOperand accessor");
-    offset = Offset;
+    auxInfo.offset = Offset;
   }
   void setConstantPoolIndex(unsigned Idx) {
     assert(isConstantPoolIndex() && "Wrong MachineOperand accessor");
@@ -276,16 +291,20 @@ public:
   /// 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) {
+  void ChangeToRegister(unsigned Reg, bool isDef, bool isImp = false,
+                        bool isKill = false, bool isDead = false) {
     opType = MO_Register;
     contents.RegNo = Reg;
     IsDef = isDef;
-    IsImp = false;
-    IsKill = false;
-    IsDead = false;
+    IsImp = isImp;
+    IsKill = isKill;
+    IsDead = isDead;
   }
 
-  friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop);
+  friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop) {
+    mop.print(os);
+    return os;
+  }
 
   friend class MachineInstr;
 };
@@ -295,8 +314,8 @@ public:
 /// MachineInstr - Representation of each machine instruction.
 ///
 class MachineInstr {
-  short Opcode;                         // the opcode
-  short NumImplicitOps;                 // Number of implicit operands (which
+  const TargetInstrDescriptor *TID;     // Instruction descriptor.
+  unsigned short NumImplicitOps;        // Number of implicit operands (which
                                         // are determined at construction time).
 
   std::vector<MachineOperand> Operands; // the operands
@@ -314,28 +333,33 @@ class MachineInstr {
   friend struct ilist_traits<MachineInstr>;
 
 public:
-  /// MachineInstr ctor - This constructor reserves space for numOperand
-  /// operands.
-  MachineInstr(short Opcode, unsigned numOperands);
+  /// MachineInstr ctor - This constructor creates a dummy MachineInstr with
+  /// TID NULL and no operands.
+  MachineInstr();
 
   /// MachineInstr ctor - This constructor create a MachineInstr and add the
-  /// implicit operands. It reserves space for numOperand operands.
-  MachineInstr(const TargetInstrInfo &TII, short Opcode, unsigned numOperands);
+  /// 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.
   ///
@@ -350,6 +374,9 @@ public:
     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.
@@ -377,32 +404,45 @@ 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) {
-    for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
-      const MachineOperand &MO = MI->getOperand(i);
-      if (MO.isReg() && (MO.isKill() || MO.isDead())) {
-        for (unsigned j = 0, ee = getNumOperands(); j != ee; ++j) {
-          MachineOperand &MOp = getOperand(j);
-          if (MOp.isIdenticalTo(MO)) {
-            if (MO.isKill())
-              MOp.setIsKill();
-            else
-              MOp.setIsDead();
-            break;
-          }
-        }
-      }
-    }
-  }
+  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.
@@ -419,7 +459,6 @@ public:
     Op.IsKill = IsKill;
     Op.IsDead = IsDead;
     Op.contents.RegNo = Reg;
-    Op.offset = 0;
   }
 
   /// addImmOperand - Add a zero extended constant argument to the
@@ -429,14 +468,14 @@ public:
     MachineOperand &Op = AddNewOperand();
     Op.opType = MachineOperand::MO_Immediate;
     Op.contents.immedVal = Val;
-    Op.offset = 0;
+    Op.auxInfo.offset = 0;
   }
 
   void addMachineBasicBlockOperand(MachineBasicBlock *MBB) {
     MachineOperand &Op = AddNewOperand();
     Op.opType = MachineOperand::MO_MachineBasicBlock;
     Op.contents.MBB = MBB;
-    Op.offset = 0;
+    Op.auxInfo.offset = 0;
   }
 
   /// addFrameIndexOperand - Add an abstract frame index to the instruction
@@ -445,7 +484,7 @@ public:
     MachineOperand &Op = AddNewOperand();
     Op.opType = MachineOperand::MO_FrameIndex;
     Op.contents.immedVal = Idx;
-    Op.offset = 0;
+    Op.auxInfo.offset = 0;
   }
 
   /// addConstantPoolndexOperand - Add a constant pool object index to the
@@ -455,7 +494,7 @@ public:
     MachineOperand &Op = AddNewOperand();
     Op.opType = MachineOperand::MO_ConstantPoolIndex;
     Op.contents.immedVal = Idx;
-    Op.offset = Offset;
+    Op.auxInfo.offset = Offset;
   }
 
   /// addJumpTableIndexOperand - Add a jump table object index to the
@@ -465,14 +504,14 @@ public:
     MachineOperand &Op = AddNewOperand();
     Op.opType = MachineOperand::MO_JumpTableIndex;
     Op.contents.immedVal = Idx;
-    Op.offset = 0;
+    Op.auxInfo.offset = 0;
   }
   
   void addGlobalAddressOperand(GlobalValue *GV, int Offset) {
     MachineOperand &Op = AddNewOperand();
     Op.opType = MachineOperand::MO_GlobalAddress;
     Op.contents.GV = GV;
-    Op.offset = Offset;
+    Op.auxInfo.offset = Offset;
   }
 
   /// addExternalSymbolOperand - Add an external symbol operand to this instr
@@ -481,16 +520,17 @@ public:
     MachineOperand &Op = AddNewOperand();
     Op.opType = MachineOperand::MO_ExternalSymbol;
     Op.contents.SymbolName = SymName;
-    Op.offset = 0;
+    Op.auxInfo.offset = 0;
   }
 
   //===--------------------------------------------------------------------===//
   // Accessors used to modify instructions in place.
   //
 
-  /// 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);
+  void setInstrDescriptor(const TargetInstrDescriptor &tid) { TID = &tid; }
 
   /// RemoveOperand - Erase an operand  from an instruction, leaving it with one
   /// fewer operand than it started with.
@@ -502,18 +542,17 @@ private:
   MachineOperand &AddNewOperand(bool IsImp = false) {
     assert((IsImp || !OperandsComplete()) &&
            "Trying to add an operand to a machine instr that is already done!");
-    if (NumImplicitOps == 0) { // This is true most of the time.
+    if (IsImp || NumImplicitOps == 0) { // This is true most of the time.
       Operands.push_back(MachineOperand());
       return Operands.back();
-    } else {
-      return *Operands.insert(Operands.begin()+Operands.size()-NumImplicitOps,
-                              MachineOperand());
     }
+    return *Operands.insert(Operands.begin()+Operands.size()-NumImplicitOps,
+                            MachineOperand());
   }
 
   /// addImplicitDefUseOperands - Add all implicit def and use operands to
   /// this instruction.
-  void addImplicitDefUseOperands(const TargetInstrDescriptor &TID);
+  void addImplicitDefUseOperands();
 };
 
 //===----------------------------------------------------------------------===//