mirror of
https://github.com/RPCS3/llvm.git
synced 2024-11-26 05:00:39 +00:00
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
This commit is contained in:
parent
31d938a6b1
commit
f402602199
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user