Search in sources :

Example 56 with RegisterSpecList

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

the class RopperMachine method getSources.

/**
 * Helper for {@link #run}, which gets the list of sources for the.
 * instruction.
 *
 * @param opcode the opcode being translated
 * @param stackPointer {@code >= 0;} the stack pointer after the
 * instruction's arguments have been popped
 * @return {@code non-null;} the sources
 */
private RegisterSpecList getSources(int opcode, int stackPointer) {
    int count = argCount();
    if (count == 0) {
        // We get an easy out if there aren't any sources.
        return RegisterSpecList.EMPTY;
    }
    int localIndex = getLocalIndex();
    RegisterSpecList sources;
    if (localIndex >= 0) {
        // The instruction is operating on a local variable.
        sources = new RegisterSpecList(1);
        sources.set(0, RegisterSpec.make(localIndex, arg(0)));
    } else {
        sources = new RegisterSpecList(count);
        int regAt = stackPointer;
        for (int i = 0; i < count; i++) {
            RegisterSpec spec = RegisterSpec.make(regAt, arg(i));
            sources.set(i, spec);
            regAt += spec.getCategory();
        }
        switch(opcode) {
            case ByteOps.IASTORE:
                {
                    /*
                     * The Java argument order for array stores is
                     * (array, index, value), but the rop argument
                     * order is (value, array, index). The following
                     * code gets the right arguments in the right
                     * places.
                     */
                    if (count != 3) {
                        throw new RuntimeException("shouldn't happen");
                    }
                    RegisterSpec array = sources.get(0);
                    RegisterSpec index = sources.get(1);
                    RegisterSpec value = sources.get(2);
                    sources.set(0, value);
                    sources.set(1, array);
                    sources.set(2, index);
                    break;
                }
            case ByteOps.PUTFIELD:
                {
                    /*
                     * Similar to above: The Java argument order for
                     * putfield is (object, value), but the rop
                     * argument order is (value, object).
                     */
                    if (count != 2) {
                        throw new RuntimeException("shouldn't happen");
                    }
                    RegisterSpec obj = sources.get(0);
                    RegisterSpec value = sources.get(1);
                    sources.set(0, value);
                    sources.set(1, obj);
                    break;
                }
        }
    }
    sources.setImmutable();
    return sources;
}
Also used : RegisterSpecList(com.android.dx.rop.code.RegisterSpecList) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 57 with RegisterSpecList

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

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.android.dx.rop.code.RegisterSpecList)

Example 58 with RegisterSpecList

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

the class EscapeAnalysis method processUse.

/**
 * Handles non-phi uses of new objects. Checks to see how instruction is
 * used and updates the escape state accordingly.
 *
 * @param def {@code non-null;} register holding definition of new object
 * @param use {@code non-null;} use of object being processed
 * @param escSet {@code non-null;} EscapeSet for the object
 * @param regWorklist {@code non-null;} worklist of instructions left to
 * process for this object
 */
