Search in sources :

Example 56 with RegisterSpec

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

the class PhiTypeResolver method run.

/**
 * Runs the phi-type resolver.
 */
private void run() {
    int regCount = ssaMeth.getRegCount();
    for (int reg = 0; reg < regCount; reg++) {
        SsaInsn definsn = ssaMeth.getDefinitionForRegister(reg);
        if (definsn != null && (definsn.getResult().getBasicType() == Type.BT_VOID)) {
            worklist.set(reg);
        }
    }
    int reg;
    while (0 <= (reg = worklist.nextSetBit(0))) {
        worklist.clear(reg);
        /*
             * definitions on the worklist have a type of BT_VOID, which
             * must have originated from a PhiInsn.
             */
        PhiInsn definsn = (PhiInsn) ssaMeth.getDefinitionForRegister(reg);
        if (resolveResultType(definsn)) {
            /*
                 * If the result type has changed, re-resolve all phis
                 * that use this.
                 */
            List<SsaInsn> useList = ssaMeth.getUseListForRegister(reg);
            int sz = useList.size();
            for (int i = 0; i < sz; i++) {
                SsaInsn useInsn = useList.get(i);
                RegisterSpec resultReg = useInsn.getResult();
                if (resultReg != null && useInsn instanceof PhiInsn) {
                    worklist.set(resultReg.getReg());
                }
            }
        }
    }
}
Also used : RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 57 with RegisterSpec

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

the class RegisterMapper method map.

/**
 * @param sources old register set
 * @return new mapped register set, or old if nothing has changed.
 */
public final RegisterSpecSet map(RegisterSpecSet sources) {
    int sz = sources.getMaxSize();
    RegisterSpecSet newSources = new RegisterSpecSet(getNewRegisterCount());
    for (int i = 0; i < sz; i++) {
        RegisterSpec registerSpec = sources.get(i);
        if (registerSpec != null) {
            newSources.put(map(registerSpec));
        }
    }
    newSources.setImmutable();
    // Return the old sources if nothing has changed.
    return newSources.equals(sources) ? sources : newSources;
}
Also used : RegisterSpecSet(com.android.dx.rop.code.RegisterSpecSet) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 58 with RegisterSpec

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

the class SCCP method replaceConstants.

/**
 * Replaces TypeBearers in source register specs with constant type
 * bearers if possible. These are then referenced in later optimization
 * steps.
 */
private void replaceConstants() {
    for (int reg = 0; reg < regCount; reg++) {
        if (latticeValues[reg] != CONSTANT) {
            continue;
        }
        if (!(latticeConstants[reg] instanceof TypedConstant)) {
            // We can't do much with these
            continue;
        }
        SsaInsn defn = ssaMeth.getDefinitionForRegister(reg);
        TypeBearer typeBearer = defn.getResult().getTypeBearer();
        if (typeBearer.isConstant()) {
            /*
                 * The definition was a constant already.
                 * The uses should be as well.
                 */
            continue;
        }
        // Update the destination RegisterSpec with the constant value
        RegisterSpec dest = defn.getResult();
        RegisterSpec newDest = dest.withType((TypedConstant) latticeConstants[reg]);
        defn.setResult(newDest);
        /*
             * Update the sources RegisterSpec's of all non-move uses.
             * These will be used in later steps.
             */
        for (SsaInsn insn : ssaMeth.getUseListForRegister(reg)) {
            if (insn.isPhiOrMove()) {
                continue;
            }
            NormalSsaInsn nInsn = (NormalSsaInsn) insn;
            RegisterSpecList sources = insn.getSources();
            int index = sources.indexOfRegister(reg);
            RegisterSpec spec = sources.get(index);
            RegisterSpec newSpec = spec.withType((TypedConstant) latticeConstants[reg]);
            nInsn.changeOneSource(index, newSpec);
        }
    }
}
Also used : TypedConstant(com.android.dx.rop.cst.TypedConstant) TypeBearer(com.android.dx.rop.type.TypeBearer) RegisterSpecList(com.android.dx.rop.code.RegisterSpecList) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 59 with RegisterSpec

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

the class SsaConverter method placePhiFunctions.

