Search in sources :

Example 11 with SsaBasicBlock

use of com.android.dx.ssa.SsaBasicBlock in project buck by facebook.

the class SsaToRop method removePhiFunctions.

/**
     * See Appel 19.6. To remove the phi instructions in an edge-split
     * SSA representation we know we can always insert a move in a
     * predecessor block.
     */
private void removePhiFunctions() {
    ArrayList<SsaBasicBlock> blocks = ssaMeth.getBlocks();
    for (SsaBasicBlock block : blocks) {
        // Add moves in all the pred blocks for each phi insn.
        block.forEachPhiInsn(new PhiVisitor(blocks));
        // Delete the phi insns.
        block.removeAllPhiInsns();
    }
    /*
         * After all move insns have been added, sort them so they don't
         * destructively interfere.
         */
    for (SsaBasicBlock block : blocks) {
        block.scheduleMovesFromPhis();
    }
}
Also used : SsaBasicBlock(com.android.dx.ssa.SsaBasicBlock)

Example 12 with SsaBasicBlock

use of com.android.dx.ssa.SsaBasicBlock in project buck by facebook.

the class SsaDumper method endParsingMember.

/** {@inheritDoc} */
@Override
public void endParsingMember(ByteArray bytes, int offset, String name, String descriptor, Member member) {
    if (!(member instanceof Method)) {
        return;
    }
    if (!shouldDumpMethod(name)) {
        return;
    }
    if ((member.getAccessFlags() & (AccessFlags.ACC_ABSTRACT | AccessFlags.ACC_NATIVE)) != 0) {
        return;
    }
    ConcreteMethod meth = new ConcreteMethod((Method) member, classFile, true, true);
    TranslationAdvice advice = DexTranslationAdvice.THE_ONE;
    RopMethod rmeth = Ropper.convert(meth, advice, classFile.getMethods());
    SsaMethod ssaMeth = null;
    boolean isStatic = AccessFlags.isStatic(meth.getAccessFlags());
    int paramWidth = computeParamWidth(meth, isStatic);
    if (args.ssaStep == null) {
        ssaMeth = Optimizer.debugNoRegisterAllocation(rmeth, paramWidth, isStatic, true, advice, EnumSet.allOf(Optimizer.OptionalStep.class));
    } else if ("edge-split".equals(args.ssaStep)) {
        ssaMeth = Optimizer.debugEdgeSplit(rmeth, paramWidth, isStatic, true, advice);
    } else if ("phi-placement".equals(args.ssaStep)) {
        ssaMeth = Optimizer.debugPhiPlacement(rmeth, paramWidth, isStatic, true, advice);
    } else if ("renaming".equals(args.ssaStep)) {
        ssaMeth = Optimizer.debugRenaming(rmeth, paramWidth, isStatic, true, advice);
    } else if ("dead-code".equals(args.ssaStep)) {
        ssaMeth = Optimizer.debugDeadCodeRemover(rmeth, paramWidth, isStatic, true, advice);
    }
    StringBuffer sb = new StringBuffer(2000);
    sb.append("first ");
    sb.append(Hex.u2(ssaMeth.blockIndexToRopLabel(ssaMeth.getEntryBlockIndex())));
    sb.append('\n');
    ArrayList<SsaBasicBlock> blocks = ssaMeth.getBlocks();
    ArrayList<SsaBasicBlock> sortedBlocks = (ArrayList<SsaBasicBlock>) blocks.clone();
    Collections.sort(sortedBlocks, SsaBasicBlock.LABEL_COMPARATOR);
    for (SsaBasicBlock block : sortedBlocks) {
        sb.append("block ").append(Hex.u2(block.getRopLabel())).append('\n');
        BitSet preds = block.getPredecessors();
        for (int i = preds.nextSetBit(0); i >= 0; i = preds.nextSetBit(i + 1)) {
            sb.append("  pred ");
            sb.append(Hex.u2(ssaMeth.blockIndexToRopLabel(i)));
            sb.append('\n');
        }
        sb.append("  live in:" + block.getLiveInRegs());
        sb.append("\n");
        for (SsaInsn insn : block.getInsns()) {
            sb.append("  ");
            sb.append(insn.toHuman());
            sb.append('\n');
        }
        if (block.getSuccessors().cardinality() == 0) {
            sb.append("  returns\n");
        } else {
            int primary = block.getPrimarySuccessorRopLabel();
            IntList succLabelList = block.getRopLabelSuccessorList();
            int szSuccLabels = succLabelList.size();
            for (int i = 0; i < szSuccLabels; i++) {
                sb.append("  next ");
                sb.append(Hex.u2(succLabelList.get(i)));
                if (szSuccLabels != 1 && primary == succLabelList.get(i)) {
                    sb.append(" *");
                }
                sb.append('\n');
            }
        }
        sb.append("  live out:" + block.getLiveOutRegs());
        sb.append("\n");
    }
    suppressDump = false;
    setAt(bytes, 0);
    parsed(bytes, 0, bytes.size(), sb.toString());
    suppressDump = true;
}
Also used : RopMethod(com.android.dx.rop.code.RopMethod) Optimizer(com.android.dx.ssa.Optimizer) SsaBasicBlock(com.android.dx.ssa.SsaBasicBlock) ArrayList(java.util.ArrayList) BitSet(java.util.BitSet) DexTranslationAdvice(com.android.dx.rop.code.DexTranslationAdvice) TranslationAdvice(com.android.dx.rop.code.TranslationAdvice) ConcreteMethod(com.android.dx.cf.code.ConcreteMethod) RopMethod(com.android.dx.rop.code.RopMethod) SsaMethod(com.android.dx.ssa.SsaMethod) Method(com.android.dx.cf.iface.Method) IntList(com.android.dx.util.IntList) ConcreteMethod(com.android.dx.cf.code.ConcreteMethod) SsaMethod(com.android.dx.ssa.SsaMethod) SsaInsn(com.android.dx.ssa.SsaInsn)

