Commit 3fb75906 authored by Yolanda Chen's avatar Yolanda Chen Committed by Commit Bot

[regalloc] Find optimal spilling position when spill range to end

When spill a range without register uses inside a loop, it is beneficial to spill the range ealier at the loop header to reduce memory moves from the back edges.

The changes to FindOptimalSpillingPos are motivated as follows:
 - Change “next_use->pos() < pos” to “next_use->pos() <= pos”.
  The former version causes a crash of mksnapshot in debug build,
  because it is possible that a UsePosition at a split point gets split
  to the previous range according to “DetachAt”. For example, we
  have a live range with:
    UseIntervals: [1, 20[
    UsePosition: 10
  When split the live range at position 10, we will get:
    Range 0:0: UseInterval: [1, 10[
               UsePosition: 10
    Range 0:1: UseInterval: [10, 20[

 - Change “NextUsePositionRegisterIsBenefitial” to
   “NextRegisterPosition”, because there’s always a
   “Define” use position at the loop header for those phis
   that do not require a register. Using the original check
   will hence not apply the optimization.


Change-Id: I3b0bb3687ba572f1d3fc1892cefae7e866d99baa
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2094964Reviewed-by: 's avatarSigurd Schneider <sigurds@chromium.org>
Reviewed-by: 's avatarThibaud Michaud <thibaudm@chromium.org>
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Commit-Queue: Yolanda Chen <yolanda.chen@intel.com>
Cr-Commit-Position: refs/heads/master@{#66806}
parent f6b185ca
......@@ -3016,13 +3016,14 @@ LifetimePosition RegisterAllocator::FindOptimalSpillingPos(
LiveRange* check_use = live_at_header;
for (; check_use != nullptr && check_use->Start() < pos;
check_use = check_use->next()) {
UsePosition* next_use =
check_use->NextUsePositionRegisterIsBeneficial(loop_start);
if (next_use != nullptr && next_use->pos() < pos) {
UsePosition* next_use = check_use->NextRegisterPosition(loop_start);
// UsePosition at the end of a UseInterval may
// have the same value as the start of next range.
if (next_use != nullptr && next_use->pos() <= pos) {
return pos;
}
}
// No register beneficial use inside the loop before the pos.
// No register use inside the loop before the pos.
*begin_spill_out = live_at_header;
pos = loop_start;
break;
......@@ -4323,6 +4324,10 @@ void LinearScanAllocator::AllocateBlockedReg(LiveRange* current,
if (register_use == nullptr) {
// There is no use in the current live range that requires a register.
// We can just spill it.
LiveRange* begin_spill = nullptr;
LifetimePosition spill_pos = FindOptimalSpillingPos(
current, current->Start(), spill_mode, &begin_spill);
MaybeSpillPreviousRanges(begin_spill, spill_pos, current);
Spill(current, spill_mode);
return;
}
......
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