Rename some GC classes so that their roll will hopefully be clearer.
[oota-llvm.git] / include / llvm / CodeGen / MachineRegisterInfo.h
index 14d601f0bd4ef551052cd9301f88a086f9e00897..b851fdf66da9496d27bb402c6330b276d9afbc1a 100644 (file)
 #ifndef LLVM_CODEGEN_MACHINEREGISTERINFO_H
 #define LLVM_CODEGEN_MACHINEREGISTERINFO_H
 
-#include "llvm/Target/MRegisterInfo.h"
+#include "llvm/Target/TargetRegisterInfo.h"
 #include "llvm/ADT/BitVector.h"
-#include "llvm/ADT/iterator"
+#include "llvm/ADT/iterator.h"
 #include <vector>
 
 namespace llvm {
   
-/// MachineRegisterInfo - Keep track of information for each virtual register,
-/// including its register class.
+/// MachineRegisterInfo - Keep track of information for virtual and physical
+/// registers, including vreg register classes, use/def chains for registers,
+/// etc.
 class MachineRegisterInfo {
   /// VRegInfo - Information we keep for each virtual register.  The entries in
   /// this vector are actually converted to vreg numbers by adding the 
-  /// MRegisterInfo::FirstVirtualRegister delta to their index.
+  /// TargetRegisterInfo::FirstVirtualRegister delta to their index.
   ///
   /// Each element in this list contains the register class of the vreg and the
   /// start of the use/def list for the register.
@@ -54,7 +55,7 @@ class MachineRegisterInfo {
   MachineRegisterInfo(const MachineRegisterInfo&); // DO NOT IMPLEMENT
   void operator=(const MachineRegisterInfo&);      // DO NOT IMPLEMENT
 public:
-  MachineRegisterInfo(const MRegisterInfo &MRI);
+  explicit MachineRegisterInfo(const TargetRegisterInfo &TRI);
   ~MachineRegisterInfo();
   
   //===--------------------------------------------------------------------===//
@@ -64,38 +65,83 @@ public:
   /// reg_begin/reg_end - Provide iteration support to walk over all definitions
   /// and uses of a register within the MachineFunction that corresponds to this
   /// MachineRegisterInfo object.
-  class reg_iterator;
+  template<bool Uses, bool Defs>
+  class defusechain_iterator;
+
+  /// reg_iterator/reg_begin/reg_end - Walk all defs and uses of the specified
+  /// register.
+  typedef defusechain_iterator<true,true> reg_iterator;
   reg_iterator reg_begin(unsigned RegNo) const {
     return reg_iterator(getRegUseDefListHead(RegNo));
   }
   static reg_iterator reg_end() { return reg_iterator(0); }
+
+  /// def_iterator/def_begin/def_end - Walk all defs of the specified register.
+  typedef defusechain_iterator<false,true> def_iterator;
+  def_iterator def_begin(unsigned RegNo) const {
+    return def_iterator(getRegUseDefListHead(RegNo));
+  }
+  static def_iterator def_end() { return def_iterator(0); }
+
+  /// use_iterator/use_begin/use_end - Walk all uses of the specified register.
+  typedef defusechain_iterator<true,false> use_iterator;
+  use_iterator use_begin(unsigned RegNo) const {
+    return use_iterator(getRegUseDefListHead(RegNo));
+  }
+  static use_iterator use_end() { return use_iterator(0); }
+  
+  /// use_empty - Return true if there are no instructions using the specified
+  /// register.
+  bool use_empty(unsigned RegNo) const { return use_begin(RegNo) == use_end(); }
+
+  
+  /// replaceRegWith - Replace all instances of FromReg with ToReg in the
+  /// machine function.  This is like llvm-level X->replaceAllUsesWith(Y),
+  /// except that it also changes any definitions of the register as well.
+  void replaceRegWith(unsigned FromReg, unsigned ToReg);
   
   /// getRegUseDefListHead - Return the head pointer for the register use/def
   /// list for the specified virtual or physical register.
   MachineOperand *&getRegUseDefListHead(unsigned RegNo) {
-    if (RegNo < MRegisterInfo::FirstVirtualRegister)
+    if (RegNo < TargetRegisterInfo::FirstVirtualRegister)
       return PhysRegUseDefLists[RegNo];
-    RegNo -= MRegisterInfo::FirstVirtualRegister;
+    RegNo -= TargetRegisterInfo::FirstVirtualRegister;
     return VRegInfo[RegNo].second;
   }
   
   MachineOperand *getRegUseDefListHead(unsigned RegNo) const {
-    if (RegNo < MRegisterInfo::FirstVirtualRegister)
+    if (RegNo < TargetRegisterInfo::FirstVirtualRegister)
       return PhysRegUseDefLists[RegNo];
-    RegNo -= MRegisterInfo::FirstVirtualRegister;
+    RegNo -= TargetRegisterInfo::FirstVirtualRegister;
     return VRegInfo[RegNo].second;
   }
+
+  /// getVRegDef - Return the machine instr that defines the specified virtual
+  /// register or null if none is found.  This assumes that the code is in SSA
+  /// form, so there should only be one definition.
+  MachineInstr *getVRegDef(unsigned Reg) const;
+  
+#ifndef NDEBUG
+  void dumpUses(unsigned RegNo) const;
+#endif
   
   //===--------------------------------------------------------------------===//
   // Virtual Register Info
   //===--------------------------------------------------------------------===//
   
   /// getRegClass - Return the register class of the specified virtual register.
-  const TargetRegisterClass *getRegClass(unsigned Reg) {
-    Reg -= MRegisterInfo::FirstVirtualRegister;
+  const TargetRegisterClass *getRegClass(unsigned Reg) const {
+    Reg -= TargetRegisterInfo::FirstVirtualRegister;
     assert(Reg < VRegInfo.size() && "Invalid vreg!");
     return VRegInfo[Reg].first;
   }
+
+  /// setRegClass - Set the register class of the specified virtual register.
+  void setRegClass(unsigned Reg, const TargetRegisterClass *RC) {
+    Reg -= TargetRegisterInfo::FirstVirtualRegister;
+    assert(Reg < VRegInfo.size() && "Invalid vreg!");
+    VRegInfo[Reg].first = RC;
+  }
   
   /// createVirtualRegister - Create and return a new virtual register in the
   /// function with the specified register class.
@@ -103,10 +149,10 @@ public:
   unsigned createVirtualRegister(const TargetRegisterClass *RegClass) {
     assert(RegClass && "Cannot create register without RegClass!");
     // Add a reg, but keep track of whether the vector reallocated or not.
-    void *ArrayBase = &VRegInfo[0];
+    void *ArrayBase = VRegInfo.empty() ? 0 : &VRegInfo[0];
     VRegInfo.push_back(std::make_pair(RegClass, (MachineOperand*)0));
     
-    if (&VRegInfo[0] == ArrayBase)
+    if (&VRegInfo[0] == ArrayBase || VRegInfo.size() == 1)
       return getLastVirtReg();
 
     // Otherwise, the vector reallocated, handle this now.
@@ -117,9 +163,10 @@ public:
   /// getLastVirtReg - Return the highest currently assigned virtual register.
   ///
   unsigned getLastVirtReg() const {
-    return VRegInfo.size()+MRegisterInfo::FirstVirtualRegister-1;
+    return (unsigned)VRegInfo.size()+TargetRegisterInfo::FirstVirtualRegister-1;
   }
   
+  
   //===--------------------------------------------------------------------===//
   // Physical Register Use Info
   //===--------------------------------------------------------------------===//
@@ -159,29 +206,48 @@ public:
   liveout_iterator liveout_begin() const { return LiveOuts.begin(); }
   liveout_iterator liveout_end()   const { return LiveOuts.end(); }
   bool             liveout_empty() const { return LiveOuts.empty(); }
+
+  bool isLiveIn(unsigned Reg) const {
+    for (livein_iterator I = livein_begin(), E = livein_end(); I != E; ++I)
+      if (I->first == Reg || I->second == Reg)
+        return true;
+    return false;
+  }
+
 private:
   void HandleVRegListReallocation();
   
 public:
-  /// reg_iterator - This class provides iterator support for machine
-  /// operands in the function that use or define a specific register.
-  class reg_iterator : public forward_iterator<MachineOperand, ptrdiff_t> {
-    typedef forward_iterator<MachineOperand, ptrdiff_t> super;
-    
+  /// defusechain_iterator - This class provides iterator support for machine
+  /// operands in the function that use or define a specific register.  If
+  /// ReturnUses is true it returns uses of registers, if ReturnDefs is true it
+  /// returns defs.  If neither are true then you are silly and it always
+  /// returns end().
+  template<bool ReturnUses, bool ReturnDefs>
+  class defusechain_iterator
+    : public forward_iterator<MachineInstr, ptrdiff_t> {
     MachineOperand *Op;
-    reg_iterator(MachineOperand *op) : Op(op) {}
+    explicit defusechain_iterator(MachineOperand *op) : Op(op) {
+      // If the first node isn't one we're interested in, advance to one that
+      // we are interested in.
+      if (op) {
+        if ((!ReturnUses && op->isUse()) ||
+            (!ReturnDefs && op->isDef()))
+          ++*this;
+      }
+    }
     friend class MachineRegisterInfo;
   public:
-    typedef super::reference reference;
-    typedef super::pointer pointer;
+    typedef forward_iterator<MachineInstr, ptrdiff_t>::reference reference;
+    typedef forward_iterator<MachineInstr, ptrdiff_t>::pointer pointer;
     
-    reg_iterator(const reg_iterator &I) : Op(I.Op) {}
-    reg_iterator() : Op(0) {}
+    defusechain_iterator(const defusechain_iterator &I) : Op(I.Op) {}
+    defusechain_iterator() : Op(0) {}
     
-    bool operator==(const reg_iterator &x) const {
+    bool operator==(const defusechain_iterator &x) const {
       return Op == x.Op;
     }
-    bool operator!=(const reg_iterator &x) const {
+    bool operator!=(const defusechain_iterator &x) const {
       return !operator==(x);
     }
     
@@ -189,22 +255,43 @@ public:
     bool atEnd() const { return Op == 0; }
     
     // Iterator traversal: forward iteration only
-    reg_iterator &operator++() {          // Preincrement
+    defusechain_iterator &operator++() {          // Preincrement
       assert(Op && "Cannot increment end iterator!");
       Op = Op->getNextOperandForReg();
+      
+      // If this is an operand we don't care about, skip it.
+      while (Op && ((!ReturnUses && Op->isUse()) || 
+                    (!ReturnDefs && Op->isDef())))
+        Op = Op->getNextOperandForReg();
+      
       return *this;
     }
-    reg_iterator operator++(int) {        // Postincrement
-      reg_iterator tmp = *this; ++*this; return tmp;
+    defusechain_iterator operator++(int) {        // Postincrement
+      defusechain_iterator tmp = *this; ++*this; return tmp;
     }
     
-    // Retrieve a reference to the current operand.
-    MachineOperand &operator*() const {
+    MachineOperand &getOperand() const {
       assert(Op && "Cannot dereference end iterator!");
       return *Op;
     }
     
-    MachineOperand *operator->() const { return Op; }
+    /// getOperandNo - Return the operand # of this MachineOperand in its
+    /// MachineInstr.
+    unsigned getOperandNo() const {
+      assert(Op && "Cannot dereference end iterator!");
+      return Op - &Op->getParent()->getOperand(0);
+    }
+    
+    // Retrieve a reference to the current operand.
+    MachineInstr &operator*() const {
+      assert(Op && "Cannot dereference end iterator!");
+      return *Op->getParent();
+    }
+    
+    MachineInstr *operator->() const {
+      assert(Op && "Cannot dereference end iterator!");
+      return Op->getParent();
+    }
   };
   
 };