Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(92)

Unified Diff: src/compiler/live-range-separator.cc

Issue 1415833002: [turbofan] Alternative splintering mechanism. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/compiler/register-allocator.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/live-range-separator.cc
diff --git a/src/compiler/live-range-separator.cc b/src/compiler/live-range-separator.cc
index f29e4b4a202efb26c320c5892b464ba62fa38ea4..44e9dba7b58b13e9e80bc82f1a9cb6cb79b47f6a 100644
--- a/src/compiler/live-range-separator.cc
+++ b/src/compiler/live-range-separator.cc
@@ -18,40 +18,6 @@ namespace compiler {
namespace {
-// Starting from a deferred block, find the last consecutive deferred block.
-RpoNumber GetLastDeferredBlock(const InstructionBlock *block,
- const InstructionSequence *code) {
- DCHECK(block->IsDeferred());
- RpoNumber first = block->rpo_number();
-
- RpoNumber last = first;
- for (int i = first.ToInt(); i < code->InstructionBlockCount(); ++i) {
- RpoNumber at_i = RpoNumber::FromInt(i);
- const InstructionBlock *block_at_i = code->InstructionBlockAt(at_i);
- if (!block_at_i->IsDeferred()) break;
- last = at_i;
- }
-
- return last;
-}
-
-
-// Delimits consecutive deferred block sequences.
-void AssociateDeferredBlockSequences(InstructionSequence *code) {
- for (int blk_id = 0; blk_id < code->InstructionBlockCount(); ++blk_id) {
- InstructionBlock *block =
- code->InstructionBlockAt(RpoNumber::FromInt(blk_id));
- if (!block->IsDeferred()) continue;
- RpoNumber last = GetLastDeferredBlock(block, code);
- block->set_last_deferred(last);
- // We know last is still deferred, and that last + 1, is not (or is an
- // invalid index). So skip over last + 1 and continue from last + 2. This
- // way, we visit each block exactly once, and the total complexity of this
- // function is O(n), n being jthe number of blocks.
- blk_id = last.ToInt() + 1;
- }
-}
-
void CreateSplinter(TopLevelLiveRange *range, RegisterAllocationData *data,
LifetimePosition first_cut, LifetimePosition last_cut) {
@@ -88,66 +54,78 @@ void CreateSplinter(TopLevelLiveRange *range, RegisterAllocationData *data,
}
-// Splinter all ranges live inside successive deferred blocks.
-// No control flow analysis is performed. After the register allocation, we will
-// merge the splinters back into the original ranges, and then rely on the
-// range connector to properly connect them.
-void SplinterRangesInDeferredBlocks(RegisterAllocationData *data) {
- InstructionSequence *code = data->code();
- int code_block_count = code->InstructionBlockCount();
- Zone *zone = data->allocation_zone();
- ZoneVector<BitVector *> &in_sets = data->live_in_sets();
-
- for (int i = 0; i < code_block_count; ++i) {
- InstructionBlock *block = code->InstructionBlockAt(RpoNumber::FromInt(i));
- if (!block->IsDeferred()) continue;
-
- RpoNumber last_deferred = block->last_deferred();
- // last_deferred + 1 is not deferred, so no point in visiting it.
- i = last_deferred.ToInt() + 1;
-
- LifetimePosition first_cut = LifetimePosition::GapFromInstructionIndex(
- block->first_instruction_index());
-
- LifetimePosition last_cut = LifetimePosition::GapFromInstructionIndex(
- static_cast<int>(code->instructions().size()));
-
- const BitVector *in_set = in_sets[block->rpo_number().ToInt()];
- BitVector ranges_to_splinter(*in_set, zone);
- InstructionBlock *last = code->InstructionBlockAt(last_deferred);
- for (int deferred_id = block->rpo_number().ToInt();
- deferred_id <= last->rpo_number().ToInt(); ++deferred_id) {
- const BitVector *ins = in_sets[deferred_id];
- ranges_to_splinter.Union(*ins);
- const BitVector *outs = LiveRangeBuilder::ComputeLiveOut(
- code->InstructionBlockAt(RpoNumber::FromInt(deferred_id)), data);
- ranges_to_splinter.Union(*outs);
- }
+int FirstInstruction(const UseInterval *interval) {
+ LifetimePosition start = interval->start();
+ int ret = start.ToInstructionIndex();
+ if (start.IsInstructionPosition() && start.IsEnd()) {
+ ++ret;
+ }
+ return ret;
+}
- int last_index = last->last_instruction_index();
- if (code->InstructionAt(last_index)->opcode() ==
- ArchOpcode::kArchDeoptimize) {
- ++last_index;
- }
- last_cut = LifetimePosition::GapFromInstructionIndex(last_index);
- BitVector::Iterator iterator(&ranges_to_splinter);
+int LastInstruction(const UseInterval *interval) {
+ LifetimePosition end = interval->end();
+ int ret = end.ToInstructionIndex();
+ if (end.IsGapPosition() || end.IsStart()) {
+ --ret;
+ }
+ return ret;
+}
- while (!iterator.Done()) {
- int range_id = iterator.Current();
- iterator.Advance();
- TopLevelLiveRange *range = data->live_ranges()[range_id];
- CreateSplinter(range, data, first_cut, last_cut);
+void SplinterLiveRange(TopLevelLiveRange *range, RegisterAllocationData *data) {
+ const InstructionSequence *code = data->code();
+ UseInterval *interval = range->first_interval();
+
+ LifetimePosition first_cut = LifetimePosition::Invalid();
+ LifetimePosition last_cut = LifetimePosition::Invalid();
+
+ while (interval != nullptr) {
+ UseInterval *next_interval = interval->next();
+ const InstructionBlock *first_block =
+ code->GetInstructionBlock(FirstInstruction(interval));
+ const InstructionBlock *last_block =
+ code->GetInstructionBlock(LastInstruction(interval));
+ 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) {
+ const InstructionBlock *current_block =
+ code->InstructionBlockAt(RpoNumber::FromInt(block_id));
+ if (current_block->IsDeferred()) {
+ if (!first_cut.IsValid()) {
+ first_cut = LifetimePosition::GapFromInstructionIndex(
+ current_block->first_instruction_index());
+ }
+ last_cut = LifetimePosition::GapFromInstructionIndex(
+ current_block->last_instruction_index());
+ } else {
+ if (first_cut.IsValid()) {
+ CreateSplinter(range, data, first_cut, last_cut);
+ first_cut = LifetimePosition::Invalid();
+ last_cut = LifetimePosition::Invalid();
+ }
+ }
}
+ interval = next_interval;
+ }
+ // When the range ends in deferred blocks, first_cut will be valid here.
+ if (first_cut.IsValid()) {
+ CreateSplinter(range, data, first_cut, range->End());
}
}
} // namespace
void LiveRangeSeparator::Splinter() {
- AssociateDeferredBlockSequences(data()->code());
- SplinterRangesInDeferredBlocks(data());
+ size_t virt_reg_count = data()->live_ranges().size();
+ for (size_t vreg = 0; vreg < virt_reg_count; ++vreg) {
+ TopLevelLiveRange *range = data()->live_ranges()[vreg];
+ if (range == nullptr || range->IsEmpty() || range->IsSplinter()) {
+ continue;
+ }
+ SplinterLiveRange(range, data());
+ }
}
« no previous file with comments | « no previous file | src/compiler/register-allocator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698