/**
 * See Appel algorithm 19.6:
 *
 * Place Phi functions in appropriate locations.
 *
 * @param ssaMeth {@code non-null;} method to process.
 * Modifications are made in-place.
 * @param localInfo {@code non-null;} local variable info, used
 * when placing phis
 * @param threshold registers below this number are ignored
 */
private static void placePhiFunctions(SsaMethod ssaMeth, LocalVariableInfo localInfo, int threshold) {
    ArrayList<SsaBasicBlock> ssaBlocks;
    int regCount;
    int blockCount;
    ssaBlocks = ssaMeth.getBlocks();
    blockCount = ssaBlocks.size();
    regCount = ssaMeth.getRegCount() - threshold;
    DomFront df = new DomFront(ssaMeth);
    DomFront.DomInfo[] domInfos = df.run();
    // Bit set of registers vs block index "definition sites"
    BitSet[] defsites = new BitSet[regCount];
    // Bit set of registers vs block index "phi placement sites"
    BitSet[] phisites = new BitSet[regCount];
    for (int i = 0; i < regCount; i++) {
        defsites[i] = new BitSet(blockCount);
        phisites[i] = new BitSet(blockCount);
    }
    /*
         * For each register, build a set of all basic blocks where
         * containing an assignment to that register.
         */
    for (int bi = 0, s = ssaBlocks.size(); bi < s; bi++) {
        SsaBasicBlock b = ssaBlocks.get(bi);
        for (SsaInsn insn : b.getInsns()) {
            RegisterSpec rs = insn.getResult();
            if (rs != null && rs.getReg() - threshold >= 0) {
                defsites[rs.getReg() - threshold].set(bi);
            }
        }
    }
    if (DEBUG) {
        System.out.println("defsites");
        for (int i = 0; i < regCount; i++) {
            StringBuilder sb = new StringBuilder();
            sb.append('v').append(i).append(": ");
            sb.append(defsites[i].toString());
            System.out.println(sb);
        }
    }
    BitSet worklist;
    /*
         * For each register, compute all locations for phi placement
         * based on dominance-frontier algorithm.
         */
    for (int reg = 0, s = regCount; reg < s; reg++) {
        int workBlockIndex;
        /* Worklist set starts out with each node where reg is assigned. */
        worklist = (BitSet) (defsites[reg].clone());
        while (0 <= (workBlockIndex = worklist.nextSetBit(0))) {
            worklist.clear(workBlockIndex);
            IntIterator dfIterator = domInfos[workBlockIndex].dominanceFrontiers.iterator();
            while (dfIterator.hasNext()) {
                int dfBlockIndex = dfIterator.next();
                if (!phisites[reg].get(dfBlockIndex)) {
                    phisites[reg].set(dfBlockIndex);
                    int tReg = reg + threshold;
                    RegisterSpec rs = localInfo.getStarts(dfBlockIndex).get(tReg);
                    if (rs == null) {
                        ssaBlocks.get(dfBlockIndex).addPhiInsnForReg(tReg);
                    } else {
                        ssaBlocks.get(dfBlockIndex).addPhiInsnForReg(rs);
                    }
                    if (!defsites[reg].get(dfBlockIndex)) {
                        worklist.set(dfBlockIndex);
                    }
                }
            }
        }
    }
    if (DEBUG) {
        System.out.println("phisites");
        for (int i = 0; i < regCount; i++) {
            StringBuilder sb = new StringBuilder();
            sb.append('v').append(i).append(": ");
            sb.append(phisites[i].toString());
            System.out.println(sb);
        }
    }
}
Also used : IntIterator(com.android.dx.util.IntIterator) BitSet(java.util.BitSet) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 60 with RegisterSpec

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

the class SsaInsn method mapRegisters.

/**
 * Map registers after register allocation.
 *
 * @param mapper {@code non-null;} mapping from old to new registers
 */
public final void mapRegisters(RegisterMapper mapper) {
    RegisterSpec oldResult = result;
    result = mapper.map(result);
    block.getParent().updateOneDefinition(this, oldResult);
    mapSourceRegisters(mapper);
}
Also used : 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