Java Code Examples for com.android.dx.rop.code.RegisterSpecList#get()

The following examples show how to use com.android.dx.rop.code.RegisterSpecList#get() . 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: InsnFormat.java    From J2ME-Loader with Apache License 2.0 6 votes vote down vote up
/**
 * Helper method to determine if a list of registers are sequential,
 * including degenerate cases for empty or single-element lists.
 *
 * @param list {@code non-null;} the list of registers
 * @return {@code true} iff the list is sequentially ordered
 */
protected static boolean isRegListSequential(RegisterSpecList list) {
    int sz = list.size();

    if (sz < 2) {
        return true;
    }

    int first = list.get(0).getReg();
    int next = first;

    for (int i = 0; i < sz; i++) {
        RegisterSpec one = list.get(i);
        if (one.getReg() != next) {
            return false;
        }
        next += one.getCategory();
    }

    return true;
}
 
Example 2
Source File: InterferenceRegisterMapper.java    From buck with Apache License 2.0 6 votes vote down vote up
/**
 * 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;
}
 
Example 3
Source File: Form35c.java    From Box with Apache License 2.0 6 votes vote down vote up
/** {@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;
}
 
Example 4
Source File: HighRegisterPrefix.java    From Box with Apache License 2.0 6 votes vote down vote up
/** {@inheritDoc} */
@Override
protected String listingString0(boolean noteIndices) {
    RegisterSpecList registers = getRegisters();
    int sz = registers.size();
    StringBuilder sb = new StringBuilder(100);

    for (int i = 0, outAt = 0; i < sz; i++) {
        RegisterSpec src = registers.get(i);
        SimpleInsn insn = moveInsnFor(src, outAt);

        if (i != 0) {
            sb.append('\n');
        }

        sb.append(insn.listingString0(noteIndices));

        outAt += src.getCategory();
    }

    return sb.toString();
}
 
Example 5
Source File: HighRegisterPrefix.java    From J2ME-Loader with Apache License 2.0 6 votes vote down vote up
/**
 * Helper for {@link #codeSize} and {@link #writeTo} which sets up
 * {@link #insns} if not already done.
 */
private void calculateInsnsIfNecessary() {
    if (insns != null) {
        return;
    }

    RegisterSpecList registers = getRegisters();
    int sz = registers.size();

    insns = new SimpleInsn[sz];

    for (int i = 0, outAt = 0; i < sz; i++) {
      RegisterSpec src = registers.get(i);
      insns[i] = moveInsnFor(src, outAt);
      outAt += src.getCategory();
    }
}
 
Example 6
Source File: HighRegisterPrefix.java    From Box with Apache License 2.0 6 votes vote down vote up
/** {@inheritDoc} */
@Override
protected String listingString0(boolean noteIndices) {
    RegisterSpecList registers = getRegisters();
    int sz = registers.size();
    StringBuilder sb = new StringBuilder(100);

    for (int i = 0, outAt = 0; i < sz; i++) {
        RegisterSpec src = registers.get(i);
        SimpleInsn insn = moveInsnFor(src, outAt);

        if (i != 0) {
            sb.append('\n');
        }

        sb.append(insn.listingString0(noteIndices));

        outAt += src.getCategory();
    }

    return sb.toString();
}
 
Example 7
Source File: Form35c.java    From J2ME-Loader with Apache License 2.0 5 votes vote down vote up
/**
 * Returns a register list which is equivalent to the given one,
 * except that it splits category-2 registers into two explicit
 * entries. This returns the original list if no modification is
 * required
 *
 * @param orig {@code non-null;} the original list
 * @return {@code non-null;} the list with the described transformation
 */
