When folding memory operands in machine instructions be careful to
[oota-llvm.git] / include / llvm / CodeGen / MachineInstr.h
index 721b513c747d0d5b4bd6d0186ae9e7ca459a569e..65d5ccae70a7f37c4d40c92daa26f00c83a15357 100644 (file)
@@ -1,7 +1,14 @@
-//===-- llvm/CodeGen/MachineInstr.h - MachineInstr class ---------*- C++ -*--=//
+//===-- llvm/CodeGen/MachineInstr.h - MachineInstr class --------*- C++ -*-===//
+// 
+//                     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 contains the declaration of the MachineInstr class, which is the
-// basic representation for all target dependant machine instructions used by
+// basic representation for all target dependent machine instructions used by
 // the back end.
 //
 //===----------------------------------------------------------------------===//
 #ifndef LLVM_CODEGEN_MACHINEINSTR_H
 #define LLVM_CODEGEN_MACHINEINSTR_H
 
-#include "llvm/Target/MRegisterInfo.h"
 #include "Support/Annotation.h"
 #include "Support/iterator"
-#include <set>
+#include <vector>
+
+namespace llvm {
 
 class Value;
 class Function;
@@ -20,18 +28,10 @@ class MachineBasicBlock;
 class TargetMachine;
 class GlobalValue;
 
-typedef int MachineOpCode;
+template <typename T> class ilist_traits;
+template <typename T> class ilist;
 
-//===----------------------------------------------------------------------===//
-/// Special flags on instructions that modify the opcode.
-/// These flags are unused for now, but having them enforces that some
-/// changes will be needed if they are used.
-///
-enum MachineOpCodeFlags {
-  AnnulFlag,         /// 1 if annul bit is set on a branch
-  PredTakenFlag,     /// 1 if branch should be predicted taken
-  PredNotTakenFlag   /// 1 if branch should be predicted not taken
-};
+typedef short MachineOpCode;
 
 //===----------------------------------------------------------------------===//
 /// MOTy - MachineOperandType - This namespace contains an enum that describes
@@ -101,15 +101,13 @@ struct MachineOperand {
 private:
   // Bit fields of the flags variable used for different operand properties
   enum {
-    DEFONLYFLAG = 0x01,       // this is a def but not a use of the operand
-    DEFUSEFLAG  = 0x02,       // this is both a def and a use
+    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
-  
-    USEDEFMASK = 0x03,
   };
 
 private:
@@ -132,13 +130,7 @@ private:
   int regNum;                  // register number for an explicit register
                                 // will be set for a value after reg allocation
 private:
-  MachineOperand()
-    : immedVal(0),
-      flags(0),
-      opType(MO_VirtualRegister),
-      regNum(-1) {}
-
-  MachineOperand(int64_t ImmVal, MachineOperandType OpTy)
+  MachineOperand(int64_t ImmVal = 0, MachineOperandType OpTy = MO_VirtualRegister)
     : immedVal(ImmVal),
       flags(0),
       opType(OpTy),
@@ -149,9 +141,9 @@ private:
       opType(OpTy),
       regNum(Reg) {
     switch (UseTy) {
-    case MOTy::Use:       flags = 0; break;
-    case MOTy::Def:       flags = DEFONLYFLAG; break;
-    case MOTy::UseAndDef: flags = DEFUSEFLAG; break;
+    case MOTy::Use:       flags = USEFLAG; break;
+    case MOTy::Def:       flags = DEFFLAG; break;
+    case MOTy::UseAndDef: flags = DEFFLAG | USEFLAG; break;
     default: assert(0 && "Invalid value for UseTy!");
     }
   }
@@ -160,9 +152,9 @@ private:
                 bool isPCRelative = false)
     : value(V), opType(OpTy), regNum(-1) {
     switch (UseTy) {
-    case MOTy::Use:       flags = 0; break;
-    case MOTy::Def:       flags = DEFONLYFLAG; break;
-    case MOTy::UseAndDef: flags = DEFUSEFLAG; break;
+    case MOTy::Use:       flags = USEFLAG; break;
+    case MOTy::Def:       flags = DEFFLAG; break;
+    case MOTy::UseAndDef: flags = DEFFLAG | USEFLAG; break;
     default: assert(0 && "Invalid value for UseTy!");
     }
     if (isPCRelative) flags |= PCRELATIVE;
@@ -190,6 +182,8 @@ public:
   }
   
   const MachineOperand &operator=(const MachineOperand &MO) {
+    if (isExternalSymbol())             // if old operand had a symbol name,
+      delete SymbolName;                // release old memory
     immedVal = MO.immedVal;
     flags    = MO.flags;
     opType   = MO.opType;
@@ -199,11 +193,17 @@ public:
     return *this;
   }
 
-  // Accessor methods.  Caller is responsible for checking the
-  // operand type before invoking the corresponding accessor.
-  // 
+  /// getType - Returns the MachineOperandType for this operand.
+  /// 
   MachineOperandType getType() const { return opType; }
 
+  /// getUseType - Returns the MachineOperandUseType of this operand.
+  ///
+  MOTy::UseType getUseType() const {
+      return isUse() ^ isDef() ? MOTy::UseAndDef :
+          (isUse() ? MOTy::Use : MOTy::Def);
+  }
+
   /// 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:
@@ -211,22 +211,16 @@ public:
   ///
   bool isPCRelative() const { return (flags & PCRELATIVE) != 0; }
 
-
-  // This is to finally stop caring whether we have a virtual or machine
-  // register -- an easier interface is to simply call both virtual and machine
-  // registers essentially the same, yet be able to distinguish when
-  // necessary. Thus the instruction selector can just add registers without
-  // abandon, and the register allocator won't be confused.
-  bool isVirtualRegister() const {
-    return (opType == MO_VirtualRegister || opType == MO_MachineRegister) 
-      && regNum >= MRegisterInfo::FirstVirtualRegister;
-  }
-  bool isPhysicalRegister() const {
-    return (opType == MO_VirtualRegister || opType == MO_MachineRegister) 
-      && (unsigned)regNum < MRegisterInfo::FirstVirtualRegister;
+  /// 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;
   }
-  bool isRegister() const { return isVirtualRegister() || isPhysicalRegister();}
-  bool isMachineRegister() const { return !isVirtualRegister(); }
+
   bool isMachineBasicBlock() const { return opType == MO_MachineBasicBlock; }
   bool isPCRelativeDisp() const { return opType == MO_PCRelativeDisp; }
   bool isImmediate() const {
@@ -251,6 +245,8 @@ public:
     return regNum;
   }
   int64_t getImmedValue() const { assert(isImmediate()); return immedVal; }
+  void setImmedValue(int64_t ImmVal) { assert(isImmediate()); immedVal=ImmVal; }
+
   MachineBasicBlock *getMachineBasicBlock() const {
     assert(isMachineBasicBlock() && "Can't get MBB in non-MBB operand!");
     return MBB;
@@ -271,13 +267,14 @@ public:
     return *SymbolName;
   }
 
-  bool          opIsUse         () const { return (flags & USEDEFMASK) == 0; }
-  bool         opIsDefOnly     () const { return flags & DEFONLYFLAG; }
-  bool         opIsDefAndUse   () const { return flags & DEFUSEFLAG; }
-  bool          opHiBits32      () const { return flags & HIFLAG32; }
-  bool          opLoBits32      () const { return flags & LOFLAG32; }
-  bool          opHiBits64      () const { return flags & HIFLAG64; }
-  bool          opLoBits64      () const { return flags & LOFLAG64; }
+  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; }
 
   // used to check if a machine register has been allocated to this operand
   bool hasAllocatedReg() const {
@@ -287,14 +284,15 @@ public:
   }
 
   // used to get the reg number if when one is allocated
-  int getAllocatedRegNum() const {
+  unsigned getReg() const {
     assert(hasAllocatedReg());
     return regNum;
   }
 
   // ********** TODO: get rid of this duplicate code! ***********
-  unsigned getReg() const {
-    return getAllocatedRegNum();
+  void setReg(unsigned Reg) {
+    assert(hasAllocatedReg() && "This operand cannot have a register number!");
+    regNum = Reg;
   }    
 
   friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop);
@@ -339,49 +337,49 @@ private:
 //===----------------------------------------------------------------------===//
 
 class MachineInstr {
-  int              opCode;              // the opcode
-  unsigned         opCodeFlags;         // flags modifying instrn behavior
+  short            Opcode;              // the opcode
+  unsigned char numImplicitRefs;        // number of implicit operands
   std::vector<MachineOperand> operands; // the operands
-  unsigned numImplicitRefs;             // number of implicit operands
-
-  // regsUsed - all machine registers used for this instruction, including regs
-  // used to save values across the instruction.  This is a bitset of registers.
-  std::set<int>    regsUsed;
-
+  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;
 
   MachineInstr(const MachineInstr &);  // DO NOT IMPLEMENT
   void operator=(const MachineInstr&); // DO NOT IMPLEMENT
+
+private:
+  // Intrusive list support
+  //
+  friend class ilist_traits<MachineInstr>;
+
 public:
-  MachineInstr(int Opcode, unsigned numOperands);
+  MachineInstr(short Opcode, unsigned numOperands);
 
   /// 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(int Opcode, unsigned numOperands, bool XX, bool YY);
+  MachineInstr(short Opcode, unsigned numOperands, bool XX, bool YY);
 
   /// 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, int Opcode, unsigned numOps);
+  MachineInstr(MachineBasicBlock *MBB, short Opcode, unsigned numOps);
   
+  ~MachineInstr();
 
-  // The opcode.
-  // 
-  const int getOpcode() const { return opCode; }
-  const int getOpCode() const { return opCode; }
+  const MachineBasicBlock* getParent() const { return parent; }
+  MachineBasicBlock* getParent() { return parent; }
 
-  // Opcode flags.
-  // 
-  unsigned       getOpCodeFlags() const { return opCodeFlags; }
+  /// Accessors for opcode.
+  ///
+  const int getOpcode() const { return Opcode; }
 
-  //
-  // Access to explicit operands of the instruction
-  // 
+  /// Access to explicit operands of the instruction.
+  ///
   unsigned getNumOperands() const { return operands.size() - numImplicitRefs; }
   
   const MachineOperand& getOperand(unsigned i) const {
@@ -430,27 +428,10 @@ public:
     ++numImplicitRefs;
     addRegOperand(V, isDef, isDefAndUse);
   }
-  void setImplicitRef(unsigned i, Value* V, bool isDef=false,
-                      bool isDefAndUse=false) {
+  void setImplicitRef(unsigned i, Value* V) {
     assert(i < getNumImplicitRefs() && "setImplicitRef() out of range!");
     SetMachineOperandVal(i + getNumOperands(),
-                         MachineOperand::MO_VirtualRegister,
-                         V, isDef, isDefAndUse);
-  }
-
-  //
-  // Information about registers used in this instruction.
-  // 
-  const std::set<int> &getRegsUsed() const {
-    return regsUsed;
-  }
-  bool isRegUsed(int regNum) const {
-    return regsUsed.find(regNum) != regsUsed.end();
-  }
-  
-  // insertusedreg - Add a register to the Used registers set...
-  void insertUsedReg(unsigned Reg) {
-    regsUsed.insert((int) Reg);
+                         MachineOperand::MO_VirtualRegister, V);
   }
 
   //
@@ -534,7 +515,6 @@ public:
            "Trying to add an operand to a machine instr that is already done!");
     operands.push_back(MachineOperand(reg, MachineOperand::MO_MachineRegister,
                                       isDef ? MOTy::Def : MOTy::Use));
-    insertUsedReg(reg);
   }
 
   /// addMachineRegOperand - Add a virtual register operand to this MachineInstr
