diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2011-12-15 16:48:55 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2011-12-15 16:48:55 +0000 |
commit | 7e56831a6804812b2295c5446a05f4ec457b6b3e (patch) | |
tree | 949d64e077d694e5a10036116bf3c1149eeb8bea /utils/TableGen | |
parent | 27a7859bf72b740cdb0cb32bc1e4e24b684eab0c (diff) | |
download | llvm-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.cpp | 40 | ||||
-rw-r--r-- | utils/TableGen/CodeGenRegisters.h | 1 |
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. |