Search in sources :

Example 86 with RegisterSpec

use of com.android.dx.rop.code.RegisterSpec 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 87 with RegisterSpec

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

the class SsaBasicBlock method scheduleUseBeforeAssigned.

/**
     * Ensures that all move operations in this block occur such that
     * reads of any register happen before writes to that register.
     * NOTE: caller is expected to returnSpareRegisters()!
     *
     * TODO: See Briggs, et al "Practical Improvements to the Construction and
     * Destruction of Static Single Assignment Form" section 5. a) This can
     * be done in three passes.
     *
     * @param toSchedule List of instructions. Must consist only of moves.
     */
private void scheduleUseBeforeAssigned(List<SsaInsn> toSchedule) {
    BitSet regsUsedAsSources = new BitSet(parent.getRegCount());
    // TODO: Get rid of this.
    BitSet regsUsedAsResults = new BitSet(parent.getRegCount());
    int sz = toSchedule.size();
    int insertPlace = 0;
    while (insertPlace < sz) {
        int oldInsertPlace = insertPlace;
        // Record all registers used as sources in this block.
        for (int i = insertPlace; i < sz; i++) {
            setRegsUsed(regsUsedAsSources, toSchedule.get(i).getSources().get(0));
            setRegsUsed(regsUsedAsResults, toSchedule.get(i).getResult());
        }
        /*
             * If there are no circular dependencies, then there exists
             * n instructions where n > 1 whose result is not used as a source.
             */
        for (int i = insertPlace; i < sz; i++) {
            SsaInsn insn = toSchedule.get(i);
            /*
                 * Move these n registers to the front, since they overwrite
                 * nothing.
                 */
            if (!checkRegUsed(regsUsedAsSources, insn.getResult())) {
                Collections.swap(toSchedule, i, insertPlace++);
            }
        }
        /*
             * If we've made no progress in this iteration, there's a
             * circular dependency. Split it using the temp reg.
             */
        if (oldInsertPlace == insertPlace) {
            SsaInsn insnToSplit = null;
            // Find an insn whose result is used as a source.
            for (int i = insertPlace; i < sz; i++) {
                SsaInsn insn = toSchedule.get(i);
                if (checkRegUsed(regsUsedAsSources, insn.getResult()) && checkRegUsed(regsUsedAsResults, insn.getSources().get(0))) {
                    insnToSplit = insn;
                    /*
                         * We're going to split this insn; move it to the
                         * front.
                         */
                    Collections.swap(toSchedule, insertPlace, i);
                    break;
                }
            }
            // At least one insn will be set above.
            RegisterSpec result = insnToSplit.getResult();
            RegisterSpec tempSpec = result.withReg(parent.borrowSpareRegister(result.getCategory()));
            NormalSsaInsn toAdd = new NormalSsaInsn(new PlainInsn(Rops.opMove(result.getType()), SourcePosition.NO_INFO, tempSpec, insnToSplit.getSources()), this);
            toSchedule.add(insertPlace++, toAdd);
            RegisterSpecList newSources = RegisterSpecList.make(tempSpec);
            NormalSsaInsn toReplace = new NormalSsaInsn(new PlainInsn(Rops.opMove(result.getType()), SourcePosition.NO_INFO, result, newSources), this);
            toSchedule.set(insertPlace, toReplace);
            // The size changed.
            sz = toSchedule.size();
        }
        regsUsedAsSources.clear();
        regsUsedAsResults.clear();
    }
}
Also used : PlainInsn(com.android.dx.rop.code.PlainInsn) BitSet(java.util.BitSet) RegisterSpecList(com.android.dx.rop.code.RegisterSpecList) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 88 with RegisterSpec

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

the class NormalSsaInsn method getLocalAssignment.

/** {@inheritDoc} */
@Override
public RegisterSpec getLocalAssignment() {
    RegisterSpec assignment;
    if (insn.getOpcode().getOpcode() == RegOps.MARK_LOCAL) {
        assignment = insn.getSources().get(0);
    } else {
        assignment = getResult();
    }
    if (assignment == null) {
        return null;
    }
    LocalItem local = assignment.getLocalItem();
    if (local == null) {
        return null;
    }
    return assignment;
}
Also used : LocalItem(com.android.dx.rop.code.LocalItem) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 89 with RegisterSpec

use of com.android.dx.rop.code.RegisterSpec 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 90 with RegisterSpec

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

the class HighRegisterPrefix method calculateInsnsIfNecessary.

/**
     * Helper for {@link #codeSize} and {@link #writeTo} which sets up
     * {@link #insns} if not already done.
     */
private void calculateInsnsIfNecessary() {
    if (insns != null) {
        return;
    }
    RegisterSpecList registers = getRegisters();
    int sz = registers.size();
    insns = new SimpleInsn[sz];
    for (int i = 0, outAt = 0; i < sz; i++) {
        RegisterSpec src = registers.get(i);
        insns[i] = moveInsnFor(src, outAt);
        outAt += src.getCategory();
    }
}
Also used : RegisterSpecList(com.android.dx.rop.code.RegisterSpecList) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Aggregations

RegisterSpec (com.android.dx.rop.code.RegisterSpec)135 RegisterSpecList (com.android.dx.rop.code.RegisterSpecList)50 PlainInsn (com.android.dx.rop.code.PlainInsn)24 Constant (com.android.dx.rop.cst.Constant)20 TypedConstant (com.android.dx.rop.cst.TypedConstant)16 TypeBearer (com.android.dx.rop.type.TypeBearer)16 ArrayList (java.util.ArrayList)16 Insn (com.android.dx.rop.code.Insn)14 PlainCstInsn (com.android.dx.rop.code.PlainCstInsn)14 Rop (com.android.dx.rop.code.Rop)14 ThrowingCstInsn (com.android.dx.rop.code.ThrowingCstInsn)14 CstType (com.android.dx.rop.cst.CstType)14 BitSet (java.util.BitSet)11 LocalItem (com.android.dx.rop.code.LocalItem)10 RegisterSpecSet (com.android.dx.rop.code.RegisterSpecSet)10 ThrowingInsn (com.android.dx.rop.code.ThrowingInsn)10 CstString (com.android.dx.rop.cst.CstString)10 HashSet (java.util.HashSet)10 SourcePosition (com.android.dx.rop.code.SourcePosition)8 CstFieldRef (com.android.dx.rop.cst.CstFieldRef)8