summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/backend/register-allocator.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/backend/register-allocator.cc')
-rw-r--r--deps/v8/src/compiler/backend/register-allocator.cc344
1 files changed, 180 insertions, 164 deletions
diff --git a/deps/v8/src/compiler/backend/register-allocator.cc b/deps/v8/src/compiler/backend/register-allocator.cc
index 21eef0485c..945554eb32 100644
--- a/deps/v8/src/compiler/backend/register-allocator.cc
+++ b/deps/v8/src/compiler/backend/register-allocator.cc
@@ -6,7 +6,7 @@
#include <iomanip>
-#include "src/base/adapters.h"
+#include "src/base/iterator.h"
#include "src/base/small-vector.h"
#include "src/codegen/assembler-inl.h"
#include "src/codegen/tick-counter.h"
@@ -317,7 +317,6 @@ UsePositionHintType UsePosition::HintTypeForOperand(
switch (op.kind()) {
case InstructionOperand::CONSTANT:
case InstructionOperand::IMMEDIATE:
- case InstructionOperand::EXPLICIT:
return UsePositionHintType::kNone;
case InstructionOperand::UNALLOCATED:
return UsePositionHintType::kUnresolved;
@@ -797,12 +796,13 @@ LifetimePosition LiveRange::NextEndAfter(LifetimePosition position) const {
return start_search->end();
}
-LifetimePosition LiveRange::NextStartAfter(LifetimePosition position) const {
+LifetimePosition LiveRange::NextStartAfter(LifetimePosition position) {
UseInterval* start_search = FirstSearchIntervalForPosition(position);
while (start_search->start() < position) {
start_search = start_search->next();
}
- return start_search->start();
+ next_start_ = start_search->start();
+ return next_start_;
}
LifetimePosition LiveRange::FirstIntersection(LiveRange* other) const {
@@ -1940,8 +1940,8 @@ void ConstraintBuilder::MeetConstraintsBefore(int instr_index) {
// Handle fixed input operands of second instruction.
for (size_t i = 0; i < second->InputCount(); i++) {
InstructionOperand* input = second->InputAt(i);
- if (input->IsImmediate() || input->IsExplicit()) {
- continue; // Ignore immediates and explicitly reserved registers.
+ if (input->IsImmediate()) {
+ continue; // Ignore immediates.
}
UnallocatedOperand* cur_input = UnallocatedOperand::cast(input);
if (cur_input->HasFixedPolicy()) {
@@ -2323,8 +2323,8 @@ void LiveRangeBuilder::ProcessInstructions(const InstructionBlock* block,
for (size_t i = 0; i < instr->InputCount(); i++) {
InstructionOperand* input = instr->InputAt(i);
- if (input->IsImmediate() || input->IsExplicit()) {
- continue; // Ignore immediates and explicitly reserved registers.
+ if (input->IsImmediate()) {
+ continue; // Ignore immediates.
}
LifetimePosition use_pos;
if (input->IsUnallocated() &&
@@ -2504,10 +2504,10 @@ void LiveRangeBuilder::ProcessPhis(const InstructionBlock* block,
predecessor_hint_preference |= kNotDeferredBlockPreference;
}
- // - Prefer hints from allocated (or explicit) operands.
+ // - Prefer hints from allocated operands.
//
- // Already-allocated or explicit operands are typically assigned using
- // the parallel moves on the last instruction. For example:
+ // Already-allocated operands are typically assigned using the parallel
+ // moves on the last instruction. For example:
//
// gap (v101 = [x0|R|w32]) (v100 = v101)
// ArchJmp
@@ -2515,7 +2515,7 @@ void LiveRangeBuilder::ProcessPhis(const InstructionBlock* block,
// phi: v100 = v101 v102
//
// We have already found the END move, so look for a matching START move
- // from an allocated (or explicit) operand.
+ // from an allocated operand.
//
// Note that we cannot simply look up data()->live_ranges()[vreg] here
// because the live ranges are still being built when this function is
@@ -2527,7 +2527,7 @@ void LiveRangeBuilder::ProcessPhis(const InstructionBlock* block,
for (MoveOperands* move : *moves) {
InstructionOperand& to = move->destination();
if (predecessor_hint->Equals(to)) {
- if (move->source().IsAllocated() || move->source().IsExplicit()) {
+ if (move->source().IsAllocated()) {
predecessor_hint_preference |= kMoveIsAllocatedPreference;
}
break;
@@ -3095,11 +3095,11 @@ LinearScanAllocator::LinearScanAllocator(RegisterAllocationData* data,
: RegisterAllocator(data, kind),
unhandled_live_ranges_(local_zone),
active_live_ranges_(local_zone),
- inactive_live_ranges_(local_zone),
+ inactive_live_ranges_(num_registers(), InactiveLiveRangeQueue(local_zone),
+ local_zone),
next_active_ranges_change_(LifetimePosition::Invalid()),
next_inactive_ranges_change_(LifetimePosition::Invalid()) {
active_live_ranges().reserve(8);
- inactive_live_ranges().reserve(8);
}
void LinearScanAllocator::MaybeSpillPreviousRanges(LiveRange* begin_range,
@@ -3143,15 +3143,15 @@ void LinearScanAllocator::MaybeUndoPreviousSplit(LiveRange* range) {
}
}
-void LinearScanAllocator::SpillNotLiveRanges(RangeWithRegisterSet& to_be_live,
+void LinearScanAllocator::SpillNotLiveRanges(RangeWithRegisterSet* to_be_live,
LifetimePosition position,
SpillMode spill_mode) {
for (auto it = active_live_ranges().begin();
it != active_live_ranges().end();) {
LiveRange* active_range = *it;
TopLevelLiveRange* toplevel = (*it)->TopLevel();
- auto found = to_be_live.find({toplevel, kUnassignedRegister});
- if (found == to_be_live.end()) {
+ auto found = to_be_live->find({toplevel, kUnassignedRegister});
+ if (found == to_be_live->end()) {
// Is not contained in {to_be_live}, spill it.
// Fixed registers are exempt from this. They might have been
// added from inactive at the block boundary but we know that
@@ -3207,7 +3207,7 @@ void LinearScanAllocator::SpillNotLiveRanges(RangeWithRegisterSet& to_be_live,
} else {
// This range is contained in {to_be_live}, so we can keep it.
int expected_register = (*found).expected_register;
- to_be_live.erase(found);
+ to_be_live->erase(found);
if (expected_register == active_range->assigned_register()) {
// Was life and in correct register, simply pass through.
TRACE("Keeping %d:%d in %s\n", toplevel->vreg(),
@@ -3238,31 +3238,22 @@ LiveRange* LinearScanAllocator::AssignRegisterOnReload(LiveRange* range,
// give reloading registers pecedence. That way we would compute the
// intersection for the entire future.
LifetimePosition new_end = range->End();
- for (const auto inactive : inactive_live_ranges()) {
- if (kSimpleFPAliasing || !check_fp_aliasing()) {
- if (inactive->assigned_register() != reg) continue;
- } else {
- bool conflict = inactive->assigned_register() == reg;
- if (!conflict) {
- int alias_base_index = -1;
- int aliases = data()->config()->GetAliases(range->representation(), reg,
- inactive->representation(),
- &alias_base_index);
- DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1));
- while (aliases-- && !conflict) {
- int aliased_reg = alias_base_index + aliases;
- if (aliased_reg == reg) {
- conflict = true;
- }
- }
- }
- if (!conflict) continue;
+ for (int cur_reg = 0; cur_reg < num_registers(); ++cur_reg) {
+ if ((kSimpleFPAliasing || !check_fp_aliasing()) && cur_reg != reg) {
+ continue;
}
- for (auto interval = inactive->first_interval(); interval != nullptr;
- interval = interval->next()) {
- if (interval->start() > new_end) break;
- if (interval->end() <= range->Start()) continue;
- if (new_end > interval->start()) new_end = interval->start();
+ for (const auto cur_inactive : inactive_live_ranges(cur_reg)) {
+ if (!kSimpleFPAliasing && check_fp_aliasing() &&
+ !data()->config()->AreAliases(cur_inactive->representation(), cur_reg,
+ range->representation(), reg)) {
+ continue;
+ }
+ for (auto interval = cur_inactive->first_interval(); interval != nullptr;
+ interval = interval->next()) {
+ if (interval->start() > new_end) break;
+ if (interval->end() <= range->Start()) continue;
+ if (new_end > interval->start()) new_end = interval->start();
+ }
}
}
if (new_end != range->End()) {
@@ -3275,8 +3266,8 @@ LiveRange* LinearScanAllocator::AssignRegisterOnReload(LiveRange* range,
return range;
}
-void LinearScanAllocator::ReloadLiveRanges(RangeWithRegisterSet& to_be_live,
- LifetimePosition position) {
+void LinearScanAllocator::ReloadLiveRanges(
+ RangeWithRegisterSet const& to_be_live, LifetimePosition position) {
// Assumption: All ranges in {to_be_live} are currently spilled and there are
// no conflicting registers in the active ranges.
// The former is ensured by SpillNotLiveRanges, the latter is by construction
@@ -3558,11 +3549,17 @@ void LinearScanAllocator::UpdateDeferredFixedRanges(SpillMode spill_mode,
Min(updated->End(), next_active_ranges_change_);
});
}
- for (auto inactive : inactive_live_ranges()) {
- split_conflicting(range, inactive, [this](LiveRange* updated) {
- next_inactive_ranges_change_ =
- Min(updated->End(), next_inactive_ranges_change_);
- });
+ for (int reg = 0; reg < num_registers(); ++reg) {
+ if ((kSimpleFPAliasing || !check_fp_aliasing()) &&
+ reg != range->assigned_register()) {
+ continue;
+ }
+ for (auto inactive : inactive_live_ranges(reg)) {
+ split_conflicting(range, inactive, [this](LiveRange* updated) {
+ next_inactive_ranges_change_ =
+ Min(updated->End(), next_inactive_ranges_change_);
+ });
+ }
}
};
if (mode() == GENERAL_REGISTERS) {
@@ -3600,12 +3597,14 @@ void LinearScanAllocator::UpdateDeferredFixedRanges(SpillMode spill_mode,
}
} else {
// Remove all ranges.
- for (auto it = inactive_live_ranges().begin();
- it != inactive_live_ranges().end();) {
- if ((*it)->TopLevel()->IsDeferredFixed()) {
- it = inactive_live_ranges().erase(it);
- } else {
- ++it;
+ for (int reg = 0; reg < num_registers(); ++reg) {
+ for (auto it = inactive_live_ranges(reg).begin();
+ it != inactive_live_ranges(reg).end();) {
+ if ((*it)->TopLevel()->IsDeferredFixed()) {
+ it = inactive_live_ranges(reg).erase(it);
+ } else {
+ ++it;
+ }
}
}
}
@@ -3636,7 +3635,9 @@ bool LinearScanAllocator::HasNonDeferredPredecessor(InstructionBlock* block) {
void LinearScanAllocator::AllocateRegisters() {
DCHECK(unhandled_live_ranges().empty());
DCHECK(active_live_ranges().empty());
- DCHECK(inactive_live_ranges().empty());
+ for (int reg = 0; reg < num_registers(); ++reg) {
+ DCHECK(inactive_live_ranges(reg).empty());
+ }
SplitAndSpillRangesDefinedByMemoryOperand();
data()->ResetSpillState();
@@ -3853,7 +3854,7 @@ void LinearScanAllocator::AllocateRegisters() {
}
if (!no_change_required) {
- SpillNotLiveRanges(to_be_live, next_block_boundary, spill_mode);
+ SpillNotLiveRanges(&to_be_live, next_block_boundary, spill_mode);
ReloadLiveRanges(to_be_live, next_block_boundary);
}
@@ -3941,9 +3942,10 @@ void LinearScanAllocator::AddToActive(LiveRange* range) {
void LinearScanAllocator::AddToInactive(LiveRange* range) {
TRACE("Add live range %d:%d to inactive\n", range->TopLevel()->vreg(),
range->relative_id());
- inactive_live_ranges().push_back(range);
next_inactive_ranges_change_ = std::min(
next_inactive_ranges_change_, range->NextStartAfter(range->Start()));
+ DCHECK(range->HasRegisterAssigned());
+ inactive_live_ranges(range->assigned_register()).insert(range);
}
void LinearScanAllocator::AddToUnhandled(LiveRange* range) {
@@ -3966,30 +3968,36 @@ ZoneVector<LiveRange*>::iterator LinearScanAllocator::ActiveToHandled(
ZoneVector<LiveRange*>::iterator LinearScanAllocator::ActiveToInactive(
const ZoneVector<LiveRange*>::iterator it, LifetimePosition position) {
LiveRange* range = *it;
- inactive_live_ranges().push_back(range);
TRACE("Moving live range %d:%d from active to inactive\n",
(range)->TopLevel()->vreg(), range->relative_id());
+ LifetimePosition next_active = range->NextStartAfter(position);
next_inactive_ranges_change_ =
- std::min(next_inactive_ranges_change_, range->NextStartAfter(position));
+ std::min(next_inactive_ranges_change_, next_active);
+ DCHECK(range->HasRegisterAssigned());
+ inactive_live_ranges(range->assigned_register()).insert(range);
return active_live_ranges().erase(it);
}
-ZoneVector<LiveRange*>::iterator LinearScanAllocator::InactiveToHandled(
- ZoneVector<LiveRange*>::iterator it) {
+LinearScanAllocator::InactiveLiveRangeQueue::iterator
+LinearScanAllocator::InactiveToHandled(InactiveLiveRangeQueue::iterator it) {
+ LiveRange* range = *it;
TRACE("Moving live range %d:%d from inactive to handled\n",
- (*it)->TopLevel()->vreg(), (*it)->relative_id());
- return inactive_live_ranges().erase(it);
+ range->TopLevel()->vreg(), range->relative_id());
+ int reg = range->assigned_register();
+ return inactive_live_ranges(reg).erase(it);
}
-ZoneVector<LiveRange*>::iterator LinearScanAllocator::InactiveToActive(
- ZoneVector<LiveRange*>::iterator it, LifetimePosition position) {
+LinearScanAllocator::InactiveLiveRangeQueue::iterator
+LinearScanAllocator::InactiveToActive(InactiveLiveRangeQueue::iterator it,
+ LifetimePosition position) {
LiveRange* range = *it;
active_live_ranges().push_back(range);
TRACE("Moving live range %d:%d from inactive to active\n",
range->TopLevel()->vreg(), range->relative_id());
next_active_ranges_change_ =
std::min(next_active_ranges_change_, range->NextEndAfter(position));
- return inactive_live_ranges().erase(it);
+ int reg = range->assigned_register();
+ return inactive_live_ranges(reg).erase(it);
}
void LinearScanAllocator::ForwardStateTo(LifetimePosition position) {
@@ -4012,18 +4020,25 @@ void LinearScanAllocator::ForwardStateTo(LifetimePosition position) {
if (position >= next_inactive_ranges_change_) {
next_inactive_ranges_change_ = LifetimePosition::MaxPosition();
- for (auto it = inactive_live_ranges().begin();
- it != inactive_live_ranges().end();) {
- LiveRange* cur_inactive = *it;
- if (cur_inactive->End() <= position) {
- it = InactiveToHandled(it);
- } else if (cur_inactive->Covers(position)) {
- it = InactiveToActive(it, position);
- } else {
- next_inactive_ranges_change_ =
- std::min(next_inactive_ranges_change_,
- cur_inactive->NextStartAfter(position));
- ++it;
+ for (int reg = 0; reg < num_registers(); ++reg) {
+ ZoneVector<LiveRange*> reorder(data()->allocation_zone());
+ for (auto it = inactive_live_ranges(reg).begin();
+ it != inactive_live_ranges(reg).end();) {
+ LiveRange* cur_inactive = *it;
+ if (cur_inactive->End() <= position) {
+ it = InactiveToHandled(it);
+ } else if (cur_inactive->Covers(position)) {
+ it = InactiveToActive(it, position);
+ } else {
+ next_inactive_ranges_change_ =
+ std::min(next_inactive_ranges_change_,
+ cur_inactive->NextStartAfter(position));
+ it = inactive_live_ranges(reg).erase(it);
+ reorder.push_back(cur_inactive);
+ }
+ }
+ for (LiveRange* range : reorder) {
+ inactive_live_ranges(reg).insert(range);
}
}
}
@@ -4094,31 +4109,34 @@ void LinearScanAllocator::FindFreeRegistersForRange(
}
}
- for (LiveRange* cur_inactive : inactive_live_ranges()) {
- DCHECK(cur_inactive->End() > range->Start());
- int cur_reg = cur_inactive->assigned_register();
- // No need to carry out intersections, when this register won't be
- // interesting to this range anyway.
- // TODO(mtrofin): extend to aliased ranges, too.
- if ((kSimpleFPAliasing || !check_fp_aliasing()) &&
- positions[cur_reg] < range->Start()) {
- continue;
- }
-
- LifetimePosition next_intersection = cur_inactive->FirstIntersection(range);
- if (!next_intersection.IsValid()) continue;
- if (kSimpleFPAliasing || !check_fp_aliasing()) {
- positions[cur_reg] = Min(positions[cur_reg], next_intersection);
- TRACE("Register %s is free until pos %d (2)\n", RegisterName(cur_reg),
- Min(positions[cur_reg], next_intersection).value());
- } else {
- int alias_base_index = -1;
- int aliases = data()->config()->GetAliases(
- cur_inactive->representation(), cur_reg, rep, &alias_base_index);
- DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1));
- while (aliases--) {
- int aliased_reg = alias_base_index + aliases;
- positions[aliased_reg] = Min(positions[aliased_reg], next_intersection);
+ for (int cur_reg = 0; cur_reg < num_regs; ++cur_reg) {
+ for (LiveRange* cur_inactive : inactive_live_ranges(cur_reg)) {
+ DCHECK_GT(cur_inactive->End(), range->Start());
+ CHECK_EQ(cur_inactive->assigned_register(), cur_reg);
+ // No need to carry out intersections, when this register won't be
+ // interesting to this range anyway.
+ // TODO(mtrofin): extend to aliased ranges, too.
+ if ((kSimpleFPAliasing || !check_fp_aliasing()) &&
+ positions[cur_reg] <= cur_inactive->NextStart()) {
+ break;
+ }
+ LifetimePosition next_intersection =
+ cur_inactive->FirstIntersection(range);
+ if (!next_intersection.IsValid()) continue;
+ if (kSimpleFPAliasing || !check_fp_aliasing()) {
+ positions[cur_reg] = std::min(positions[cur_reg], next_intersection);
+ TRACE("Register %s is free until pos %d (2)\n", RegisterName(cur_reg),
+ positions[cur_reg].value());
+ } else {
+ int alias_base_index = -1;
+ int aliases = data()->config()->GetAliases(
+ cur_inactive->representation(), cur_reg, rep, &alias_base_index);
+ DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1));
+ while (aliases--) {
+ int aliased_reg = alias_base_index + aliases;
+ positions[aliased_reg] =
+ std::min(positions[aliased_reg], next_intersection);
+ }
}
}
}
@@ -4337,46 +4355,46 @@ void LinearScanAllocator::AllocateBlockedReg(LiveRange* current,
}
}
- for (LiveRange* range : inactive_live_ranges()) {
- DCHECK(range->End() > current->Start());
- int cur_reg = range->assigned_register();
- bool is_fixed = range->TopLevel()->IsFixed();
-
- // Don't perform costly intersections if they are guaranteed to not update
- // block_pos or use_pos.
- // TODO(mtrofin): extend to aliased ranges, too.
- if ((kSimpleFPAliasing || !check_fp_aliasing())) {
- if (is_fixed) {
- if (block_pos[cur_reg] < range->Start()) continue;
- } else {
- if (use_pos[cur_reg] < range->Start()) continue;
+ for (int cur_reg = 0; cur_reg < num_registers(); ++cur_reg) {
+ for (LiveRange* range : inactive_live_ranges(cur_reg)) {
+ DCHECK(range->End() > current->Start());
+ DCHECK_EQ(range->assigned_register(), cur_reg);
+ bool is_fixed = range->TopLevel()->IsFixed();
+
+ // Don't perform costly intersections if they are guaranteed to not update
+ // block_pos or use_pos.
+ // TODO(mtrofin): extend to aliased ranges, too.
+ if ((kSimpleFPAliasing || !check_fp_aliasing())) {
+ DCHECK_LE(use_pos[cur_reg], block_pos[cur_reg]);
+ if (block_pos[cur_reg] <= range->NextStart()) break;
+ if (!is_fixed && use_pos[cur_reg] <= range->NextStart()) continue;
}
- }
- LifetimePosition next_intersection = range->FirstIntersection(current);
- if (!next_intersection.IsValid()) continue;
+ LifetimePosition next_intersection = range->FirstIntersection(current);
+ if (!next_intersection.IsValid()) continue;
- if (kSimpleFPAliasing || !check_fp_aliasing()) {
- if (is_fixed) {
- block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection);
- use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]);
- } else {
- use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection);
- }
- } else {
- int alias_base_index = -1;
- int aliases = data()->config()->GetAliases(
- range->representation(), cur_reg, rep, &alias_base_index);
- DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1));
- while (aliases--) {
- int aliased_reg = alias_base_index + aliases;
+ if (kSimpleFPAliasing || !check_fp_aliasing()) {
if (is_fixed) {
- block_pos[aliased_reg] =
- Min(block_pos[aliased_reg], next_intersection);
- use_pos[aliased_reg] =
- Min(block_pos[aliased_reg], use_pos[aliased_reg]);
+ block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection);
+ use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]);
} else {
- use_pos[aliased_reg] = Min(use_pos[aliased_reg], next_intersection);
+ use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection);
+ }
+ } else {
+ int alias_base_index = -1;
+ int aliases = data()->config()->GetAliases(
+ range->representation(), cur_reg, rep, &alias_base_index);
+ DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1));
+ while (aliases--) {
+ int aliased_reg = alias_base_index + aliases;
+ if (is_fixed) {
+ block_pos[aliased_reg] =
+ Min(block_pos[aliased_reg], next_intersection);
+ use_pos[aliased_reg] =
+ Min(block_pos[aliased_reg], use_pos[aliased_reg]);
+ } else {
+ use_pos[aliased_reg] = Min(use_pos[aliased_reg], next_intersection);
+ }
}
}
}
@@ -4490,40 +4508,38 @@ void LinearScanAllocator::SplitAndSpillIntersecting(LiveRange* current,
it = ActiveToHandled(it);
}
- for (auto it = inactive_live_ranges().begin();
- it != inactive_live_ranges().end();) {
- LiveRange* range = *it;
- DCHECK(range->End() > current->Start());
- if (range->TopLevel()->IsFixed()) {
- ++it;
- continue;
- }
+ for (int cur_reg = 0; cur_reg < num_registers(); ++cur_reg) {
if (kSimpleFPAliasing || !check_fp_aliasing()) {
- if (range->assigned_register() != reg) {
+ if (cur_reg != reg) continue;
+ }
+ for (auto it = inactive_live_ranges(cur_reg).begin();
+ it != inactive_live_ranges(cur_reg).end();) {
+ LiveRange* range = *it;
+ if (!kSimpleFPAliasing && check_fp_aliasing() &&
+ !data()->config()->AreAliases(current->representation(), reg,
+ range->representation(), cur_reg)) {
++it;
continue;
}
- } else {
- if (!data()->config()->AreAliases(current->representation(), reg,
- range->representation(),
- range->assigned_register())) {
+ DCHECK(range->End() > current->Start());
+ if (range->TopLevel()->IsFixed()) {
++it;
continue;
}
- }
- LifetimePosition next_intersection = range->FirstIntersection(current);
- if (next_intersection.IsValid()) {
- UsePosition* next_pos = range->NextRegisterPosition(current->Start());
- if (next_pos == nullptr) {
- SpillAfter(range, split_pos, spill_mode);
+ LifetimePosition next_intersection = range->FirstIntersection(current);
+ if (next_intersection.IsValid()) {
+ UsePosition* next_pos = range->NextRegisterPosition(current->Start());
+ if (next_pos == nullptr) {
+ SpillAfter(range, split_pos, spill_mode);
+ } else {
+ next_intersection = Min(next_intersection, next_pos->pos());
+ SpillBetween(range, split_pos, next_intersection, spill_mode);
+ }
+ it = InactiveToHandled(it);
} else {
- next_intersection = Min(next_intersection, next_pos->pos());
- SpillBetween(range, split_pos, next_intersection, spill_mode);
+ ++it;
}
- it = InactiveToHandled(it);
- } else {
- ++it;
}
}
}