Search in sources :

Example 6 with PlainInsn

use of com.taobao.android.dx.rop.code.PlainInsn in project atlas by alibaba.

the class LiteralOpUpgrader method replacePlainInsn.

/**
     * Replaces an SsaInsn containing a PlainInsn with a new PlainInsn. The
     * new PlainInsn is constructed with a new RegOp and new sources.
     *
     * TODO move this somewhere else.
     *
     * @param insn {@code non-null;} an SsaInsn containing a PlainInsn
     * @param newSources {@code non-null;} new sources list for new insn
     * @param newOpcode A RegOp from {@link RegOps}
     * @param cst {@code null-ok;} constant for new instruction, if any
     */
private void replacePlainInsn(NormalSsaInsn insn, RegisterSpecList newSources, int newOpcode, Constant cst) {
    Insn originalRopInsn = insn.getOriginalRopInsn();
    Rop newRop = Rops.ropFor(newOpcode, insn.getResult(), newSources, cst);
    Insn newRopInsn;
    if (cst == null) {
        newRopInsn = new PlainInsn(newRop, originalRopInsn.getPosition(), insn.getResult(), newSources);
    } else {
        newRopInsn = new PlainCstInsn(newRop, originalRopInsn.getPosition(), insn.getResult(), newSources, cst);
    }
    NormalSsaInsn newInsn = new NormalSsaInsn(newRopInsn, insn.getBlock());
    List<SsaInsn> insns = insn.getBlock().getInsns();
    ssaMeth.onInsnRemoved(insn);
    insns.set(insns.lastIndexOf(insn), newInsn);
    ssaMeth.onInsnAdded(newInsn);
}
Also used : PlainCstInsn(com.taobao.android.dx.rop.code.PlainCstInsn) PlainInsn(com.taobao.android.dx.rop.code.PlainInsn) Insn(com.taobao.android.dx.rop.code.Insn) PlainCstInsn(com.taobao.android.dx.rop.code.PlainCstInsn) PlainInsn(com.taobao.android.dx.rop.code.PlainInsn) Rop(com.taobao.android.dx.rop.code.Rop)

Example 7 with PlainInsn

use of com.taobao.android.dx.rop.code.PlainInsn in project atlas by alibaba.

the class SsaBasicBlock method scheduleUseBeforeAssigned.

/**
     * Ensures that all move operations in this block occur such that
     * reads of any register happen before writes to that register.
     * NOTE: caller is expected to returnSpareRegisters()!
     *
     * TODO: See Briggs, et al "Practical Improvements to the Construction and
     * Destruction of Static Single Assignment Form" section 5. a) This can
     * be done in three passes.
     *
     * @param toSchedule List of instructions. Must consist only of moves.
     */
private void scheduleUseBeforeAssigned(List<SsaInsn> toSchedule) {
    BitSet regsUsedAsSources = new BitSet(parent.getRegCount());
    // TODO: Get rid of this.
    BitSet regsUsedAsResults = new BitSet(parent.getRegCount());
    int sz = toSchedule.size();
    int insertPlace = 0;
    while (insertPlace < sz) {
        int oldInsertPlace = insertPlace;
        // Record all registers used as sources in this block.
        for (int i = insertPlace; i < sz; i++) {
            setRegsUsed(regsUsedAsSources, toSchedule.get(i).getSources().get(0));
            setRegsUsed(regsUsedAsResults, toSchedule.get(i).getResult());
        }
        /*
             * If there are no circular dependencies, then there exists
             * n instructions where n > 1 whose result is not used as a source.
             */
        for (int i = insertPlace; i < sz; i++) {
            SsaInsn insn = toSchedule.get(i);
            /*
                 * Move these n registers to the front, since they overwrite
                 * nothing.
                 */
            if (!checkRegUsed(regsUsedAsSources, insn.getResult())) {
                Collections.swap(toSchedule, i, insertPlace++);
            }
        }
        /*
             * If we've made no progress in this iteration, there's a
             * circular dependency. Split it using the temp reg.
             */
        if (oldInsertPlace == insertPlace) {
            SsaInsn insnToSplit = null;
            // Find an insn whose result is used as a source.
            for (int i = insertPlace; i < sz; i++) {
                SsaInsn insn = toSchedule.get(i);
                if (checkRegUsed(regsUsedAsSources, insn.getResult()) && checkRegUsed(regsUsedAsResults, insn.getSources().get(0))) {
                    insnToSplit = insn;
                    /*
                         * We're going to split this insn; move it to the
                         * front.
                         */
                    Collections.swap(toSchedule, insertPlace, i);
                    break;
                }
            }
            // At least one insn will be set above.
            RegisterSpec result = insnToSplit.getResult();
            RegisterSpec tempSpec = result.withReg(parent.borrowSpareRegister(result.getCategory()));
            NormalSsaInsn toAdd = new NormalSsaInsn(new PlainInsn(Rops.opMove(result.getType()), SourcePosition.NO_INFO, tempSpec, insnToSplit.getSources()), this);
            toSchedule.add(insertPlace++, toAdd);
            RegisterSpecList newSources = RegisterSpecList.make(tempSpec);
            NormalSsaInsn toReplace = new NormalSsaInsn(new PlainInsn(Rops.opMove(result.getType()), SourcePosition.NO_INFO, result, newSources), this);
            toSchedule.set(insertPlace, toReplace);
            // The size changed.
            sz = toSchedule.size();
        }
        regsUsedAsSources.clear();
        regsUsedAsResults.clear();
    }
}
Also used : PlainInsn(com.taobao.android.dx.rop.code.PlainInsn) BitSet(java.util.BitSet) RegisterSpecList(com.taobao.android.dx.rop.code.RegisterSpecList) RegisterSpec(com.taobao.android.dx.rop.code.RegisterSpec)

