[regalloc] More aggressively reuse spill ranges for phi inputs

The register allocator has an optimization that makes it try reuse
spill-slots between phi-inputs and assign the same spill slot to a phi
output, if possible.
Furthermore, if the phi has no immediate register use, the output is
kept spilled.

With this change, no longer require that a phi input was spilled in an
immediate predecessor. Instead, it is good enough if it was spilled
at definition.

Change-Id: I317b9d5f9a9dda6a47972cdf84dc2627b996f3db
Reviewed-on: https://chromium-review.googlesource.com/c/1273053
Commit-Queue: Stephan Herhut <herhut@chromium.org>
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56594}
This commit is contained in:
Stephan Herhut 2018-10-12 10:41:25 +02:00 committed by Commit Bot
parent 85b7f1cd91
commit b79cbd5615

View File

@ -3355,7 +3355,6 @@ bool LinearScanAllocator::TryReuseSpillForPhi(TopLevelLiveRange* range) {
RegisterAllocationData::PhiMapValue* phi_map_value =
data()->GetPhiMapValueFor(range);
const PhiInstruction* phi = phi_map_value->phi();
const InstructionBlock* block = phi_map_value->block();
// Count the number of spilled operands.
size_t spilled_count = 0;
LiveRange* first_op = nullptr;
@ -3363,15 +3362,9 @@ bool LinearScanAllocator::TryReuseSpillForPhi(TopLevelLiveRange* range) {
int op = phi->operands()[i];
LiveRange* op_range = data()->GetOrCreateLiveRangeFor(op);
if (!op_range->TopLevel()->HasSpillRange()) continue;
const InstructionBlock* pred =
code()->InstructionBlockAt(block->predecessors()[i]);
LifetimePosition pred_end =
LifetimePosition::InstructionFromInstructionIndex(
pred->last_instruction_index());
while (op_range != nullptr && !op_range->CanCover(pred_end)) {
op_range = op_range->next();
}
if (op_range != nullptr && op_range->spilled()) {
if (!op_range->TopLevel()->IsSpilledOnlyInDeferredBlocks()) {
// This value was spilled at definition, so it is available in a spillslot
// regardless of control flow.
spilled_count++;
if (first_op == nullptr) {
first_op = op_range->TopLevel();