When folding memory operands in machine instructions be careful to
[oota-llvm.git] / include / llvm / CodeGen / MachineInstr.h
index f171d776cc9bda6ece2dca728479fe25871b6ebf..65d5ccae70a7f37c4d40c92daa26f00c83a15357 100644 (file)
@@ -1,4 +1,11 @@
 //===-- 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 dependent machine instructions used by
@@ -9,9 +16,11 @@
 #ifndef LLVM_CODEGEN_MACHINEINSTR_H
 #define LLVM_CODEGEN_MACHINEINSTR_H
 
-#include "llvm/Target/MRegisterInfo.h"
 #include "Support/Annotation.h"
 #include "Support/iterator"
+#include <vector>
+
+namespace llvm {
 
 class Value;
 class Function;
@@ -19,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
@@ -100,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:
@@ -131,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),
@@ -148,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!");
     }
   }
@@ -159,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;
@@ -200,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:
@@ -212,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 {
@@ -252,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;
@@ -272,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 {
@@ -288,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);
@@ -340,45 +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
-
+  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 {
@@ -591,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.
@@ -666,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; }
@@ -700,7 +700,6 @@ public:
   }
 };
 
-
 //===----------------------------------------------------------------------===//
 // Debugging Support
 
@@ -708,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