add efficient iteration support for register use/def's
authorChris Lattner <sabre@nondot.org>
Tue, 1 Jan 2008 02:55:32 +0000 (02:55 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 1 Jan 2008 02:55:32 +0000 (02:55 +0000)
within a machine function.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45479 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/MachineOperand.h
include/llvm/CodeGen/MachineRegisterInfo.h

index 66f106a40141d71a5b202c008491be89af5409b7..a782ff538ca90a2923bea401b6d41fe417b03ab9 100644 (file)
@@ -175,6 +175,13 @@ public:
     assert(isRegister() && "Wrong MachineOperand accessor");
     return IsKill;
   }
+  
+  /// getNextOperandForReg - Return the next MachineOperand in the function that
+  /// uses or defines this register.
+  MachineOperand *getNextOperandForReg() const {
+    assert(isRegister() && "This is not a register operand!");
+    return Contents.Reg.Next;
+  }
 
   //===--------------------------------------------------------------------===//
   // Mutators for Register Operands
index 65eae08889bb5385c4dbb013d097576b42454f0d..14d601f0bd4ef551052cd9301f88a086f9e00897 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "llvm/Target/MRegisterInfo.h"
 #include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/iterator"
 #include <vector>
 
 namespace llvm {
@@ -56,6 +57,19 @@ public:
   MachineRegisterInfo(const MRegisterInfo &MRI);
   ~MachineRegisterInfo();
   
+  //===--------------------------------------------------------------------===//
+  // Register Info
+  //===--------------------------------------------------------------------===//
+
+  /// 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;
+  reg_iterator reg_begin(unsigned RegNo) const {
+    return reg_iterator(getRegUseDefListHead(RegNo));
+  }
+  static reg_iterator reg_end() { return reg_iterator(0); }
+  
   /// getRegUseDefListHead - Return the head pointer for the register use/def
   /// list for the specified virtual or physical register.
   MachineOperand *&getRegUseDefListHead(unsigned RegNo) {
@@ -65,6 +79,12 @@ public:
     return VRegInfo[RegNo].second;
   }
   
+  MachineOperand *getRegUseDefListHead(unsigned RegNo) const {
+    if (RegNo < MRegisterInfo::FirstVirtualRegister)
+      return PhysRegUseDefLists[RegNo];
+    RegNo -= MRegisterInfo::FirstVirtualRegister;
+    return VRegInfo[RegNo].second;
+  }
   
   //===--------------------------------------------------------------------===//
   // Virtual Register Info
@@ -141,6 +161,52 @@ public:
   bool             liveout_empty() const { return LiveOuts.empty(); }
 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;
+    
+    MachineOperand *Op;
+    reg_iterator(MachineOperand *op) : Op(op) {}
+    friend class MachineRegisterInfo;
+  public:
+    typedef super::reference reference;
+    typedef super::pointer pointer;
+    
+    reg_iterator(const reg_iterator &I) : Op(I.Op) {}
+    reg_iterator() : Op(0) {}
+    
+    bool operator==(const reg_iterator &x) const {
+      return Op == x.Op;
+    }
+    bool operator!=(const reg_iterator &x) const {
+      return !operator==(x);
+    }
+    
+    /// atEnd - return true if this iterator is equal to reg_end() on the value.
+    bool atEnd() const { return Op == 0; }
+    
+    // Iterator traversal: forward iteration only
+    reg_iterator &operator++() {          // Preincrement
+      assert(Op && "Cannot increment end iterator!");
+      Op = Op->getNextOperandForReg();
+      return *this;
+    }
+    reg_iterator operator++(int) {        // Postincrement
+      reg_iterator tmp = *this; ++*this; return tmp;
+    }
+    
+    // Retrieve a reference to the current operand.
+    MachineOperand &operator*() const {
+      assert(Op && "Cannot dereference end iterator!");
+      return *Op;
+    }
+    
+    MachineOperand *operator->() const { return Op; }
+  };
+  
 };
 
 } // End llvm namespace