Add a SuperRegClassIterator class.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Fri, 4 May 2012 01:48:29 +0000 (01:48 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Fri, 4 May 2012 01:48:29 +0000 (01:48 +0000)
This iterator class provides a more abstract interface to the (Idx,
Mask) lists of super-registers for a register class. The layout of the
tables shouldn't be exposed to clients.

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

include/llvm/Target/TargetRegisterInfo.h
lib/Target/TargetRegisterInfo.cpp

index b8097a231edf4c3df522c52997757c966d7093a0..f5cd7a88f7f68478acce33475b4630e6d3680f4e 100644 (file)
@@ -738,6 +738,62 @@ public:
 };
 
 
+//===----------------------------------------------------------------------===//
+//                           SuperRegClassIterator
+//===----------------------------------------------------------------------===//
+//
+// Iterate over the possible super-registers for a given register class. The
+// iterator will visit a list of pairs (Idx, Mask) corresponding to the
+// possible classes of super-registers.
+//
+// Each bit mask will have at least one set bit, and each set bit in Mask
+// corresponds to a SuperRC such that:
+//
+//   For all Reg in SuperRC: Reg:Idx is in RC.
+//
+// The iterator can include (O, RC->getSubClassMask()) as the first entry which
+// also satisfies the above requirement, assuming Reg:0 == Reg.
+//
+class SuperRegClassIterator {
+  const unsigned RCMaskWords;
+  unsigned SubReg;
+  const uint16_t *Idx;
+  const uint32_t *Mask;
+
+public:
+  /// Create a SuperRegClassIterator that visits all the super-register classes
+  /// of RC. When IncludeSelf is set, also include the (0, sub-classes) entry.
+  SuperRegClassIterator(const TargetRegisterClass *RC,
+                        const TargetRegisterInfo *TRI,
+                        bool IncludeSelf = false)
+    : RCMaskWords((TRI->getNumRegClasses() + 31) / 32),
+      SubReg(0),
+      Idx(RC->getSuperRegIndices()),
+      Mask(RC->getSubClassMask()) {
+    if (!IncludeSelf)
+      ++*this;
+  }
+
+  /// Returns true if this iterator is still pointing at a valid entry.
+  bool isValid() const { return Idx; }
+
+  /// Returns the current sub-register index.
+  unsigned getSubReg() const { return SubReg; }
+
+  /// Returns the bit mask if register classes that getSubReg() projects into
+  /// RC.
+  const uint32_t *getMask() const { return Mask; }
+
+  /// Advance iterator to the next entry.
+  void operator++() {
+    assert(isValid() && "Cannot move iterator past end.");
+    Mask += RCMaskWords;
+    SubReg = *Idx++;
+    if (!SubReg)
+      Idx = 0;
+  }
+};
+
 // This is useful when building IndexedMaps keyed on virtual registers
 struct VirtReg2IndexFunctor : public std::unary_function<unsigned, unsigned> {
   unsigned operator()(unsigned Reg) const {
index 3ae3fed5d59e1181cf30aead5f18a592495cb76b..d5518ea2c19a3f0a08e70eb1b2838d4f4fc8e3ac 100644 (file)
@@ -154,24 +154,22 @@ TargetRegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A,
   assert(Idx && "Bad sub-register index");
 
   // Find Idx in the list of super-register indices.
-  const uint16_t *SRI = B->getSuperRegIndices();
-  unsigned Offset = 0;
-  while (SRI[Offset] != Idx) {
-    if (!SRI[Offset])
-      return 0;
-    ++Offset;
-  }
+  const uint32_t *Mask = 0;
+  for (SuperRegClassIterator RCI(B, this); RCI.isValid(); ++RCI)
+    if (RCI.getSubReg() == Idx) {
+      Mask = RCI.getMask();
+      break;
+    }
+  if (!Mask)
+    return 0;
 
-  // The register class bit mask corresponding to SRI[Offset]. The bit mask
-  // contains all register classes that are projected into B by Idx. Find a
-  // class that is also a sub-class of A.
-  const unsigned RCMaskWords = (getNumRegClasses()+31)/32;
-  const uint32_t *TV = B->getSubClassMask() + (Offset + 1) * RCMaskWords;
+  // The bit mask contains all register classes that are projected into B by
+  // Idx. Find a class that is also a sub-class of A.
   const uint32_t *SC = A->getSubClassMask();
 
   // Find the first common register class in TV and SC.
-  for (unsigned i = 0; i != RCMaskWords ; ++i)
-    if (unsigned Common = TV[i] & SC[i])
-      return getRegClass(32*i + CountTrailingZeros_32(Common));
+  for (unsigned Base = 0, BaseE = getNumRegClasses(); Base < BaseE; Base += 32)
+    if (unsigned Common = *Mask++ & *SC++)
+      return getRegClass(Base + CountTrailingZeros_32(Common));
   return 0;
 }