diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-05-04 01:48:29 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-05-04 01:48:29 +0000 |
commit | 89e38f87211f6cf34c8b2e88a06c275a70c05421 (patch) | |
tree | a1e6b20b9a7ed9ae1baadc46816e9511d5b35c4e | |
parent | d5003cafd6fc86acaf8e09ef0ca1dc899da8850e (diff) |
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.h | 56 | ||||
-rw-r--r-- | lib/Target/TargetRegisterInfo.cpp | 28 |
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; } |