Reviewers: Jarin (OOO), Benedikt Meurer,

Description:
[turbofan] LiveRange splintering optimizations.

Related to 1318893002 - another source of regressions in
benchmarks sensitive to compile time is the splintering
logic. This change addresses some, but not all, of that. In
particular, there are still some places (figuring out if a
range has a hole right where a deferred set of blocks is)
that need another look.

BUG=

Please review this at https://codereview.chromium.org/1319843002/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+48, -36 lines):
  M src/compiler/live-range-separator.cc
  M src/compiler/register-allocator.h
  M src/compiler/register-allocator.cc


Index: src/compiler/live-range-separator.cc
diff --git a/src/compiler/live-range-separator.cc b/src/compiler/live-range-separator.cc index 47116b9a2d25c901f9e7a3090b990fc04ebbb396..aea64fcc5ffe00873c657738e9cf6a330397e63d 100644
--- a/src/compiler/live-range-separator.cc
+++ b/src/compiler/live-range-separator.cc
@@ -118,7 +118,8 @@ void SplinterRangesInDeferredBlocks(RegisterAllocationData *data) {
     if (!block->IsDeferred()) continue;

     RpoNumber last_deferred = block->last_deferred();
-    i = last_deferred.ToInt();
+    // 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());
Index: src/compiler/register-allocator.cc
diff --git a/src/compiler/register-allocator.cc b/src/compiler/register-allocator.cc index ebfb932b086be5d3a16cd437a46884f3c418f006..f2c86c45c0d90f2b9dbbdb36afe45dbac0ff6569 100644
--- a/src/compiler/register-allocator.cc
+++ b/src/compiler/register-allocator.cc
@@ -1199,13 +1199,14 @@ RegisterAllocationData::RegisterAllocationData(
       config_(config),
       phi_map_(allocation_zone()),
live_in_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()), + live_out_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()),
       live_ranges_(code->VirtualRegisterCount() * 2, nullptr,
                    allocation_zone()),
       fixed_live_ranges_(this->config()->num_general_registers(), nullptr,
                          allocation_zone()),
fixed_double_live_ranges_(this->config()->num_double_registers(), nullptr,
                                 allocation_zone()),
-      spill_ranges_(allocation_zone()),
+ spill_ranges_(code->VirtualRegisterCount(), nullptr, allocation_zone()),
       delayed_references_(allocation_zone()),
       assigned_registers_(nullptr),
       assigned_double_registers_(nullptr),
@@ -1332,7 +1333,11 @@ SpillRange* RegisterAllocationData::AssignSpillRangeToLiveRange(
   }
   range->set_spill_type(TopLevelLiveRange::SpillType::kSpillRange);

-  spill_ranges().insert(spill_range);
+  int spill_range_index =
+ range->IsSplinter() ? range->splintered_from()->vreg() : range->vreg();
+
+  spill_ranges()[spill_range_index] = spill_range;
+
   return spill_range;
 }

