Search in sources :

Example 46 with RegisterSpecList

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

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

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

the class SsaMethod method onSourcesChanged.

/**
     * Updates the use list for a source list change.
     *
     * @param insn {@code insn non-null;} insn being changed.
     * {@code insn.getSources()} must return the new source list.
     * @param oldSources {@code null-ok;} list of sources that were
     * previously used
     */
/*package*/
void onSourcesChanged(SsaInsn insn, RegisterSpecList oldSources) {
    if (useList == null)
        return;
    if (oldSources != null) {
        removeFromUseList(insn, oldSources);
    }
    RegisterSpecList sources = insn.getSources();
    int szNew = sources.size();
    for (int i = 0; i < szNew; i++) {
        int reg = sources.get(i).getReg();
        useList[reg].add(insn);
    }
}
Also used : RegisterSpecList(com.taobao.android.dx.rop.code.RegisterSpecList)

Example 49 with RegisterSpecList

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

the class Form3rc method writeTo.

/** {@inheritDoc} */
@Override
public void writeTo(AnnotatedOutput out, DalvInsn insn) {
    RegisterSpecList regs = insn.getRegisters();
    int cpi = ((CstInsn) insn).getIndex();
    int firstReg = (regs.size() == 0) ? 0 : regs.get(0).getReg();
    int count = regs.getWordCount();
    write(out, opcodeUnit(insn, count), (short) cpi, (short) firstReg);
}
Also used : CstInsn(com.taobao.android.dx.dex.code.CstInsn) RegisterSpecList(com.taobao.android.dx.rop.code.RegisterSpecList)

Example 50 with RegisterSpecList

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

the class Form51l method insnArgString.

/** {@inheritDoc} */
@Override
public String insnArgString(DalvInsn insn) {
    RegisterSpecList regs = insn.getRegisters();
    CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();
    return regs.get(0).regString() + ", " + literalBitsString(value);
}
Also used : CstLiteralBits(com.taobao.android.dx.rop.cst.CstLiteralBits) RegisterSpecList(com.taobao.android.dx.rop.code.RegisterSpecList)

Aggregations

RegisterSpecList (com.taobao.android.dx.rop.code.RegisterSpecList)98 RegisterSpec (com.taobao.android.dx.rop.code.RegisterSpec)24 BitSet (java.util.BitSet)22 CstLiteralBits (com.taobao.android.dx.rop.cst.CstLiteralBits)21 CstInsn (com.taobao.android.dx.dex.code.CstInsn)17 Constant (com.taobao.android.dx.rop.cst.Constant)17 PlainInsn (com.taobao.android.dx.rop.code.PlainInsn)9 CstType (com.taobao.android.dx.rop.cst.CstType)6 TargetInsn (com.taobao.android.dx.dex.code.TargetInsn)5 Insn (com.taobao.android.dx.rop.code.Insn)5 TypedConstant (com.taobao.android.dx.rop.cst.TypedConstant)5 PlainCstInsn (com.taobao.android.dx.rop.code.PlainCstInsn)4 Rop (com.taobao.android.dx.rop.code.Rop)4 CstFieldRef (com.taobao.android.dx.rop.cst.CstFieldRef)4 ThrowingCstInsn (com.taobao.android.dx.rop.code.ThrowingCstInsn)3 ThrowingInsn (com.taobao.android.dx.rop.code.ThrowingInsn)3 CstInteger (com.taobao.android.dx.rop.cst.CstInteger)3 CstMethodRef (com.taobao.android.dx.rop.cst.CstMethodRef)3 TypeBearer (com.taobao.android.dx.rop.type.TypeBearer)3 FillArrayDataInsn (com.taobao.android.dx.rop.code.FillArrayDataInsn)2