Search in sources :

Example 71 with RegisterSpec

use of com.android.dx.rop.code.RegisterSpec in project J2ME-Loader by nikita36078.

the class Form45cc method compatibleRegs.

/**
 * {@inheritDoc}
 */
@Override
public BitSet compatibleRegs(DalvInsn insn) {
    RegisterSpecList regs = insn.getRegisters();
    int sz = regs.size();
    BitSet bits = new BitSet(sz);
    for (int i = 0; i < sz; i++) {
        RegisterSpec reg = regs.get(i);
        /*
             * The check below adds (category - 1) to the register, to
             * account for the fact that the second half of a
             * category-2 register has to be represented explicitly in
             * the result.
             */
        bits.set(i, unsignedFitsInNibble(reg.getReg() + reg.getCategory() - 1));
    }
    return bits;
}
Also used : BitSet(java.util.BitSet) RegisterSpecList(com.android.dx.rop.code.RegisterSpecList) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 72 with RegisterSpec

use of com.android.dx.rop.code.RegisterSpec in project J2ME-Loader by nikita36078.

the class ConstCollector method getConstsSortedByCountUse.

/**
 * Gets all of the collectable constant values used in this method,
 * sorted by most used first. Skips non-collectable consts, such as
 * non-string object constants
 *
 * @return {@code non-null;} list of constants in most-to-least used order
 */
private ArrayList<TypedConstant> getConstsSortedByCountUse() {
    int regSz = ssaMeth.getRegCount();
    final HashMap<TypedConstant, Integer> countUses = new HashMap<TypedConstant, Integer>();
    /*
         * Each collected constant can be used by just one local
         * (used only if COLLECT_ONE_LOCAL is true).
         */
    final HashSet<TypedConstant> usedByLocal = new HashSet<TypedConstant>();
    // Count how many times each const value is used.
    for (int i = 0; i < regSz; i++) {
        SsaInsn insn = ssaMeth.getDefinitionForRegister(i);
        if (insn == null || insn.getOpcode() == null)
            continue;
        RegisterSpec result = insn.getResult();
        TypeBearer typeBearer = result.getTypeBearer();
        if (!typeBearer.isConstant())
            continue;
        TypedConstant cst = (TypedConstant) typeBearer;
        // Find defining instruction for move-result-pseudo instructions
        if (insn.getOpcode().getOpcode() == RegOps.MOVE_RESULT_PSEUDO) {
            int pred = insn.getBlock().getPredecessors().nextSetBit(0);
            ArrayList<SsaInsn> predInsns;
            predInsns = ssaMeth.getBlocks().get(pred).getInsns();
            insn = predInsns.get(predInsns.size() - 1);
        }
        if (insn.canThrow()) {
            /*
                 * Don't move anything other than strings -- the risk
                 * of changing where an exception is thrown is too high.
                 */
            if (!(cst instanceof CstString) || !COLLECT_STRINGS) {
                continue;
            }
            /*
                 * We can't move any throwable const whose throw will be
                 * caught, so don't count them.
                 */
            if (insn.getBlock().getSuccessors().cardinality() > 1) {
                continue;
            }
        }
        /*
             * TODO: Might be nice to try and figure out which local
             * wins most when collected.
             */
        if (ssaMeth.isRegALocal(result)) {
            if (!COLLECT_ONE_LOCAL) {
                continue;
            } else {
                if (usedByLocal.contains(cst)) {
                    // Count one local usage only.
                    continue;
                } else {
                    usedByLocal.add(cst);
                }
            }
        }
        Integer has = countUses.get(cst);
        if (has == null) {
            countUses.put(cst, 1);
        } else {
            countUses.put(cst, has + 1);
        }
    }
    // Collect constants that have been reused.
    ArrayList<TypedConstant> constantList = new ArrayList<TypedConstant>();
    for (Map.Entry<TypedConstant, Integer> entry : countUses.entrySet()) {
        if (entry.getValue() > 1) {
            constantList.add(entry.getKey());
        }
    }
    // Sort by use, with most used at the beginning of the list.
    Collections.sort(constantList, new Comparator<Constant>() {

        public int compare(Constant a, Constant b) {
            int ret;
            ret = countUses.get(b) - countUses.get(a);
            if (ret == 0) {
                /*
                     * Provide sorting determinisim for constants with same
                     * usage count.
                     */
                ret = a.compareTo(b);
            }
            return ret;
        }

        @Override
        public boolean equals(Object obj) {
            return obj == this;
        }
    });
    return constantList;
}
Also used : HashMap(java.util.HashMap) Constant(com.android.dx.rop.cst.Constant) TypedConstant(com.android.dx.rop.cst.TypedConstant) CstString(com.android.dx.rop.cst.CstString) ArrayList(java.util.ArrayList) TypedConstant(com.android.dx.rop.cst.TypedConstant) TypeBearer(com.android.dx.rop.type.TypeBearer) HashMap(java.util.HashMap) Map(java.util.Map) RegisterSpec(com.android.dx.rop.code.RegisterSpec) HashSet(java.util.HashSet)

