Bug 804636 part 3 - Remove JM+TI loop test analysis. r=bhackett
authorJan de Mooij <jdemooij@mozilla.com>
Sat, 27 Oct 2012 20:56:19 +0200
changeset 111748 43e09a8466c25bdd618cfae78bf39364ea32a80e
parent 111746 dcf78e64e1bd32c776699cb5d58b41ea9020a7b4
child 111749 fdefe523f873a2022d3e0c78026ac87940344f40
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewersbhackett
bugs804636
milestone19.0a1
Bug 804636 part 3 - Remove JM+TI loop test analysis. r=bhackett
js/src/methodjit/LoopState.cpp
js/src/methodjit/LoopState.h
--- a/js/src/methodjit/LoopState.cpp
+++ b/js/src/methodjit/LoopState.cpp
@@ -43,18 +43,16 @@ LoopState::init(jsbytecode *head, Jump e
 {
     this->lifetime = outerAnalysis->getLoop(head);
     JS_ASSERT(lifetime);
     JS_ASSERT(lifetime->head == uint32_t(head - outerScript->code));
     JS_ASSERT(lifetime->entry == uint32_t(entryTarget - outerScript->code));
 
     this->entry = entry;
 
-    analyzeLoopTest();
-    analyzeLoopIncrements();
     for (unsigned i = 0; i < ssa->numFrames(); i++) {
         /* Only analyze this frame if it is nested within the loop itself. */
         uint32_t index = ssa->iterFrame(i).index;
         if (index != CrossScriptSSA::OUTER_FRAME) {
             unsigned pframe = index;
             while (ssa->getFrame(pframe).parent != CrossScriptSSA::OUTER_FRAME)
                 pframe = ssa->getFrame(pframe).parent;
             uint32_t offset = ssa->getFrame(pframe).parentpc - outerScript->code;
@@ -1405,191 +1403,16 @@ LoopState::restoreInvariants(jsbytecode 
     }
 
     if (temporaryCopies)
         js_delete(temporaryCopies);
 }
 
 /* Loop analysis methods. */
 
-/*
- * Get any slot/constant accessed by a loop test operand, in terms of its value
- * at the start of the next loop iteration.
- */
-bool
-LoopState::getLoopTestAccess(const SSAValue &v, uint32_t *pslot, int32_t *pconstant)
-{
-    *pslot = UNASSIGNED;
-    *pconstant = 0;
-
-    if (v.kind() == SSAValue::PHI || v.kind() == SSAValue::VAR) {
-        /*
-         * Getting the value of a variable at a previous offset. Check that it
-         * is not updated before the start of the next loop iteration.
-         */
-        uint32_t slot;
-        uint32_t offset;
-        if (v.kind() == SSAValue::PHI) {
-            slot = v.phiSlot();
-            offset = v.phiOffset();
-        } else {
-            slot = v.varSlot();
-            offset = v.varInitial() ? 0 : v.varOffset();
-        }
-        if (outerAnalysis->slotEscapes(slot))
-            return false;
-        if (outerAnalysis->liveness(slot).firstWrite(offset + 1, lifetime->backedge) != UINT32_MAX)
-            return false;
-        *pslot = slot;
-        *pconstant = 0;
-        return true;
-    }
-
-    jsbytecode *pc = outerScript->code + v.pushedOffset();
-    JSOp op = JSOp(*pc);
-
-    switch (op) {
-      case JSOP_ZERO:
-      case JSOP_ONE:
-      case JSOP_UINT16:
-      case JSOP_UINT24:
-      case JSOP_INT8:
-      case JSOP_INT32:
-        *pconstant = GetBytecodeInteger(pc);
-        return true;
-
-      default:
-        return false;
-    }
-}
-
-void
-LoopState::analyzeLoopTest()
-{
-    if (cc.debugMode())
-        return;
-
-    /* Don't handle do-while loops. */
-    if (lifetime->entry == lifetime->head)
-        return;
-
-    /* Don't handle loops with branching inside their condition. */
-    if (lifetime->entry < lifetime->lastBlock)
-        return;
-
-    /* Get the test performed before branching. */
-    jsbytecode *backedge = outerScript->code + lifetime->backedge;
-    if (JSOp(*backedge) != JSOP_IFNE)
-        return;
-    const SSAValue &test = outerAnalysis->poppedValue(backedge, 0);
-    if (test.kind() != SSAValue::PUSHED)
-        return;
-    JSOp cmpop = JSOp(outerScript->code[test.pushedOffset()]);
-    switch (cmpop) {
-      case JSOP_GT:
-      case JSOP_GE:
-      case JSOP_LT:
-      case JSOP_LE:
-        break;
-      default:
-        return;
-    }
-
-    SSAValue one = outerAnalysis->poppedValue(test.pushedOffset(), 1);
-    SSAValue two = outerAnalysis->poppedValue(test.pushedOffset(), 0);
-
-    /* The test must be comparing known integers. */
-    if (outerAnalysis->getValueTypes(one)->getKnownTypeTag() != JSVAL_TYPE_INT32 ||
-        outerAnalysis->getValueTypes(two)->getKnownTypeTag() != JSVAL_TYPE_INT32) {
-        return;
-    }
-
-    /* Reverse the condition if the RHS is modified by the loop. */
-    uint32_t swapRHS;
-    int32_t swapConstant;
-    if (getLoopTestAccess(two, &swapRHS, &swapConstant)) {
-        if (swapRHS != UNASSIGNED && outerAnalysis->liveness(swapRHS).firstWrite(lifetime) != UINT32_MAX) {
-            SSAValue tmp = one;
-            one = two;
-            two = tmp;
-            cmpop = ReverseCompareOp(cmpop);
-        }
-    }
-
-    uint32_t lhs;
-    int32_t lhsConstant;
-    if (!getLoopTestAccess(one, &lhs, &lhsConstant))
-        return;
-
-    uint32_t rhs = UNASSIGNED;
-    int32_t rhsConstant = 0;
-    CrossSSAValue rhsv(CrossScriptSSA::OUTER_FRAME, two);
-    if (!getEntryValue(rhsv, &rhs, &rhsConstant))
-        return;
-    if (!loopInvariantEntry(rhs))
-        return;
-
-    if (lhs == UNASSIGNED)
-        return;
-
-    int32_t constant;
-    if (!SafeSub(rhsConstant, lhsConstant, &constant))
-        return;
-
-    /* x > y ==> x >= y + 1 */
-    if (cmpop == JSOP_GT && !SafeAdd(constant, 1, &constant))
-        return;
-
-    /* x < y ==> x <= y - 1 */
-    if (cmpop == JSOP_LT && !SafeSub(constant, 1, &constant))
-        return;
-
-    /* Passed all filters, this is a loop test we can capture. */
-
-    this->testLHS = lhs;
-    this->testRHS = rhs;
-    this->testConstant = constant;
-    this->testLessEqual = (cmpop == JSOP_LT || cmpop == JSOP_LE);
-}
-
-void
-LoopState::analyzeLoopIncrements()
-{
-    if (cc.debugMode())
-        return;
-
-    /*
-     * Find locals and arguments which are used in exactly one inc/dec operation in every
-     * iteration of the loop (we only match against the last basic block, but could
-     * also handle the first basic block).
-     */
-
-    for (uint32_t slot = ArgSlot(0); slot < LocalSlot(outerScript, outerScript->nfixed); slot++) {
-        if (outerAnalysis->slotEscapes(slot))
-            continue;
-
-        uint32_t offset = outerAnalysis->liveness(slot).onlyWrite(lifetime);
-        if (offset == UINT32_MAX || offset < lifetime->lastBlock)
-            continue;
-
-        jsbytecode *pc = outerScript->code + offset;
-        JSOp op = JSOp(*pc);
-        const JSCodeSpec *cs = &js_CodeSpec[op];
-        if (cs->format & (JOF_INC | JOF_DEC)) {
-            if (!outerAnalysis->integerOperation(pc))
-                continue;
-
-            Increment inc;
-            inc.slot = slot;
-            inc.offset = offset;
-            increments.append(inc);
-        }
-    }
-}
-
 bool
 LoopState::definiteArrayAccess(const SSAValue &obj, const SSAValue &index)
 {
     /*
      * Check that an index on obj is definitely accessing a dense array, giving
      * either a value modelled by the pushed types or a hole. This needs to be
      * robust against recompilations that could be triggered inside the loop:
      * the array must be loop invariant, and the index must definitely be an
--- a/js/src/methodjit/LoopState.h
+++ b/js/src/methodjit/LoopState.h
@@ -325,22 +325,19 @@ class LoopState : public MacroAssemblerT
 
     /*
      * Whether this loop only performs integer and double arithmetic and dense
      * array accesses. Integer overflows in this loop which only flow to bitops
      * can be ignored.
      */
     bool constrainedLoop;
 
-    void analyzeLoopTest();
-    void analyzeLoopIncrements();
     void analyzeLoopBody(unsigned frame);
 
     bool definiteArrayAccess(const analyze::SSAValue &obj, const analyze::SSAValue &index);
-    bool getLoopTestAccess(const analyze::SSAValue &v, uint32_t *pslot, int32_t *pconstant);
 
     bool addGrowArray(types::TypeObject *object);
     bool addModifiedProperty(types::TypeObject *object, jsid id);
 
     bool hasGrowArray(types::TypeObject *object);
     bool hasModifiedProperty(types::TypeObject *object, jsid id);
 
     uint32_t getIncrement(uint32_t slot);