Bug 675381: Remove broken opportunistic phi elimination from linear scan register allocator. r=dvander
authorAndrew Drake <adrake@adrake.org>
Wed, 10 Aug 2011 05:34:21 -0700
changeset 108710 28a71ebcf6c56255a62e18926af1eea4c5a13762
parent 108709 97ac85295f203175562783cb0e12abfe0a38802d
child 108711 73b80b0c344a2c6716def0fe420da6e707954643
push id2248
push userakeybl@mozilla.com
push dateMon, 08 Oct 2012 19:23:44 +0000
treeherdermozilla-aurora@118a3b748323 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdvander
bugs675381
milestone8.0a1
Bug 675381: Remove broken opportunistic phi elimination from linear scan register allocator. r=dvander
js/src/ion/LinearScan.cpp
js/src/jit-test/tests/ion/bug675381.js
--- a/js/src/ion/LinearScan.cpp
+++ b/js/src/ion/LinearScan.cpp
@@ -452,37 +452,39 @@ LinearScanAllocator::buildLivenessInfo()
                     live->insert(use->virtualRegister());
                 }
             }
         }
 
         // Phis have simultaneous assignment semantics at block begin, so at
         // the beginning of the block we can be sure that liveIn does not
         // contain any phi outputs.
-        for (unsigned int i = 0; i < block->numPhis();) {
-            if (live->contains(block->getPhi(i)->getDef(0)->virtualRegister())) {
-                live->remove(block->getPhi(i)->getDef(0)->virtualRegister());
-                i++;
+        for (unsigned int i = 0; i < block->numPhis(); i++) {
+            LDefinition *def = block->getPhi(i)->getDef(0);
+            if (live->contains(def->virtualRegister())) {
+                live->remove(def->virtualRegister());
             } else {
-                // This is a dead phi, so we can be shamelessly opportunistic
-                // and remove it here.
-                block->removePhi(i);
+                // This is a dead phi, so add a dummy range over all phis. This
+                // can go away if we have an earlier dead code elimination pass.
+                vregs[def].getInterval(0)->addRange(inputOf(block->firstId()),
+                                                    inputOf(*block->begin()).previous());
             }
         }
 
         if (mblock->isLoopHeader()) {
             // A divergence from the published algorithm is required here, as
             // our block order does not guarantee that blocks of a loop are
             // contiguous. As a result, a single live interval spanning the
             // loop is not possible. Additionally, we require liveIn in a later
             // pass for resolution, so that must also be fixed up here.
             MBasicBlock *loopBlock = mblock->backedge();
             while (true) {
                 // Add an interval for this entire loop block
                 for (BitSet::Iterator i(live->begin()); i != live->end(); i++) {
+                    IonSpew(IonSpew_LSRA, " Marking %d live for all of block %d", *i, loopBlock->id());
                     vregs[*i].getInterval(0)->addRange(inputOf(loopBlock->lir()->firstId()),
                                                        outputOf(loopBlock->lir()->lastId()));
                 }
 
                 // Fix up the liveIn set to account for the new interval
                 liveIn[loopBlock->id()]->insertAll(live);
 
                 // Make sure we don't visit this node again
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug675381.js
@@ -0,0 +1,17 @@
+function f0(p0,p1) {
+    var v0;
+    var v1;
+    while (p0) {
+        if (p0) {
+           v1 = v0 + p0;
+           v0 = v1;
+        }
+        v0 = p1;
+        if (v1) {
+            while (v1);
+            break;
+        }
+    }
+}
+f0();
+/* Don't assert. */