Search in sources :

Example 16 with RegisterSpec

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

the class FirstFitLocalCombiningAllocator method printLocalVars.

/**
     * Dumps local variable table to stdout for debugging.
     */
private void printLocalVars() {
    System.out.println("Printing local vars");
    for (Map.Entry<LocalItem, ArrayList<RegisterSpec>> e : localVariables.entrySet()) {
        StringBuilder regs = new StringBuilder();
        regs.append('{');
        regs.append(' ');
        for (RegisterSpec reg : e.getValue()) {
            regs.append('v');
            regs.append(reg.getReg());
            regs.append(' ');
        }
        regs.append('}');
        System.out.printf("Local: %s Registers: %s\n", e.getKey(), regs);
    }
}
Also used : ArrayList(java.util.ArrayList) LocalItem(com.taobao.android.dx.rop.code.LocalItem) TreeMap(java.util.TreeMap) Map(java.util.Map) RegisterSpec(com.taobao.android.dx.rop.code.RegisterSpec)

Example 17 with RegisterSpec

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

the class FirstFitLocalCombiningAllocator method tryMapRegs.

/**
     * Tries to map a list of SSA registers into the a rop reg, marking
     * used rop space as reserved. SSA registers that don't fit are left
     * unmapped.
     *
     * @param specs {@code non-null;} SSA registers to attempt to map
     * @param ropReg {@code >=0;} rop register to map to
     * @param maxAllowedCategory {@code 1..2;} maximum category
     * allowed in mapping.
     * @param markReserved do so if {@code true}
     * @return {@code true} if all registers were mapped, {@code false}
     * if some remain unmapped
     */
private boolean tryMapRegs(ArrayList<RegisterSpec> specs, int ropReg, int maxAllowedCategory, boolean markReserved) {
    boolean remaining = false;
    for (RegisterSpec spec : specs) {
        if (ssaRegsMapped.get(spec.getReg())) {
            continue;
        }
        boolean succeeded;
        succeeded = tryMapReg(spec, ropReg, maxAllowedCategory);
        remaining = !succeeded || remaining;
        if (succeeded && markReserved) {
            // This only needs to be called once really with
            // the widest category used, but <shrug>
            markReserved(ropReg, spec.getCategory());
        }
    }
    return !remaining;
}
Also used : RegisterSpec(com.taobao.android.dx.rop.code.RegisterSpec)

Example 18 with RegisterSpec

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

the class FirstFitLocalCombiningAllocator method fitPlanForRange.

/**
     * Attempts to build a plan for fitting a range of sources into rop
     * registers.
     *
     * @param ropReg {@code >= 0;} rop reg that begins range
     * @param insn {@code non-null;} insn to plan range for
     * @param categoriesForIndex {@code non-null;} indexed by source index;
     * the category for each source
     * @param outMovesRequired {@code non-null;} an output parameter indexed by
     * source index that will contain the set of sources which need
     * moves inserted
     * @return the width of the fit that that does not involve added moves or
     * {@code -1} if "no fit possible"
     */
private int fitPlanForRange(int ropReg, NormalSsaInsn insn, int[] categoriesForIndex, BitSet outMovesRequired) {
    RegisterSpecList sources = insn.getSources();
    int szSources = sources.size();
    int fitWidth = 0;
    IntSet liveOut = insn.getBlock().getLiveOutRegs();
    RegisterSpecList liveOutSpecs = ssaSetToSpecs(liveOut);
    // An SSA reg may only be mapped into a range once.
    BitSet seen = new BitSet(ssaMeth.getRegCount());
    for (int i = 0; i < szSources; i++) {
        RegisterSpec ssaSpec = sources.get(i);
        int ssaReg = ssaSpec.getReg();
        int category = categoriesForIndex[i];
        if (i != 0) {
            ropReg += categoriesForIndex[i - 1];
        }
        if (ssaRegsMapped.get(ssaReg) && mapper.oldToNew(ssaReg) == ropReg) {
            // This is a register that is already mapped appropriately.
            fitWidth += category;
        } else if (rangeContainsReserved(ropReg, category)) {
            fitWidth = -1;
            break;
        } else if (!ssaRegsMapped.get(ssaReg) && canMapReg(ssaSpec, ropReg) && !seen.get(ssaReg)) {
            // This is a register that can be mapped appropriately.
            fitWidth += category;
        } else if (!mapper.areAnyPinned(liveOutSpecs, ropReg, category) && !mapper.areAnyPinned(sources, ropReg, category)) {
            /*
                 * This is a source that can be moved. We can insert a
                 * move as long as:
                 *
                 *   * no SSA register pinned to the desired rop reg
                 *     is live out on the block
                 *
                 *   * no SSA register pinned to desired rop reg is
                 *     a source of this insn (since this may require
                 *     overlapping moves, which we can't presently handle)
                 */
            outMovesRequired.set(i);
        } else {
            fitWidth = -1;
            break;
        }
        seen.set(ssaReg);
    }
    return fitWidth;
}
Also used : IntSet(com.taobao.android.dx.util.IntSet) BitSet(java.util.BitSet) RegisterSpecList(com.taobao.android.dx.rop.code.RegisterSpecList) RegisterSpec(com.taobao.android.dx.rop.code.RegisterSpec)

