com.android.dx.rop.code.PlainInsn Java Examples

The following examples show how to use com.android.dx.rop.code.PlainInsn. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: SsaBasicBlock.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Adds a move instruction after the phi insn block.
 *
 * @param result move destination
 * @param source move source
 */
public void addMoveToBeginning (RegisterSpec result, RegisterSpec source) {
    if (result.getReg() == source.getReg()) {
        // Sometimes we end up with no-op moves. Ignore them here.
        return;
    }

    RegisterSpecList sources = RegisterSpecList.make(source);
    NormalSsaInsn toAdd = new NormalSsaInsn(
            new PlainInsn(Rops.opMove(result.getType()),
                    SourcePosition.NO_INFO, result, sources), this);

    insns.add(getCountPhiInsns(), toAdd);
    movesFromPhisAtBeginning++;
}
 
Example #2
Source File: SsaBasicBlock.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Adds a move instruction after the phi insn block.
 *
 * @param result move destination
 * @param source move source
 */
public void addMoveToBeginning (RegisterSpec result, RegisterSpec source) {
    if (result.getReg() == source.getReg()) {
        // Sometimes we end up with no-op moves. Ignore them here.
        return;
    }

    RegisterSpecList sources = RegisterSpecList.make(source);
    NormalSsaInsn toAdd = new NormalSsaInsn(
            new PlainInsn(Rops.opMove(result.getType()),
                    SourcePosition.NO_INFO, result, sources), this);

    insns.add(getCountPhiInsns(), toAdd);
    movesFromPhisAtBeginning++;
}
 
Example #3
Source File: ConstCollector.java    From buck with Apache License 2.0 5 votes vote down vote up
/**
 * Inserts mark-locals if necessary when changing a register. If
 * the definition of {@code origReg} is associated with a local
 * variable, then insert a mark-local for {@code newReg} just below
 * it. We expect the definition of  {@code origReg} to ultimately
 * be removed by the dead code eliminator
 *
 * @param origReg {@code non-null;} original register
 * @param newReg {@code non-null;} new register that will replace
 * {@code origReg}
 */
private void fixLocalAssignment(RegisterSpec origReg,
        RegisterSpec newReg) {
    for (SsaInsn use : ssaMeth.getUseListForRegister(origReg.getReg())) {
        RegisterSpec localAssignment = use.getLocalAssignment();
        if (localAssignment == null) {
            continue;
        }

        if (use.getResult() == null) {
            /*
             * This is a mark-local. it will be updated when all uses
             * are updated.
             */
            continue;
        }

        LocalItem local = localAssignment.getLocalItem();

        // Un-associate original use.
        use.setResultLocal(null);

        // Now add a mark-local to the new reg immediately after.
        newReg = newReg.withLocalItem(local);

        SsaInsn newInsn
                = SsaInsn.makeFromRop(
                    new PlainInsn(Rops.opMarkLocal(newReg),
                    SourcePosition.NO_INFO, null,
                            RegisterSpecList.make(newReg)),
                use.getBlock());

        ArrayList<SsaInsn> insns = use.getBlock().getInsns();

        insns.add(insns.indexOf(use) + 1, newInsn);
    }
}
 
Example #4
Source File: SsaBasicBlock.java    From buck with Apache License 2.0 5 votes vote down vote up
/**
 * Adds a move instruction after the phi insn block.
 *
 * @param result move destination
 * @param source move source
 */
public void addMoveToBeginning (RegisterSpec result, RegisterSpec source) {
    if (result.getReg() == source.getReg()) {
        // Sometimes we end up with no-op moves. Ignore them here.
        return;
    }

    RegisterSpecList sources = RegisterSpecList.make(source);
    NormalSsaInsn toAdd = new NormalSsaInsn(
            new PlainInsn(Rops.opMove(result.getType()),
                    SourcePosition.NO_INFO, result, sources), this);

    insns.add(getCountPhiInsns(), toAdd);
    movesFromPhisAtBeginning++;
}
 
Example #5
Source File: ConstCollector.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Inserts mark-locals if necessary when changing a register. If
 * the definition of {@code origReg} is associated with a local
 * variable, then insert a mark-local for {@code newReg} just below
 * it. We expect the definition of  {@code origReg} to ultimately
 * be removed by the dead code eliminator
 *
 * @param origReg {@code non-null;} original register
 * @param newReg {@code non-null;} new register that will replace
 * {@code origReg}
 */
private void fixLocalAssignment(RegisterSpec origReg,
        RegisterSpec newReg) {
    for (SsaInsn use : ssaMeth.getUseListForRegister(origReg.getReg())) {
        RegisterSpec localAssignment = use.getLocalAssignment();
        if (localAssignment == null) {
            continue;
        }

        if (use.getResult() == null) {
            /*
             * This is a mark-local. it will be updated when all uses
             * are updated.
             */
            continue;
        }

        LocalItem local = localAssignment.getLocalItem();

        // Un-associate original use.
        use.setResultLocal(null);

        // Now add a mark-local to the new reg immediately after.
        newReg = newReg.withLocalItem(local);

        SsaInsn newInsn
                = SsaInsn.makeFromRop(
                    new PlainInsn(Rops.opMarkLocal(newReg),
                    SourcePosition.NO_INFO, null,
                            RegisterSpecList.make(newReg)),
                use.getBlock());

        ArrayList<SsaInsn> insns = use.getBlock().getInsns();

        insns.add(insns.indexOf(use) + 1, newInsn);
    }
}
 
Example #6
Source File: SCCP.java    From buck with Apache License 2.0 5 votes vote down vote up
/**
 * Replaces branches that have constant conditions with gotos
 */
private void replaceBranches() {
    for (SsaInsn insn : branchWorklist) {
        // Find if a successor block is never executed
        int oldSuccessor = -1;
        SsaBasicBlock block = insn.getBlock();
        int successorSize = block.getSuccessorList().size();
        for (int i = 0; i < successorSize; i++) {
            int successorBlock = block.getSuccessorList().get(i);
            if (!executableBlocks.get(successorBlock)) {
                oldSuccessor = successorBlock;
            }
        }

        /*
         * Prune branches that have already been handled and ones that no
         * longer have constant conditions (no nonexecutable successors)
         */
        if (successorSize != 2 || oldSuccessor == -1) continue;

        // Replace branch with goto
        Insn originalRopInsn = insn.getOriginalRopInsn();
        block.replaceLastInsn(new PlainInsn(Rops.GOTO,
            originalRopInsn.getPosition(), null, RegisterSpecList.EMPTY));
        block.removeSuccessor(oldSuccessor);
    }
}
 
Example #7
Source File: ConstCollector.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Inserts mark-locals if necessary when changing a register. If
 * the definition of {@code origReg} is associated with a local
 * variable, then insert a mark-local for {@code newReg} just below
 * it. We expect the definition of  {@code origReg} to ultimately
 * be removed by the dead code eliminator
 *
 * @param origReg {@code non-null;} original register
 * @param newReg {@code non-null;} new register that will replace
 * {@code origReg}
 */
private void fixLocalAssignment(RegisterSpec origReg,
        RegisterSpec newReg) {
    for (SsaInsn use : ssaMeth.getUseListForRegister(origReg.getReg())) {
        RegisterSpec localAssignment = use.getLocalAssignment();
        if (localAssignment == null) {
            continue;
        }

        if (use.getResult() == null) {
            /*
             * This is a mark-local. it will be updated when all uses
             * are updated.
             */
            continue;
        }

        LocalItem local = localAssignment.getLocalItem();

        // Un-associate original use.
        use.setResultLocal(null);

        // Now add a mark-local to the new reg immediately after.
        newReg = newReg.withLocalItem(local);

        SsaInsn newInsn
                = SsaInsn.makeFromRop(
                    new PlainInsn(Rops.opMarkLocal(newReg),
                    SourcePosition.NO_INFO, null,
                            RegisterSpecList.make(newReg)),
                use.getBlock());

        ArrayList<SsaInsn> insns = use.getBlock().getInsns();

        insns.add(insns.indexOf(use) + 1, newInsn);
    }
}
 
Example #8
Source File: SCCP.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Replaces branches that have constant conditions with gotos
 */
private void replaceBranches() {
    for (SsaInsn insn : branchWorklist) {
        // Find if a successor block is never executed
        int oldSuccessor = -1;
        SsaBasicBlock block = insn.getBlock();
        int successorSize = block.getSuccessorList().size();
        for (int i = 0; i < successorSize; i++) {
            int successorBlock = block.getSuccessorList().get(i);
            if (!executableBlocks.get(successorBlock)) {
                oldSuccessor = successorBlock;
            }
        }

        /*
         * Prune branches that have already been handled and ones that no
         * longer have constant conditions (no nonexecutable successors)
         */
        if (successorSize != 2 || oldSuccessor == -1) continue;

        // Replace branch with goto
        Insn originalRopInsn = insn.getOriginalRopInsn();
        block.replaceLastInsn(new PlainInsn(Rops.GOTO,
            originalRopInsn.getPosition(), null, RegisterSpecList.EMPTY));
        block.removeSuccessor(oldSuccessor);
    }
}
 
Example #9
Source File: SCCP.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Replaces branches that have constant conditions with gotos
 */
private void replaceBranches() {
    for (SsaInsn insn : branchWorklist) {
        // Find if a successor block is never executed
        int oldSuccessor = -1;
        SsaBasicBlock block = insn.getBlock();
        int successorSize = block.getSuccessorList().size();
        for (int i = 0; i < successorSize; i++) {
            int successorBlock = block.getSuccessorList().get(i);
            if (!executableBlocks.get(successorBlock)) {
                oldSuccessor = successorBlock;
            }
        }

        /*
         * Prune branches that have already been handled and ones that no
         * longer have constant conditions (no nonexecutable successors)
         */
        if (successorSize != 2 || oldSuccessor == -1) continue;

        // Replace branch with goto
        Insn originalRopInsn = insn.getOriginalRopInsn();
        block.replaceLastInsn(new PlainInsn(Rops.GOTO,
            originalRopInsn.getPosition(), null, RegisterSpecList.EMPTY));
        block.removeSuccessor(oldSuccessor);
    }
}
 
Example #10
Source File: SsaMethod.java    From buck with Apache License 2.0 5 votes vote down vote up
/**
 * Deletes all insns in the set from this method.
 *
 * @param deletedInsns {@code non-null;} insns to delete
 */
public void deleteInsns(Set<SsaInsn> deletedInsns) {
    for (SsaBasicBlock block : getBlocks()) {
        ArrayList<SsaInsn> insns = block.getInsns();

        for (int i = insns.size() - 1; i >= 0; i--) {
            SsaInsn insn = insns.get(i);

            if (deletedInsns.contains(insn)) {
                onInsnRemoved(insn);
                insns.remove(i);
            }
        }

        // Check to see if we need to add a GOTO

        int insnsSz = insns.size();
        SsaInsn lastInsn = (insnsSz == 0) ? null : insns.get(insnsSz - 1);

        if (block != getExitBlock() && (insnsSz == 0
                || lastInsn.getOriginalRopInsn() == null
                || lastInsn.getOriginalRopInsn().getOpcode()
                    .getBranchingness() == Rop.BRANCH_NONE)) {
            // We managed to eat a throwable insn

            Insn gotoInsn = new PlainInsn(Rops.GOTO,
                    SourcePosition.NO_INFO, null, RegisterSpecList.EMPTY);
            insns.add(SsaInsn.makeFromRop(gotoInsn, block));

            // Remove secondary successors from this block
            BitSet succs = block.getSuccessors();
            for (int i = succs.nextSetBit(0); i >= 0;
                     i = succs.nextSetBit(i + 1)) {
                if (i != block.getPrimarySuccessorIndex()) {
                    block.removeSuccessor(i);
                }
            }
        }
    }
}
 
Example #11
Source File: Code.java    From dexmaker with Apache License 2.0 5 votes vote down vote up
/**
 * Returns from a {@code void} method. After a return it is an error to
 * define further instructions after a return without first {@link #mark
 * marking} an existing unmarked label.
 */
public void returnVoid() {
    if (!method.returnType.equals(TypeId.VOID)) {
        throw new IllegalArgumentException("declared " + method.returnType
                + " but returned void");
    }
    addInstruction(new PlainInsn(Rops.RETURN_VOID, sourcePosition, null,
            RegisterSpecList.EMPTY));
}
 
Example #12
Source File: Code.java    From dexmaker with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the value in {@code result} to the calling method. After a return
 * it is an error to define further instructions after a return without
 * first {@link #mark marking} an existing unmarked label.
 */
public void returnValue(Local<?> result) {
    if (!result.type.equals(method.returnType)) {
        // TODO: this is probably too strict.
        throw new IllegalArgumentException("declared " + method.returnType
                + " but returned " + result.type);
    }
    addInstruction(new PlainInsn(Rops.opReturn(result.type.ropType), sourcePosition,
            null, RegisterSpecList.make(result.spec())));
}
 
Example #13
Source File: Code.java    From dexmaker with Apache License 2.0 5 votes vote down vote up
/**
 * Compare floats or doubles. This stores -1 in {@code target} if {@code
 * a < b}, 0 in {@code target} if {@code a == b} and 1 in target if {@code
 * a > b}. This stores {@code nanValue} in {@code target} if either value
 * is {@code NaN}.
 */
public <T extends Number> void compareFloatingPoint(
        Local<Integer> target, Local<T> a, Local<T> b, int nanValue) {
    Rop rop;
    if (nanValue == 1) {
        rop = Rops.opCmpg(a.type.ropType);
    } else if (nanValue == -1) {
        rop = Rops.opCmpl(a.type.ropType);
    } else {
        throw new IllegalArgumentException("expected 1 or -1 but was " + nanValue);
    }
    addInstruction(new PlainInsn(rop, sourcePosition, target.spec(),
            RegisterSpecList.make(a.spec(), b.spec())));
}
 
Example #14
Source File: Code.java    From dexmaker with Apache License 2.0 5 votes vote down vote up
/**
 * Check if an int or reference equals to zero. If the comparison is true,
 * execution jumps to {@code trueLabel}. If it is false, execution continues to
 * the next instruction.
 */
public <T> void compareZ(Comparison comparison, Label trueLabel, Local<?> a) {
    adopt(trueLabel);
    Rop rop = comparison.rop(StdTypeList.make(a.type.ropType));
    addInstruction(new PlainInsn(rop, sourcePosition, null,
            RegisterSpecList.make(a.spec())), trueLabel);
}
 
Example #15
Source File: Code.java    From dexmaker with Apache License 2.0 5 votes vote down vote up
/**
 * Compare ints or references. If the comparison is true, execution jumps to
 * {@code trueLabel}. If it is false, execution continues to the next
 * instruction.
 */
public <T> void compare(Comparison comparison, Label trueLabel, Local<T> a, Local<T> b) {
    adopt(trueLabel);
    Rop rop = comparison.rop(StdTypeList.make(a.type.ropType, b.type.ropType));
    addInstruction(new PlainInsn(rop, sourcePosition, null,
            RegisterSpecList.make(a.spec(), b.spec())), trueLabel);
}
 
Example #16
Source File: Code.java    From lua-for-android with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
/**
 * Compare ints or references. If the comparison is true, execution jumps to
 * {@code trueLabel}. If it is false, execution continues to the next
 * instruction.
 */
public <T> void compare(Comparison comparison, Label trueLabel, Local<T> a, Local<T> b) {
    adopt(trueLabel);
    Rop rop = comparison.rop(StdTypeList.make(a.type.ropType, b.type.ropType));
    addInstruction(new PlainInsn(rop, sourcePosition, null,
            RegisterSpecList.make(a.spec(), b.spec())), trueLabel);
}
 
Example #17
Source File: Code.java    From lua-for-android with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
/**
 * Check if an int or reference equals to zero. If the comparison is true,
 * execution jumps to {@code trueLabel}. If it is false, execution continues to
 * the next instruction.
 */
public <T> void compareZ(Comparison comparison, Label trueLabel, Local<?> a) {
    adopt(trueLabel);
    Rop rop = comparison.rop(StdTypeList.make(a.type.ropType));
    addInstruction(new PlainInsn(rop, sourcePosition, null,
            RegisterSpecList.make(a.spec())), trueLabel);
}
 
Example #18
Source File: Code.java    From lua-for-android with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
/**
 * Compare floats or doubles. This stores -1 in {@code target} if {@code
 * a < b}, 0 in {@code target} if {@code a == b} and 1 in target if {@code
 * a > b}. This stores {@code nanValue} in {@code target} if either value
 * is {@code NaN}.
 */
public <T extends Number> void compareFloatingPoint(
        Local<Integer> target, Local<T> a, Local<T> b, int nanValue) {
    Rop rop;
    if (nanValue == 1) {
        rop = Rops.opCmpg(a.type.ropType);
    } else if (nanValue == -1) {
        rop = Rops.opCmpl(a.type.ropType);
    } else {
        throw new IllegalArgumentException("expected 1 or -1 but was " + nanValue);
    }
    addInstruction(new PlainInsn(rop, sourcePosition, target.spec(),
            RegisterSpecList.make(a.spec(), b.spec())));
}
 
Example #19
Source File: SsaMethod.java    From J2ME-Loader with Apache License 2.0 5 votes vote down vote up
/**
 * Deletes all insns in the set from this method.
 *
 * @param deletedInsns {@code non-null;} insns to delete
 */
public void deleteInsns(Set<SsaInsn> deletedInsns) {
    for (SsaBasicBlock block : getBlocks()) {
        ArrayList<SsaInsn> insns = block.getInsns();

        for (int i = insns.size() - 1; i >= 0; i--) {
            SsaInsn insn = insns.get(i);

            if (deletedInsns.contains(insn)) {
                onInsnRemoved(insn);
                insns.remove(i);
            }
        }

        // Check to see if we need to add a GOTO

        int insnsSz = insns.size();
        SsaInsn lastInsn = (insnsSz == 0) ? null : insns.get(insnsSz - 1);

        if (block != getExitBlock() && (insnsSz == 0
                || lastInsn.getOriginalRopInsn() == null
                || lastInsn.getOriginalRopInsn().getOpcode()
                    .getBranchingness() == Rop.BRANCH_NONE)) {
            // We managed to eat a throwable insn

            Insn gotoInsn = new PlainInsn(Rops.GOTO,
                    SourcePosition.NO_INFO, null, RegisterSpecList.EMPTY);
            insns.add(SsaInsn.makeFromRop(gotoInsn, block));

            // Remove secondary successors from this block
            BitSet succs = block.getSuccessors();
            for (int i = succs.nextSetBit(0); i >= 0;
                     i = succs.nextSetBit(i + 1)) {
                if (i != block.getPrimarySuccessorIndex()) {
                    block.removeSuccessor(i);
                }
            }
        }
    }
}
 
Example #20
Source File: Code.java    From lua-for-android with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
/**
 * Returns from a {@code void} method. After a return it is an error to
 * define further instructions after a return without first {@link #mark
 * marking} an existing unmarked label.
 */
public void returnVoid() {
    if (!method.returnType.equals(TypeId.VOID)) {
        throw new IllegalArgumentException("declared " + method.returnType
                + " but returned void");
    }
    addInstruction(new PlainInsn(Rops.RETURN_VOID, sourcePosition, null,
            RegisterSpecList.EMPTY));
}
 
Example #21
Source File: Code.java    From lua-for-android with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
/**
 * Returns the value in {@code result} to the calling method. After a return
 * it is an error to define further instructions after a return without
 * first {@link #mark marking} an existing unmarked label.
 */
public void returnValue(Local<?> result) {
    if (!result.type.equals(method.returnType)) {
        // TODO: this is probably too strict.
        throw new IllegalArgumentException("declared " + method.returnType
                + " but returned " + result.type);
    }
    addInstruction(new PlainInsn(Rops.opReturn(result.type.ropType), sourcePosition,
            null, RegisterSpecList.make(result.spec())));
}
 
Example #22
Source File: SsaBasicBlock.java    From J2ME-Loader with Apache License 2.0 5 votes vote down vote up
/**
 * Adds a move instruction after the phi insn block.
 *
 * @param result move destination
 * @param source move source
 */
public void addMoveToBeginning (RegisterSpec result, RegisterSpec source) {
    if (result.getReg() == source.getReg()) {
        // Sometimes we end up with no-op moves. Ignore them here.
        return;
    }

    RegisterSpecList sources = RegisterSpecList.make(source);
    NormalSsaInsn toAdd = new NormalSsaInsn(
            new PlainInsn(Rops.opMove(result.getType()),
                    SourcePosition.NO_INFO, result, sources), this);

    insns.add(getCountPhiInsns(), toAdd);
    movesFromPhisAtBeginning++;
}
 
Example #23
Source File: SCCP.java    From J2ME-Loader with Apache License 2.0 5 votes vote down vote up
/**
 * Replaces branches that have constant conditions with gotos
 */
private void replaceBranches() {
    for (SsaInsn insn : branchWorklist) {
        // Find if a successor block is never executed
        int oldSuccessor = -1;
        SsaBasicBlock block = insn.getBlock();
        int successorSize = block.getSuccessorList().size();
        for (int i = 0; i < successorSize; i++) {
            int successorBlock = block.getSuccessorList().get(i);
            if (!executableBlocks.get(successorBlock)) {
                oldSuccessor = successorBlock;
            }
        }

        /*
         * Prune branches that have already been handled and ones that no
         * longer have constant conditions (no nonexecutable successors)
         */
        if (successorSize != 2 || oldSuccessor == -1) continue;

        // Replace branch with goto
        Insn originalRopInsn = insn.getOriginalRopInsn();
        block.replaceLastInsn(new PlainInsn(Rops.GOTO,
            originalRopInsn.getPosition(), null, RegisterSpecList.EMPTY));
        block.removeSuccessor(oldSuccessor);
    }
}
 
Example #24
Source File: ConstCollector.java    From J2ME-Loader with Apache License 2.0 5 votes vote down vote up
/**
 * Inserts mark-locals if necessary when changing a register. If
 * the definition of {@code origReg} is associated with a local
 * variable, then insert a mark-local for {@code newReg} just below
 * it. We expect the definition of  {@code origReg} to ultimately
 * be removed by the dead code eliminator
 *
 * @param origReg {@code non-null;} original register
 * @param newReg {@code non-null;} new register that will replace
 * {@code origReg}
 */
private void fixLocalAssignment(RegisterSpec origReg,
        RegisterSpec newReg) {
    for (SsaInsn use : ssaMeth.getUseListForRegister(origReg.getReg())) {
        RegisterSpec localAssignment = use.getLocalAssignment();
        if (localAssignment == null) {
            continue;
        }

        if (use.getResult() == null) {
            /*
             * This is a mark-local. it will be updated when all uses
             * are updated.
             */
            continue;
        }

        LocalItem local = localAssignment.getLocalItem();

        // Un-associate original use.
        use.setResultLocal(null);

        // Now add a mark-local to the new reg immediately after.
        newReg = newReg.withLocalItem(local);

        SsaInsn newInsn
                = SsaInsn.makeFromRop(
                    new PlainInsn(Rops.opMarkLocal(newReg),
                    SourcePosition.NO_INFO, null,
                            RegisterSpecList.make(newReg)),
                use.getBlock());

        ArrayList<SsaInsn> insns = use.getBlock().getInsns();

        insns.add(insns.indexOf(use) + 1, newInsn);
    }
}
 
Example #25
Source File: RopTranslator.java    From buck with Apache License 2.0 4 votes vote down vote up
/** {@inheritDoc} */
public void visitPlainInsn(PlainInsn insn) {
    Rop rop = insn.getOpcode();
    if (rop.getOpcode() == RegOps.MARK_LOCAL) {
        /*
         * Ignore these. They're dealt with by
         * the LocalVariableAwareTranslationVisitor
         */
        return;
    }
    if (rop.getOpcode() == RegOps.MOVE_RESULT_PSEUDO) {
        // These get skipped
        return;
    }

    SourcePosition pos = insn.getPosition();
    Dop opcode = RopToDop.dopFor(insn);
    DalvInsn di;

    switch (rop.getBranchingness()) {
        case Rop.BRANCH_NONE:
        case Rop.BRANCH_RETURN:
        case Rop.BRANCH_THROW: {
            di = new SimpleInsn(opcode, pos, getRegs(insn));
            break;
        }
        case Rop.BRANCH_GOTO: {
            /*
             * Code in the main translation loop will emit a
             * goto if necessary (if the branch isn't to the
             * immediately subsequent block).
             */
            return;
        }
        case Rop.BRANCH_IF: {
            int target = block.getSuccessors().get(1);
            di = new TargetInsn(opcode, pos, getRegs(insn),
                                addresses.getStart(target));
            break;
        }
        default: {
            throw new RuntimeException("shouldn't happen");
        }
    }

    addOutput(di);
}
 
Example #26
Source File: SsaBasicBlock.java    From buck with Apache License 2.0 4 votes vote down vote up
/**
 * 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) {
        /*
         * The final insn in this block has a source or result
         * register, and the moves we may need to place and
         * schedule may interfere. We need to insert this
         * instruction at the beginning of the primary successor
         * block instead. We know this is safe, because when we
         * edge-split earlier, we ensured that each successor has
         * only us as a predecessor.
         */

        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++;
    }
}
 
