Bug 1259476 - Branch Pruning: Check if the Phi nodes have removed uses after popping them out of the worklist. r=jandem
authorNicolas B. Pierron <nicolas.b.pierron@mozilla.com>
Tue, 29 Mar 2016 13:43:22 +0000
changeset 290927 b6f0f273f2f7aee9a145ff48e640418175579a37
parent 290926 e93f8207a0b8a7c285fcf315e2a45c3a27c021a0
child 290928 b400541913a66025d9eb301a82a5946bdd7523c4
push id19656
push usergwagner@mozilla.com
push dateMon, 04 Apr 2016 13:43:23 +0000
treeherderb2g-inbound@e99061fde28a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1259476
milestone48.0a1
Bug 1259476 - Branch Pruning: Check if the Phi nodes have removed uses after popping them out of the worklist. r=jandem
js/src/jit-test/tests/ion/pgo-bug1259476.js
js/src/jit/IonAnalysis.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/pgo-bug1259476.js
@@ -0,0 +1,16 @@
+// |jit-test| --ion-pgo=on;
+
+try {
+    x = evalcx('');
+    x.__proto__ = 0;
+} catch (e) {}
+(function() {
+    for (var i = 0; i < 1; ++i) {
+        if (i % 5 == 0) {
+            for (let z of[0, 0, new Boolean(false), new Boolean(false),
+                          new Boolean(false), new Boolean(false)]) {
+                this.x;
+            }
+        }
+    }
+})()
--- a/js/src/jit/IonAnalysis.cpp
+++ b/js/src/jit/IonAnalysis.cpp
@@ -115,16 +115,22 @@ FlagPhiInputsAsHavingRemovedUses(MBasicB
 
         // Fill the work list with all the Phi nodes uses until we reach either:
         //  - A resume point which uses the Phi as an observable operand.
         //  - An explicit use of the Phi instruction.
         //  - An implicit use of the Phi instruction.
         bool isUsed = false;
         for (size_t idx = 0; !isUsed && idx < worklist.length(); idx++) {
             phi = worklist[idx];
+            if (phi->isUseRemoved() || phi->isImplicitlyUsed()) {
+                // The phi is implicitly used.
+                isUsed = true;
+                break;
+            }
+
             MUseIterator usesEnd(phi->usesEnd());
             for (MUseIterator use(phi->usesBegin()); use != usesEnd; use++) {
                 MNode* consumer = (*use)->consumer();
                 if (consumer->isResumePoint()) {
                     MResumePoint* rp = consumer->toResumePoint();
                     if (rp->isObservableOperand(*use)) {
                         // The phi is observable via a resume point operand.
                         isUsed = true;
@@ -139,22 +145,16 @@ FlagPhiInputsAsHavingRemovedUses(MBasicB
                     isUsed = true;
                     break;
                 }
 
                 phi = cdef->toPhi();
                 if (phi->isInWorklist())
                     continue;
 
-                if (phi->isUseRemoved() || phi->isImplicitlyUsed()) {
-                    // The phi is implicitly used.
-                    isUsed = true;
-                    break;
-                }
-
                 phi->setInWorklist();
                 if (!worklist.append(phi))
                     return false;
             }
 
             // Use a conservative upper bound to avoid iterating too many times
             // on very large graphs.
             if (idx >= conservativeUsesLimit) {