Search in sources :

Example 6 with SsaBasicBlock

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

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

Example 7 with SsaBasicBlock

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

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.taobao.android.dx.ssa.SsaBasicBlock) SsaBasicBlock(com.taobao.android.dx.ssa.SsaBasicBlock) BasicBlock(com.taobao.android.dx.rop.code.BasicBlock) IntList(com.taobao.android.dx.util.IntList)

Example 8 with SsaBasicBlock

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

the class FirstFitLocalCombiningAllocator method handleCheckCastResults.

/**
     * Handles check cast results to reuse the same source register.
     * Inserts a move if it can't map the same register to both and the
     * check cast is not caught.
     */
private void handleCheckCastResults() {
    for (NormalSsaInsn insn : moveResultPseudoInsns) {
        RegisterSpec moveRegSpec = insn.getResult();
        int moveReg = moveRegSpec.getReg();
        BitSet predBlocks = insn.getBlock().getPredecessors();
        // Expect one predecessor block only
        if (predBlocks.cardinality() != 1) {
            continue;
        }
        SsaBasicBlock predBlock = ssaMeth.getBlocks().get(predBlocks.nextSetBit(0));
        ArrayList<SsaInsn> insnList = predBlock.getInsns();
        /**
             * If the predecessor block has a check-cast, it will be the last
             * instruction
             */
        SsaInsn checkCastInsn = insnList.get(insnList.size() - 1);
        if (checkCastInsn.getOpcode().getOpcode() != RegOps.CHECK_CAST) {
            continue;
        }
        RegisterSpec checkRegSpec = checkCastInsn.getSources().get(0);
        int checkReg = checkRegSpec.getReg();
        /**
             * See if either register is already mapped. Most likely the move
             * result will be mapped already since the cast result is stored
             * in a local variable.
             */
        int category = checkRegSpec.getCategory();
        boolean moveMapped = ssaRegsMapped.get(moveReg);
        boolean checkMapped = ssaRegsMapped.get(checkReg);
        if (moveMapped & !checkMapped) {
            int moveRopReg = mapper.oldToNew(moveReg);
            checkMapped = tryMapReg(checkRegSpec, moveRopReg, category);
        }
        if (checkMapped & !moveMapped) {
            int checkRopReg = mapper.oldToNew(checkReg);
            moveMapped = tryMapReg(moveRegSpec, checkRopReg, category);
        }
        // Map any unmapped registers to anything available
        if (!moveMapped || !checkMapped) {
            int ropReg = findNextUnreservedRopReg(paramRangeEnd, category);
            ArrayList<RegisterSpec> ssaRegs = new ArrayList<RegisterSpec>(2);
            ssaRegs.add(moveRegSpec);
            ssaRegs.add(checkRegSpec);
            while (!tryMapRegs(ssaRegs, ropReg, category, false)) {
                ropReg = findNextUnreservedRopReg(ropReg + 1, category);
            }
        }
        /*
             * If source and result have a different mapping, insert a move so
             * they can have the same mapping. Don't do this if the check cast
             * is caught, since it will overwrite a potentially live value.
             */
        boolean hasExceptionHandlers = checkCastInsn.getOriginalRopInsn().getCatches().size() != 0;
        int moveRopReg = mapper.oldToNew(moveReg);
        int checkRopReg = mapper.oldToNew(checkReg);
        if (moveRopReg != checkRopReg && !hasExceptionHandlers) {
            ((NormalSsaInsn) checkCastInsn).changeOneSource(0, insertMoveBefore(checkCastInsn, checkRegSpec));
            addMapping(checkCastInsn.getSources().get(0), moveRopReg);
        }
    }
}
Also used : NormalSsaInsn(com.taobao.android.dx.ssa.NormalSsaInsn) SsaBasicBlock(com.taobao.android.dx.ssa.SsaBasicBlock) BitSet(java.util.BitSet) ArrayList(java.util.ArrayList) SsaInsn(com.taobao.android.dx.ssa.SsaInsn) NormalSsaInsn(com.taobao.android.dx.ssa.NormalSsaInsn) 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