Search in sources :

Example 26 with RegisterSpec

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

the class PhiInsn method updateSourcesToDefinitions.

/**
     * Updates the TypeBearers of all the sources (phi operands) to be
     * the current TypeBearer of the register-defining instruction's result.
     * This is used during phi-type resolution.<p>
     *
     * Note that local association of operands are preserved in this step.
     *
     * @param ssaMeth method that contains this insn
     */
public void updateSourcesToDefinitions(SsaMethod ssaMeth) {
    for (Operand o : operands) {
        RegisterSpec def = ssaMeth.getDefinitionForRegister(o.regSpec.getReg()).getResult();
        o.regSpec = o.regSpec.withType(def.getType());
    }
    sources = null;
}
Also used : RegisterSpec(com.taobao.android.dx.rop.code.RegisterSpec)

Example 27 with RegisterSpec

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

the class RegisterMapper method map.

/**
     *
     * @param sources old register set
     * @return new mapped register set, or old if nothing has changed.
     */
public final RegisterSpecSet map(RegisterSpecSet sources) {
    int sz = sources.getMaxSize();
    RegisterSpecSet newSources = new RegisterSpecSet(getNewRegisterCount());
    for (int i = 0; i < sz; i++) {
        RegisterSpec registerSpec = sources.get(i);
        if (registerSpec != null) {
            newSources.put(map(registerSpec));
        }
    }
    newSources.setImmutable();
    // Return the old sources if nothing has changed.
    return newSources.equals(sources) ? sources : newSources;
}
Also used : RegisterSpecSet(com.taobao.android.dx.rop.code.RegisterSpecSet) RegisterSpec(com.taobao.android.dx.rop.code.RegisterSpec)

Example 28 with RegisterSpec

use of com.taobao.android.dx.rop.code.RegisterSpec 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 29 with RegisterSpec

use of com.taobao.android.dx.rop.code.RegisterSpec 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 30 with RegisterSpec

use of com.taobao.android.dx.rop.code.RegisterSpec 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

RegisterSpec (com.taobao.android.dx.rop.code.RegisterSpec)66 RegisterSpecList (com.taobao.android.dx.rop.code.RegisterSpecList)24 PlainInsn (com.taobao.android.dx.rop.code.PlainInsn)12 Constant (com.taobao.android.dx.rop.cst.Constant)10 TypedConstant (com.taobao.android.dx.rop.cst.TypedConstant)8 ArrayList (java.util.ArrayList)8 Insn (com.taobao.android.dx.rop.code.Insn)7 PlainCstInsn (com.taobao.android.dx.rop.code.PlainCstInsn)7 Rop (com.taobao.android.dx.rop.code.Rop)7 ThrowingCstInsn (com.taobao.android.dx.rop.code.ThrowingCstInsn)7 CstType (com.taobao.android.dx.rop.cst.CstType)7 TypeBearer (com.taobao.android.dx.rop.type.TypeBearer)7 LocalItem (com.taobao.android.dx.rop.code.LocalItem)5 RegisterSpecSet (com.taobao.android.dx.rop.code.RegisterSpecSet)5 ThrowingInsn (com.taobao.android.dx.rop.code.ThrowingInsn)5 CstString (com.taobao.android.dx.rop.cst.CstString)5 BitSet (java.util.BitSet)5 HashSet (java.util.HashSet)5 SourcePosition (com.taobao.android.dx.rop.code.SourcePosition)4 CstFieldRef (com.taobao.android.dx.rop.cst.CstFieldRef)4