Search in sources :

Example 1 with CstInsn

use of com.android.dx.rop.code.CstInsn in project buck by facebook.

the class SCCP method simulateMath.

/**
     * Simulates math insns, if possible.
     *
     * @param insn non-null insn to simulate
     * @param resultType basic type of the result
     * @return constant result or null if not simulatable.
     */
private Constant simulateMath(SsaInsn insn, int resultType) {
    Insn ropInsn = insn.getOriginalRopInsn();
    int opcode = insn.getOpcode().getOpcode();
    RegisterSpecList sources = insn.getSources();
    int regA = sources.get(0).getReg();
    Constant cA;
    Constant cB;
    if (latticeValues[regA] != CONSTANT) {
        cA = null;
    } else {
        cA = latticeConstants[regA];
    }
    if (sources.size() == 1) {
        CstInsn cstInsn = (CstInsn) ropInsn;
        cB = cstInsn.getConstant();
    } else {
        /* sources.size() == 2 */
        int regB = sources.get(1).getReg();
        if (latticeValues[regB] != CONSTANT) {
            cB = null;
        } else {
            cB = latticeConstants[regB];
        }
    }
    if (cA == null || cB == null) {
        //TODO handle a constant of 0 with MUL or AND
        return null;
    }
    switch(resultType) {
        case Type.BT_INT:
            int vR;
            boolean skip = false;
            int vA = ((CstInteger) cA).getValue();
            int vB = ((CstInteger) cB).getValue();
            switch(opcode) {
                case RegOps.ADD:
                    vR = vA + vB;
                    break;
                case RegOps.SUB:
                    // 1 source for reverse sub, 2 sources for regular sub
                    if (sources.size() == 1) {
                        vR = vB - vA;
                    } else {
                        vR = vA - vB;
                    }
                    break;
                case RegOps.MUL:
                    vR = vA * vB;
                    break;
                case RegOps.DIV:
                    if (vB == 0) {
                        skip = true;
                        // just to hide a warning
                        vR = 0;
                    } else {
                        vR = vA / vB;
                    }
                    break;
                case RegOps.AND:
                    vR = vA & vB;
                    break;
                case RegOps.OR:
                    vR = vA | vB;
                    break;
                case RegOps.XOR:
                    vR = vA ^ vB;
                    break;
                case RegOps.SHL:
                    vR = vA << vB;
                    break;
                case RegOps.SHR:
                    vR = vA >> vB;
                    break;
                case RegOps.USHR:
                    vR = vA >>> vB;
                    break;
                case RegOps.REM:
                    if (vB == 0) {
                        skip = true;
                        // just to hide a warning
                        vR = 0;
                    } else {
                        vR = vA % vB;
                    }
                    break;
                default:
                    throw new RuntimeException("Unexpected op");
            }
            return skip ? null : CstInteger.make(vR);
        default:
            // not yet supported
            return null;
    }
}
Also used : CstInsn(com.android.dx.rop.code.CstInsn) Insn(com.android.dx.rop.code.Insn) PlainInsn(com.android.dx.rop.code.PlainInsn) CstInsn(com.android.dx.rop.code.CstInsn) Constant(com.android.dx.rop.cst.Constant) TypedConstant(com.android.dx.rop.cst.TypedConstant) CstInteger(com.android.dx.rop.cst.CstInteger) RegisterSpecList(com.android.dx.rop.code.RegisterSpecList)

Example 2 with CstInsn

use of com.android.dx.rop.code.CstInsn in project buck by facebook.

the class SCCP method simulateStmt.

/**
     * Simulates a statement and set the result lattice value.
     * @param insn instruction to simulate
     */
