in builds without asserts we do not need to allocate the Next pointer in "ghostly...
[oota-llvm.git] / include / llvm / CodeGen / MachineRegisterInfo.h
index 8af42b7cf5f0ecde656245d3fab314f20a888dba..b313fce182f802ae21c8bdd9ebbeec20b9dde058 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.
   std::vector<std::pair<const TargetRegisterClass*, MachineOperand*> > VRegInfo;
+
+  /// RegClassVRegMap - This vector acts as a map from TargetRegisterClass to
+  /// virtual registers. For each target register class, it keeps a list of
+  /// virtual registers belonging to the class.
+  std::vector<std::vector<unsigned> > RegClass2VRegMap;
   
   /// PhysRegUseDefLists - This is an array of the head of the use/def list for
   /// physical registers.
@@ -54,7 +60,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,11 +70,43 @@ 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); }
+
+  /// reg_empty - Return true if there are no instructions using or defining the
+  /// specified register (it may be live-in).
+  bool reg_empty(unsigned RegNo) const { return reg_begin(RegNo) == reg_end(); }
+
+  /// 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); }
+
+  /// def_empty - Return true if there are no instructions defining the
+  /// specified register (it may be live-in).
+  bool def_empty(unsigned RegNo) const { return def_begin(RegNo) == def_end(); }
+
+  /// 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),
@@ -78,58 +116,75 @@ public:
   /// 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) {
+    unsigned VR = Reg;
+    Reg -= TargetRegisterInfo::FirstVirtualRegister;
+    assert(Reg < VRegInfo.size() && "Invalid vreg!");
+    const TargetRegisterClass *OldRC = VRegInfo[Reg].first;
+    VRegInfo[Reg].first = RC;
+
+    // Remove from old register class's vregs list. This may be slow but
+    // fortunately this operation is rarely needed.
+    std::vector<unsigned> &VRegs = RegClass2VRegMap[OldRC->getID()];
+    std::vector<unsigned>::iterator I=std::find(VRegs.begin(), VRegs.end(), VR);
+    VRegs.erase(I);
+
+    // Add to new register class's vregs list.
+    RegClass2VRegMap[RC->getID()].push_back(VR);
+  }
   
   /// createVirtualRegister - Create and return a new virtual register in the
   /// function with the specified register class.
   ///
-  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.empty() ? 0 : &VRegInfo[0];
-    VRegInfo.push_back(std::make_pair(RegClass, (MachineOperand*)0));
-    
-    if (&VRegInfo[0] == ArrayBase || VRegInfo.size() == 1)
-      return getLastVirtReg();
-
-    // Otherwise, the vector reallocated, handle this now.
-    HandleVRegListReallocation();
-    return getLastVirtReg();
-  }
+  unsigned createVirtualRegister(const TargetRegisterClass *RegClass);
 
   /// getLastVirtReg - Return the highest currently assigned virtual register.
   ///
   unsigned getLastVirtReg() const {
-    return VRegInfo.size()+MRegisterInfo::FirstVirtualRegister-1;
+    return (unsigned)VRegInfo.size()+TargetRegisterInfo::FirstVirtualRegister-1;
+  }
+
+  /// getRegClassVirtRegs - Return the list of virtual registers of the given
+  /// target register class.
+  std::vector<unsigned> &getRegClassVirtRegs(const TargetRegisterClass *RC) {
+    return RegClass2VRegMap[RC->getID()];
   }
-  
-  /// 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;
-  
   
   //===--------------------------------------------------------------------===//
   // Physical Register Use Info
@@ -170,27 +225,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<MachineInstr, ptrdiff_t> {
+  /// 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 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);
     }
     
@@ -198,13 +274,19 @@ 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;
     }
     
     MachineOperand &getOperand() const {