Index: src/compiler/live-range-separator.cc |
diff --git a/src/compiler/live-range-separator.cc b/src/compiler/live-range-separator.cc |
index 6591d71e72b3f66a309452cb4d88ea2d2f2109bb..23331542421845291be88a169238c4c1046d02a0 100644 |
--- a/src/compiler/live-range-separator.cc |
+++ b/src/compiler/live-range-separator.cc |
@@ -58,26 +58,6 @@ void CreateSplinter(TopLevelLiveRange *range, RegisterAllocationData *data, |
} |
-int FirstInstruction(const UseInterval *interval) { |
- LifetimePosition start = interval->start(); |
- int ret = start.ToInstructionIndex(); |
- if (start.IsInstructionPosition() && start.IsEnd()) { |
- ++ret; |
- } |
- return ret; |
-} |
- |
- |
-int LastInstruction(const UseInterval *interval) { |
- LifetimePosition end = interval->end(); |
- int ret = end.ToInstructionIndex(); |
- if (end.IsGapPosition() || end.IsStart()) { |
- --ret; |
- } |
- return ret; |
-} |
- |
- |
void SplinterLiveRange(TopLevelLiveRange *range, RegisterAllocationData *data) { |
const InstructionSequence *code = data->code(); |
UseInterval *interval = range->first_interval(); |
@@ -88,9 +68,9 @@ void SplinterLiveRange(TopLevelLiveRange *range, RegisterAllocationData *data) { |
while (interval != nullptr) { |
UseInterval *next_interval = interval->next(); |
const InstructionBlock *first_block = |
- code->GetInstructionBlock(FirstInstruction(interval)); |
+ code->GetInstructionBlock(interval->FirstInstructionIndex()); |
const InstructionBlock *last_block = |
- code->GetInstructionBlock(LastInstruction(interval)); |
+ code->GetInstructionBlock(interval->LastInstructionIndex()); |
int first_block_nr = first_block->rpo_number().ToInt(); |
int last_block_nr = last_block->rpo_number().ToInt(); |
for (int block_id = first_block_nr; block_id <= last_block_nr; ++block_id) { |
@@ -129,12 +109,35 @@ void LiveRangeSeparator::Splinter() { |
if (range == nullptr || range->IsEmpty() || range->IsSplinter()) { |
continue; |
} |
- SplinterLiveRange(range, data()); |
+ int first_instr = range->first_interval()->FirstInstructionIndex(); |
+ if (!data()->code()->GetInstructionBlock(first_instr)->IsDeferred()) { |
+ SplinterLiveRange(range, data()); |
+ } |
+ } |
+} |
+ |
+ |
+void LiveRangeMerger::MarkRangesSpilledInDeferredBlocks() { |
+ for (TopLevelLiveRange *top : data()->live_ranges()) { |
+ if (top == nullptr || top->IsEmpty() || top->splinter() == nullptr) { |
+ continue; |
+ } |
+ |
+ LiveRange *child = top; |
+ for (; child != nullptr; child = child->next()) { |
+ if (child->spilled() || |
+ child->NextSlotPosition(child->Start()) != nullptr) { |
+ break; |
+ } |
+ } |
+ if (child == nullptr) top->MarkSpilledInDeferredBlock(); |
} |
} |
void LiveRangeMerger::Merge() { |
+ MarkRangesSpilledInDeferredBlocks(); |
+ |
int live_range_count = static_cast<int>(data()->live_ranges().size()); |
for (int i = 0; i < live_range_count; ++i) { |
TopLevelLiveRange *range = data()->live_ranges()[i]; |