Search in sources :

Example 1 with SsaBasicBlock

use of com.taobao.android.dx.ssa.SsaBasicBlock in project atlas by alibaba.

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 = new Optimizer().debugNoRegisterAllocation(rmeth, paramWidth, isStatic, true, advice, EnumSet.allOf(Optimizer.OptionalStep.class));
    } else if ("edge-split".equals(args.ssaStep)) {
        ssaMeth = new Optimizer().debugEdgeSplit(rmeth, paramWidth, isStatic, true, advice);
    } else if ("phi-placement".equals(args.ssaStep)) {
        ssaMeth = new Optimizer().debugPhiPlacement(rmeth, paramWidth, isStatic, true, advice);
    } else if ("renaming".equals(args.ssaStep)) {
        ssaMeth = new Optimizer().debugRenaming(rmeth, paramWidth, isStatic, true, advice);
    } else if ("dead-code".equals(args.ssaStep)) {
        ssaMeth = new 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.taobao.android.dx.rop.code.RopMethod) Optimizer(com.taobao.android.dx.ssa.Optimizer) SsaBasicBlock(com.taobao.android.dx.ssa.SsaBasicBlock) ArrayList(java.util.ArrayList) BitSet(java.util.BitSet) DexTranslationAdvice(com.taobao.android.dx.rop.code.DexTranslationAdvice) TranslationAdvice(com.taobao.android.dx.rop.code.TranslationAdvice) ConcreteMethod(com.taobao.android.dx.cf.code.ConcreteMethod) RopMethod(com.taobao.android.dx.rop.code.RopMethod) Method(com.taobao.android.dx.cf.iface.Method) SsaMethod(com.taobao.android.dx.ssa.SsaMethod) IntList(com.taobao.android.dx.util.IntList) ConcreteMethod(com.taobao.android.dx.cf.code.ConcreteMethod) SsaMethod(com.taobao.android.dx.ssa.SsaMethod) SsaInsn(com.taobao.android.dx.ssa.SsaInsn)

Example 2 with SsaBasicBlock

use of com.taobao.android.dx.ssa.SsaBasicBlock in project atlas by alibaba.

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.taobao.android.dx.ssa.SsaBasicBlock) SsaInsn(com.taobao.android.dx.ssa.SsaInsn)

Example 3 with SsaBasicBlock

use of com.taobao.android.dx.ssa.SsaBasicBlock in project atlas by alibaba.

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.taobao.android.dx.ssa.PhiInsn) SsaBasicBlock(com.taobao.android.dx.ssa.SsaBasicBlock) SsaInsn(com.taobao.android.dx.ssa.SsaInsn)

Example 4 with SsaBasicBlock

use of com.taobao.android.dx.ssa.SsaBasicBlock in project atlas by alibaba.

the class SsaToRop method convertBasicBlocks.

/**
     * @return rop-form basic block list
     */
private BasicBlockList convertBasicBlocks() {
    ArrayList<SsaBasicBlock> blocks = ssaMeth.getBlocks();
    // Exit block may be null.
    SsaBasicBlock exitBlock = ssaMeth.getExitBlock();
    ssaMeth.computeReachability();
    int ropBlockCount = ssaMeth.getCountReachableBlocks();
    // Don't count the exit block, if it exists and is reachable.
    ropBlockCount -= (exitBlock != null && exitBlock.isReachable()) ? 1 : 0;
    BasicBlockList result = new BasicBlockList(ropBlockCount);
    // Convert all the reachable blocks except the exit block.
    int ropBlockIndex = 0;
    for (SsaBasicBlock b : blocks) {
        if (b.isReachable() && b != exitBlock) {
            result.set(ropBlockIndex++, convertBasicBlock(b));
        }
    }
    // The exit block, which is discarded, must do nothing.
    if (exitBlock != null && exitBlock.getInsns().size() != 0) {
        throw new RuntimeException("Exit block must have no insns when leaving SSA form");
    }
    return result;
}
Also used : SsaBasicBlock(com.taobao.android.dx.ssa.SsaBasicBlock) BasicBlockList(com.taobao.android.dx.rop.code.BasicBlockList)

Example 5 with SsaBasicBlock

use of com.taobao.android.dx.ssa.SsaBasicBlock in project atlas by alibaba.

the class RegisterAllocator method insertMoveBefore.