private static RegisterSpecList explicitize(RegisterSpecList orig) {
    int wordCount = wordCount(orig);
    int sz = orig.size();

    if (wordCount == sz) {
        return orig;
    }

    RegisterSpecList result = new RegisterSpecList(wordCount);
    int wordAt = 0;

    for (int i = 0; i < sz; i++) {
        RegisterSpec one = orig.get(i);
        result.set(wordAt, one);
        if (one.getCategory() == 2) {
            result.set(wordAt + 1,
                       RegisterSpec.make(one.getReg() + 1, Type.VOID));
            wordAt += 2;
        } else {
            wordAt++;
        }
    }

    result.setImmutable();
    return result;
}
 
Example 8
Source File: Form12x.java    From buck with Apache License 2.0 5 votes vote down vote up
/** {@inheritDoc} */
@Override
public boolean isCompatible(DalvInsn insn) {
    if (!(insn instanceof SimpleInsn)) {
        return false;
    }

    RegisterSpecList regs = insn.getRegisters();
    RegisterSpec rs1;
    RegisterSpec rs2;

    switch (regs.size()) {
        case 2: {
            rs1 = regs.get(0);
            rs2 = regs.get(1);
            break;
        }
        case 3: {
            /*
             * This format is allowed for ops that are effectively
             * 3-arg but where the first two args are identical.
             */
            rs1 = regs.get(1);
            rs2 = regs.get(2);
            if (rs1.getReg() != regs.get(0).getReg()) {
                return false;
            }
            break;
        }
        default: {
            return false;
        }
    }

    return unsignedFitsInNibble(rs1.getReg()) &&
        unsignedFitsInNibble(rs2.getReg());
}
 
Example 9
Source File: SsaToRop.java    From Box with Apache License 2.0 5 votes vote down vote up
@Override
public void visitPhiInsn(PhiInsn insn) {
    RegisterSpecList sources = insn.getSources();
    RegisterSpec result = insn.getResult();
    int sz = sources.size();

    for (int i = 0; i < sz; i++) {
        RegisterSpec source = sources.get(i);
        SsaBasicBlock predBlock = blocks.get(
                insn.predBlockIndexForSourcesIndex(i));

        predBlock.addMoveToEnd(result, source);
    }
}
 
Example 10
Source File: Form45cc.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Returns a register list which is equivalent to the given one,
 * except that it splits category-2 registers into two explicit
 * entries. This returns the original list if no modification is
 * required
 *
 * @param orig {@code non-null;} the original list
 * @return {@code non-null;} the list with the described transformation
 */
private static RegisterSpecList explicitize(RegisterSpecList orig) {
    int wordCount = wordCount(orig);
    int sz = orig.size();

    if (wordCount == sz) {
        return orig;
    }

    RegisterSpecList result = new RegisterSpecList(wordCount);
    int wordAt = 0;

    for (int i = 0; i < sz; i++) {
        RegisterSpec one = orig.get(i);
        result.set(wordAt, one);
        if (one.getCategory() == 2) {
            result.set(wordAt + 1,
                       RegisterSpec.make(one.getReg() + 1, Type.VOID));
            wordAt += 2;
        } else {
            wordAt++;
        }
    }

    result.setImmutable();
    return result;
}
 
Example 11
Source File: FirstFitLocalCombiningAllocator.java    From J2ME-Loader with Apache License 2.0 4 votes vote down vote up
/**
 * 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;
}
 
Example 12
Source File: Form21c.java    From J2ME-Loader with Apache License 2.0 4 votes vote down vote up
/** {@inheritDoc} */
@Override
public boolean isCompatible(DalvInsn insn) {
    if (!(insn instanceof CstInsn)) {
        return false;
    }

    RegisterSpecList regs = insn.getRegisters();
    RegisterSpec reg;

    switch (regs.size()) {
        case 1: {
            reg = regs.get(0);
            break;
        }
        case 2: {
            /*
             * This format is allowed for ops that are effectively
             * 2-arg but where the two args are identical.
             */
            reg = regs.get(0);
            if (reg.getReg() != regs.get(1).getReg()) {
                return false;
            }
            break;
        }
        default: {
            return false;
        }
    }

    if (!unsignedFitsInByte(reg.getReg())) {
        return false;
    }

    CstInsn ci = (CstInsn) insn;
    int cpi = ci.getIndex();
    Constant cst = ci.getConstant();

    if (! unsignedFitsInShort(cpi)) {
        return false;
    }

    return (cst instanceof CstType) ||
        (cst instanceof CstFieldRef) ||
        (cst instanceof CstString);
}
 
Example 13
Source File: FirstFitLocalCombiningAllocator.java    From J2ME-Loader with Apache License 2.0 4 votes vote down vote up
/**
 * Maps the source registers of the specified instruction such that they
 * will fall in a contiguous range in rop form. Moves are inserted as
 * necessary to allow the range to be allocated.
 *
 * @param insn {@code non-null;} insn whos sources to process
 */
private void adjustAndMapSourceRangeRange(NormalSsaInsn insn) {
    int newRegStart = findRangeAndAdjust(insn);

    RegisterSpecList sources = insn.getSources();
    int szSources = sources.size();
    int nextRopReg = newRegStart;

    for (int i = 0; i < szSources; i++) {
        RegisterSpec source = sources.get(i);
        int sourceReg = source.getReg();
        int category = source.getCategory();
        int curRopReg = nextRopReg;
        nextRopReg += category;

        if (ssaRegsMapped.get(sourceReg)) {
            continue;
        }

        LocalItem localItem = getLocalItemForReg(sourceReg);
        addMapping(source, curRopReg);

        if (localItem != null) {
            markReserved(curRopReg, category);
            ArrayList<RegisterSpec> similarRegisters
                    = localVariables.get(localItem);

            int szSimilar = similarRegisters.size();

            /*
             * Try to map all SSA registers also associated with
             * this local.
             */
            for (int j = 0; j < szSimilar; j++) {
                RegisterSpec similarSpec = similarRegisters.get(j);
                int similarReg = similarSpec.getReg();

                // Don't map anything that's also a source.
                if (-1 != sources.indexOfRegister(similarReg)) {
                    continue;
                }

                // Registers left unmapped will get handled later.
                tryMapReg(similarSpec, curRopReg, category);
            }
        }
    }
}
 
Example 14
Source File: DeadCodeRemover.java    From Box with Apache License 2.0 4 votes vote down vote up
/**
 * Removes all instructions from every unreachable block.
 */
private void pruneDeadInstructions() {
    HashSet<SsaInsn> deletedInsns = new HashSet<SsaInsn>();

    BitSet reachable = ssaMeth.computeReachability();
    ArrayList<SsaBasicBlock> blocks = ssaMeth.getBlocks();
    int blockIndex = 0;

    while ((blockIndex = reachable.nextClearBit(blockIndex)) < blocks.size()) {
        SsaBasicBlock block = blocks.get(blockIndex);
        blockIndex++;

        // Prune instructions from unreachable blocks
        for (int i = 0; i < block.getInsns().size(); i++) {
            SsaInsn insn = block.getInsns().get(i);
            RegisterSpecList sources = insn.getSources();
            int sourcesSize = sources.size();

            // Delete this instruction completely if it has sources
            if (sourcesSize != 0) {
                deletedInsns.add(insn);
            }

            // Delete this instruction from all usage lists.
            for (int j = 0; j < sourcesSize; j++) {
                RegisterSpec source = sources.get(j);
                useList[source.getReg()].remove(insn);
            }

            // Remove this instruction result from the sources of any phis
            RegisterSpec result = insn.getResult();
            if (result == null) continue;
            for (SsaInsn use : useList[result.getReg()]) {
                if (use instanceof PhiInsn) {
                    PhiInsn phiUse = (PhiInsn) use;
                    phiUse.removePhiRegister(result);
                }
            }
        }
    }

    ssaMeth.deleteInsns(deletedInsns);
}
 
