Bug 1118894 - IonMonkey: Don't insist on making loops contiguous if they contain OSR entries into former loop blocks. r=jandem
authorDan Gohman <sunfish@mozilla.com>
Sat, 24 Jan 2015 13:39:35 -0500
changeset 225568 946d72dae3dff47243919086e1c5747eb0022455
parent 225567 e1aaece372a55264c08c08532fe15199b6a42cd9
child 225569 f313202b1e25cc0779c8287d3e3a34709fb018ff
push id28167
push userryanvm@gmail.com
push dateSun, 25 Jan 2015 00:24:46 +0000
treeherdermozilla-central@c18776175a69 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1118894
milestone38.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 1118894 - IonMonkey: Don't insist on making loops contiguous if they contain OSR entries into former loop blocks. r=jandem
js/src/jit/IonAnalysis.cpp
--- a/js/src/jit/IonAnalysis.cpp
+++ b/js/src/jit/IonAnalysis.cpp
@@ -3477,38 +3477,52 @@ MakeLoopContiguous(MIRGraph &graph, MBas
     ReversePostorderIterator insertIter = graph.rpoBegin(backedge);
     insertIter++;
     MBasicBlock *insertPt = *insertIter;
 
     // Visit all the blocks from the loop header to the loop backedge.
     size_t headerId = header->id();
     size_t inLoopId = headerId;
     size_t notInLoopId = inLoopId + numMarked;
+    size_t numOSRDominated = 0;
     ReversePostorderIterator i = graph.rpoBegin(header);
+    MBasicBlock *osrBlock = graph.osrBlock();
     for (;;) {
         MBasicBlock *block = *i++;
         MOZ_ASSERT(block->id() >= header->id() && block->id() <= backedge->id(),
                    "Loop backedge should be last block in loop");
 
         if (block->isMarked()) {
             // This block is in the loop.
             block->unmark();
             block->setId(inLoopId++);
             // If we've reached the loop backedge, we're done!
             if (block == backedge)
                 break;
+        } else if (osrBlock && osrBlock->dominates(block)) {
+            // This block is not in the loop, but since it's dominated by the
+            // OSR entry, the block was probably in the loop before some
+            // folding. This probably means that the block has outgoing paths
+            // which re-enter the loop in the middle. And that, finally, means
+            // that we can't move this block to the end, since it could create a
+            // backwards branch to a block which is not the loop header.
+            block->setId(inLoopId++);
+            ++numOSRDominated;
         } else {
             // This block is not in the loop. Move it to the end.
             graph.moveBlockBefore(insertPt, block);
             block->setId(notInLoopId++);
         }
     }
     MOZ_ASSERT(header->id() == headerId, "Loop header id changed");
-    MOZ_ASSERT(inLoopId == headerId + numMarked, "Wrong number of blocks kept in loop");
-    MOZ_ASSERT(notInLoopId == (insertIter != graph.rpoEnd() ? insertPt->id() : graph.numBlocks()),
+    MOZ_ASSERT(inLoopId == headerId + numMarked + numOSRDominated,
+               "Wrong number of blocks kept in loop");
+    MOZ_ASSERT(notInLoopId == (insertIter != graph.rpoEnd()
+                               ? insertPt->id()
+                               : graph.numBlocks()) - numOSRDominated,
                "Wrong number of blocks moved out of loop");
 }
 
 // Reorder the blocks in the graph so that loops are contiguous.
 bool
 jit::MakeLoopsContiguous(MIRGraph &graph)
 {
     // Visit all loop headers (in any order).