Example 8 with PlainInsn

use of com.taobao.android.dx.rop.code.PlainInsn in project atlas by alibaba.

the class SsaBasicBlock method addMoveToEnd.

/**
     * Adds a move instruction to the end of this basic block, just
     * before the last instruction. If the result of the final instruction
     * is the source in question, then the move is placed at the beginning of
     * the primary successor block. This is for unversioned registers.
     *
     * @param result move destination
     * @param source move source
     */
public void addMoveToEnd(RegisterSpec result, RegisterSpec source) {
    if (result.getReg() == source.getReg()) {
        // Sometimes we end up with no-op moves. Ignore them here.
        return;
    }
    /*
         * The last Insn has to be a normal SSA insn: a phi can't branch
         * or return or cause an exception, etc.
         */
    NormalSsaInsn lastInsn;
    lastInsn = (NormalSsaInsn) insns.get(insns.size() - 1);
    if (lastInsn.getResult() != null || lastInsn.getSources().size() > 0) {
        for (int i = successors.nextSetBit(0); i >= 0; i = successors.nextSetBit(i + 1)) {
            SsaBasicBlock succ;
            succ = parent.getBlocks().get(i);
            succ.addMoveToBeginning(result, source);
        }
    } else {
        /*
             * We can safely add a move to the end of the block just
             * before the last instruction, because the final insn does
             * not assign to anything.
             */
        RegisterSpecList sources = RegisterSpecList.make(source);
        NormalSsaInsn toAdd = new NormalSsaInsn(new PlainInsn(Rops.opMove(result.getType()), SourcePosition.NO_INFO, result, sources), this);
        insns.add(insns.size() - 1, toAdd);
        movesFromPhisAtEnd++;
    }
}
Also used : PlainInsn(com.taobao.android.dx.rop.code.PlainInsn) RegisterSpecList(com.taobao.android.dx.rop.code.RegisterSpecList)

Example 9 with PlainInsn

use of com.taobao.android.dx.rop.code.PlainInsn in project atlas by alibaba.

the class ConstCollector method fixLocalAssignment.

/**
     * Inserts mark-locals if necessary when changing a register. If
     * the definition of {@code origReg} is associated with a local
     * variable, then insert a mark-local for {@code newReg} just below
     * it. We expect the definition of  {@code origReg} to ultimately
     * be removed by the dead code eliminator
     *
     * @param origReg {@code non-null;} original register
     * @param newReg {@code non-null;} new register that will replace
     * {@code origReg}
     */
private void fixLocalAssignment(RegisterSpec origReg, RegisterSpec newReg) {
    for (SsaInsn use : ssaMeth.getUseListForRegister(origReg.getReg())) {
        RegisterSpec localAssignment = use.getLocalAssignment();
        if (localAssignment == null) {
            continue;
        }
        if (use.getResult() == null) {
            /*
                 * This is a mark-local. it will be updated when all uses
                 * are updated.
                 */
            continue;
        }
        LocalItem local = localAssignment.getLocalItem();
        // Un-associate original use.
        use.setResultLocal(null);
        // Now add a mark-local to the new reg immediately after.
        newReg = newReg.withLocalItem(local);
        SsaInsn newInsn = SsaInsn.makeFromRop(new PlainInsn(Rops.opMarkLocal(newReg), SourcePosition.NO_INFO, null, RegisterSpecList.make(newReg)), use.getBlock());
        ArrayList<SsaInsn> insns = use.getBlock().getInsns();
        insns.add(insns.indexOf(use) + 1, newInsn);
    }
}
Also used : PlainInsn(com.taobao.android.dx.rop.code.PlainInsn) LocalItem(com.taobao.android.dx.rop.code.LocalItem) RegisterSpec(com.taobao.android.dx.rop.code.RegisterSpec)

