Bug 1028580 - Fold and/or and condition tests before critical edge splitting, r=sunfish.
authorBrian Hackett <bhackett1024@gmail.com>
Tue, 29 Jul 2014 09:18:14 -0800
changeset 196607 6d31e024845ffab1f2c7ed701a7d2d7b63143400
parent 196606 2960a81f4ff5b5852e25880fba8ec52c193a1959
child 196608 b697c227effeb4b04d809ccdc60ba9ca5f27b728
push id46921
push userbhackett@mozilla.com
push dateTue, 29 Jul 2014 17:18:21 +0000
treeherdermozilla-inbound@6d31e024845f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssunfish
bugs1028580
milestone34.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 1028580 - Fold and/or and condition tests before critical edge splitting, r=sunfish.
js/src/jit/Ion.cpp
js/src/jit/IonAnalysis.cpp
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -1285,37 +1285,37 @@ OptimizeMIR(MIRGenerator *mir)
     }
 
     IonSpewPass("BuildSSA");
     AssertBasicGraphCoherency(graph);
 
     if (mir->shouldCancel("Start"))
         return false;
 
+    if (!mir->compilingAsmJS()) {
+        AutoTraceLog log(logger, TraceLogger::FoldTests);
+        FoldTests(graph);
+        IonSpewPass("Fold Tests");
+        AssertBasicGraphCoherency(graph);
+
+        if (mir->shouldCancel("Fold Tests"))
+            return false;
+    }
+
     {
         AutoTraceLog log(logger, TraceLogger::SplitCriticalEdges);
         if (!SplitCriticalEdges(graph))
             return false;
         IonSpewPass("Split Critical Edges");
         AssertGraphCoherency(graph);
 
         if (mir->shouldCancel("Split Critical Edges"))
             return false;
     }
 
-    if (!mir->compilingAsmJS()) {
-        AutoTraceLog log(logger, TraceLogger::FoldTests);
-        FoldTests(graph);
-        IonSpewPass("Fold Tests");
-        AssertBasicGraphCoherency(graph);
-
-        if (mir->shouldCancel("Fold Tests"))
-            return false;
-    }
-
     {
         AutoTraceLog log(logger, TraceLogger::RenumberBlocks);
         if (!RenumberBlocks(graph))
             return false;
         IonSpewPass("Renumber Blocks");
         AssertGraphCoherency(graph);
 
         if (mir->shouldCancel("Renumber Blocks"))
--- a/js/src/jit/IonAnalysis.cpp
+++ b/js/src/jit/IonAnalysis.cpp
@@ -199,16 +199,23 @@ MaybeFoldConditionBlock(MIRGraph &graph,
     if (falseBranch->numPredecessors() != 1 || falseBranch->numSuccessors() != 1)
         return;
     MBasicBlock *testBlock = trueBranch->getSuccessor(0);
     if (testBlock != falseBranch->getSuccessor(0))
         return;
     if (testBlock->numPredecessors() != 2)
         return;
 
+    if (initialBlock->isLoopBackedge() || trueBranch->isLoopBackedge() || falseBranch->isLoopBackedge())
+        return;
+
+    // Make sure the test block does not have any outgoing loop backedges.
+    if (!SplitCriticalEdgesForBlock(graph, testBlock))
+        CrashAtUnhandlableOOM("MaybeFoldConditionBlock");
+
     MPhi *phi;
     MTest *finalTest;
     if (!BlockIsSingleTest(testBlock, &phi, &finalTest))
         return;
 
     if (&testBlock->info() != &initialBlock->info() ||
         &trueBranch->info() != &initialBlock->info() ||
         &falseBranch->info() != &initialBlock->info())
@@ -268,24 +275,16 @@ MaybeFoldConditionBlock(MIRGraph &graph,
     // Short circuit the initial test to skip any constant branch eliminated above.
     UpdateTestSuccessors(graph.alloc(), initialBlock, initialTest->input(),
                          trueTarget, falseTarget, testBlock);
 
     // Remove testBlock itself.
     finalTest->ifTrue()->removePredecessor(testBlock);
     finalTest->ifFalse()->removePredecessor(testBlock);
     graph.removeBlock(testBlock);
-
-    // Split any new critical edges which were introduced.
-    if (!SplitCriticalEdgesForBlock(graph, initialBlock) ||
-        (trueTarget == trueBranch && !SplitCriticalEdgesForBlock(graph, trueBranch)) ||
-        (falseTarget == falseBranch && !SplitCriticalEdgesForBlock(graph, falseBranch)))
-    {
-        CrashAtUnhandlableOOM("MaybeFoldConditionBlock");
-    }
 }
 
 static void
 MaybeFoldAndOrBlock(MIRGraph &graph, MBasicBlock *initialBlock)
 {
     // Optimize the MIR graph to improve the code generated for && and ||
     // operations when they are used in tests. This is very similar to the
     // above method for folding condition blocks, though the two are
@@ -318,16 +317,23 @@ MaybeFoldAndOrBlock(MIRGraph &graph, MBa
         testBlock = initialTest->ifTrue();
     }
 
     if (branchBlock->numSuccessors() != 1 || branchBlock->getSuccessor(0) != testBlock)
         return;
     if (branchBlock->numPredecessors() != 1 || testBlock->numPredecessors() != 2)
         return;
 
+    if (initialBlock->isLoopBackedge() || branchBlock->isLoopBackedge())
+        return;
+
+    // Make sure the test block does not have any outgoing loop backedges.
+    if (!SplitCriticalEdgesForBlock(graph, testBlock))
+        CrashAtUnhandlableOOM("MaybeFoldAndOrBlock");
+
     MPhi *phi;
     MTest *finalTest;
     if (!BlockIsSingleTest(testBlock, &phi, &finalTest))
         return;
 
     if (&testBlock->info() != &initialBlock->info() || &branchBlock->info() != &initialBlock->info())
         return;
 
@@ -361,23 +367,16 @@ MaybeFoldAndOrBlock(MIRGraph &graph, MBa
 
     UpdateTestSuccessors(graph.alloc(), branchBlock, branchResult,
                          finalTest->ifTrue(), finalTest->ifFalse(), testBlock);
 
     // Remove testBlock itself.
     finalTest->ifTrue()->removePredecessor(testBlock);
     finalTest->ifFalse()->removePredecessor(testBlock);
     graph.removeBlock(testBlock);
-
-    // Split any new critical edges which were introduced.
-    if (!SplitCriticalEdgesForBlock(graph, initialBlock) ||
-        !SplitCriticalEdgesForBlock(graph, branchBlock))
-    {
-        CrashAtUnhandlableOOM("MaybeFoldConditionBlock");
-    }
 }
 
 void
 jit::FoldTests(MIRGraph &graph)
 {
     for (MBasicBlockIterator block(graph.begin()); block != graph.end(); block++) {
         MaybeFoldConditionBlock(graph, *block);
         MaybeFoldAndOrBlock(graph, *block);