Bug 1175397 - Do not eliminate dead resume point operands after GVN. r=nbp CLOSED TREE
authorShu-yu Guo <shu@rfrn.org>
Wed, 17 Jun 2015 19:24:30 -0700
changeset 267576 a8e0bde30bd4d0e1c07630354bd077dabbb41b78
parent 267575 65703a2dc548f63a8fc49f36487929533542becd
child 267577 9d4f6d787c9f7454de191817feeb3967288a9acf
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-esr52@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs1175397
milestone41.0a1
Bug 1175397 - Do not eliminate dead resume point operands after GVN. r=nbp CLOSED TREE
js/src/jit/Ion.cpp
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -1405,17 +1405,60 @@ OptimizeMIR(MIRGenerator* mir)
         if (!analysis.analyze())
             return false;
         gs.spewPass("Alias analysis");
         AssertExtendedGraphCoherency(graph);
 
         if (mir->shouldCancel("Alias analysis"))
             return false;
 
-        if (!mir->compilingAsmJS()) {
+        // We only eliminate dead resume point operands in the first pass
+        // because it is currently unsound to do so after GVN.
+        //
+        // Consider the following example, where def1 dominates, and is
+        // congruent with def4, and use3 dominates, and is congruent with,
+        // use6.
+        //
+        // def1
+        // nop2
+        //   resumepoint def1
+        // use3 def1
+        // def4
+        // nop5
+        //   resumepoint def4
+        // use6 def4
+        // use7 use3 use6
+        //
+        // Assume that use3, use6, and use7 can cause OSI and are
+        // non-effectful. That is, use3 will resume at nop2, and use6 and use7
+        // will resume at nop5.
+        //
+        // After GVN, since def1 =~ def4, we have:
+        //
+        // def4 - replaced with def1 and pruned
+        // use6 - replaced with use3 and pruned
+        // use7 - renumbered to use5
+        //
+        // def1
+        // nop2
+        //   resumepoint def1
+        // use3 def1
+        // nop4
+        //   resumepoint def1
+        // use5 use3 use3
+        //
+        // nop4's resumepoint's operand of def1 is considered dead, because it
+        // is dominated by the last use of def1, use3.
+        //
+        // However, if use5 causes OSI, we will resume at nop4's resume
+        // point. The baseline frame at that point expects the now-pruned def4
+        // to exist. However, since it was replaced with def1 by GVN, and def1
+        // is dead at the point of nop4, the baseline frame incorrectly gets
+        // an optimized out value.
+        if (!mir->compilingAsmJS() && doRepeatOptimizations == 1) {
             // Eliminating dead resume point operands requires basic block
             // instructions to be numbered. Reuse the numbering computed during
             // alias analysis.
             if (!EliminateDeadResumePointOperands(mir, graph))
                 return false;
 
             if (mir->shouldCancel("Eliminate dead resume point operands"))
                 return false;