Example 19 with RegisterSpec

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

the class EscapeAnalysis method scalarReplacement.

/**
     * Performs scalar replacement on all eligible arrays.
     */
private void scalarReplacement() {
    // Iterate through lattice, looking for non-escaping replaceable arrays
    for (EscapeSet escSet : latticeValues) {
        if (!escSet.replaceableArray || escSet.escape != EscapeState.NONE) {
            continue;
        }
        // Get the instructions for the definition and move of the array
        int e = escSet.regSet.nextSetBit(0);
        SsaInsn def = ssaMeth.getDefinitionForRegister(e);
        SsaInsn prev = getInsnForMove(def);
        // Create a map for the new registers that will be created
        TypeBearer lengthReg = prev.getSources().get(0).getTypeBearer();
        int length = ((CstLiteralBits) lengthReg).getIntBits();
        ArrayList<RegisterSpec> newRegs = new ArrayList<RegisterSpec>(length);
        HashSet<SsaInsn> deletedInsns = new HashSet<SsaInsn>();
        // Replace the definition of the array with registers
        replaceDef(def, prev, length, newRegs);
        // Mark definition instructions for deletion
        deletedInsns.add(prev);
        deletedInsns.add(def);
        // Go through all uses of the array
        List<SsaInsn> useList = ssaMeth.getUseListForRegister(e);
        for (SsaInsn use : useList) {
            // Replace the use with scalars and then mark it for deletion
            replaceUse(use, prev, newRegs, deletedInsns);
            deletedInsns.add(use);
        }
        // Delete all marked instructions
        ssaMeth.deleteInsns(deletedInsns);
        ssaMeth.onInsnsChanged();
        // Convert the method back to SSA form
        SsaConverter.updateSsaMethod(optimizer, ssaMeth, regCount);
        // Propagate and remove extra moves added by scalar replacement
        movePropagate();
    }
}
Also used : CstLiteralBits(com.taobao.android.dx.rop.cst.CstLiteralBits) ArrayList(java.util.ArrayList) TypeBearer(com.taobao.android.dx.rop.type.TypeBearer) RegisterSpec(com.taobao.android.dx.rop.code.RegisterSpec) HashSet(java.util.HashSet)

Example 20 with RegisterSpec

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

the class InterferenceRegisterMapper method areAnyPinned.

/**
     * Checks to see if any of a set of old-namespace registers are
     * pinned to the specified new-namespace reg + category. Takes into
     * account the category of the old-namespace registers.
     *
     * @param oldSpecs {@code non-null;} set of old-namespace regs
     * @param newReg {@code >= 0;} new-namespace register
     * @param targetCategory {@code 1..2;} the number of adjacent new-namespace
     * registers (starting at ropReg) to consider
     * @return true if any of the old-namespace register have been mapped
     * to the new-namespace register + category
     */
public boolean areAnyPinned(RegisterSpecList oldSpecs, int newReg, int targetCategory) {
    int sz = oldSpecs.size();
    for (int i = 0; i < sz; i++) {
        RegisterSpec oldSpec = oldSpecs.get(i);
        int r = oldToNew(oldSpec.getReg());
        /*
             * If oldSpec is a category-2 register, then check both newReg
             * and newReg - 1.
             */
        if (r == newReg || (oldSpec.getCategory() == 2 && (r + 1) == newReg) || (targetCategory == 2 && (r == newReg + 1))) {
            return true;
        }
    }
    return false;
}
Also used : 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