diff options
author | Andrew Trick <atrick@apple.com> | 2013-07-31 03:24:31 +0000 |
---|---|---|
committer | Andrew Trick <atrick@apple.com> | 2013-07-31 03:24:31 +0000 |
commit | c408335bf5128cb24214cce95863d9717e4cdb76 (patch) | |
tree | c199a74882c2ec8b8022fd36e3bc57c108d367da /utils | |
parent | bbf20d4d4af06f0410e7b3ffc71d9be751867067 (diff) | |
download | llvm-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.cpp | 34 |
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";); + } } } |