Example 13 with SsaBasicBlock

use of com.android.dx.ssa.SsaBasicBlock in project J2ME-Loader by nikita36078.

the class LivenessAnalyzer method run.

/**
 * From Appel algorithm 19.17.
 */
public void run() {
    List<SsaInsn> useList = ssaMeth.getUseListForRegister(regV);
    for (SsaInsn insn : useList) {
        nextFunction = NextFunction.DONE;
        if (insn instanceof PhiInsn) {
            // If s is a phi-function with V as it's ith argument.
            PhiInsn phi = (PhiInsn) insn;
            for (SsaBasicBlock pred : phi.predBlocksForReg(regV, ssaMeth)) {
                blockN = pred;
                nextFunction = NextFunction.LIVE_OUT_AT_BLOCK;
                handleTailRecursion();
            }
        } else {
            blockN = insn.getBlock();
            statementIndex = blockN.getInsns().indexOf(insn);
            if (statementIndex < 0) {
                throw new RuntimeException("insn not found in it's own block");
            }
            nextFunction = NextFunction.LIVE_IN_AT_STATEMENT;
            handleTailRecursion();
        }
    }
    int nextLiveOutBlock;
    while ((nextLiveOutBlock = liveOutBlocks.nextSetBit(0)) >= 0) {
        blockN = ssaMeth.getBlocks().get(nextLiveOutBlock);
        liveOutBlocks.clear(nextLiveOutBlock);
        nextFunction = NextFunction.LIVE_OUT_AT_BLOCK;
        handleTailRecursion();
    }
}
Also used : PhiInsn(com.android.dx.ssa.PhiInsn) SsaBasicBlock(com.android.dx.ssa.SsaBasicBlock) SsaInsn(com.android.dx.ssa.SsaInsn)

Example 14 with SsaBasicBlock

use of com.android.dx.ssa.SsaBasicBlock in project J2ME-Loader by nikita36078.

the class LivenessAnalyzer method coInterferePhis.

