Search in sources :

Example 16 with TypeBearer

use of com.android.dx.rop.type.TypeBearer in project buck by facebook.

the class LiteralOpUpgrader method tryReplacingWithConstant.

/**
     * Tries to replace an instruction with a const instruction. The given
     * instruction must have a constant result for it to be replaced.
     *
     * @param insn {@code non-null;} instruction to try to replace
     * @return true if the instruction was replaced
     */
private boolean tryReplacingWithConstant(NormalSsaInsn insn) {
    Insn originalRopInsn = insn.getOriginalRopInsn();
    Rop opcode = originalRopInsn.getOpcode();
    RegisterSpec result = insn.getResult();
    if (result != null && !ssaMeth.isRegALocal(result) && opcode.getOpcode() != RegOps.CONST) {
        TypeBearer type = insn.getResult().getTypeBearer();
        if (type.isConstant() && type.getBasicType() == Type.BT_INT) {
            // Replace the instruction with a constant
            replacePlainInsn(insn, RegisterSpecList.EMPTY, RegOps.CONST, (Constant) type);
            // Remove the source as well if this is a move-result-pseudo
            if (opcode.getOpcode() == RegOps.MOVE_RESULT_PSEUDO) {
                int pred = insn.getBlock().getPredecessors().nextSetBit(0);
                ArrayList<SsaInsn> predInsns = ssaMeth.getBlocks().get(pred).getInsns();
                NormalSsaInsn sourceInsn = (NormalSsaInsn) predInsns.get(predInsns.size() - 1);
                replacePlainInsn(sourceInsn, RegisterSpecList.EMPTY, RegOps.GOTO, null);
            }
            return true;
        }
    }
    return false;
}
Also used : Insn(com.android.dx.rop.code.Insn) PlainInsn(com.android.dx.rop.code.PlainInsn) PlainCstInsn(com.android.dx.rop.code.PlainCstInsn) Rop(com.android.dx.rop.code.Rop) TypeBearer(com.android.dx.rop.type.TypeBearer) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 17 with TypeBearer

use of com.android.dx.rop.type.TypeBearer in project buck by facebook.

the class PhiTypeResolver method resolveResultType.

/**
     * Resolves the result of a phi insn based on its operands. The "void"
     * type, which is a nonsensical type for a register, is used for
     * registers defined by as-of-yet-unresolved phi operations.
     *
     * @return true if the result type changed, false if no change
     */
boolean resolveResultType(PhiInsn insn) {
    insn.updateSourcesToDefinitions(ssaMeth);
    RegisterSpecList sources = insn.getSources();
    // Start by finding the first non-void operand
    RegisterSpec first = null;
    int firstIndex = -1;
    int szSources = sources.size();
    for (int i = 0; i < szSources; i++) {
        RegisterSpec rs = sources.get(i);
        if (rs.getBasicType() != Type.BT_VOID) {
            first = rs;
            firstIndex = i;
        }
    }
    if (first == null) {
        // All operands are void -- we're not ready to resolve yet
        return false;
    }
    LocalItem firstLocal = first.getLocalItem();
    TypeBearer mergedType = first.getType();
    boolean sameLocals = true;
    for (int i = 0; i < szSources; i++) {
        if (i == firstIndex) {
            continue;
        }
        RegisterSpec rs = sources.get(i);
        // Just skip void (unresolved phi results) for now
        if (rs.getBasicType() == Type.BT_VOID) {
            continue;
        }
        sameLocals = sameLocals && equalsHandlesNulls(firstLocal, rs.getLocalItem());
        mergedType = Merger.mergeType(mergedType, rs.getType());
    }
    TypeBearer newResultType;
    if (mergedType != null) {
        newResultType = mergedType;
    } else {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < szSources; i++) {
            sb.append(sources.get(i).toString());
            sb.append(' ');
        }
        throw new RuntimeException("Couldn't map types in phi insn:" + sb);
    }
    LocalItem newLocal = sameLocals ? firstLocal : null;
    RegisterSpec result = insn.getResult();
    if ((result.getTypeBearer() == newResultType) && equalsHandlesNulls(newLocal, result.getLocalItem())) {
        return false;
    }
    insn.changeResultType(newResultType, newLocal);
    return true;
}
Also used : LocalItem(com.android.dx.rop.code.LocalItem) TypeBearer(com.android.dx.rop.type.TypeBearer) RegisterSpecList(com.android.dx.rop.code.RegisterSpecList) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 18 with TypeBearer