Example 10 with PlainInsn

use of com.taobao.android.dx.rop.code.PlainInsn in project atlas by alibaba.

the class ConstCollector method run.

/**
     * Applies the optimization.
     */
private void run() {
    int regSz = ssaMeth.getRegCount();
    ArrayList<TypedConstant> constantList = getConstsSortedByCountUse();
    int toCollect = Math.min(constantList.size(), MAX_COLLECTED_CONSTANTS);
    SsaBasicBlock start = ssaMeth.getEntryBlock();
    // Constant to new register containing the constant
    HashMap<TypedConstant, RegisterSpec> newRegs = new HashMap<TypedConstant, RegisterSpec>(toCollect);
    for (int i = 0; i < toCollect; i++) {
        TypedConstant cst = constantList.get(i);
        RegisterSpec result = RegisterSpec.make(ssaMeth.makeNewSsaReg(), cst);
        Rop constRop = Rops.opConst(cst);
        if (constRop.getBranchingness() == Rop.BRANCH_NONE) {
            start.addInsnToHead(new PlainCstInsn(Rops.opConst(cst), SourcePosition.NO_INFO, result, RegisterSpecList.EMPTY, cst));
        } else {
            // We need two new basic blocks along with the new insn
            SsaBasicBlock entryBlock = ssaMeth.getEntryBlock();
            SsaBasicBlock successorBlock = entryBlock.getPrimarySuccessor();
            // Insert a block containing the const insn.
            SsaBasicBlock constBlock = entryBlock.insertNewSuccessor(successorBlock);
            constBlock.replaceLastInsn(new ThrowingCstInsn(constRop, SourcePosition.NO_INFO, RegisterSpecList.EMPTY, StdTypeList.EMPTY, cst));
            // Insert a block containing the move-result-pseudo insn.
            SsaBasicBlock resultBlock = constBlock.insertNewSuccessor(successorBlock);
            PlainInsn insn = new PlainInsn(Rops.opMoveResultPseudo(result.getTypeBearer()), SourcePosition.NO_INFO, result, RegisterSpecList.EMPTY);
            resultBlock.addInsnToHead(insn);
        }
        newRegs.put(cst, result);
    }
    updateConstUses(newRegs, regSz);
}
Also used : PlainCstInsn(com.taobao.android.dx.rop.code.PlainCstInsn) PlainInsn(com.taobao.android.dx.rop.code.PlainInsn) Rop(com.taobao.android.dx.rop.code.Rop) ThrowingCstInsn(com.taobao.android.dx.rop.code.ThrowingCstInsn) TypedConstant(com.taobao.android.dx.rop.cst.TypedConstant) HashMap(java.util.HashMap) RegisterSpec(com.taobao.android.dx.rop.code.RegisterSpec)

Aggregations

PlainInsn (com.taobao.android.dx.rop.code.PlainInsn)17 Insn (com.taobao.android.dx.rop.code.Insn)10 PlainCstInsn (com.taobao.android.dx.rop.code.PlainCstInsn)9 RegisterSpec (com.taobao.android.dx.rop.code.RegisterSpec)9 ThrowingCstInsn (com.taobao.android.dx.rop.code.ThrowingCstInsn)8 ThrowingInsn (com.taobao.android.dx.rop.code.ThrowingInsn)7 RegisterSpecList (com.taobao.android.dx.rop.code.RegisterSpecList)6 SourcePosition (com.taobao.android.dx.rop.code.SourcePosition)6 BasicBlock (com.taobao.android.dx.rop.code.BasicBlock)5 InsnList (com.taobao.android.dx.rop.code.InsnList)5 Rop (com.taobao.android.dx.rop.code.Rop)5 CstType (com.taobao.android.dx.rop.cst.CstType)3 FillArrayDataInsn (com.taobao.android.dx.rop.code.FillArrayDataInsn)2 StdTypeList (com.taobao.android.dx.rop.type.StdTypeList)2 Type (com.taobao.android.dx.rop.type.Type)2 IntList (com.taobao.android.dx.util.IntList)2 BitSet (java.util.BitSet)2 CstInsn (com.taobao.android.dx.rop.code.CstInsn)1 LocalItem (com.taobao.android.dx.rop.code.LocalItem)1 SwitchInsn (com.taobao.android.dx.rop.code.SwitchInsn)1