Example #27
Source File: SsaBasicBlock.java    From J2ME-Loader with Apache License 2.0 4 votes vote down vote up
/**
 * 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) {
        /*
         * The final insn in this block has a source or result
         * register, and the moves we may need to place and
         * schedule may interfere. We need to insert this
         * instruction at the beginning of the primary successor
         * block instead. We know this is safe, because when we
         * edge-split earlier, we ensured that each successor has
         * only us as a predecessor.
         */

        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++;
    }
}
 
Example #28
Source File: SsaRenamer.java    From J2ME-Loader with Apache License 2.0 4 votes vote down vote up
/**
       * {@inheritDoc}
       *
       * Move insns are treated as a simple mapping operation, and
       * will later be removed unless they represent a local variable
       * assignment. If they represent a local variable assignement, they
       * are preserved.
       */
      @Override
public void visitMoveInsn(NormalSsaInsn insn) {
          /*
           * For moves: copy propogate the move if we can, but don't
           * if we need to preserve local variable info and the
           * result has a different name than the source.
           */

          RegisterSpec ropResult = insn.getResult();
          int ropResultReg = ropResult.getReg();
          int ropSourceReg = insn.getSources().get(0).getReg();

          insn.mapSourceRegisters(mapper);
          int ssaSourceReg = insn.getSources().get(0).getReg();

          LocalItem sourceLocal
              = currentMapping[ropSourceReg].getLocalItem();
          LocalItem resultLocal = ropResult.getLocalItem();

          /*
           * A move from a register that's currently associated with a local
           * to one that will not be associated with a local does not need
           * to be preserved, but the local association should remain.
           * Hence, we inherit the sourceLocal where the resultLocal is null.
           */

          LocalItem newLocal
              = (resultLocal == null) ? sourceLocal : resultLocal;
          LocalItem associatedLocal = getLocalForNewReg(ssaSourceReg);

          /*
           * If we take the new local, will only one local have ever
           * been associated with this SSA reg?
           */
          boolean onlyOneAssociatedLocal
                  = associatedLocal == null || newLocal == null
                  || newLocal.equals(associatedLocal);

          /*
           * If we're going to copy-propogate, then the ssa register
           * spec that's going to go into the mapping is made up of
           * the source register number mapped from above, the type
           * of the result, and the name either from the result (if
           * specified) or inherited from the existing mapping.
           *
           * The move source has incomplete type information in null
           * object cases, so the result type is used.
           */
          RegisterSpec ssaReg
                  = RegisterSpec.makeLocalOptional(
                      ssaSourceReg, ropResult.getType(), newLocal);

          if (!Optimizer.getPreserveLocals() || (onlyOneAssociatedLocal
                  && equalsHandlesNulls(newLocal, sourceLocal)) &&
                  threshold == 0) {
              /*
               * We don't have to keep this move to preserve local
               * information. Either the name is the same, or the result
               * register spec is unnamed.
               */

              addMapping(ropResultReg, ssaReg);
          } else if (onlyOneAssociatedLocal && sourceLocal == null &&
                  threshold == 0) {
              /*
               * The register was previously unnamed. This means that a
               * local starts after it's first assignment in SSA form
               */

              RegisterSpecList ssaSources = RegisterSpecList.make(
                      RegisterSpec.make(ssaReg.getReg(),
                              ssaReg.getType(), newLocal));

              SsaInsn newInsn
                      = SsaInsn.makeFromRop(
                          new PlainInsn(Rops.opMarkLocal(ssaReg),
                          SourcePosition.NO_INFO, null, ssaSources),block);

              insnsToReplace.put(insn, newInsn);

              // Just map as above.
              addMapping(ropResultReg, ssaReg);
          } else {
              /*
               * Do not copy-propogate, since the two registers have
               * two different local-variable names.
               */
              processResultReg(insn);

              movesToKeep.add(insn);
          }
      }
 