Example 15
Source File: Form31c.java    From buck with Apache License 2.0 4 votes vote down vote up
/** {@inheritDoc} */
@Override
public boolean isCompatible(DalvInsn insn) {
    if (!(insn instanceof CstInsn)) {
        return false;
    }

    RegisterSpecList regs = insn.getRegisters();
    RegisterSpec reg;

    switch (regs.size()) {
        case 1: {
            reg = regs.get(0);
            break;
        }
        case 2: {
            /*
             * This format is allowed for ops that are effectively
             * 2-arg but where the two args are identical.
             */
            reg = regs.get(0);
            if (reg.getReg() != regs.get(1).getReg()) {
                return false;
            }
            break;
        }
        default: {
            return false;
        }
    }

    if (!unsignedFitsInByte(reg.getReg())) {
        return false;
    }

    CstInsn ci = (CstInsn) insn;
    Constant cst = ci.getConstant();

    return (cst instanceof CstType) ||
        (cst instanceof CstFieldRef) ||
        (cst instanceof CstString);
}
 
Example 16
Source File: SCCP.java    From buck with Apache License 2.0 4 votes vote down vote up
/**
 * Replaces TypeBearers in source register specs with constant type
 * bearers if possible. These are then referenced in later optimization
 * steps.
 */
private void replaceConstants() {
    for (int reg = 0; reg < regCount; reg++) {
        if (latticeValues[reg] != CONSTANT) {
            continue;
        }
        if (!(latticeConstants[reg] instanceof TypedConstant)) {
            // We can't do much with these
            continue;
        }

        SsaInsn defn = ssaMeth.getDefinitionForRegister(reg);
        TypeBearer typeBearer = defn.getResult().getTypeBearer();

        if (typeBearer.isConstant()) {
            /*
             * The definition was a constant already.
             * The uses should be as well.
             */
            continue;
        }

        // Update the destination RegisterSpec with the constant value
        RegisterSpec dest = defn.getResult();
        RegisterSpec newDest
                = dest.withType((TypedConstant)latticeConstants[reg]);
        defn.setResult(newDest);

        /*
         * Update the sources RegisterSpec's of all non-move uses.
         * These will be used in later steps.
         */
        for (SsaInsn insn : ssaMeth.getUseListForRegister(reg)) {
            if (insn.isPhiOrMove()) {
                continue;
            }

            NormalSsaInsn nInsn = (NormalSsaInsn) insn;
            RegisterSpecList sources = insn.getSources();

            int index = sources.indexOfRegister(reg);

            RegisterSpec spec = sources.get(index);
            RegisterSpec newSpec
                    = spec.withType((TypedConstant)latticeConstants[reg]);

            nInsn.changeOneSource(index, newSpec);
        }
    }
}
 
Example 17
Source File: FirstFitLocalCombiningAllocator.java    From Box with Apache License 2.0 4 votes vote down vote up
/**
 * 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;
}
 
Example 18
Source File: FirstFitLocalCombiningAllocator.java    From buck with Apache License 2.0 4 votes vote down vote up
/**
 * 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;
}
 
Example 19
Source File: Form31c.java    From Box with Apache License 2.0 4 votes vote down vote up
/** {@inheritDoc} */
@Override
public boolean isCompatible(DalvInsn insn) {
    if (!(insn instanceof CstInsn)) {
        return false;
    }

    RegisterSpecList regs = insn.getRegisters();
    RegisterSpec reg;

    switch (regs.size()) {
        case 1: {
            reg = regs.get(0);
            break;
        }
        case 2: {
            /*
             * This format is allowed for ops that are effectively
             * 2-arg but where the two args are identical.
             */
            reg = regs.get(0);
            if (reg.getReg() != regs.get(1).getReg()) {
                return false;
            }
            break;
        }
        default: {
            return false;
        }
    }

    if (!unsignedFitsInByte(reg.getReg())) {
        return false;
    }

    CstInsn ci = (CstInsn) insn;
    Constant cst = ci.getConstant();

    return (cst instanceof CstType) ||
        (cst instanceof CstFieldRef) ||
        (cst instanceof CstString);
}
 
