forked from OSchip/llvm-project
Synthesize register classes for TRI::getMatchingSuperRegClass().
Teach TableGen to create the missing register classes needed for getMatchingSuperRegClass() to return maximal results. The function is still not auto-generated, so it still returns inexact results. This produces these new register classes: ARM: QQPR_with_dsub_0_in_DPR_8 QQQQPR_with_dsub_0_in_DPR_8 X86: GR64_with_sub_32bit_in_GR32_NOAX GR64_with_sub_32bit_in_GR32_NOAX_and_GR32_NOSP GR64_with_sub_16bit_in_GR16_NOREX GR64_with_sub_32bit_in_GR32_NOAX_and_GR32_NOREX GR64_TC_and_GR64_with_sub_32bit_in_GR32_NOAX GR64_with_sub_32bit_in_GR32_NOAX_and_GR32_NOREX_NOSP GR64_TCW64_and_GR64_with_sub_32bit_in_GR32_NOAX GR64_TC_and_GR64_with_sub_32bit_in_GR32_NOAX_and_GR32_NOREX GR64_with_sub_32bit_in_GR32_TC GR64_with_sub_32bit_in_GR32_ABCD_and_GR32_NOAX GR64_with_sub_32bit_in_GR32_NOAX_and_GR32_TC GR64_with_sub_32bit_in_GR32_AD GR64_with_sub_32bit_in_GR32_AD_and_GR32_NOAX The other targets in the tree are not weird enough to be affected. llvm-svn: 146872
This commit is contained in:
parent
ba9cc6c1bb
commit
b92f557c40
|
@ -835,6 +835,62 @@ void CodeGenRegBank::inferSubClassWithSubReg(CodeGenRegisterClass *RC) {
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Synthesize missing sub-classes of RC for getMatchingSuperRegClass().
|
||||
//
|
||||
// Create sub-classes of RC such that getMatchingSuperRegClass(RC, SubIdx, X)
|
||||
// has a maximal result for any SubIdx and any X >= FirstSubRegRC.
|
||||
//
|
||||
|
||||
void CodeGenRegBank::inferMatchingSuperRegClass(CodeGenRegisterClass *RC,
|
||||
unsigned FirstSubRegRC) {
|
||||
SmallVector<std::pair<const CodeGenRegister*,
|
||||
const CodeGenRegister*>, 16> SSPairs;
|
||||
|
||||
// Iterate in SubRegIndex numerical order to visit synthetic indices last.
|
||||
for (unsigned sri = 0, sre = SubRegIndices.size(); sri != sre; ++sri) {
|
||||
Record *SubIdx = SubRegIndices[sri];
|
||||
// Skip indexes that aren't fully supported by RC's registers. This was
|
||||
// computed by inferSubClassWithSubReg() above which should have been
|
||||
// called first.
|
||||
if (RC->getSubClassWithSubReg(SubIdx) != RC)
|
||||
continue;
|
||||
|
||||
// Build list of (Super, Sub) pairs for this SubIdx.
|
||||
SSPairs.clear();
|
||||
for (CodeGenRegister::Set::const_iterator RI = RC->getMembers().begin(),
|
||||
RE = RC->getMembers().end(); RI != RE; ++RI) {
|
||||
const CodeGenRegister *Super = *RI;
|
||||
const CodeGenRegister *Sub = Super->getSubRegs().find(SubIdx)->second;
|
||||
assert(Sub && "Missing sub-register");
|
||||
SSPairs.push_back(std::make_pair(Super, Sub));
|
||||
}
|
||||
|
||||
// Iterate over sub-register class candidates. Ignore classes created by
|
||||
// this loop. They will never be useful.
|
||||
for (unsigned rci = FirstSubRegRC, rce = RegClasses.size(); rci != rce;
|
||||
++rci) {
|
||||
CodeGenRegisterClass *SubRC = RegClasses[rci];
|
||||
// Compute the subset of RC that maps into SubRC.
|
||||
CodeGenRegister::Set SubSet;
|
||||
for (unsigned i = 0, e = SSPairs.size(); i != e; ++i)
|
||||
if (SubRC->contains(SSPairs[i].second))
|
||||
SubSet.insert(SSPairs[i].first);
|
||||
if (SubSet.empty())
|
||||
continue;
|
||||
// RC injects completely into SubRC.
|
||||
if (SubSet.size() == SSPairs.size())
|
||||
continue;
|
||||
// Only a subset of RC maps into SubRC. Make sure it is represented by a
|
||||
// class.
|
||||
getOrCreateSubClass(RC, &SubSet, RC->getName() +
|
||||
"_with_" + SubIdx->getName() +
|
||||
"_in_" + SubRC->getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Infer missing register classes.
|
||||
//
|
||||
|
@ -842,6 +898,7 @@ void CodeGenRegBank::computeInferredRegisterClasses() {
|
|||
// When this function is called, the register classes have not been sorted
|
||||
// and assigned EnumValues yet. That means getSubClasses(),
|
||||
// getSuperClasses(), and hasSubClass() functions are defunct.
|
||||
unsigned FirstNewRC = RegClasses.size();
|
||||
|
||||
// Visit all register classes, including the ones being added by the loop.
|
||||
for (unsigned rci = 0; rci != RegClasses.size(); ++rci) {
|
||||
|
@ -852,6 +909,22 @@ void CodeGenRegBank::computeInferredRegisterClasses() {
|
|||
|
||||
// Synthesize answers for getCommonSubClass().
|
||||
inferCommonSubClass(RC);
|
||||
|
||||
// Synthesize answers for getMatchingSuperRegClass().
|
||||
inferMatchingSuperRegClass(RC);
|
||||
|
||||
// New register classes are created while this loop is running, and we need
|
||||
// to visit all of them. I particular, inferMatchingSuperRegClass needs
|
||||
// to match old super-register classes with sub-register classes created
|
||||
// after inferMatchingSuperRegClass was called. At this point,
|
||||
// inferMatchingSuperRegClass has checked SuperRC = [0..rci] with SubRC =
|
||||
// [0..FirstNewRC). We need to cover SubRC = [FirstNewRC..rci].
|
||||
if (rci + 1 == FirstNewRC) {
|
||||
unsigned NextNewRC = RegClasses.size();
|
||||
for (unsigned rci2 = 0; rci2 != FirstNewRC; ++rci2)
|
||||
inferMatchingSuperRegClass(RegClasses[rci2], FirstNewRC);
|
||||
FirstNewRC = NextNewRC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -246,6 +246,8 @@ namespace llvm {
|
|||
void computeInferredRegisterClasses();
|
||||
void inferCommonSubClass(CodeGenRegisterClass *RC);
|
||||
void inferSubClassWithSubReg(CodeGenRegisterClass *RC);
|
||||
void inferMatchingSuperRegClass(CodeGenRegisterClass *RC,
|
||||
unsigned FirstSubRegRC = 0);
|
||||
|
||||
// Composite SubRegIndex instances.
|
||||
// Map (SubRegIndex, SubRegIndex) -> SubRegIndex.
|
||||
|
|
Loading…
Reference in New Issue