Example #29
Source File: RegisterAllocator.java    From J2ME-Loader with Apache License 2.0 4 votes vote down vote up
/**
 * Inserts a move instruction for a specified SSA register before a
 * specified instruction, creating a new SSA register and adjusting the
 * interference graph in the process. The insn currently must be the
 * last insn in a block.
 *
 * @param insn {@code non-null;} insn to insert move before, must
 * be last insn in block
 * @param reg {@code non-null;} SSA register to duplicate
 * @return {@code non-null;} spec of new SSA register created by move
 */
protected final RegisterSpec insertMoveBefore(SsaInsn insn,
        RegisterSpec reg) {
    SsaBasicBlock block = insn.getBlock();
    ArrayList<SsaInsn> insns = block.getInsns();
    int insnIndex = insns.indexOf(insn);

    if (insnIndex < 0) {
        throw new IllegalArgumentException (
                "specified insn is not in this block");
    }

    if (insnIndex != insns.size() - 1) {
        /*
         * Presently, the interference updater only works when
         * adding before the last insn, and the last insn must have no
         * result
         */
        throw new IllegalArgumentException(
                "Adding move here not supported:" + insn.toHuman());
    }

    /*
     * Get new register and make new move instruction.
     */

    // The new result must not have an associated local variable.
    RegisterSpec newRegSpec = RegisterSpec.make(ssaMeth.makeNewSsaReg(),
            reg.getTypeBearer());

    SsaInsn toAdd = SsaInsn.makeFromRop(
            new PlainInsn(Rops.opMove(newRegSpec.getType()),
                    SourcePosition.NO_INFO, newRegSpec,
                    RegisterSpecList.make(reg)), block);

    insns.add(insnIndex, toAdd);

    int newReg = newRegSpec.getReg();

    /*
     * Adjust interference graph based on what's live out of the current
     * block and what's used by the final instruction.
     */

    IntSet liveOut = block.getLiveOutRegs();
    IntIterator liveOutIter = liveOut.iterator();

    while (liveOutIter.hasNext()) {
        interference.add(newReg, liveOutIter.next());
    }

    // Everything that's a source in the last insn interferes.
    RegisterSpecList sources = insn.getSources();
    int szSources = sources.size();

    for (int i = 0; i < szSources; i++) {
        interference.add(newReg, sources.get(i).getReg());
    }

    ssaMeth.onInsnsChanged();

    return newRegSpec;
}
 