Example 73 with RegisterSpec

use of com.android.dx.rop.code.RegisterSpec in project buck by facebook.

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.android.dx.rop.code.LocalItem) TreeMap(java.util.TreeMap) Map(java.util.Map) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 74 with RegisterSpec

use of com.android.dx.rop.code.RegisterSpec in project buck by facebook.

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.android.dx.util.IntSet) BitSet(java.util.BitSet) RegisterSpecList(com.android.dx.rop.code.RegisterSpecList) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 75 with RegisterSpec

use of com.android.dx.rop.code.RegisterSpec in project buck by facebook.

the class FirstFitLocalCombiningAllocator method handleLocalAssociatedParams.

/**
     * Maps all local-associated parameters to rop registers.
     */
private void handleLocalAssociatedParams() {
    for (ArrayList<RegisterSpec> ssaRegs : localVariables.values()) {
        int sz = ssaRegs.size();
        int paramIndex = -1;
        int paramCategory = 0;
        // First, find out if this local variable is a parameter.
        for (int i = 0; i < sz; i++) {
            RegisterSpec ssaSpec = ssaRegs.get(i);
            int ssaReg = ssaSpec.getReg();
            paramIndex = getParameterIndexForReg(ssaReg);
            if (paramIndex >= 0) {
                paramCategory = ssaSpec.getCategory();
                addMapping(ssaSpec, paramIndex);
                break;
            }
        }
        if (paramIndex < 0) {
            // This local wasn't a parameter.
            continue;
        }
        // Any remaining local-associated registers will be mapped later.
        tryMapRegs(ssaRegs, paramIndex, paramCategory, true);
    }
}
Also used : RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Aggregations

RegisterSpec (com.android.dx.rop.code.RegisterSpec)135 RegisterSpecList (com.android.dx.rop.code.RegisterSpecList)50 PlainInsn (com.android.dx.rop.code.PlainInsn)24 Constant (com.android.dx.rop.cst.Constant)20 TypedConstant (com.android.dx.rop.cst.TypedConstant)16 TypeBearer (com.android.dx.rop.type.TypeBearer)16 ArrayList (java.util.ArrayList)16 Insn (com.android.dx.rop.code.Insn)14 PlainCstInsn (com.android.dx.rop.code.PlainCstInsn)14 Rop (com.android.dx.rop.code.Rop)14 ThrowingCstInsn (com.android.dx.rop.code.ThrowingCstInsn)14 CstType (com.android.dx.rop.cst.CstType)14 BitSet (java.util.BitSet)11 LocalItem (com.android.dx.rop.code.LocalItem)10 RegisterSpecSet (com.android.dx.rop.code.RegisterSpecSet)10 ThrowingInsn (com.android.dx.rop.code.ThrowingInsn)10 CstString (com.android.dx.rop.cst.CstString)10 HashSet (java.util.HashSet)10 SourcePosition (com.android.dx.rop.code.SourcePosition)8 CstFieldRef (com.android.dx.rop.cst.CstFieldRef)8