forked from OSchip/llvm-project
Synthesize missing register class intersections.
The function TRI::getCommonSubClass(A, B) returns the largest common sub-class of the register classes A and B. This patch teaches TableGen to synthesize sub-classes such that the answer is always maximal. In other words, every register that is in both A and B will also be present in getCommonSubClass(A, B). This introduces these synthetic register classes: ARM: GPRnopc_and_hGPR GPRnopc_and_hGPR hGPR_and_rGPR GPRnopc_and_hGPR GPRnopc_and_hGPR hGPR_and_rGPR tGPR_and_tcGPR hGPR_and_tcGPR X86: GR32_NOAX_and_GR32_NOSP GR32_NOAX_and_GR32_NOREX GR64_NOSP_and_GR64_TC GR64_NOSP_and_GR64_TC GR64_NOREX_and_GR64_TC GR32_NOAX_and_GR32_NOSP GR32_NOAX_and_GR32_NOREX GR32_NOAX_and_GR32_NOREX_NOSP GR64_NOSP_and_GR64_TC GR64_NOREX_and_GR64_TC GR64_NOREX_NOSP_and_GR64_TC GR32_NOAX_and_GR32_NOSP GR32_NOAX_and_GR32_NOREX GR32_NOAX_and_GR32_NOREX_NOSP GR32_ABCD_and_GR32_NOAX GR32_NOAX_and_GR32_NOSP GR32_NOAX_and_GR32_NOREX GR32_NOAX_and_GR32_NOREX_NOSP GR32_ABCD_and_GR32_NOAX GR32_NOAX_and_GR32_TC GR32_NOAX_and_GR32_NOSP GR64_NOSP_and_GR64_TC GR32_NOAX_and_GR32_NOREX GR32_NOAX_and_GR32_NOREX_NOSP GR64_NOREX_and_GR64_TC GR64_NOREX_NOSP_and_GR64_TC GR32_ABCD_and_GR32_NOAX GR64_ABCD_and_GR64_TC GR32_NOAX_and_GR32_TC GR32_AD_and_GR32_NOAX Other targets are unaffected. llvm-svn: 146657
This commit is contained in:
parent
275e874c67
commit
c0f97e3dd4
|
@ -756,6 +756,43 @@ void CodeGenRegBank::computeDerivedInfo() {
|
||||||
computeComposites();
|
computeComposites();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Synthesize missing register class intersections.
|
||||||
|
//
|
||||||
|
// Make sure that sub-classes of RC exists such that getCommonSubClass(RC, X)
|
||||||
|
// returns a maximal register class for all X.
|
||||||
|
//
|
||||||
|
void CodeGenRegBank::inferCommonSubClass(CodeGenRegisterClass *RC) {
|
||||||
|
for (unsigned rci = 0, rce = RegClasses.size(); rci != rce; ++rci) {
|
||||||
|
CodeGenRegisterClass *RC1 = RC;
|
||||||
|
CodeGenRegisterClass *RC2 = RegClasses[rci];
|
||||||
|
if (RC1 == RC2)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Compute the set intersection of RC1 and RC2.
|
||||||
|
const CodeGenRegister::Set &Memb1 = RC1->getMembers();
|
||||||
|
const CodeGenRegister::Set &Memb2 = RC2->getMembers();
|
||||||
|
CodeGenRegister::Set Intersection;
|
||||||
|
std::set_intersection(Memb1.begin(), Memb1.end(),
|
||||||
|
Memb2.begin(), Memb2.end(),
|
||||||
|
std::inserter(Intersection, Intersection.begin()));
|
||||||
|
|
||||||
|
// Skip disjoint class pairs.
|
||||||
|
if (Intersection.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// If RC1 and RC2 have different spill sizes or alignments, use the
|
||||||
|
// larger size for sub-classing. If they are equal, prefer RC1.
|
||||||
|
if (RC2->SpillSize > RC1->SpillSize ||
|
||||||
|
(RC2->SpillSize == RC1->SpillSize &&
|
||||||
|
RC2->SpillAlignment > RC1->SpillAlignment))
|
||||||
|
std::swap(RC1, RC2);
|
||||||
|
|
||||||
|
getOrCreateSubClass(RC1, &Intersection,
|
||||||
|
RC1->getName() + "_and_" + RC2->getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Infer missing register classes.
|
// Infer missing register classes.
|
||||||
//
|
//
|
||||||
// For every register class RC, make sure that the set of registers in RC with
|
// For every register class RC, make sure that the set of registers in RC with
|
||||||
|
@ -801,6 +838,9 @@ void CodeGenRegBank::computeInferredRegisterClasses() {
|
||||||
RC.getName() + "_with_" + I->first->getName());
|
RC.getName() + "_with_" + I->first->getName());
|
||||||
RC.setSubClassWithSubReg(SubIdx, SubRC);
|
RC.setSubClassWithSubReg(SubIdx, SubRC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Synthesize answers for getCommonSubClass().
|
||||||
|
inferCommonSubClass(&RC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -244,6 +244,7 @@ namespace llvm {
|
||||||
|
|
||||||
// Infer missing register classes.
|
// Infer missing register classes.
|
||||||
void computeInferredRegisterClasses();
|
void computeInferredRegisterClasses();
|
||||||
|
void inferCommonSubClass(CodeGenRegisterClass *RC);
|
||||||
|
|
||||||
// Composite SubRegIndex instances.
|
// Composite SubRegIndex instances.
|
||||||
// Map (SubRegIndex, SubRegIndex) -> SubRegIndex.
|
// Map (SubRegIndex, SubRegIndex) -> SubRegIndex.
|
||||||
|
|
Loading…
Reference in New Issue