Search in sources :

Example 6 with SsaInsn

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

Example 7 with SsaInsn

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

the class FirstFitLocalCombiningAllocator method processPhiInsn.

/**
 * Attempts to map the sources and result of a phi to a common register.
 * Will try existing mappings first, from most to least common. If none
 * of the registers have mappings yet, a new mapping is created.
 */
private void processPhiInsn(PhiInsn insn) {
    RegisterSpec result = insn.getResult();
    int resultReg = result.getReg();
    int category = result.getCategory();
    RegisterSpecList sources = insn.getSources();
    int sourcesSize = sources.size();
    // List of phi sources / result that need mapping
    ArrayList<RegisterSpec> ssaRegs = new ArrayList<RegisterSpec>();
    // Track how many times a particular mapping is found
    Multiset mapSet = new Multiset(sourcesSize + 1);
    /*
         * If the result of the phi has an existing mapping, get it.
         * Otherwise, add it to the list of regs that need mapping.
         */
    if (ssaRegsMapped.get(resultReg)) {
        mapSet.add(mapper.oldToNew(resultReg));
    } else {
        ssaRegs.add(result);
    }
    for (int i = 0; i < sourcesSize; i++) {
        RegisterSpec source = sources.get(i);
        SsaInsn def = ssaMeth.getDefinitionForRegister(source.getReg());
        RegisterSpec sourceDef = def.getResult();
        int sourceReg = sourceDef.getReg();
        /*
             * If a source of the phi has an existing mapping, get it.
             * Otherwise, add it to the list of regs that need mapping.
             */
        if (ssaRegsMapped.get(sourceReg)) {
            mapSet.add(mapper.oldToNew(sourceReg));
        } else {
            ssaRegs.add(sourceDef);
        }
    }
    // Try all existing mappings, with the most common ones first
    for (int i = 0; i < mapSet.getSize(); i++) {
        int maxReg = mapSet.getAndRemoveHighestCount();
        tryMapRegs(ssaRegs, maxReg, category, false);
    }
    // Map any remaining unmapped regs with whatever fits
    int mapReg = findNextUnreservedRopReg(paramRangeEnd, category);
    while (!tryMapRegs(ssaRegs, mapReg, category, false)) {
        mapReg = findNextUnreservedRopReg(mapReg + 1, category);
    }
}
Also used : ArrayList(java.util.ArrayList) RegisterSpecList(com.taobao.android.dx.rop.code.RegisterSpecList) SsaInsn(com.taobao.android.dx.ssa.SsaInsn) NormalSsaInsn(com.taobao.android.dx.ssa.NormalSsaInsn) RegisterSpec(com.taobao.android.dx.rop.code.RegisterSpec)

Example 8 with SsaInsn

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

the class LivenessAnalyzer method liveOutAtStatement.

/**
 * "v is live-out at s."
 */
private void liveOutAtStatement() {
    SsaInsn statement = blockN.getInsns().get(statementIndex);
    RegisterSpec rs = statement.getResult();
    if (!statement.isResultReg(regV)) {
        if (rs != null) {
            interference.add(regV, rs.getReg());
        }
        nextFunction = NextFunction.LIVE_IN_AT_STATEMENT;
    }
}
Also used : SsaInsn(com.taobao.android.dx.ssa.SsaInsn) RegisterSpec(com.taobao.android.dx.rop.code.RegisterSpec)

Example 9 with SsaInsn

use of com.taobao.android.dx.ssa.SsaInsn 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

SsaInsn (com.taobao.android.dx.ssa.SsaInsn)9 SsaBasicBlock (com.taobao.android.dx.ssa.SsaBasicBlock)5 RegisterSpec (com.taobao.android.dx.rop.code.RegisterSpec)4 NormalSsaInsn (com.taobao.android.dx.ssa.NormalSsaInsn)4 ArrayList (java.util.ArrayList)3 RegisterSpecList (com.taobao.android.dx.rop.code.RegisterSpecList)2 Rop (com.taobao.android.dx.rop.code.Rop)2 BitSet (java.util.BitSet)2 ConcreteMethod (com.taobao.android.dx.cf.code.ConcreteMethod)1 Method (com.taobao.android.dx.cf.iface.Method)1 CstInsn (com.taobao.android.dx.rop.code.CstInsn)1 DexTranslationAdvice (com.taobao.android.dx.rop.code.DexTranslationAdvice)1 PlainInsn (com.taobao.android.dx.rop.code.PlainInsn)1 RopMethod (com.taobao.android.dx.rop.code.RopMethod)1 TranslationAdvice (com.taobao.android.dx.rop.code.TranslationAdvice)1 CstInteger (com.taobao.android.dx.rop.cst.CstInteger)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