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 111616 43e09a8466c25bdd618cfae78bf39364ea32a80e
parent 111614 dcf78e64e1bd32c776699cb5d58b41ea9020a7b4
child 111617 fdefe523f873a2022d3e0c78026ac87940344f40
push id23757
push userryanvm@gmail.com
push dateSun, 28 Oct 2012 01:05:54 +0000
treeherdermozilla-central@3c70c13dd261 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbhackett
bugs804636
milestone19.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 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);