/**
 * Ensures that all the phi result registers for all the phis in the
 * same basic block interfere with each other. This is needed since
 * the dead code remover has allowed through "dead-end phis" whose
 * results are not used except as local assignments. Without this step,
 * a the result of a dead-end phi might be assigned the same register
 * as the result of another phi, and the phi removal move scheduler may
 * generate moves that over-write the live result.
 *
 * @param ssaMeth {@code non-null;} method to pricess
 * @param interference {@code non-null;} interference graph
 */
private static void coInterferePhis(SsaMethod ssaMeth, InterferenceGraph interference) {
    for (SsaBasicBlock b : ssaMeth.getBlocks()) {
        List<SsaInsn> phis = b.getPhiInsns();
        int szPhis = phis.size();
        for (int i = 0; i < szPhis; i++) {
            for (int j = 0; j < szPhis; j++) {
                if (i == j) {
                    continue;
                }
                interference.add(phis.get(i).getResult().getReg(), phis.get(j).getResult().getReg());
            }
        }
    }
}
Also used : SsaBasicBlock(com.android.dx.ssa.SsaBasicBlock) SsaInsn(com.android.dx.ssa.SsaInsn)

Example 15 with SsaBasicBlock

use of com.android.dx.ssa.SsaBasicBlock in project J2ME-Loader by nikita36078.

the class SsaToRop method convertBasicBlock.

/**
 * Converts a single basic block to rop form.
 *
 * @param block SSA block to process
 * @return {@code non-null;} ROP block
 */
private BasicBlock convertBasicBlock(SsaBasicBlock block) {
    IntList successorList = block.getRopLabelSuccessorList();
    int primarySuccessorLabel = block.getPrimarySuccessorRopLabel();
    // Filter out any reference to the SSA form's exit block.
    // Exit block may be null.
    SsaBasicBlock exitBlock = ssaMeth.getExitBlock();
    int exitRopLabel = (exitBlock == null) ? -1 : exitBlock.getRopLabel();
    if (successorList.contains(exitRopLabel)) {
        if (successorList.size() > 1) {
            throw new RuntimeException("Exit predecessor must have no other successors" + Hex.u2(block.getRopLabel()));
        } else {
            successorList = IntList.EMPTY;
            primarySuccessorLabel = -1;
            verifyValidExitPredecessor(block);
        }
    }
    successorList.setImmutable();
    BasicBlock result = new BasicBlock(block.getRopLabel(), convertInsns(block.getInsns()), successorList, primarySuccessorLabel);
    return result;
}
Also used : SsaBasicBlock(com.android.dx.ssa.SsaBasicBlock) SsaBasicBlock(com.android.dx.ssa.SsaBasicBlock) BasicBlock(com.android.dx.rop.code.BasicBlock) IntList(com.android.dx.util.IntList)

Aggregations

SsaBasicBlock (com.android.dx.ssa.SsaBasicBlock)15 SsaInsn (com.android.dx.ssa.SsaInsn)9 RegisterSpec (com.android.dx.rop.code.RegisterSpec)4 NormalSsaInsn (com.android.dx.ssa.NormalSsaInsn)4 IntList (com.android.dx.util.IntList)3 ArrayList (java.util.ArrayList)3 BitSet (java.util.BitSet)3 BasicBlock (com.android.dx.rop.code.BasicBlock)2 BasicBlockList (com.android.dx.rop.code.BasicBlockList)2 PlainInsn (com.android.dx.rop.code.PlainInsn)2 RegisterSpecList (com.android.dx.rop.code.RegisterSpecList)2 PhiInsn (com.android.dx.ssa.PhiInsn)2 IntIterator (com.android.dx.util.IntIterator)2 IntSet (com.android.dx.util.IntSet)2 ConcreteMethod (com.android.dx.cf.code.ConcreteMethod)1 Method (com.android.dx.cf.iface.Method)1 DexTranslationAdvice (com.android.dx.rop.code.DexTranslationAdvice)1 RopMethod (com.android.dx.rop.code.RopMethod)1 TranslationAdvice (com.android.dx.rop.code.TranslationAdvice)1 Optimizer (com.android.dx.ssa.Optimizer)1