@@ -1681,28 +1686,33 @@ LiveRangeBuilder::LiveRangeBuilder(RegisterAllocationData* data,

 BitVector* LiveRangeBuilder::ComputeLiveOut(const InstructionBlock* block,
                                             RegisterAllocationData* data) {
-  // Compute live out for the given block, except not including backward
-  // successor edges.
-  Zone* zone = data->allocation_zone();
-  const InstructionSequence* code = data->code();
-
-  auto live_out = new (zone) BitVector(code->VirtualRegisterCount(), zone);
-
-  // Process all successor blocks.
-  for (auto succ : block->successors()) {
-    // Add values live on entry to the successor.
-    if (succ <= block->rpo_number()) continue;
-    auto live_in = data->live_in_sets()[succ.ToSize()];
-    if (live_in != nullptr) live_out->Union(*live_in);
-
-    // All phi input operands corresponding to this successor edge are live
-    // out from this block.
-    auto successor = code->InstructionBlockAt(succ);
-    size_t index = successor->PredecessorIndexOf(block->rpo_number());
-    DCHECK(index < successor->PredecessorCount());
-    for (auto phi : successor->phis()) {
-      live_out->Add(phi->operands()[index]);
+  size_t block_index = block->rpo_number().ToSize();
+  BitVector* live_out = data->live_out_sets()[block_index];
+  if (live_out == nullptr) {
+    // Compute live out for the given block, except not including backward
+    // successor edges.
+    Zone* zone = data->allocation_zone();
+    const InstructionSequence* code = data->code();
+
+    live_out = new (zone) BitVector(code->VirtualRegisterCount(), zone);
+
+    // Process all successor blocks.
+    for (const RpoNumber& succ : block->successors()) {
+      // Add values live on entry to the successor.
+      if (succ <= block->rpo_number()) continue;
+      BitVector* live_in = data->live_in_sets()[succ.ToSize()];
+      if (live_in != nullptr) live_out->Union(*live_in);
+
+ // All phi input operands corresponding to this successor edge are live
+      // out from this block.
+      auto successor = code->InstructionBlockAt(succ);
+      size_t index = successor->PredecessorIndexOf(block->rpo_number());
+      DCHECK(index < successor->PredecessorCount());
+      for (PhiInstruction* phi : successor->phis()) {
+        live_out->Add(phi->operands()[index]);
+      }
     }
+    data->live_out_sets()[block_index] = live_out;
   }
   return live_out;
 }
@@ -2827,23 +2837,22 @@ OperandAssigner::OperandAssigner(RegisterAllocationData* data) : data_(data) {}


 void OperandAssigner::AssignSpillSlots() {
-  ZoneSet<SpillRange*>& spill_ranges = data()->spill_ranges();
+  ZoneVector<SpillRange*>& spill_ranges = data()->spill_ranges();
   // Merge disjoint spill ranges
- for (auto i = spill_ranges.begin(), end = spill_ranges.end(); i != end; ++i) {
-    SpillRange* range = *i;
+  for (size_t i = 0; i < spill_ranges.size(); ++i) {
+    SpillRange* range = spill_ranges[i];
+    if (range == nullptr) continue;
     if (range->IsEmpty()) continue;
-    auto j = i;
-    j++;
-    for (; j != end; ++j) {
-      SpillRange* other = *j;
-      if (!other->IsEmpty()) {
+    for (size_t j = i + 1; j < spill_ranges.size(); ++j) {
+      SpillRange* other = spill_ranges[j];
+      if (other != nullptr && !other->IsEmpty()) {
         range->TryMerge(other);
       }
     }
   }
   // Allocate slots for the merged spill ranges.
-  for (auto range : spill_ranges) {
-    if (range->IsEmpty()) continue;
+  for (SpillRange* range : spill_ranges) {
+    if (range == nullptr || range->IsEmpty()) continue;
     // Allocate a new operand referring to the spill slot.
     int byte_width = range->ByteWidth();
     int index = data()->frame()->AllocateSpillSlot(byte_width);
Index: src/compiler/register-allocator.h
diff --git a/src/compiler/register-allocator.h b/src/compiler/register-allocator.h index ff4ddd0c741403528424b3afc66e259f6ff4acae..9590b673eb0b9f1be148c6afa61bbe736b73c455 100644
--- a/src/compiler/register-allocator.h
+++ b/src/compiler/register-allocator.h
@@ -681,7 +681,8 @@ class RegisterAllocationData final : public ZoneObject {
     return fixed_double_live_ranges_;
   }
   ZoneVector<BitVector*>& live_in_sets() { return live_in_sets_; }
-  ZoneSet<SpillRange*>& spill_ranges() { return spill_ranges_; }
+  ZoneVector<BitVector*>& live_out_sets() { return live_out_sets_; }
+  ZoneVector<SpillRange*>& spill_ranges() { return spill_ranges_; }
   DelayedReferences& delayed_references() { return delayed_references_; }
   InstructionSequence* code() const { return code_; }
   // This zone is for datastructures only needed during register allocation
@@ -739,10 +740,11 @@ class RegisterAllocationData final : public ZoneObject {
   const RegisterConfiguration* const config_;
   PhiMap phi_map_;
   ZoneVector<BitVector*> live_in_sets_;
+  ZoneVector<BitVector*> live_out_sets_;
   ZoneVector<TopLevelLiveRange*> live_ranges_;
   ZoneVector<TopLevelLiveRange*> fixed_live_ranges_;
   ZoneVector<TopLevelLiveRange*> fixed_double_live_ranges_;
-  ZoneSet<SpillRange*> spill_ranges_;
+  ZoneVector<SpillRange*> spill_ranges_;
   DelayedReferences delayed_references_;
   BitVector* assigned_registers_;
   BitVector* assigned_double_registers_;


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to