summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2012-05-04 01:48:29 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2012-05-04 01:48:29 +0000
commit89e38f87211f6cf34c8b2e88a06c275a70c05421 (patch)
treea1e6b20b9a7ed9ae1baadc46816e9511d5b35c4e
parentd5003cafd6fc86acaf8e09ef0ca1dc899da8850e (diff)
downloadllvm-89e38f87211f6cf34c8b2e88a06c275a70c05421.tar.gz
llvm-89e38f87211f6cf34c8b2e88a06c275a70c05421.tar.bz2
llvm-89e38f87211f6cf34c8b2e88a06c275a70c05421.tar.xz
Add a SuperRegClassIterator class.
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
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h56
-rw-r--r--lib/Target/TargetRegisterInfo.cpp28
2 files changed, 69 insertions, 15 deletions
diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h
index b8097a231e..f5cd7a88f7 100644
--- a/include/llvm/Target/TargetRegisterInfo.h
+++ b/include/llvm/Target/TargetRegisterInfo.h
@@ -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 {
diff --git a/lib/Target/TargetRegisterInfo.cpp b/lib/Target/TargetRegisterInfo.cpp
index 3ae3fed5d5..d5518ea2c1 100644
--- a/lib/Target/TargetRegisterInfo.cpp
+++ b/lib/Target/TargetRegisterInfo.cpp
@@ -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;
}