summaryrefslogtreecommitdiff
path: root/chromium/v8/src/compiler/live-range-separator.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/v8/src/compiler/live-range-separator.cc')
-rw-r--r--chromium/v8/src/compiler/live-range-separator.cc31
1 files changed, 24 insertions, 7 deletions
diff --git a/chromium/v8/src/compiler/live-range-separator.cc b/chromium/v8/src/compiler/live-range-separator.cc
index 67d1c77a83c..2d43ba92a08 100644
--- a/chromium/v8/src/compiler/live-range-separator.cc
+++ b/chromium/v8/src/compiler/live-range-separator.cc
@@ -52,8 +52,9 @@ void CreateSplinter(TopLevelLiveRange *range, RegisterAllocationData *data,
range->SetSplinter(splinter);
}
Zone *zone = data->allocation_zone();
- TRACE("creating splinter for range %d between %d and %d\n", range->vreg(),
- start.ToInstructionIndex(), end.ToInstructionIndex());
+ TRACE("creating splinter %d for range %d between %d and %d\n",
+ range->splinter()->vreg(), range->vreg(), start.ToInstructionIndex(),
+ end.ToInstructionIndex());
range->Splinter(start, end, zone);
}
}
@@ -76,7 +77,10 @@ void SplinterLiveRange(TopLevelLiveRange *range, RegisterAllocationData *data) {
LifetimePosition last_cut = LifetimePosition::Invalid();
while (interval != nullptr) {
+ // We have to cache these here, as splintering might destroy the original
+ // interval below.
UseInterval *next_interval = interval->next();
+ LifetimePosition interval_end = interval->end();
const InstructionBlock *first_block =
code->GetInstructionBlock(interval->FirstGapIndex());
const InstructionBlock *last_block =
@@ -91,6 +95,12 @@ void SplinterLiveRange(TopLevelLiveRange *range, RegisterAllocationData *data) {
first_cut = LifetimePosition::GapFromInstructionIndex(
current_block->first_instruction_index());
}
+ // We splinter until the last gap in the block. I assume this is done to
+ // leave a little range to be allocated by normal register allocation
+ // and then use that range to connect when splinters are merged back.
+ // This might be done as control flow resolution does not insert moves
+ // if two consecutive blocks in rpo order are also consecutive in
+ // control flow.
last_cut = LifetimePosition::GapFromInstructionIndex(
current_block->last_instruction_index());
} else {
@@ -101,13 +111,20 @@ void SplinterLiveRange(TopLevelLiveRange *range, RegisterAllocationData *data) {
}
}
}
+ // If we reach the end of an interval with a first_cut and last_cut set, it
+ // means that we can splinter to the end of the interval, as the value dies
+ // in this control flow branch or is not live in the next block. In the
+ // former case, we won't need to reload the value, so we can splinter to the
+ // end of its lifetime. In the latter case, control flow resolution will
+ // have to connect blocks anyway, so we can also splinter to the end of the
+ // block, too.
+ if (first_cut.IsValid()) {
+ CreateSplinter(range, data, first_cut, interval_end);
+ first_cut = LifetimePosition::Invalid();
+ last_cut = LifetimePosition::Invalid();
+ }
interval = next_interval;
}
- // When the range ends in deferred blocks, first_cut will be valid here.
- // Splinter from there to the last instruction that was in a deferred block.
- if (first_cut.IsValid()) {
- CreateSplinter(range, data, first_cut, last_cut);
- }
// Redo has_slot_use
if (range->has_slot_use() && range->splinter() != nullptr) {