Search in sources :

Example 11 with LocalItem

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

use of com.android.dx.rop.code.LocalItem in project J2ME-Loader by nikita36078.

the class ConstCollector method fixLocalAssignment.

/**
 * Inserts mark-locals if necessary when changing a register. If
 * the definition of {@code origReg} is associated with a local
 * variable, then insert a mark-local for {@code newReg} just below
 * it. We expect the definition of  {@code origReg} to ultimately
 * be removed by the dead code eliminator
 *
 * @param origReg {@code non-null;} original register
 * @param newReg {@code non-null;} new register that will replace
 * {@code origReg}
 */
private void fixLocalAssignment(RegisterSpec origReg, RegisterSpec newReg) {
    for (SsaInsn use : ssaMeth.getUseListForRegister(origReg.getReg())) {
        RegisterSpec localAssignment = use.getLocalAssignment();
        if (localAssignment == null) {
            continue;
        }
        if (use.getResult() == null) {
            /*
                 * This is a mark-local. it will be updated when all uses
                 * are updated.
                 */
            continue;
        }
        LocalItem local = localAssignment.getLocalItem();
        // Un-associate original use.
        use.setResultLocal(null);
        // Now add a mark-local to the new reg immediately after.
        newReg = newReg.withLocalItem(local);
        SsaInsn newInsn = SsaInsn.makeFromRop(new PlainInsn(Rops.opMarkLocal(newReg), SourcePosition.NO_INFO, null, RegisterSpecList.make(newReg)), use.getBlock());
        ArrayList<SsaInsn> insns = use.getBlock().getInsns();
        insns.add(insns.indexOf(use) + 1, newInsn);
    }
}
Also used : PlainInsn(com.android.dx.rop.code.PlainInsn) LocalItem(com.android.dx.rop.code.LocalItem) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 13 with LocalItem

use of com.android.dx.rop.code.LocalItem in project J2ME-Loader by nikita36078.

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 14 with LocalItem

use of com.android.dx.rop.code.LocalItem in project J2ME-Loader by nikita36078.

the class FirstFitLocalCombiningAllocator method adjustAndMapSourceRangeRange.

/**
 * Maps the source registers of the specified instruction such that they
 * will fall in a contiguous range in rop form. Moves are inserted as
 * necessary to allow the range to be allocated.
 *
 * @param insn {@code non-null;} insn whos sources to process
 */
private void adjustAndMapSourceRangeRange(NormalSsaInsn insn) {
    int newRegStart = findRangeAndAdjust(insn);
    RegisterSpecList sources = insn.getSources();
    int szSources = sources.size();
    int nextRopReg = newRegStart;
    for (int i = 0; i < szSources; i++) {
        RegisterSpec source = sources.get(i);
        int sourceReg = source.getReg();
        int category = source.getCategory();
        int curRopReg = nextRopReg;
        nextRopReg += category;
        if (ssaRegsMapped.get(sourceReg)) {
            continue;
        }
        LocalItem localItem = getLocalItemForReg(sourceReg);
        addMapping(source, curRopReg);
        if (localItem != null) {
            markReserved(curRopReg, category);
            ArrayList<RegisterSpec> similarRegisters = localVariables.get(localItem);
            int szSimilar = similarRegisters.size();
            /*
                 * Try to map all SSA registers also associated with
                 * this local.
                 */
            for (int j = 0; j < szSimilar; j++) {
                RegisterSpec similarSpec = similarRegisters.get(j);
                int similarReg = similarSpec.getReg();
                // Don't map anything that's also a source.
                if (-1 != sources.indexOfRegister(similarReg)) {
                    continue;
                }
                // Registers left unmapped will get handled later.
                tryMapReg(similarSpec, curRopReg, category);
            }
        }
    }
}
Also used : LocalItem(com.android.dx.rop.code.LocalItem) RegisterSpecList(com.android.dx.rop.code.RegisterSpecList) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Aggregations

LocalItem (com.android.dx.rop.code.LocalItem)14 RegisterSpec (com.android.dx.rop.code.RegisterSpec)10 RegisterSpecList (com.android.dx.rop.code.RegisterSpecList)4 PlainInsn (com.android.dx.rop.code.PlainInsn)2 CstString (com.android.dx.rop.cst.CstString)2 CstType (com.android.dx.rop.cst.CstType)2 Type (com.android.dx.rop.type.Type)2 TypeBearer (com.android.dx.rop.type.TypeBearer)2 ArrayList (java.util.ArrayList)2 Map (java.util.Map)2 TreeMap (java.util.TreeMap)2