[turbofan] Merge group spill ranges.
authormtrofin <mtrofin@chromium.org>
Fri, 18 Sep 2015 16:01:52 +0000 (09:01 -0700)
committerCommit bot <commit-bot@chromium.org>
Fri, 18 Sep 2015 16:02:03 +0000 (16:02 +0000)
Akin to linear scan's TryReuseSpillForPhi, we attempt to merge the
spill ranges of grouped live ranges (which are phi inputs and output),
to avoid inefficient slot-to-slot moves.

BUG=

Review URL: https://codereview.chromium.org/1353023003

Cr-Commit-Position: refs/heads/master@{#30833}

src/compiler/greedy-allocator.cc
src/compiler/greedy-allocator.h

index 0a8a1f7986c4129eea0f3f9ca236aac865d68a8c..7852830c03d439f86bc6dc818a63f32d81289d0b 100644 (file)
@@ -479,11 +479,37 @@ void GreedyAllocator::AllocateRegisters() {
   }
   allocations_.clear();
 
+  TryReuseSpillRangesForGroups();
+
   TRACE("End allocating function %s with the Greedy Allocator\n",
         data()->debug_name());
 }
 
 
+void GreedyAllocator::TryReuseSpillRangesForGroups() {
+  for (TopLevelLiveRange* top : data()->live_ranges()) {
+    if (!CanProcessRange(top) || !top->is_phi() || top->group() == nullptr) {
+      continue;
+    }
+
+    SpillRange* spill_range = nullptr;
+    for (LiveRange* member : top->group()->ranges()) {
+      if (!member->TopLevel()->HasSpillRange()) continue;
+      SpillRange* member_range = member->TopLevel()->GetSpillRange();
+      if (spill_range == nullptr) {
+        spill_range = member_range;
+      } else {
+        // This may not always succeed, because we group non-conflicting ranges
+        // that may have been splintered, and the splinters may cause conflicts
+        // in the spill ranges.
+        // TODO(mtrofin): should the splinters own their own spill ranges?
+        spill_range->TryMerge(member_range);
+      }
+    }
+  }
+}
+
+
 float GreedyAllocator::GetMaximumConflictingWeight(
     unsigned reg_id, const LiveRange* range, float competing_weight) const {
   float ret = LiveRange::kInvalidWeight;
index 186779b052ae52c6c479366b0474f1a131dca5f1..b7398b38622a1a6855d2dc8935c059015fc264bc 100644 (file)
@@ -179,6 +179,12 @@ class GreedyAllocator final : public RegisterAllocator {
   // - the portion after the call.
   LiveRange* GetRemainderAfterSplittingAroundFirstCall(LiveRange* range);
 
+  // While we attempt to merge spill ranges later on in the allocation pipeline,
+  // we want to ensure group elements get merged. Waiting until later may hinder
+  // merge-ability, since the pipeline merger (being naive) may create conflicts
+  // between spill ranges of group members.
+  void TryReuseSpillRangesForGroups();
+
   // Necessary heuristic: spill when all else failed.
   void SpillRangeAsLastResort(LiveRange* range);