summaryrefslogtreecommitdiff
path: root/utils/TableGen
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2011-12-15 16:48:55 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2011-12-15 16:48:55 +0000
commit7e56831a6804812b2295c5446a05f4ec457b6b3e (patch)
tree949d64e077d694e5a10036116bf3c1149eeb8bea /utils/TableGen
parent27a7859bf72b740cdb0cb32bc1e4e24b684eab0c (diff)
downloadllvm-7e56831a6804812b2295c5446a05f4ec457b6b3e.tar.gz
llvm-7e56831a6804812b2295c5446a05f4ec457b6b3e.tar.bz2
llvm-7e56831a6804812b2295c5446a05f4ec457b6b3e.tar.xz
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146657 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils/TableGen')
-rw-r--r--utils/TableGen/CodeGenRegisters.cpp40
-rw-r--r--utils/TableGen/CodeGenRegisters.h1
2 files changed, 41 insertions, 0 deletions
diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp
index 7b9b0f1317..35afaf8efb 100644
--- a/utils/TableGen/CodeGenRegisters.cpp
+++ b/utils/TableGen/CodeGenRegisters.cpp
@@ -756,6 +756,43 @@ void CodeGenRegBank::computeDerivedInfo() {
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.
//
// 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.setSubClassWithSubReg(SubIdx, SubRC);
}
+
+ // Synthesize answers for getCommonSubClass().
+ inferCommonSubClass(&RC);
}
}
diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h
index b75bf0b8fd..da5cf10eab 100644
--- a/utils/TableGen/CodeGenRegisters.h
+++ b/utils/TableGen/CodeGenRegisters.h
@@ -244,6 +244,7 @@ namespace llvm {
// Infer missing register classes.
void computeInferredRegisterClasses();
+ void inferCommonSubClass(CodeGenRegisterClass *RC);
// Composite SubRegIndex instances.
// Map (SubRegIndex, SubRegIndex) -> SubRegIndex.