aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;
}