Commit 4c5c5715 by Jim Stichnoth

Subzero: Fix a performance regression in the register allocator.

The register allocator does not need to be considering rematerializable variables at all. When it does, there tends to be a big performance cost because the live range of a rematerializable variable tends to be large, leading to lots of expensive overlap computations against register allocation candidates. BUG= none R=jpp@chromium.org, sehr@chromium.org Review URL: https://codereview.chromium.org/1450233002 .
parent 0d9cf487
...@@ -98,6 +98,9 @@ void LinearScan::initForGlobal() { ...@@ -98,6 +98,9 @@ void LinearScan::initForGlobal() {
UnhandledPrecolored.reserve(Vars.size()); UnhandledPrecolored.reserve(Vars.size());
// Gather the live ranges of all variables and add them to the Unhandled set. // Gather the live ranges of all variables and add them to the Unhandled set.
for (Variable *Var : Vars) { for (Variable *Var : Vars) {
// Don't consider rematerializable variables.
if (Var->isRematerializable())
continue;
// Explicitly don't consider zero-weight variables, which are meant to be // Explicitly don't consider zero-weight variables, which are meant to be
// spill slots. // spill slots.
if (Var->mustNotHaveReg()) if (Var->mustNotHaveReg())
...@@ -201,6 +204,8 @@ void LinearScan::initForInfOnly() { ...@@ -201,6 +204,8 @@ void LinearScan::initForInfOnly() {
if (Inst.isDeleted()) if (Inst.isDeleted())
continue; continue;
FOREACH_VAR_IN_INST(Var, Inst) { FOREACH_VAR_IN_INST(Var, Inst) {
if (Var->isRematerializable())
continue;
if (Var->getIgnoreLiveness()) if (Var->getIgnoreLiveness())
continue; continue;
if (Var->hasReg() || Var->mustHaveReg()) { if (Var->hasReg() || Var->mustHaveReg()) {
...@@ -211,7 +216,7 @@ void LinearScan::initForInfOnly() { ...@@ -211,7 +216,7 @@ void LinearScan::initForInfOnly() {
} }
} }
if (const Variable *Var = Inst.getDest()) { if (const Variable *Var = Inst.getDest()) {
if (!Var->getIgnoreLiveness() && if (!Var->isRematerializable() && !Var->getIgnoreLiveness() &&
(Var->hasReg() || Var->mustHaveReg())) { (Var->hasReg() || Var->mustHaveReg())) {
if (LRBegin[Var->getIndex()] == Inst::NumberSentinel) { if (LRBegin[Var->getIndex()] == Inst::NumberSentinel) {
LRBegin[Var->getIndex()] = Inst.getNumber(); LRBegin[Var->getIndex()] = Inst.getNumber();
...@@ -226,6 +231,8 @@ void LinearScan::initForInfOnly() { ...@@ -226,6 +231,8 @@ void LinearScan::initForInfOnly() {
UnhandledPrecolored.reserve(NumVars); UnhandledPrecolored.reserve(NumVars);
for (SizeT i = 0; i < Vars.size(); ++i) { for (SizeT i = 0; i < Vars.size(); ++i) {
Variable *Var = Vars[i]; Variable *Var = Vars[i];
if (Var->isRematerializable())
continue;
if (LRBegin[i] != Inst::NumberSentinel) { if (LRBegin[i] != Inst::NumberSentinel) {
if (LREnd[i] == Inst::NumberSentinel) { if (LREnd[i] == Inst::NumberSentinel) {
DefsWithoutUses.push_back(i); DefsWithoutUses.push_back(i);
...@@ -284,6 +291,8 @@ void LinearScan::initForSecondChance() { ...@@ -284,6 +291,8 @@ void LinearScan::initForSecondChance() {
Unhandled.reserve(Vars.size()); Unhandled.reserve(Vars.size());
UnhandledPrecolored.reserve(Vars.size()); UnhandledPrecolored.reserve(Vars.size());
for (Variable *Var : Vars) { for (Variable *Var : Vars) {
if (Var->isRematerializable())
continue;
if (Var->hasReg()) { if (Var->hasReg()) {
Var->untrimLiveRange(); Var->untrimLiveRange();
Var->setRegNumTmp(Var->getRegNum()); Var->setRegNumTmp(Var->getRegNum());
...@@ -567,6 +576,8 @@ void LinearScan::filterFreeWithInactiveRanges(IterationState &Iter) { ...@@ -567,6 +576,8 @@ void LinearScan::filterFreeWithInactiveRanges(IterationState &Iter) {
// early exit check that turns a guaranteed O(N^2) algorithm into expected // early exit check that turns a guaranteed O(N^2) algorithm into expected
// linear complexity. // linear complexity.
void LinearScan::filterFreeWithPrecoloredRanges(IterationState &Iter) { void LinearScan::filterFreeWithPrecoloredRanges(IterationState &Iter) {
// TODO(stichnot): Partition UnhandledPrecolored according to register class,
// to restrict the number of overlap comparisons needed.
for (Variable *Item : reverse_range(UnhandledPrecolored)) { for (Variable *Item : reverse_range(UnhandledPrecolored)) {
assert(Item->hasReg()); assert(Item->hasReg());
if (Iter.Cur->rangeEndsBefore(Item)) if (Iter.Cur->rangeEndsBefore(Item))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment