Bug 1315596 - Don't evict bundles which won't help with allocating the target bundle, r=sunfish.
authorBrian Hackett <bhackett1024@gmail.com>
Wed, 16 Nov 2016 13:09:44 -0700
changeset 323110 1e14d92676fb3d75fe5302b20c3df6a934b4a253
parent 323109 0371c68cb1299f237de97ea134e926fff0bdf413
child 323111 1fdb5a1b0d86d274c23f5d4232432c13dc42df79
push id30967
push userphilringnalda@gmail.com
push dateFri, 18 Nov 2016 03:21:38 +0000
treeherdermozilla-central@8e476f8bd52d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssunfish
bugs1315596
milestone53.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1315596 - Don't evict bundles which won't help with allocating the target bundle, r=sunfish.
js/src/jit/BacktrackingAllocator.cpp
js/src/jit/BacktrackingAllocator.h
--- a/js/src/jit/BacktrackingAllocator.cpp
+++ b/js/src/jit/BacktrackingAllocator.cpp
@@ -1378,16 +1378,39 @@ BacktrackingAllocator::computeRequiremen
                     return false;
             }
         }
     }
 
     return true;
 }
 
+// Return whether |conflicting| has any fixed uses of registers which overlap
+// with |bundle|.
+bool
+BacktrackingAllocator::hasFixedUseOverlap(LiveBundle* bundle, const LiveBundleVector& conflicting)
+{
+    for (size_t i = 0; i < conflicting.length(); i++) {
+        LiveBundle* existing = conflicting[i];
+        for (LiveRange::BundleLinkIterator iter = existing->rangesBegin(); iter; iter++) {
+            LiveRange* range = LiveRange::get(*iter);
+            if (range->hasDefinition()) {
+                LDefinition* def = vregs[range->vreg()].def();
+                if (def->policy() == LDefinition::FIXED && bundle->rangeFor(range->from()))
+                    return true;
+            }
+            for (UsePositionIterator iter(range->usesBegin()); iter; iter++) {
+                if (iter->usePolicy() == LUse::FIXED && bundle->rangeFor(iter->pos))
+                    return true;
+            }
+        }
+    }
+    return false;
+}
+
 bool
 BacktrackingAllocator::tryAllocateRegister(PhysicalRegister& r, LiveBundle* bundle,
                                            bool* success, bool* pfixed, LiveBundleVector& conflicting)
 {
     *success = false;
 
     if (!r.allocatable)
         return true;
@@ -1445,17 +1468,22 @@ BacktrackingAllocator::tryAllocateRegist
                     LiveBundle* existing = aliasedConflicting[i];
                     JitSpew(JitSpew_RegAlloc, "      %s [weight %" PRIuSIZE "]",
                             existing->toString().get(), computeSpillWeight(existing));
                 }
             }
         }
 #endif
 
-        if (conflicting.empty()) {
+        if (hasFixedUseOverlap(bundle, aliasedConflicting)) {
+            // Ignore conflicting bundles whose eviction will not allow the
+            // bundle to be allocated.
+            JitSpew(JitSpew_RegAlloc,
+                    "  Ignoring conflict due to fixed use/def overlap with bundle");
+        } else if (conflicting.empty()) {
             if (!conflicting.appendAll(aliasedConflicting))
                 return false;
         } else {
             if (maximumSpillWeight(aliasedConflicting) < maximumSpillWeight(conflicting)) {
                 conflicting.clear();
                 if (!conflicting.appendAll(aliasedConflicting))
                     return false;
             }
--- a/js/src/jit/BacktrackingAllocator.h
+++ b/js/src/jit/BacktrackingAllocator.h
@@ -708,16 +708,17 @@ class BacktrackingAllocator : protected 
     MOZ_MUST_USE bool tryAllocateFixed(LiveBundle* bundle, Requirement requirement,
                                        bool* success, bool* pfixed, LiveBundleVector& conflicting);
     MOZ_MUST_USE bool tryAllocateNonFixed(LiveBundle* bundle, Requirement requirement,
                                           Requirement hint, bool* success, bool* pfixed,
                                           LiveBundleVector& conflicting);
     MOZ_MUST_USE bool processBundle(MIRGenerator* mir, LiveBundle* bundle);
     MOZ_MUST_USE bool computeRequirement(LiveBundle* bundle, Requirement *prequirement,
                                          Requirement *phint);
+    bool hasFixedUseOverlap(LiveBundle* bundle, const LiveBundleVector& conflicting);
     MOZ_MUST_USE bool tryAllocateRegister(PhysicalRegister& r, LiveBundle* bundle, bool* success,
                                           bool* pfixed, LiveBundleVector& conflicting);
     MOZ_MUST_USE bool evictBundle(LiveBundle* bundle);
     MOZ_MUST_USE bool splitAndRequeueBundles(LiveBundle* bundle,
                                              const LiveBundleVector& newBundles);
     MOZ_MUST_USE bool spill(LiveBundle* bundle);
 
     bool isReusedInput(LUse* use, LNode* ins, bool considerCopy);