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
This commit is contained in:
Jakob Stoklund Olesen 2012-05-04 01:48:29 +00:00
parent d5003cafd6
commit 89e38f8721
2 changed files with 69 additions and 15 deletions

View 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 // This is useful when building IndexedMaps keyed on virtual registers
struct VirtReg2IndexFunctor : public std::unary_function<unsigned, unsigned> { struct VirtReg2IndexFunctor : public std::unary_function<unsigned, unsigned> {
unsigned operator()(unsigned Reg) const { unsigned operator()(unsigned Reg) const {

View File

@ -154,24 +154,22 @@ TargetRegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A,
assert(Idx && "Bad sub-register index"); assert(Idx && "Bad sub-register index");
// Find Idx in the list of super-register indices. // Find Idx in the list of super-register indices.
const uint16_t *SRI = B->getSuperRegIndices(); const uint32_t *Mask = 0;
unsigned Offset = 0; for (SuperRegClassIterator RCI(B, this); RCI.isValid(); ++RCI)
while (SRI[Offset] != Idx) { if (RCI.getSubReg() == Idx) {
if (!SRI[Offset]) Mask = RCI.getMask();
return 0; break;
++Offset; }
} if (!Mask)
return 0;
// The register class bit mask corresponding to SRI[Offset]. The bit mask // The bit mask contains all register classes that are projected into B by
// contains all register classes that are projected into B by Idx. Find a // Idx. Find a class that is also a sub-class of 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;
const uint32_t *SC = A->getSubClassMask(); const uint32_t *SC = A->getSubClassMask();
// Find the first common register class in TV and SC. // Find the first common register class in TV and SC.
for (unsigned i = 0; i != RCMaskWords ; ++i) for (unsigned Base = 0, BaseE = getNumRegClasses(); Base < BaseE; Base += 32)
if (unsigned Common = TV[i] & SC[i]) if (unsigned Common = *Mask++ & *SC++)
return getRegClass(32*i + CountTrailingZeros_32(Common)); return getRegClass(Base + CountTrailingZeros_32(Common));
return 0; return 0;
} }