forked from OSchip/llvm-project
Table-generated register pressure fixes.
Handle mixing allocatable and unallocatable register gracefully. Simplify the pruning of register unit sets. llvm-svn: 154474
This commit is contained in:
parent
3ef01cdb2e
commit
0d94c73c26
|
@ -945,22 +945,34 @@ static void computeUberSets(std::vector<UberRegSet> &UberSets,
|
||||||
|
|
||||||
// For simplicitly make the SetID the same as EnumValue.
|
// For simplicitly make the SetID the same as EnumValue.
|
||||||
IntEqClasses UberSetIDs(Registers.size()+1);
|
IntEqClasses UberSetIDs(Registers.size()+1);
|
||||||
|
std::set<unsigned> AllocatableRegs;
|
||||||
for (unsigned i = 0, e = RegBank.getRegClasses().size(); i != e; ++i) {
|
for (unsigned i = 0, e = RegBank.getRegClasses().size(); i != e; ++i) {
|
||||||
|
|
||||||
CodeGenRegisterClass *RegClass = RegBank.getRegClasses()[i];
|
CodeGenRegisterClass *RegClass = RegBank.getRegClasses()[i];
|
||||||
|
if (!RegClass->Allocatable)
|
||||||
|
continue;
|
||||||
|
|
||||||
const CodeGenRegister::Set &Regs = RegClass->getMembers();
|
const CodeGenRegister::Set &Regs = RegClass->getMembers();
|
||||||
if (Regs.empty()) continue;
|
if (Regs.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
unsigned USetID = UberSetIDs.findLeader((*Regs.begin())->EnumValue);
|
unsigned USetID = UberSetIDs.findLeader((*Regs.begin())->EnumValue);
|
||||||
assert(USetID && "register number 0 is invalid");
|
assert(USetID && "register number 0 is invalid");
|
||||||
|
|
||||||
// combine non-allocatable classes
|
AllocatableRegs.insert((*Regs.begin())->EnumValue);
|
||||||
if (!RegClass->Allocatable) {
|
|
||||||
UberSetIDs.join(0, USetID);
|
|
||||||
USetID = 0;
|
|
||||||
}
|
|
||||||
for (CodeGenRegister::Set::const_iterator I = llvm::next(Regs.begin()),
|
for (CodeGenRegister::Set::const_iterator I = llvm::next(Regs.begin()),
|
||||||
E = Regs.end(); I != E; ++I)
|
E = Regs.end(); I != E; ++I) {
|
||||||
|
AllocatableRegs.insert((*I)->EnumValue);
|
||||||
UberSetIDs.join(USetID, (*I)->EnumValue);
|
UberSetIDs.join(USetID, (*I)->EnumValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Combine non-allocatable regs.
|
||||||
|
for (unsigned i = 0, e = Registers.size(); i != e; ++i) {
|
||||||
|
unsigned RegNum = Registers[i]->EnumValue;
|
||||||
|
if (AllocatableRegs.count(RegNum))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
UberSetIDs.join(0, RegNum);
|
||||||
}
|
}
|
||||||
UberSetIDs.compress();
|
UberSetIDs.compress();
|
||||||
|
|
||||||
|
@ -1155,29 +1167,34 @@ void CodeGenRegBank::pruneUnitSets() {
|
||||||
assert(RegClassUnitSets.empty() && "this invalidates RegClassUnitSets");
|
assert(RegClassUnitSets.empty() && "this invalidates RegClassUnitSets");
|
||||||
|
|
||||||
// Form an equivalence class of UnitSets with no significant difference.
|
// Form an equivalence class of UnitSets with no significant difference.
|
||||||
IntEqClasses RepUnitSetIDs(RegUnitSets.size());
|
// Populate PrunedUnitSets with each equivalence class's superset.
|
||||||
|
std::vector<RegUnitSet> PrunedUnitSets;
|
||||||
for (unsigned SubIdx = 0, EndIdx = RegUnitSets.size();
|
for (unsigned SubIdx = 0, EndIdx = RegUnitSets.size();
|
||||||
SubIdx != EndIdx; ++SubIdx) {
|
SubIdx != EndIdx; ++SubIdx) {
|
||||||
const RegUnitSet &SubSet = RegUnitSets[SubIdx];
|
const RegUnitSet &SubSet = RegUnitSets[SubIdx];
|
||||||
for (unsigned SuperIdx = 0; SuperIdx != EndIdx; ++SuperIdx) {
|
unsigned SuperIdx = 0;
|
||||||
|
for (; SuperIdx != EndIdx; ++SuperIdx) {
|
||||||
if (SuperIdx == SubIdx)
|
if (SuperIdx == SubIdx)
|
||||||
continue;
|
continue;
|
||||||
|
const RegUnitSet *SuperSet = 0;
|
||||||
const RegUnitSet &SuperSet = RegUnitSets[SuperIdx];
|
if (SuperIdx > SubIdx)
|
||||||
if (isRegUnitSubSet(SubSet.Units, SuperSet.Units)
|
SuperSet = &RegUnitSets[SuperIdx];
|
||||||
&& (SubSet.Units.size() + 3 > SuperSet.Units.size())) {
|
else {
|
||||||
RepUnitSetIDs.join(SubIdx, SuperIdx);
|
// Compare with already-pruned sets.
|
||||||
|
if (SuperIdx >= PrunedUnitSets.size())
|
||||||
|
continue;
|
||||||
|
SuperSet = &PrunedUnitSets[SuperIdx];
|
||||||
|
}
|
||||||
|
if (isRegUnitSubSet(SubSet.Units, SuperSet->Units)
|
||||||
|
&& (SubSet.Units.size() + 3 > SuperSet->Units.size())) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (SuperIdx != EndIdx)
|
||||||
RepUnitSetIDs.compress();
|
continue;
|
||||||
|
PrunedUnitSets.resize(PrunedUnitSets.size()+1);
|
||||||
// Populate PrunedUnitSets with each equivalence class's superset.
|
PrunedUnitSets.back().Name = RegUnitSets[SubIdx].Name;
|
||||||
std::vector<RegUnitSet> PrunedUnitSets(RepUnitSetIDs.getNumClasses());
|
PrunedUnitSets.back().Units.swap(RegUnitSets[SubIdx].Units);
|
||||||
for (unsigned i = 0, e = RegUnitSets.size(); i != e; ++i) {
|
|
||||||
RegUnitSet &SuperSet = PrunedUnitSets[RepUnitSetIDs[i]];
|
|
||||||
if (SuperSet.Units.size() < RegUnitSets[i].Units.size())
|
|
||||||
SuperSet = RegUnitSets[i];
|
|
||||||
}
|
}
|
||||||
RegUnitSets.swap(PrunedUnitSets);
|
RegUnitSets.swap(PrunedUnitSets);
|
||||||
}
|
}
|
||||||
|
@ -1195,6 +1212,8 @@ void CodeGenRegBank::computeRegUnitSets() {
|
||||||
const ArrayRef<CodeGenRegisterClass*> &RegClasses = getRegClasses();
|
const ArrayRef<CodeGenRegisterClass*> &RegClasses = getRegClasses();
|
||||||
unsigned NumRegClasses = RegClasses.size();
|
unsigned NumRegClasses = RegClasses.size();
|
||||||
for (unsigned RCIdx = 0, RCEnd = NumRegClasses; RCIdx != RCEnd; ++RCIdx) {
|
for (unsigned RCIdx = 0, RCEnd = NumRegClasses; RCIdx != RCEnd; ++RCIdx) {
|
||||||
|
if (!RegClasses[RCIdx]->Allocatable)
|
||||||
|
continue;
|
||||||
|
|
||||||
// Speculatively grow the RegUnitSets to hold the new set.
|
// Speculatively grow the RegUnitSets to hold the new set.
|
||||||
RegUnitSets.resize(RegUnitSets.size() + 1);
|
RegUnitSets.resize(RegUnitSets.size() + 1);
|
||||||
|
@ -1253,12 +1272,15 @@ void CodeGenRegBank::computeRegUnitSets() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iteratively prune unit sets again after inferring supersets.
|
// Iteratively prune unit sets after inferring supersets.
|
||||||
pruneUnitSets();
|
pruneUnitSets();
|
||||||
|
|
||||||
// For each register class, list the UnitSets that are supersets.
|
// For each register class, list the UnitSets that are supersets.
|
||||||
RegClassUnitSets.resize(NumRegClasses);
|
RegClassUnitSets.resize(NumRegClasses);
|
||||||
for (unsigned RCIdx = 0, RCEnd = NumRegClasses; RCIdx != RCEnd; ++RCIdx) {
|
for (unsigned RCIdx = 0, RCEnd = NumRegClasses; RCIdx != RCEnd; ++RCIdx) {
|
||||||
|
if (!RegClasses[RCIdx]->Allocatable)
|
||||||
|
continue;
|
||||||
|
|
||||||
// Recompute the sorted list of units in this class.
|
// Recompute the sorted list of units in this class.
|
||||||
std::vector<unsigned> RegUnits;
|
std::vector<unsigned> RegUnits;
|
||||||
buildRegUnitSet(RegClasses[RCIdx]->getMembers(), RegUnits);
|
buildRegUnitSet(RegClasses[RCIdx]->getMembers(), RegUnits);
|
||||||
|
@ -1273,6 +1295,7 @@ void CodeGenRegBank::computeRegUnitSets() {
|
||||||
if (isRegUnitSubSet(RegUnits, RegUnitSets[USIdx].Units))
|
if (isRegUnitSubSet(RegUnits, RegUnitSets[USIdx].Units))
|
||||||
RegClassUnitSets[RCIdx].push_back(USIdx);
|
RegClassUnitSets[RCIdx].push_back(USIdx);
|
||||||
}
|
}
|
||||||
|
assert(!RegClassUnitSets[RCIdx].empty() && "missing unit set for regclass");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue