Bug 1004363 - IonMonkey: Teach range analysis to mark unreachable dominator subtrees r=nbp
authorDan Gohman <sunfish@mozilla.com>
Wed, 04 Jun 2014 07:44:46 -0700
changeset 205857 51b269a9c5c9ada5291547ce405457ee23b3a87e
parent 205856 07ab6ede1eff8b32bf070da17529972bb5d7b356
child 205858 d37aa03d00fb837dad340f62fb99ecb1886b27c0
push id3741
push userasasaki@mozilla.com
push dateMon, 21 Jul 2014 20:25:18 +0000
treeherdermozilla-beta@4d6f46f5af68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs1004363
milestone32.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 1004363 - IonMonkey: Teach range analysis to mark unreachable dominator subtrees r=nbp
js/src/jit/MIRGraph.cpp
js/src/jit/MIRGraph.h
js/src/jit/RangeAnalysis.cpp
--- a/js/src/jit/MIRGraph.cpp
+++ b/js/src/jit/MIRGraph.cpp
@@ -940,25 +940,16 @@ MBasicBlock::assertUsesAreNotWithin(MUse
 bool
 MBasicBlock::dominates(const MBasicBlock *other) const
 {
     uint32_t high = domIndex() + numDominated();
     uint32_t low  = domIndex();
     return other->domIndex() >= low && other->domIndex() < high;
 }
 
-void
-MBasicBlock::setUnreachable()
-{
-    unreachable_ = true;
-    size_t numDom = numImmediatelyDominatedBlocks();
-    for (size_t d = 0; d < numDom; d++)
-        getImmediatelyDominatedBlock(d)->unreachable_ = true;
-}
-
 AbortReason
 MBasicBlock::setBackedge(MBasicBlock *pred)
 {
     // Predecessors must be finished, and at the correct stack depth.
     JS_ASSERT(lastIns_);
     JS_ASSERT(pred->lastIns_);
     JS_ASSERT(pred->stackDepth() == entryResumePoint()->stackDepth());
 
--- a/js/src/jit/MIRGraph.h
+++ b/js/src/jit/MIRGraph.h
@@ -83,18 +83,21 @@ class MBasicBlock : public TempObject, p
                                  MBasicBlock *pred, Kind kind);
 
     bool dominates(const MBasicBlock *other) const;
 
     void setId(uint32_t id) {
         id_ = id;
     }
 
-    // Mark the current block and all dominated blocks as unreachable.
-    void setUnreachable();
+    // Mark this block (and only this block) as unreachable.
+    void setUnreachable() {
+        JS_ASSERT(!unreachable_);
+        unreachable_ = true;
+    }
     bool unreachable() const {
         return unreachable_;
     }
     // Move the definition to the top of the stack.
     void pick(int32_t depth);
 
     // Exchange 2 stack slots at the defined depth
     void swapAt(int32_t depth);
--- a/js/src/jit/RangeAnalysis.cpp
+++ b/js/src/jit/RangeAnalysis.cpp
@@ -1999,28 +1999,39 @@ RangeAnalysis::tryHoistBoundsCheck(MBasi
 
 bool
 RangeAnalysis::analyze()
 {
     IonSpew(IonSpew_Range, "Doing range propagation");
 
     for (ReversePostorderIterator iter(graph_.rpoBegin()); iter != graph_.rpoEnd(); iter++) {
         MBasicBlock *block = *iter;
-
-        if (block->unreachable())
+        JS_ASSERT(!block->unreachable());
+
+        // If the block's immediate dominator is unreachable, the block is
+        // unreachable. Iterating in RPO, we'll always see the immediate
+        // dominator before the block.
+        if (block->immediateDominator()->unreachable()) {
+            block->setUnreachable();
             continue;
+        }
 
         for (MDefinitionIterator iter(block); iter; iter++) {
             MDefinition *def = *iter;
 
             def->computeRange(alloc());
             IonSpew(IonSpew_Range, "computing range on %d", def->id());
             SpewRange(def);
         }
 
+        // Beta node range analysis may have marked this block unreachable. If
+        // so, it's no longer interesting to continue processing it.
+        if (block->unreachable())
+            continue;
+
         if (block->isLoopHeader()) {
             if (!analyzeLoop(block))
                 return false;
         }
 
         // First pass at collecting range info - while the beta nodes are still
         // around and before truncation.
         for (MInstructionIterator iter(block->begin()); iter != block->end(); iter++) {