Example #30
Source File: RegisterAllocator.java    From buck with Apache License 2.0 4 votes vote down vote up
/**
 * Inserts a move instruction for a specified SSA register before a
 * specified instruction, creating a new SSA register and adjusting the
 * interference graph in the process. The insn currently must be the
 * last insn in a block.
 *
 * @param insn {@code non-null;} insn to insert move before, must
 * be last insn in block
 * @param reg {@code non-null;} SSA register to duplicate
 * @return {@code non-null;} spec of new SSA register created by move
 */
protected final RegisterSpec insertMoveBefore(SsaInsn insn,
        RegisterSpec reg) {
    SsaBasicBlock block = insn.getBlock();
    ArrayList<SsaInsn> insns = block.getInsns();
    int insnIndex = insns.indexOf(insn);

    if (insnIndex < 0) {
        throw new IllegalArgumentException (
                "specified insn is not in this block");
    }

    if (insnIndex != insns.size() - 1) {
        /*
         * Presently, the interference updater only works when
         * adding before the last insn, and the last insn must have no
         * result
         */
        throw new IllegalArgumentException(
                "Adding move here not supported:" + insn.toHuman());
    }

    /*
     * Get new register and make new move instruction.
     */

    // The new result must not have an associated local variable.
    RegisterSpec newRegSpec = RegisterSpec.make(ssaMeth.makeNewSsaReg(),
            reg.getTypeBearer());

    SsaInsn toAdd = SsaInsn.makeFromRop(
            new PlainInsn(Rops.opMove(newRegSpec.getType()),
                    SourcePosition.NO_INFO, newRegSpec,
                    RegisterSpecList.make(reg)), block);

    insns.add(insnIndex, toAdd);

    int newReg = newRegSpec.getReg();

    /*
     * Adjust interference graph based on what's live out of the current
     * block and what's used by the final instruction.
     */

    IntSet liveOut = block.getLiveOutRegs();
    IntIterator liveOutIter = liveOut.iterator();

    while (liveOutIter.hasNext()) {
        interference.add(newReg, liveOutIter.next());
    }

    // Everything that's a source in the last insn interferes.
    RegisterSpecList sources = insn.getSources();
    int szSources = sources.size();

    for (int i = 0; i < szSources; i++) {
        interference.add(newReg, sources.get(i).getReg());
    }

    ssaMeth.onInsnsChanged();

    return newRegSpec;
}