Example 20
Source File: EscapeAnalysis.java    From J2ME-Loader with Apache License 2.0 4 votes vote down vote up
/**
 * Replaces the use for a scalar replaceable array. Gets and puts become
 * move instructions, and array lengths and fills are handled. Can also
 * identify ArrayIndexOutOfBounds exceptions and throw them if detected.
 *
 * @param use {@code non-null;} move result instruction for array
 * @param prev {@code non-null;} instruction for instantiating new array
 * @param newRegs {@code non-null;} mapping of array indices to new
 * registers
 * @param deletedInsns {@code non-null;} set of instructions marked for
 * deletion
 */
private void replaceUse(SsaInsn use, SsaInsn prev,
                            ArrayList<RegisterSpec> newRegs,
                            HashSet<SsaInsn> deletedInsns) {
    int index;
    int length = newRegs.size();
    SsaInsn next;
    RegisterSpecList sources;
    RegisterSpec source, result;
    CstLiteralBits indexReg;

    switch (use.getOpcode().getOpcode()) {
        case RegOps.AGET:
            // Replace array gets with moves
            next = getMoveForInsn(use);
            sources = use.getSources();
            indexReg = ((CstLiteralBits) sources.get(1).getTypeBearer());
            index = indexReg.getIntBits();
            if (index < length) {
                source = newRegs.get(index);
                result = source.withReg(next.getResult().getReg());
                insertPlainInsnBefore(next, RegisterSpecList.make(source),
                                          result, RegOps.MOVE, null);
            } else {
                // Throw an exception if the index is out of bounds
                insertExceptionThrow(next, sources.get(1), deletedInsns);
                deletedInsns.add(next.getBlock().getInsns().get(2));
            }
            deletedInsns.add(next);
            break;
        case RegOps.APUT:
            // Replace array puts with moves
            sources = use.getSources();
            indexReg = ((CstLiteralBits) sources.get(2).getTypeBearer());
            index = indexReg.getIntBits();
            if (index < length) {
                source = sources.get(0);
                result = source.withReg(newRegs.get(index).getReg());
                insertPlainInsnBefore(use, RegisterSpecList.make(source),
                                          result, RegOps.MOVE, null);
                // Update the newReg entry to mark value as unknown now
                newRegs.set(index, result.withSimpleType());
            } else {
                // Throw an exception if the index is out of bounds
                insertExceptionThrow(use, sources.get(2), deletedInsns);
            }
            break;
        case RegOps.ARRAY_LENGTH:
            // Replace array lengths with const instructions
            TypeBearer lengthReg = prev.getSources().get(0).getTypeBearer();
            //CstInteger lengthReg = CstInteger.make(length);
            next = getMoveForInsn(use);
            insertPlainInsnBefore(next, RegisterSpecList.EMPTY,
                                      next.getResult(), RegOps.CONST,
                                      (Constant) lengthReg);
            deletedInsns.add(next);
            break;
        case RegOps.MARK_LOCAL:
            // Remove mark local instructions
            break;
        case RegOps.FILL_ARRAY_DATA:
            // Create const instructions for each fill value
            Insn ropUse = use.getOriginalRopInsn();
            FillArrayDataInsn fill = (FillArrayDataInsn) ropUse;
            ArrayList<Constant> constList = fill.getInitValues();
            for (int i = 0; i < length; i++) {
                RegisterSpec newFill =
                    RegisterSpec.make(newRegs.get(i).getReg(),
                                          (TypeBearer) constList.get(i));
                insertPlainInsnBefore(use, RegisterSpecList.EMPTY, newFill,
                                          RegOps.CONST, constList.get(i));
                // Update the newRegs to hold the new const value
                newRegs.set(i, newFill);
            }
            break;
        default:
    }
}