Exemplo n.º 1
0
static void dumpIVList(CompilationUnit *cUnit)
{
    unsigned int i;
    GrowableList *ivList = cUnit->loopAnalysis->ivList;

    for (i = 0; i < ivList->numUsed; i++) {
        InductionVariableInfo *ivInfo =
            (InductionVariableInfo *) ivList->elemList[i];
        int iv = dvmConvertSSARegToDalvik(cUnit, ivInfo->ssaReg);
        /* Basic IV */
        if (ivInfo->ssaReg == ivInfo->basicSSAReg) {
            LOGE("BIV %d: s%d(v%d_%d) + %d", i,
                 ivInfo->ssaReg,
                 DECODE_REG(iv), DECODE_SUB(iv),
                 ivInfo->inc);
        /* Dependent IV */
        } else {
            int biv = dvmConvertSSARegToDalvik(cUnit, ivInfo->basicSSAReg);

            LOGE("DIV %d: s%d(v%d_%d) = %d * s%d(v%d_%d) + %d", i,
                 ivInfo->ssaReg,
                 DECODE_REG(iv), DECODE_SUB(iv),
                 ivInfo->m,
                 ivInfo->basicSSAReg,
                 DECODE_REG(biv), DECODE_SUB(biv),
                 ivInfo->c);
        }
    }
}
Exemplo n.º 2
0
/* Debugging routines */
static void dumpConstants(CompilationUnit *cUnit)
{
    int i;
    LOGE("LOOP starting offset: %x", cUnit->entryBlock->startOffset);
    for (i = 0; i < cUnit->numSSARegs; i++) {
        if (dvmIsBitSet(cUnit->isConstantV, i)) {
            int subNReg = dvmConvertSSARegToDalvik(cUnit, i);
            LOGE("CONST: s%d(v%d_%d) has %d", i,
                 DECODE_REG(subNReg), DECODE_SUB(subNReg),
                 cUnit->constantValues[i]);
        }
    }
}
Exemplo n.º 3
0
/* Setup a new SSA register for a given Dalvik register */
static void handleSSADef(CompilationUnit *cUnit, int *defs, int dalvikReg,
                         int regIndex)
{
    int encodedValue = cUnit->dalvikToSSAMap[dalvikReg];
    int ssaReg = cUnit->numSSARegs++;
    /* Bump up the subscript */
    int dalvikSub = DECODE_SUB(encodedValue) + 1;
    int newD2SMapping = ENCODE_REG_SUB(ssaReg, dalvikSub);

    cUnit->dalvikToSSAMap[dalvikReg] = newD2SMapping;

    int newS2DMapping = ENCODE_REG_SUB(dalvikReg, dalvikSub);
    dvmInsertGrowableList(cUnit->ssaToDalvikMap, (void *) newS2DMapping);
	LOG("the insert newS2DMapping is %x\n", newS2DMapping);

    defs[regIndex] = ssaReg;
}
Exemplo n.º 4
0
/*
 * A loop is considered optimizable if:
 * 1) It has one basic induction variable.
 * 2) The loop back branch compares the BIV with a constant.
 * 3) We need to normalize the loop exit condition so that the loop is exited
 *    via the taken path.
 * 4) If it is a count-up loop, the condition is GE/GT. Otherwise it is
 *    LE/LT/LEZ/LTZ for a count-down loop.
 *
 * Return false for loops that fail the above tests.
 */
static bool isSimpleCountedLoop(CompilationUnit *cUnit)
{
    unsigned int i;
    BasicBlock *loopBackBlock = cUnit->entryBlock->fallThrough;
    LoopAnalysis *loopAnalysis = cUnit->loopAnalysis;

    if (loopAnalysis->numBasicIV != 1) return false;
    for (i = 0; i < loopAnalysis->ivList->numUsed; i++) {
        InductionVariableInfo *ivInfo;

        ivInfo = GET_ELEM_N(loopAnalysis->ivList, InductionVariableInfo*, i);
        /* Count up or down loop? */
        if (ivInfo->ssaReg == ivInfo->basicSSAReg) {
            /* Infinite loop */
            if (ivInfo->inc == 0) {
                return false;
            }
            loopAnalysis->isCountUpLoop = ivInfo->inc > 0;
            break;
        }
    }

    /* Find the block that ends with a branch to exit the loop */
    while (true) {
        loopBackBlock = findPredecessorBlock(cUnit, loopBackBlock);
        /* Loop structure not recognized as counted blocks */
        if (loopBackBlock == NULL) {
            return false;
        }
        /* Unconditional goto - continue to trace up the predecessor chain */
        if (loopBackBlock->taken == NULL) {
            continue;
        }
        break;
    }

    MIR *branch = loopBackBlock->lastMIRInsn;
    Opcode opcode = branch->dalvikInsn.opcode;

    /* Last instruction is not a conditional branch - bail */
    if (dexGetFlagsFromOpcode(opcode) != (kInstrCanContinue|kInstrCanBranch)) {
        return false;
    }

    int endSSAReg;
    int endDalvikReg;

    /* reg/reg comparison */
    if (branch->ssaRep->numUses == 2) {
        if (branch->ssaRep->uses[0] == loopAnalysis->ssaBIV) {
            endSSAReg = branch->ssaRep->uses[1];
        } else if (branch->ssaRep->uses[1] == loopAnalysis->ssaBIV) {
            endSSAReg = branch->ssaRep->uses[0];
            opcode = negateOpcode(opcode);
        } else {
            return false;
        }
        endDalvikReg = dvmConvertSSARegToDalvik(cUnit, endSSAReg);
        /*
         * If the comparison is not between the BIV and a loop invariant,
         * return false. endDalvikReg is loop invariant if one of the
         * following is true:
         * - It is not defined in the loop (ie DECODE_SUB returns 0)
         * - It is reloaded with a constant
         */
        if ((DECODE_SUB(endDalvikReg) != 0) &&
            !dvmIsBitSet(cUnit->isConstantV, endSSAReg)) {
            return false;
        }
    /* Compare against zero */
    } else if (branch->ssaRep->numUses == 1) {
        if (branch->ssaRep->uses[0] == loopAnalysis->ssaBIV) {
            /* Keep the compiler happy */
            endDalvikReg = -1;
        } else {
            return false;
        }
    } else {
        return false;
    }

    /* Normalize the loop exit check as "if (iv op end) exit;" */
    if (loopBackBlock->taken->blockType == kDalvikByteCode) {
        opcode = negateOpcode(opcode);
    }

    if (loopAnalysis->isCountUpLoop) {
        /*
         * If the normalized condition op is not > or >=, this is not an
         * optimization candidate.
         */
        switch (opcode) {
            case OP_IF_GT:
            case OP_IF_GE:
                break;
            default:
                return false;
        }
        loopAnalysis->endConditionReg = DECODE_REG(endDalvikReg);
    } else  {
        /*
         * If the normalized condition op is not < or <=, this is not an
         * optimization candidate.
         */
        switch (opcode) {
            case OP_IF_LT:
            case OP_IF_LE:
                loopAnalysis->endConditionReg = DECODE_REG(endDalvikReg);
                break;
            case OP_IF_LTZ:
            case OP_IF_LEZ:
                break;
            default:
                return false;
        }
    }
    /*
     * Remember the normalized opcode, which will be used to determine the end
     * value used for the yanked range checks.
     */
    loopAnalysis->loopBranchOpcode = opcode;
    return true;
}