forked from OSchip/llvm-project
Add TRI::getCommonSuperRegClass().
This function is a generalization of getMatchingSuperRegClass() to the symmetric case where both sides are using a sub-register index. It will find a super-register class and sub-register indexes that make this diagram commute: PreA SuperRC ----------> RCA | | | | PreB | | SubA | | | | V V RCB ----------> SubRC SubB This can be used to coalesce copies like: %vreg1:sub16 = COPY %vreg2:sub16; GR64:%vreg1, GR32: %vreg2 llvm-svn: 156317
This commit is contained in:
parent
d8287fec17
commit
65a6dafc8d
|
@ -458,6 +458,34 @@ public:
|
|||
return b;
|
||||
}
|
||||
|
||||
/// getCommonSuperRegClass - Find a common super-register class if it exists.
|
||||
///
|
||||
/// Find a register class, SuperRC and two sub-register indices, PreA and
|
||||
/// PreB, such that:
|
||||
///
|
||||
/// 1. PreA + SubA == PreB + SubB (using composeSubRegIndices()), and
|
||||
///
|
||||
/// 2. For all Reg in SuperRC: Reg:PreA in RCA and Reg:PreB in RCB, and
|
||||
///
|
||||
/// 3. SuperRC->getSize() >= max(RCA->getSize(), RCB->getSize()).
|
||||
///
|
||||
/// SuperRC will be chosen such that no super-class of SuperRC satisfies the
|
||||
/// requirements, and there is no register class with a smaller spill size
|
||||
/// that satisfies the requirements.
|
||||
///
|
||||
/// SubA and SubB must not be 0. Use getMatchingSuperRegClass() instead.
|
||||
///
|
||||
/// Either of the PreA and PreB sub-register indices may be returned as 0. In
|
||||
/// that case, the returned register class will be a sub-class of the
|
||||
/// corresponding argument register class.
|
||||
///
|
||||
/// The function returns NULL if no register class can be found.
|
||||
///
|
||||
const TargetRegisterClass*
|
||||
getCommonSuperRegClass(const TargetRegisterClass *RCA, unsigned SubA,
|
||||
const TargetRegisterClass *RCB, unsigned SubB,
|
||||
unsigned &PreA, unsigned &PreB) const;
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Register Class Information
|
||||
//
|
||||
|
|
|
@ -122,6 +122,16 @@ BitVector TargetRegisterInfo::getAllocatableSet(const MachineFunction &MF,
|
|||
return Allocatable;
|
||||
}
|
||||
|
||||
static inline
|
||||
const TargetRegisterClass *firstCommonClass(const uint32_t *A,
|
||||
const uint32_t *B,
|
||||
const TargetRegisterInfo *TRI) {
|
||||
for (unsigned I = 0, E = TRI->getNumRegClasses(); I < E; I += 32)
|
||||
if (unsigned Common = *A++ & *B++)
|
||||
return TRI->getRegClass(I + CountTrailingZeros_32(Common));
|
||||
return 0;
|
||||
}
|
||||
|
||||
const TargetRegisterClass *
|
||||
TargetRegisterInfo::getCommonSubClass(const TargetRegisterClass *A,
|
||||
const TargetRegisterClass *B) const {
|
||||
|
@ -173,3 +183,64 @@ TargetRegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A,
|
|||
return getRegClass(Base + CountTrailingZeros_32(Common));
|
||||
return 0;
|
||||
}
|
||||
|
||||
const TargetRegisterClass *TargetRegisterInfo::
|
||||
getCommonSuperRegClass(const TargetRegisterClass *RCA, unsigned SubA,
|
||||
const TargetRegisterClass *RCB, unsigned SubB,
|
||||
unsigned &PreA, unsigned &PreB) const {
|
||||
assert(RCA && SubA && RCB && SubB && "Invalid arguments");
|
||||
|
||||
// Search all pairs of sub-register indices that project into RCA and RCB
|
||||
// respectively. This is quadratic, but usually the sets are very small. On
|
||||
// most targets like X86, there will only be a single sub-register index
|
||||
// (e.g., sub_16bit projecting into GR16).
|
||||
//
|
||||
// The worst case is a register class like DPR on ARM.
|
||||
// We have indices dsub_0..dsub_7 projecting into that class.
|
||||
//
|
||||
// It is very common that one register class is a sub-register of the other.
|
||||
// Arrange for RCA to be the larger register so the answer will be found in
|
||||
// the first iteration. This makes the search linear for the most common
|
||||
// case.
|
||||
const TargetRegisterClass *BestRC = 0;
|
||||
unsigned *BestPreA = &PreA;
|
||||
unsigned *BestPreB = &PreB;
|
||||
if (RCA->getSize() < RCB->getSize()) {
|
||||
std::swap(RCA, RCB);
|
||||
std::swap(BestPreA, BestPreB);
|
||||
}
|
||||
|
||||
// Also terminate the search one we have found a register class as small as
|
||||
// RCA.
|
||||
unsigned MinSize = RCA->getSize();
|
||||
|
||||
for (SuperRegClassIterator IA(RCA, this, true); IA.isValid(); ++IA) {
|
||||
unsigned FinalA = composeSubRegIndices(IA.getSubReg(), SubA);
|
||||
for (SuperRegClassIterator IB(RCB, this, true); IB.isValid(); ++IB) {
|
||||
// Check if a common super-register class exists for this index pair.
|
||||
const TargetRegisterClass *RC =
|
||||
firstCommonClass(IA.getMask(), IB.getMask(), this);
|
||||
if (!RC || RC->getSize() < MinSize)
|
||||
continue;
|
||||
|
||||
// The indexes must compose identically: PreA+SubA == PreB+SubB.
|
||||
unsigned FinalB = composeSubRegIndices(IB.getSubReg(), SubB);
|
||||
if (FinalA != FinalB)
|
||||
continue;
|
||||
|
||||
// Is RC a better candidate than BestRC?
|
||||
if (BestRC && RC->getSize() >= BestRC->getSize())
|
||||
continue;
|
||||
|
||||
// Yes, RC is the smallest super-register seen so far.
|
||||
BestRC = RC;
|
||||
*BestPreA = IA.getSubReg();
|
||||
*BestPreB = IB.getSubReg();
|
||||
|
||||
// Bail early if we reached MinSize. We won't find a better candidate.
|
||||
if (BestRC->getSize() == MinSize)
|
||||
return BestRC;
|
||||
}
|
||||
}
|
||||
return BestRC;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue