Bug 1158344 part 1 - Use the an instruction which is not a beta node for hoisting bounds checks. r=sunfish
authorNicolas B. Pierron <nicolas.b.pierron@mozilla.com>
Mon, 04 May 2015 15:14:39 +0200
changeset 272090 a656694f7aed5f67f2daa13b2f19d96cbaeba0b8
parent 272089 edfafb7271a65daee507417ecb1357db48f4ab55
child 272091 e9e47135019ef9cbbfc822e7f5edc72caaba3b7f
push id4830
push userjlund@mozilla.com
push dateMon, 29 Jun 2015 20:18:48 +0000
treeherdermozilla-beta@4c2175bb0420 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssunfish
bugs1158344
milestone40.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 1158344 part 1 - Use the an instruction which is not a beta node for hoisting bounds checks. r=sunfish
js/src/jit/RangeAnalysis.cpp
--- a/js/src/jit/RangeAnalysis.cpp
+++ b/js/src/jit/RangeAnalysis.cpp
@@ -1890,16 +1890,26 @@ RangeAnalysis::analyzeLoop(MBasicBlock* 
             ins->block()->discard(ins);
         }
     }
 
     UnmarkLoopBlocks(graph_, header);
     return true;
 }
 
+// Unbox beta nodes in order to hoist instruction properly, and not be limited
+// by the beta nodes which are added after each branch.
+static inline MDefinition*
+DefinitionOrBetaInputDefinition(MDefinition* ins)
+{
+    while (ins->isBeta())
+        ins = ins->toBeta()->input();
+    return ins;
+}
+
 LoopIterationBound*
 RangeAnalysis::analyzeLoopIterationCount(MBasicBlock* header,
                                          MTest* test, BranchDirection direction)
 {
     SimpleLinearSum lhs(nullptr, 0);
     MDefinition* rhs;
     bool lessEqual;
     if (!ExtractLinearInequality(test, direction, &lhs, &rhs, &lessEqual))
@@ -1935,19 +1945,18 @@ RangeAnalysis::analyzeLoopIterationCount
     // the first executed iteration, and not a value written which could
     // replace the second operand below during the middle of execution.
     MDefinition* lhsInitial = lhs.term->toPhi()->getLoopPredecessorOperand();
     if (lhsInitial->block()->isMarked())
         return nullptr;
 
     // The second operand of the phi should be a value written by an add/sub
     // in every loop iteration, i.e. in a block which dominates the backedge.
-    MDefinition* lhsWrite = lhs.term->toPhi()->getLoopBackedgeOperand();
-    if (lhsWrite->isBeta())
-        lhsWrite = lhsWrite->getOperand(0);
+    MDefinition* lhsWrite =
+        DefinitionOrBetaInputDefinition(lhs.term->toPhi()->getLoopBackedgeOperand());
     if (!lhsWrite->isAdd() && !lhsWrite->isSub())
         return nullptr;
     if (!lhsWrite->block()->isMarked())
         return nullptr;
     MBasicBlock* bb = header->backedge();
     for (; bb != lhsWrite->block() && bb != header; bb = bb->immediateDominator()) {}
     if (bb != lhsWrite->block())
         return nullptr;
@@ -2102,17 +2111,18 @@ SymbolicBoundIsValid(MBasicBlock* header
         bb = bb->immediateDominator();
     return bb == bound->loop->test->block();
 }
 
 bool
 RangeAnalysis::tryHoistBoundsCheck(MBasicBlock* header, MBoundsCheck* ins)
 {
     // The bounds check's length must be loop invariant.
-    if (ins->length()->block()->isMarked())
+    MDefinition *length = DefinitionOrBetaInputDefinition(ins->length());
+    if (length->block()->isMarked())
         return false;
 
     // The bounds check's index should not be loop invariant (else we would
     // already have hoisted it during LICM).
     SimpleLinearSum index = ExtractLinearSum(ins->index());
     if (!index.term || !index.term->block()->isMarked())
         return false;
 
@@ -2160,17 +2170,17 @@ RangeAnalysis::tryHoistBoundsCheck(MBasi
     if (!SafeAdd(upper->sum.constant(), upperConstant, &upperConstant))
         return false;
 
     MBoundsCheckLower* lowerCheck = MBoundsCheckLower::New(alloc(), lowerTerm);
     lowerCheck->setMinimum(lowerConstant);
     lowerCheck->computeRange(alloc());
     lowerCheck->collectRangeInfoPreTrunc();
 
-    MBoundsCheck* upperCheck = MBoundsCheck::New(alloc(), upperTerm, ins->length());
+    MBoundsCheck* upperCheck = MBoundsCheck::New(alloc(), upperTerm, length);
     upperCheck->setMinimum(upperConstant);
     upperCheck->setMaximum(upperConstant);
     upperCheck->computeRange(alloc());
     upperCheck->collectRangeInfoPreTrunc();
 
     // Hoist the loop invariant upper and lower bounds checks.
     preLoop->insertBefore(preLoop->lastIns(), lowerCheck);
     preLoop->insertBefore(preLoop->lastIns(), upperCheck);