private void processUse(RegisterSpec def, SsaInsn use, EscapeSet escSet, ArrayList<RegisterSpec> regWorklist) {
    int useOpcode = use.getOpcode().getOpcode();
    switch(useOpcode) {
        case RegOps.MOVE:
            // Follow uses of the move by adding it to the worklist
            escSet.regSet.set(use.getResult().getReg());
            regWorklist.add(use.getResult());
            break;
        case RegOps.IF_EQ:
        case RegOps.IF_NE:
        case RegOps.CHECK_CAST:
            // Compared objects can't be replaced, so promote if necessary
            if (escSet.escape.compareTo(EscapeState.METHOD) < 0) {
                escSet.escape = EscapeState.METHOD;
            }
            break;
        case RegOps.APUT:
            // For array puts, check for a constant array index
            RegisterSpec putIndex = use.getSources().get(2);
            if (!putIndex.getTypeBearer().isConstant()) {
                // If not constant, array can't be replaced
                escSet.replaceableArray = false;
            }
        // Intentional fallthrough
        case RegOps.PUT_FIELD:
            // Skip non-object puts
            RegisterSpec putValue = use.getSources().get(0);
            if (putValue.getTypeBearer().getBasicType() != Type.BT_OBJECT) {
                break;
            }
            escSet.replaceableArray = false;
            // Raise 1st object's escape state to 2nd if 2nd is higher
            RegisterSpecList sources = use.getSources();
            if (sources.get(0).getReg() == def.getReg()) {
                int setIndex = findSetIndex(sources.get(1));
                if (setIndex != latticeValues.size()) {
                    EscapeSet parentSet = latticeValues.get(setIndex);
                    addEdge(parentSet, escSet);
                    if (escSet.escape.compareTo(parentSet.escape) < 0) {
                        escSet.escape = parentSet.escape;
                    }
                }
            } else {
                int setIndex = findSetIndex(sources.get(0));
                if (setIndex != latticeValues.size()) {
                    EscapeSet childSet = latticeValues.get(setIndex);
                    addEdge(escSet, childSet);
                    if (childSet.escape.compareTo(escSet.escape) < 0) {
                        childSet.escape = escSet.escape;
                    }
                }
            }
            break;
        case RegOps.AGET:
            // For array gets, check for a constant array index
            RegisterSpec getIndex = use.getSources().get(1);
            if (!getIndex.getTypeBearer().isConstant()) {
                // If not constant, array can't be replaced
                escSet.replaceableArray = false;
            }
            break;
        case RegOps.PUT_STATIC:
            // Static puts cause an object to escape globally
            escSet.escape = EscapeState.GLOBAL;
            break;
        case RegOps.INVOKE_STATIC:
        case RegOps.INVOKE_VIRTUAL:
        case RegOps.INVOKE_SUPER:
        case RegOps.INVOKE_DIRECT:
        case RegOps.INVOKE_INTERFACE:
        case RegOps.RETURN:
        case RegOps.THROW:
            // These operations cause an object to escape interprocedurally
            escSet.escape = EscapeState.INTER;
            break;
        default:
            break;
    }
}
Also used : RegisterSpecList(com.android.dx.rop.code.RegisterSpecList) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 59 with RegisterSpecList

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

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.android.dx.rop.code.Insn) PlainInsn(com.android.dx.rop.code.PlainInsn) PlainCstInsn(com.android.dx.rop.code.PlainCstInsn) Rop(com.android.dx.rop.code.Rop) TranslationAdvice(com.android.dx.rop.code.TranslationAdvice) RegisterSpecList(com.android.dx.rop.code.RegisterSpecList)

Example 60 with RegisterSpecList

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

the class NormalSsaInsn method upgradeToLiteral.

/**
 * Upgrades this insn to a version that represents the constant source
 * literally. If the upgrade is not possible, this does nothing.
 *
 * @see Insn#withSourceLiteral
 */
public void upgradeToLiteral() {
    RegisterSpecList oldSources = insn.getSources();
    insn = insn.withSourceLiteral();
    getBlock().getParent().onSourcesChanged(this, oldSources);
}
Also used : RegisterSpecList(com.android.dx.rop.code.RegisterSpecList)

Aggregations

RegisterSpecList (com.android.dx.rop.code.RegisterSpecList)202 RegisterSpec (com.android.dx.rop.code.RegisterSpec)50 BitSet (java.util.BitSet)45 CstLiteralBits (com.android.dx.rop.cst.CstLiteralBits)42 Constant (com.android.dx.rop.cst.Constant)36 CstInsn (com.android.dx.dex.code.CstInsn)34 PlainInsn (com.android.dx.rop.code.PlainInsn)18 CstType (com.android.dx.rop.cst.CstType)12 TargetInsn (com.android.dx.dex.code.TargetInsn)10 Insn (com.android.dx.rop.code.Insn)10 TypedConstant (com.android.dx.rop.cst.TypedConstant)10 PlainCstInsn (com.android.dx.rop.code.PlainCstInsn)8 Rop (com.android.dx.rop.code.Rop)8 CstFieldRef (com.android.dx.rop.cst.CstFieldRef)8 CstMethodRef (com.android.dx.rop.cst.CstMethodRef)8 TypeBearer (com.android.dx.rop.type.TypeBearer)8 ThrowingCstInsn (com.android.dx.rop.code.ThrowingCstInsn)6 ThrowingInsn (com.android.dx.rop.code.ThrowingInsn)6 CstInteger (com.android.dx.rop.cst.CstInteger)6 MultiCstInsn (com.android.dx.dex.code.MultiCstInsn)4