/**
     * Inserts a move instruction for a specified SSA register before a
     * specified instruction, creating a new SSA register and adjusting the
     * interference graph in the process. The insn currently must be the
     * last insn in a block.
     *
     * @param insn {@code non-null;} insn to insert move before, must
     * be last insn in block
     * @param reg {@code non-null;} SSA register to duplicate
     * @return {@code non-null;} spec of new SSA register created by move
     */
protected final RegisterSpec insertMoveBefore(SsaInsn insn, RegisterSpec reg) {
    SsaBasicBlock block = insn.getBlock();
    ArrayList<SsaInsn> insns = block.getInsns();
    int insnIndex = insns.indexOf(insn);
    if (insnIndex < 0) {
        throw new IllegalArgumentException("specified insn is not in this block");
    }
    if (insnIndex != insns.size() - 1) {
        /*
             * Presently, the interference updater only works when
             * adding before the last insn, and the last insn must have no
             * result
             */
        throw new IllegalArgumentException("Adding move here not supported:" + insn.toHuman());
    }
    /*
         * Get new register and make new move instruction.
         */
    // The new result must not have an associated local variable.
    RegisterSpec newRegSpec = RegisterSpec.make(ssaMeth.makeNewSsaReg(), reg.getTypeBearer());
    SsaInsn toAdd = SsaInsn.makeFromRop(new PlainInsn(Rops.opMove(newRegSpec.getType()), SourcePosition.NO_INFO, newRegSpec, RegisterSpecList.make(reg)), block);
    insns.add(insnIndex, toAdd);
    int newReg = newRegSpec.getReg();
    /*
         * Adjust interference graph based on what's live out of the current
         * block and what's used by the final instruction.
         */
    IntSet liveOut = block.getLiveOutRegs();
    IntIterator liveOutIter = liveOut.iterator();
    while (liveOutIter.hasNext()) {
        interference.add(newReg, liveOutIter.next());
    }
    // Everything that's a source in the last insn interferes.
    RegisterSpecList sources = insn.getSources();
    int szSources = sources.size();
    for (int i = 0; i < szSources; i++) {
        interference.add(newReg, sources.get(i).getReg());
    }
    ssaMeth.onInsnsChanged();
    return newRegSpec;
}
Also used : PlainInsn(com.taobao.android.dx.rop.code.PlainInsn) IntIterator(com.taobao.android.dx.util.IntIterator) IntSet(com.taobao.android.dx.util.IntSet) SsaBasicBlock(com.taobao.android.dx.ssa.SsaBasicBlock) SsaInsn(com.taobao.android.dx.ssa.SsaInsn) NormalSsaInsn(com.taobao.android.dx.ssa.NormalSsaInsn) RegisterSpecList(com.taobao.android.dx.rop.code.RegisterSpecList) RegisterSpec(com.taobao.android.dx.rop.code.RegisterSpec)

Aggregations

SsaBasicBlock (com.taobao.android.dx.ssa.SsaBasicBlock)8 SsaInsn (com.taobao.android.dx.ssa.SsaInsn)5 RegisterSpec (com.taobao.android.dx.rop.code.RegisterSpec)2 NormalSsaInsn (com.taobao.android.dx.ssa.NormalSsaInsn)2 IntList (com.taobao.android.dx.util.IntList)2 ArrayList (java.util.ArrayList)2 BitSet (java.util.BitSet)2 ConcreteMethod (com.taobao.android.dx.cf.code.ConcreteMethod)1 Method (com.taobao.android.dx.cf.iface.Method)1 BasicBlock (com.taobao.android.dx.rop.code.BasicBlock)1 BasicBlockList (com.taobao.android.dx.rop.code.BasicBlockList)1 DexTranslationAdvice (com.taobao.android.dx.rop.code.DexTranslationAdvice)1 PlainInsn (com.taobao.android.dx.rop.code.PlainInsn)1 RegisterSpecList (com.taobao.android.dx.rop.code.RegisterSpecList)1 RopMethod (com.taobao.android.dx.rop.code.RopMethod)1 TranslationAdvice (com.taobao.android.dx.rop.code.TranslationAdvice)1 Optimizer (com.taobao.android.dx.ssa.Optimizer)1 PhiInsn (com.taobao.android.dx.ssa.PhiInsn)1 SsaMethod (com.taobao.android.dx.ssa.SsaMethod)1 IntIterator (com.taobao.android.dx.util.IntIterator)1