Search in sources :

Example 1 with RegisterSpecList

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

the class DalvInsn method expandedPrefix.

/**
 * Gets the instruction prefix required, if any, to use in an expanded
 * version of this instance. Will not generate moves for registers
 * marked compatible to the format by the given BitSet.
 *
 * @see #expandedVersion
 *
 * @param compatRegs {@code non-null;} set of compatible registers
 * @return {@code null-ok;} the prefix, if any
 */
public DalvInsn expandedPrefix(BitSet compatRegs) {
    RegisterSpecList regs = registers;
    boolean firstBit = compatRegs.get(0);
    if (hasResult())
        compatRegs.set(0);
    regs = regs.subset(compatRegs);
    if (hasResult())
        compatRegs.set(0, firstBit);
    if (regs.size() == 0)
        return null;
    return new HighRegisterPrefix(position, regs);
}
Also used : RegisterSpecList(com.taobao.android.dx.rop.code.RegisterSpecList)

Example 2 with RegisterSpecList

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

the class LiteralOpUpgrader method run.

/**
 * Run the literal op upgrader
 */
private void run() {
    final TranslationAdvice advice = Optimizer.getAdvice();
    ssaMeth.forEachInsn(new SsaInsn.Visitor() {

        public void visitMoveInsn(NormalSsaInsn insn) {
        // do nothing
        }

        public void visitPhiInsn(PhiInsn insn) {
        // do nothing
        }

        public void visitNonMoveInsn(NormalSsaInsn insn) {
            Insn originalRopInsn = insn.getOriginalRopInsn();
            Rop opcode = originalRopInsn.getOpcode();
            RegisterSpecList sources = insn.getSources();
            // Replace insns with constant results with const insns
            if (tryReplacingWithConstant(insn))
                return;
            if (sources.size() != 2) {
                // We're only dealing with two-source insns here.
                return;
            }
            if (opcode.getBranchingness() == Rop.BRANCH_IF) {
                /*
                     * An if instruction can become an if-*z instruction.
                     */
                if (isConstIntZeroOrKnownNull(sources.get(0))) {
                    replacePlainInsn(insn, sources.withoutFirst(), RegOps.flippedIfOpcode(opcode.getOpcode()), null);
                } else if (isConstIntZeroOrKnownNull(sources.get(1))) {
                    replacePlainInsn(insn, sources.withoutLast(), opcode.getOpcode(), null);
                }
            } else if (advice.hasConstantOperation(opcode, sources.get(0), sources.get(1))) {
                insn.upgradeToLiteral();
            } else if (opcode.isCommutative() && advice.hasConstantOperation(opcode, sources.get(1), sources.get(0))) {
                /*
                     * An instruction can be commuted to a literal operation
                     */
                insn.setNewSources(RegisterSpecList.make(sources.get(1), sources.get(0)));
                insn.upgradeToLiteral();
            }
        }
    });
}
Also used : 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) TranslationAdvice(com.taobao.android.dx.rop.code.TranslationAdvice) RegisterSpecList(com.taobao.android.dx.rop.code.RegisterSpecList)

Example 3 with RegisterSpecList

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

the class NormalSsaInsn method mapSourceRegisters.

/**
 * {@inheritDoc}
 */
@Override
public final void mapSourceRegisters(RegisterMapper mapper) {
    RegisterSpecList oldSources = insn.getSources();
    RegisterSpecList newSources = mapper.map(oldSources);
    if (newSources != oldSources) {
        insn = insn.withNewRegisters(getResult(), newSources);
        getBlock().getParent().onSourcesChanged(this, oldSources);
    }
}
Also used : RegisterSpecList(com.taobao.android.dx.rop.code.RegisterSpecList)

Example 4 with RegisterSpecList

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

the class NormalSsaInsn method setNewSources.

/**
 * Changes the source list of the insn. New source list should be the
 * same size and consist of sources of identical types.
 *
 * @param newSources non-null new sources list.
 */
public final void setNewSources(RegisterSpecList newSources) {
    RegisterSpecList origSources = insn.getSources();
    if (origSources.size() != newSources.size()) {
        throw new RuntimeException("Sources counts don't match");
    }
    insn = insn.withNewRegisters(getResult(), newSources);
}
Also used : RegisterSpecList(com.taobao.android.dx.rop.code.RegisterSpecList)

Example 5 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)

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 TypeBearer (com.taobao.android.dx.rop.type.TypeBearer)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 FillArrayDataInsn (com.taobao.android.dx.rop.code.FillArrayDataInsn)2