summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorAndrew Trick <atrick@apple.com>2013-07-31 03:24:31 +0000
committerAndrew Trick <atrick@apple.com>2013-07-31 03:24:31 +0000
commitc408335bf5128cb24214cce95863d9717e4cdb76 (patch)
treec199a74882c2ec8b8022fd36e3bc57c108d367da /utils
parentbbf20d4d4af06f0410e7b3ffc71d9be751867067 (diff)
downloadllvm-c408335bf5128cb24214cce95863d9717e4cdb76.tar.gz
llvm-c408335bf5128cb24214cce95863d9717e4cdb76.tar.bz2
llvm-c408335bf5128cb24214cce95863d9717e4cdb76.tar.xz
Fix register pressure tables on ARM.
The heuristic that merges register pressure sets was bogus for ARM's S/D regs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187479 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/CodeGenRegisters.cpp34
1 files changed, 31 insertions, 3 deletions
diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp
index b633257b51..9f1c9dd35f 100644
--- a/utils/TableGen/CodeGenRegisters.cpp
+++ b/utils/TableGen/CodeGenRegisters.cpp
@@ -1470,7 +1470,23 @@ static bool isRegUnitSubSet(const std::vector<unsigned> &RUSubSet,
RUSubSet.begin(), RUSubSet.end());
}
-// Iteratively prune unit sets.
+/// Iteratively prune unit sets. Prune subsets that are close the the superset,
+/// but with one or two registers removed. We occasionally have registers like
+/// APSR and PC thrown in with the general registers. We also see many
+/// special-purpose register subsets, such as tail-call and Thumb
+/// encodings. Generating all possible overlapping sets is combinatorial and
+/// overkill for modeling pressure. Ideally we could fix this statically in
+/// tablegen by (1) having the target define register classes that only include
+/// the allocatable registers and marking other classes as non-allocatable and
+/// (2) having a way to mark special purpose classes as "don't-care" classes for
+/// the purpose of pressure. However, we make an attempt to handle targets that
+/// are not nicely defined by merging nearly identical register unit sets
+/// statically. This generates smaller tables. Then, dynamically, we adjust the
+/// set limit by filtering the reserved registers.
+///
+/// Merge sets only if the units have the same weight. For example, on ARM,
+/// Q-tuples with ssub index 0 include all S regs but also include D16+. We
+/// should not expand the S set to include D regs.
void CodeGenRegBank::pruneUnitSets() {
assert(RegClassUnitSets.empty() && "this invalidates RegClassUnitSets");
@@ -1484,9 +1500,12 @@ void CodeGenRegBank::pruneUnitSets() {
if (SuperIdx == SubIdx)
continue;
+ unsigned UnitWeight = RegUnits[SubSet.Units[0]].Weight;
const RegUnitSet &SuperSet = RegUnitSets[SuperIdx];
if (isRegUnitSubSet(SubSet.Units, SuperSet.Units)
- && (SubSet.Units.size() + 3 > SuperSet.Units.size())) {
+ && (SubSet.Units.size() + 3 > SuperSet.Units.size())
+ && UnitWeight == RegUnits[SuperSet.Units[0]].Weight
+ && UnitWeight == RegUnits[SuperSet.Units.back()].Weight) {
DEBUG(dbgs() << "UnitSet " << SubIdx << " subsumed by " << SuperIdx
<< "\n");
break;
@@ -1559,7 +1578,8 @@ void CodeGenRegBank::computeRegUnitSets() {
for (unsigned i = 0, e = Units.size(); i < e; ++i)
dbgs() << " " << RegUnits[Units[i]].Roots[0]->getName();
dbgs() << "\n";
- });
+ }
+ dbgs() << "\nUnion sets:\n");
// Iterate over all unit sets, including new ones added by this loop.
unsigned NumRegUnitSubSets = RegUnitSets.size();
@@ -1598,6 +1618,14 @@ void CodeGenRegBank::computeRegUnitSets() {
findRegUnitSet(RegUnitSets, RegUnitSets.back());
if (SetI != llvm::prior(RegUnitSets.end()))
RegUnitSets.pop_back();
+ else {
+ DEBUG(dbgs() << "UnitSet " << RegUnitSets.size()-1
+ << " " << RegUnitSets.back().Name << ":";
+ ArrayRef<unsigned> Units = RegUnitSets.back().Units;
+ for (unsigned i = 0, e = Units.size(); i < e; ++i)
+ dbgs() << " " << RegUnits[Units[i]].Roots[0]->getName();
+ dbgs() << "\n";);
+ }
}
}