| Index: src/compiler/register-allocator.cc
|
| diff --git a/src/compiler/register-allocator.cc b/src/compiler/register-allocator.cc
|
| index 0410b417f84136a52c80b1a5940cd1651d99c2f2..23610fdbe01f7be0ac64a2fdba9d7a99558766ae 100644
|
| --- a/src/compiler/register-allocator.cc
|
| +++ b/src/compiler/register-allocator.cc
|
| @@ -712,11 +712,11 @@ void TopLevelLiveRange::SpillAtDefinition(Zone* zone, int gap_index,
|
| }
|
|
|
|
|
| -bool TopLevelLiveRange::TryCommitSpillInDeferredBlock(
|
| - InstructionSequence* code, const InstructionOperand& spill_operand) {
|
| +void TopLevelLiveRange::MarkSpilledInDeferredBlock(
|
| + const InstructionSequence* code) {
|
| if (!FLAG_turbo_preprocess_ranges || IsEmpty() || HasNoSpillType() ||
|
| - spill_operand.IsConstant() || spill_operand.IsImmediate()) {
|
| - return false;
|
| + !HasSpillRange()) {
|
| + return;
|
| }
|
|
|
| int count = 0;
|
| @@ -744,16 +744,23 @@ bool TopLevelLiveRange::TryCommitSpillInDeferredBlock(
|
| "Live Range %d must be spilled at definition: found a "
|
| "slot-requiring non-deferred child range %d.\n",
|
| TopLevel()->vreg(), child->relative_id());
|
| - return false;
|
| + return;
|
| }
|
| } else {
|
| if (child->spilled() || has_slot_use) ++count;
|
| }
|
| }
|
| - if (count == 0) return false;
|
| + if (count == 0) return;
|
|
|
| spill_start_index_ = -1;
|
| spilled_in_deferred_blocks_ = true;
|
| + spills_at_definition_ = nullptr;
|
| +}
|
| +
|
| +
|
| +bool TopLevelLiveRange::TryCommitSpillInDeferredBlock(
|
| + InstructionSequence* code, const InstructionOperand& spill_operand) {
|
| + if (!IsSpilledOnlyInDeferredBlocks()) return false;
|
|
|
| TRACE("Live Range %d will be spilled only in deferred blocks.\n", vreg());
|
| // If we have ranges that aren't spilled but require the operand on the stack,
|
| @@ -2962,10 +2969,20 @@ void SpillSlotLocator::LocateSpillSlots() {
|
| if (range == nullptr || range->IsEmpty()) continue;
|
| // We care only about ranges which spill in the frame.
|
| if (!range->HasSpillRange()) continue;
|
| - auto spills = range->spills_at_definition();
|
| - DCHECK_NOT_NULL(spills);
|
| - for (; spills != nullptr; spills = spills->next) {
|
| - code->GetInstructionBlock(spills->gap_index)->mark_needs_frame();
|
| + range->MarkSpilledInDeferredBlock(data()->code());
|
| + if (range->IsSpilledOnlyInDeferredBlocks()) {
|
| + for (LiveRange* child = range; child != nullptr; child = child->next()) {
|
| + if (child->spilled()) {
|
| + code->GetInstructionBlock(child->Start().ToInstructionIndex())
|
| + ->mark_needs_frame();
|
| + }
|
| + }
|
| + } else {
|
| + auto spills = range->spills_at_definition();
|
| + DCHECK_NOT_NULL(spills);
|
| + for (; spills != nullptr; spills = spills->next) {
|
| + code->GetInstructionBlock(spills->gap_index)->mark_needs_frame();
|
| + }
|
| }
|
| }
|
| }
|
|
|