private void simulateStmt(SsaInsn insn) {
    Insn ropInsn = insn.getOriginalRopInsn();
    if (ropInsn.getOpcode().getBranchingness() != Rop.BRANCH_NONE || ropInsn.getOpcode().isCallLike()) {
        simulateBranch(insn);
    }
    int opcode = insn.getOpcode().getOpcode();
    RegisterSpec result = insn.getResult();
    if (result == null) {
        // Find move-result-pseudo result for int div and int rem
        if (opcode == RegOps.DIV || opcode == RegOps.REM) {
            SsaBasicBlock succ = insn.getBlock().getPrimarySuccessor();
            result = succ.getInsns().get(0).getResult();
        } else {
            return;
        }
    }
    int resultReg = result.getReg();
    int resultValue = VARYING;
    Constant resultConstant = null;
    switch(opcode) {
        case RegOps.CONST:
            {
                CstInsn cstInsn = (CstInsn) ropInsn;
                resultValue = CONSTANT;
                resultConstant = cstInsn.getConstant();
                break;
            }
        case RegOps.MOVE:
            {
                if (insn.getSources().size() == 1) {
                    int sourceReg = insn.getSources().get(0).getReg();
                    resultValue = latticeValues[sourceReg];
                    resultConstant = latticeConstants[sourceReg];
                }
                break;
            }
        case RegOps.ADD:
        case RegOps.SUB:
        case RegOps.MUL:
        case RegOps.DIV:
        case RegOps.AND:
        case RegOps.OR:
        case RegOps.XOR:
        case RegOps.SHL:
        case RegOps.SHR:
        case RegOps.USHR:
        case RegOps.REM:
            {
                resultConstant = simulateMath(insn, result.getBasicType());
                if (resultConstant != null) {
                    resultValue = CONSTANT;
                }
                break;
            }
        case RegOps.MOVE_RESULT_PSEUDO:
            {
                if (latticeValues[resultReg] == CONSTANT) {
                    resultValue = latticeValues[resultReg];
                    resultConstant = latticeConstants[resultReg];
                }
                break;
            }
        // TODO: Eliminate check casts that we can prove the type of.
        default:
            {
            }
    }
    if (setLatticeValueTo(resultReg, resultValue, resultConstant)) {
        addUsersToWorklist(resultReg, resultValue);
    }
}
Also used : CstInsn(com.android.dx.rop.code.CstInsn) Insn(com.android.dx.rop.code.Insn) PlainInsn(com.android.dx.rop.code.PlainInsn) CstInsn(com.android.dx.rop.code.CstInsn) Constant(com.android.dx.rop.cst.Constant) TypedConstant(com.android.dx.rop.cst.TypedConstant) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 3 with CstInsn

use of com.android.dx.rop.code.CstInsn in project buck by facebook.

the class MoveParamCombiner method getParamIndex.

/**
     * Returns the parameter index associated with a move-param insn. Does
     * not verify that the insn is a move-param insn.
     *
     * @param insn {@code non-null;} a move-param insn
     * @return {@code >=0;} parameter index
     */
private int getParamIndex(NormalSsaInsn insn) {
    CstInsn cstInsn = (CstInsn) (insn.getOriginalRopInsn());
    int param = ((CstInteger) cstInsn.getConstant()).getValue();
    return param;
}
Also used : CstInsn(com.android.dx.rop.code.CstInsn) CstInteger(com.android.dx.rop.cst.CstInteger)

Example 4 with CstInsn

use of com.android.dx.rop.code.CstInsn in project buck by facebook.

the class FirstFitLocalCombiningAllocator method getParameterIndexForReg.

/**
     * Gets the parameter index for SSA registers that are method parameters.
     * {@code -1} is returned for non-parameter registers.
     *
     * @param ssaReg {@code >=0;} SSA register to look up
     * @return parameter index or {@code -1} if not a parameter
     */
private int getParameterIndexForReg(int ssaReg) {
    SsaInsn defInsn = ssaMeth.getDefinitionForRegister(ssaReg);
    if (defInsn == null) {
        return -1;
    }
    Rop opcode = defInsn.getOpcode();
    // opcode == null for phi insns.
    if (opcode != null && opcode.getOpcode() == RegOps.MOVE_PARAM) {
        CstInsn origInsn = (CstInsn) defInsn.getOriginalRopInsn();
        return ((CstInteger) origInsn.getConstant()).getValue();
    }
    return -1;
}
Also used : CstInsn(com.android.dx.rop.code.CstInsn) Rop(com.android.dx.rop.code.Rop) CstInteger(com.android.dx.rop.cst.CstInteger) NormalSsaInsn(com.android.dx.ssa.NormalSsaInsn) SsaInsn(com.android.dx.ssa.SsaInsn)

Aggregations

CstInsn (com.android.dx.rop.code.CstInsn)4 CstInteger (com.android.dx.rop.cst.CstInteger)3 Insn (com.android.dx.rop.code.Insn)2 PlainInsn (com.android.dx.rop.code.PlainInsn)2 Constant (com.android.dx.rop.cst.Constant)2 TypedConstant (com.android.dx.rop.cst.TypedConstant)2 RegisterSpec (com.android.dx.rop.code.RegisterSpec)1 RegisterSpecList (com.android.dx.rop.code.RegisterSpecList)1 Rop (com.android.dx.rop.code.Rop)1 NormalSsaInsn (com.android.dx.ssa.NormalSsaInsn)1 SsaInsn (com.android.dx.ssa.SsaInsn)1