mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-23 17:32:49 +00:00
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:
parent
d5003cafd6
commit
89e38f8721
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user