@@ -544,7 +524,6 @@ public:
            "Trying to add an operand to a machine instr that is already done!");
     operands.push_back(MachineOperand(reg, MachineOperand::MO_MachineRegister,
                                       UTy));
-    insertUsedReg(reg);
   }
 
   /// addZeroExtImmOperand - Add a zero extended constant argument to the
@@ -613,11 +592,11 @@ public:
   /// simply replace() and then set new operands with Set.*Operand methods
   /// below.
   /// 
-  void replace(int Opcode, unsigned numOperands);
+  void replace(short Opcode, unsigned numOperands);
 
   /// setOpcode - Replace the opcode of the current instruction with a new one.
   ///
-  void setOpcode(unsigned Op) { opCode = Op; }
+  void setOpcode(unsigned Op) { Opcode = Op; }
 
   /// RemoveOperand - Erase an operand  from an instruction, leaving it with one
   /// fewer operand than it started with.
@@ -630,21 +609,18 @@ public:
   // 
   void SetMachineOperandVal     (unsigned i,
                                  MachineOperand::MachineOperandType operandType,
-                                 Value* V,
-                                 bool isDef=false,
-                                 bool isDefAndUse=false);
+                                 Value* V);
 
   void SetMachineOperandConst   (unsigned i,
                                  MachineOperand::MachineOperandType operandType,
                                  int64_t intValue);
 
-  void SetMachineOperandReg     (unsigned i,
-                                 int regNum,
-                                 bool isDef=false);
+  void SetMachineOperandReg(unsigned i, int regNum);
 
 
   unsigned substituteValue(const Value* oldVal, Value* newVal,
-                           bool defsOnly = true);
+                           bool defsOnly, bool notDefsAndUses,
+                           bool& someArgsWereIgnored);
 
   void setOperandHi32(unsigned i) { operands[i].markHi32(); }
   void setOperandLo32(unsigned i) { operands[i].markLo32(); }
@@ -691,9 +667,8 @@ public:
 
     inline VTy operator->() const { return operator*(); }
 
-    inline bool isUseOnly()   const { return MI->getOperand(i).opIsUse(); } 
-    inline bool isDefOnly()   const { return MI->getOperand(i).opIsDefOnly(); } 
-    inline bool isDefAndUse() const { return MI->getOperand(i).opIsDefAndUse();}
+    inline bool isUse()   const { return MI->getOperand(i).isUse(); } 
+    inline bool isDef()   const { return MI->getOperand(i).isDef(); } 
 
     inline _Self& operator++() { i++; skipToNextVal(); return *this; }
     inline _Self  operator++(int) { _Self tmp = *this; ++*this; return tmp; }
@@ -725,7 +700,6 @@ public:
   }
 };
 
-
 //===----------------------------------------------------------------------===//
 // Debugging Support
 
@@ -733,4 +707,6 @@ std::ostream& operator<<(std::ostream &OS, const MachineInstr &MI);
 std::ostream& operator<<(std::ostream &OS, const MachineOperand &MO);
 void PrintMachineInstructions(const Function *F);
 
+} // End llvm namespace
+
 #endif