aboutsummaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2012-05-14 15:20:39 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2012-05-14 15:20:39 +0000
commitf402602199a3fc875bb9b6887869e647d0b49df2 (patch)
tree1225da92de801e10020530f46a0a2111ba97093d /utils
parent31d938a6b1173c642f975d78417459d4d8cd3677 (diff)
Consider ad hoc aliasing when building RegUnits.
Register units can be used to compute if two registers overlap: A overlaps B iff units(A) intersects units(B). With this change, the above holds true even on targets that use ad hoc aliasing (currently only ARM). This means that register units can be used to implement regsOverlap() more efficiently, and the register allocator can use the concept to model interference. When there is no ad hoc aliasing, the register units correspond to the maximal cliques in the register overlap graph. This is optimal, no other register unit assignment can have fewer units. With ad hoc aliasing, weird things are possible, and we don't try too hard to compute the maximal cliques. The current approach is always correct, and it works very well (probably optimally) as long as the ad hoc aliasing doesn't have cliques larger than pairs. It seems unlikely that any target would need more. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@156763 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/CodeGenRegisters.cpp53
1 files changed, 41 insertions, 12 deletions
diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp
index 797c31a934..1a22dc24f2 100644
--- a/utils/TableGen/CodeGenRegisters.cpp
+++ b/utils/TableGen/CodeGenRegisters.cpp
@@ -360,20 +360,49 @@ CodeGenRegister::computeSubRegs(CodeGenRegBank &RegBank) {
RegBank.addConcatSubRegIndex(Parts, ExplicitSubRegIndices[i]);
}
- // Initialize RegUnitList. A register with no subregisters creates its own
- // unit. Otherwise, it inherits all its subregister's units. Because
- // getSubRegs is called recursively, this processes the register hierarchy in
- // postorder.
+ // Initialize RegUnitList. Because getSubRegs is called recursively, this
+ // processes the register hierarchy in postorder.
//
- // TODO: We currently assume all register units correspond to a named "leaf"
- // register. We should also unify register units for ad-hoc register
- // aliases. This can be done by iteratively merging units for aliasing
- // registers using a worklist.
- assert(RegUnits.empty() && "Should only initialize RegUnits once");
- if (SubRegs.empty())
+ // Inherit all sub-register units. It is good enough to look at the explicit
+ // sub-registers, the other registers won't contribute any more units.
+ for (unsigned i = 0, e = ExplicitSubRegs.size(); i != e; ++i) {
+ CodeGenRegister *SR = ExplicitSubRegs[i];
+ // Explicit sub-registers are usually disjoint, so this is a good way of
+ // computing the union. We may pick up a few duplicates that will be
+ // eliminated below.
+ unsigned N = RegUnits.size();
+ RegUnits.append(SR->RegUnits.begin(), SR->RegUnits.end());
+ std::inplace_merge(RegUnits.begin(), RegUnits.begin() + N, RegUnits.end());
+ }
+ RegUnits.erase(std::unique(RegUnits.begin(), RegUnits.end()), RegUnits.end());
+
+ // Absent any ad hoc aliasing, we create one register unit per leaf register.
+ // These units correspond to the maximal cliques in the register overlap
+ // graph which is optimal.
+ //
+ // When there is ad hoc aliasing, we simply create one unit per edge in the
+ // undirected ad hoc aliasing graph. Technically, we could do better by
+ // identifying maximal cliques in the ad hoc graph, but cliques larger than 2
+ // are extremely rare anyway (I've never seen one), so we don't bother with
+ // the added complexity.
+ for (unsigned i = 0, e = ExplicitAliases.size(); i != e; ++i) {
+ CodeGenRegister *AR = ExplicitAliases[i];
+ // Only visit each edge once.
+ if (AR->SubRegsComplete)
+ continue;
+ // Create a RegUnit representing this alias edge, and add it to both
+ // registers.
+ unsigned Unit = RegBank.newRegUnit(0);
+ RegUnits.push_back(Unit);
+ AR->RegUnits.push_back(Unit);
+ }
+
+ // Finally, create units for leaf registers without ad hoc aliases. Note that
+ // a leaf register with ad hoc aliases doesn't get its own unit - it isn't
+ // necessary. This means the aliasing leaf registers can share a single unit.
+ if (RegUnits.empty())
RegUnits.push_back(RegBank.newRegUnit(0));
- else
- inheritRegUnits(RegBank);
+
return SubRegs;
}