use of com.android.dx.rop.type.TypeBearer in project buck by facebook.

the class OneLocalsArray method getCategory1.

/** {@inheritDoc} */
public TypeBearer getCategory1(int idx) {
    TypeBearer result = get(idx);
    Type type = result.getType();
    if (type.isUninitialized()) {
        return throwSimException(idx, "uninitialized instance");
    }
    if (type.isCategory2()) {
        return throwSimException(idx, "category-2");
    }
    return result;
}
Also used : Type(com.android.dx.rop.type.Type) TypeBearer(com.android.dx.rop.type.TypeBearer)

Example 19 with TypeBearer

use of com.android.dx.rop.type.TypeBearer in project buck by facebook.

the class ExecutionStack method pop.

/**
     * Pops the top element off of the stack.
     *
     * @return {@code non-null;} the type formerly on the top of the stack
     * @throws SimException thrown if the stack is empty
     */
public TypeBearer pop() {
    throwIfImmutable();
    TypeBearer result = peek(0);
    stack[stackPtr - 1] = null;
    local[stackPtr - 1] = false;
    stackPtr -= result.getType().getCategory();
    return result;
}
Also used : TypeBearer(com.android.dx.rop.type.TypeBearer)

Example 20 with TypeBearer

use of com.android.dx.rop.type.TypeBearer in project buck by facebook.

the class Merger method mergeLocals.

/**
     * Merges two locals arrays. If the merged result is the same as the first
     * argument, then return the first argument (not a copy).
     *
     * @param locals1 {@code non-null;} a locals array
     * @param locals2 {@code non-null;} another locals array
     * @return {@code non-null;} the result of merging the two locals arrays
     */
public static OneLocalsArray mergeLocals(OneLocalsArray locals1, OneLocalsArray locals2) {
    if (locals1 == locals2) {
        // Easy out.
        return locals1;
    }
    int sz = locals1.getMaxLocals();
    OneLocalsArray result = null;
    if (locals2.getMaxLocals() != sz) {
        throw new SimException("mismatched maxLocals values");
    }
    for (int i = 0; i < sz; i++) {
        TypeBearer tb1 = locals1.getOrNull(i);
        TypeBearer tb2 = locals2.getOrNull(i);
        TypeBearer resultType = mergeType(tb1, tb2);
        if (resultType != tb1) {
            /*
                 * We only need to do anything when the result differs
                 * from what is in the first array, since that's what the
                 * result gets initialized to.
                 */
            if (result == null) {
                result = locals1.copy();
            }
            if (resultType == null) {
                result.invalidate(i);
            } else {
                result.set(i, resultType);
            }
        }
    }
    if (result == null) {
        return locals1;
    }
    result.setImmutable();
    return result;
}
Also used : TypeBearer(com.android.dx.rop.type.TypeBearer)

Aggregations

TypeBearer (com.android.dx.rop.type.TypeBearer)20 RegisterSpec (com.android.dx.rop.code.RegisterSpec)8 Type (com.android.dx.rop.type.Type)5 RegisterSpecList (com.android.dx.rop.code.RegisterSpecList)4 Constant (com.android.dx.rop.cst.Constant)4 TypedConstant (com.android.dx.rop.cst.TypedConstant)4 Insn (com.android.dx.rop.code.Insn)3 PlainCstInsn (com.android.dx.rop.code.PlainCstInsn)3 PlainInsn (com.android.dx.rop.code.PlainInsn)3 ArrayList (java.util.ArrayList)3 HashSet (java.util.HashSet)3 FillArrayDataInsn (com.android.dx.rop.code.FillArrayDataInsn)2 Rop (com.android.dx.rop.code.Rop)2 ThrowingCstInsn (com.android.dx.rop.code.ThrowingCstInsn)2 ThrowingInsn (com.android.dx.rop.code.ThrowingInsn)2 CstInteger (com.android.dx.rop.cst.CstInteger)2 CstLiteralBits (com.android.dx.rop.cst.CstLiteralBits)2 LocalItem (com.android.dx.rop.code.LocalItem)1 SourcePosition (com.android.dx.rop.code.SourcePosition)1 SwitchInsn (com.android.dx.rop.code.SwitchInsn)1