com.android.dx.util.IntSet Java Examples

The following examples show how to use com.android.dx.util.IntSet. 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: InterferenceRegisterMapper.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Checks to see if old namespace reg {@code oldReg} interferes
 * with what currently maps to {@code newReg}.
 *
 * @param oldReg old namespace register
 * @param newReg new namespace register
 * @param category category of old namespace register
 * @return true if oldReg will interfere with newReg
 */
public boolean interferes(int oldReg, int newReg, int category) {
    if (newReg >= newRegInterference.size()) {
        return false;
    } else {
        IntSet existing = newRegInterference.get(newReg);

        if (existing == null) {
            return false;
        } else if (category == 1) {
            return existing.has(oldReg);
        } else {
            return existing.has(oldReg)
                    || (interferes(oldReg, newReg+1, category-1));
        }
    }
}
 
Example #2
Source File: InterferenceRegisterMapper.java    From buck with Apache License 2.0 6 votes vote down vote up
/**
 * Checks to see if old namespace reg {@code oldReg} interferes
 * with what currently maps to {@code newReg}.
 *
 * @param oldReg old namespace register
 * @param newReg new namespace register
 * @param category category of old namespace register
 * @return true if oldReg will interfere with newReg
 */
public boolean interferes(int oldReg, int newReg, int category) {
    if (newReg >= newRegInterference.size()) {
        return false;
    } else {
        IntSet existing = newRegInterference.get(newReg);

        if (existing == null) {
            return false;
        } else if (category == 1) {
            return existing.has(oldReg);
        } else {
            return existing.has(oldReg)
                    || (interferes(oldReg, newReg+1, category-1));
        }
    }
}
 
Example #3
Source File: InterferenceRegisterMapper.java    From J2ME-Loader with Apache License 2.0 6 votes vote down vote up
/**
 * Checks to see if old namespace reg {@code oldReg} interferes
 * with what currently maps to {@code newReg}.
 *
 * @param oldReg old namespace register
 * @param newReg new namespace register
 * @param category category of old namespace register
 * @return true if oldReg will interfere with newReg
 */
public boolean interferes(int oldReg, int newReg, int category) {
    if (newReg >= newRegInterference.size()) {
        return false;
    } else {
        IntSet existing = newRegInterference.get(newReg);

        if (existing == null) {
            return false;
        } else if (category == 1) {
            return existing.has(oldReg);
        } else {
            return existing.has(oldReg)
                    || (interferes(oldReg, newReg+1, category-1));
        }
    }
}
 
Example #4
Source File: InterferenceRegisterMapper.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Checks to see if old namespace reg {@code oldReg} interferes
 * with what currently maps to {@code newReg}.
 *
 * @param oldReg old namespace register
 * @param newReg new namespace register
 * @param category category of old namespace register
 * @return true if oldReg will interfere with newReg
 */
public boolean interferes(int oldReg, int newReg, int category) {
    if (newReg >= newRegInterference.size()) {
        return false;
    } else {
        IntSet existing = newRegInterference.get(newReg);

        if (existing == null) {
            return false;
        } else if (category == 1) {
            return existing.has(oldReg);
        } else {
            return existing.has(oldReg)
                    || (interferes(oldReg, newReg+1, category-1));
        }
    }
}
 
Example #5
Source File: FirstFitLocalCombiningAllocator.java    From J2ME-Loader with Apache License 2.0 5 votes vote down vote up
/**
 * Converts a bit set of SSA registers into a RegisterSpecList containing
 * the definition specs of all the registers.
 *
 * @param ssaSet {@code non-null;} set of SSA registers
 * @return list of RegisterSpecs as noted above
 */
RegisterSpecList ssaSetToSpecs(IntSet ssaSet) {
    RegisterSpecList result = new RegisterSpecList(ssaSet.elements());

    IntIterator iter = ssaSet.iterator();

    int i = 0;
    while (iter.hasNext()) {
        result.set(i++, getDefinitionSpecForSsaReg(iter.next()));
    }

    return result;
}
 
Example #6
Source File: InterferenceGraph.java    From buck with Apache License 2.0 5 votes vote down vote up
/**
 * Creates a new graph.
 *
 * @param countRegs {@code >= 0;} the start count of registers in
 * the namespace. New registers can be added subsequently.
 */
public InterferenceGraph(int countRegs) {
    interference = new ArrayList<IntSet>(countRegs);

    for (int i = 0; i < countRegs; i++) {
        interference.add(SetFactory.makeInterferenceSet(countRegs));
    }
}
 
Example #7
Source File: SsaBasicBlock.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the set of live-out registers. Valid after register
 * interference graph has been generated, otherwise empty.
 *
 * @return {@code non-null;} live-out register set
 */
public IntSet getLiveOutRegs() {
    if (liveOut == null) {
        liveOut = SetFactory.makeLivenessSet(parent.getRegCount());
    }
    return liveOut;
}
 
Example #8
Source File: SsaBasicBlock.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the set of live-in registers. Valid after register
 * interference graph has been generated, otherwise empty.
 *
 * @return {@code non-null;} live-in register set.
 */
public IntSet getLiveInRegs() {
    if (liveIn == null) {
        liveIn = SetFactory.makeLivenessSet(parent.getRegCount());
    }
    return liveIn;
}
 
Example #9
Source File: FirstFitLocalCombiningAllocator.java    From buck with Apache License 2.0 5 votes vote down vote up
/**
 * Converts a bit set of SSA registers into a RegisterSpecList containing
 * the definition specs of all the registers.
 *
 * @param ssaSet {@code non-null;} set of SSA registers
 * @return list of RegisterSpecs as noted above
 */
RegisterSpecList ssaSetToSpecs(IntSet ssaSet) {
    RegisterSpecList result = new RegisterSpecList(ssaSet.elements());

    IntIterator iter = ssaSet.iterator();

    int i = 0;
    while (iter.hasNext()) {
        result.set(i++, getDefinitionSpecForSsaReg(iter.next()));
    }

    return result;
}
 
Example #10
Source File: InterferenceGraph.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Creates a new graph.
 *
 * @param countRegs {@code >= 0;} the start count of registers in
 * the namespace. New registers can be added subsequently.
 */
public InterferenceGraph(int countRegs) {
    interference = new ArrayList<IntSet>(countRegs);

    for (int i = 0; i < countRegs; i++) {
        interference.add(SetFactory.makeInterferenceSet(countRegs));
    }
}
 
Example #11
Source File: FirstFitLocalCombiningAllocator.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Converts a bit set of SSA registers into a RegisterSpecList containing
 * the definition specs of all the registers.
 *
 * @param ssaSet {@code non-null;} set of SSA registers
 * @return list of RegisterSpecs as noted above
 */
RegisterSpecList ssaSetToSpecs(IntSet ssaSet) {
    RegisterSpecList result = new RegisterSpecList(ssaSet.elements());

    IntIterator iter = ssaSet.iterator();

    int i = 0;
    while (iter.hasNext()) {
        result.set(i++, getDefinitionSpecForSsaReg(iter.next()));
    }

    return result;
}
 
Example #12
Source File: SsaBasicBlock.java    From buck with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the set of live-in registers. Valid after register
 * interference graph has been generated, otherwise empty.
 *
 * @return {@code non-null;} live-in register set.
 */
public IntSet getLiveInRegs() {
    if (liveIn == null) {
        liveIn = SetFactory.makeLivenessSet(parent.getRegCount());
    }
    return liveIn;
}
 
Example #13
Source File: SsaBasicBlock.java    From buck with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the set of live-out registers. Valid after register
 * interference graph has been generated, otherwise empty.
 *
 * @return {@code non-null;} live-out register set
 */
public IntSet getLiveOutRegs() {
    if (liveOut == null) {
        liveOut = SetFactory.makeLivenessSet(parent.getRegCount());
    }
    return liveOut;
}
 
Example #14
Source File: SsaBasicBlock.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the set of live-out registers. Valid after register
 * interference graph has been generated, otherwise empty.
 *
 * @return {@code non-null;} live-out register set
 */
public IntSet getLiveOutRegs() {
    if (liveOut == null) {
        liveOut = SetFactory.makeLivenessSet(parent.getRegCount());
    }
    return liveOut;
}
 
Example #15
Source File: SsaBasicBlock.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the set of live-in registers. Valid after register
 * interference graph has been generated, otherwise empty.
 *
 * @return {@code non-null;} live-in register set.
 */
public IntSet getLiveInRegs() {
    if (liveIn == null) {
        liveIn = SetFactory.makeLivenessSet(parent.getRegCount());
    }
    return liveIn;
}
 
Example #16
Source File: InterferenceGraph.java    From J2ME-Loader with Apache License 2.0 5 votes vote down vote up
/**
 * Creates a new graph.
 *
 * @param countRegs {@code >= 0;} the start count of registers in
 * the namespace. New registers can be added subsequently.
 */
public InterferenceGraph(int countRegs) {
    interference = new ArrayList<IntSet>(countRegs);

    for (int i = 0; i < countRegs; i++) {
        interference.add(SetFactory.makeInterferenceSet(countRegs));
    }
}
 
Example #17
Source File: FirstFitLocalCombiningAllocator.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Converts a bit set of SSA registers into a RegisterSpecList containing
 * the definition specs of all the registers.
 *
 * @param ssaSet {@code non-null;} set of SSA registers
 * @return list of RegisterSpecs as noted above
 */
RegisterSpecList ssaSetToSpecs(IntSet ssaSet) {
    RegisterSpecList result = new RegisterSpecList(ssaSet.elements());

    IntIterator iter = ssaSet.iterator();

    int i = 0;
    while (iter.hasNext()) {
        result.set(i++, getDefinitionSpecForSsaReg(iter.next()));
    }

    return result;
}
 
Example #18
Source File: InterferenceGraph.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Creates a new graph.
 *
 * @param countRegs {@code >= 0;} the start count of registers in
 * the namespace. New registers can be added subsequently.
 */
public InterferenceGraph(int countRegs) {
    interference = new ArrayList<IntSet>(countRegs);

    for (int i = 0; i < countRegs; i++) {
        interference.add(SetFactory.makeInterferenceSet(countRegs));
    }
}
 
Example #19
Source File: SsaBasicBlock.java    From J2ME-Loader with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the set of live-out registers. Valid after register
 * interference graph has been generated, otherwise empty.
 *
 * @return {@code non-null;} live-out register set
 */
public IntSet getLiveOutRegs() {
    if (liveOut == null) {
        liveOut = SetFactory.makeLivenessSet(parent.getRegCount());
    }
    return liveOut;
}
 
Example #20
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 #21
Source File: FirstFitAllocator.java    From J2ME-Loader with Apache License 2.0 4 votes vote down vote up
/** {@inheritDoc} */
@Override
public RegisterMapper allocateRegisters() {
    int oldRegCount = ssaMeth.getRegCount();

    BasicRegisterMapper mapper
            = new BasicRegisterMapper(oldRegCount);

    int nextNewRegister = 0;

    if (PRESLOT_PARAMS) {
        /*
         * Reserve space for the params at the bottom of the register
         * space. Later, we'll flip the params to the end of the register
         * space.
         */

        nextNewRegister = ssaMeth.getParamWidth();
    }

    for (int i = 0; i < oldRegCount; i++) {
        if (mapped.get(i)) {
            // we already got this one
            continue;
        }

        int maxCategory = getCategoryForSsaReg(i);
        IntSet current = new BitIntSet(oldRegCount);

        interference.mergeInterferenceSet(i, current);

        boolean isPreslotted = false;
        int newReg = 0;

        if (PRESLOT_PARAMS && isDefinitionMoveParam(i)) {
            // Any move-param definition must be a NormalSsaInsn
            NormalSsaInsn defInsn = (NormalSsaInsn)
                   ssaMeth.getDefinitionForRegister(i);

            newReg = paramNumberFromMoveParam(defInsn);

            mapper.addMapping(i, newReg, maxCategory);
            isPreslotted = true;
        } else {
            mapper.addMapping(i, nextNewRegister, maxCategory);
            newReg = nextNewRegister;
        }

        for (int j = i + 1; j < oldRegCount; j++) {
            if (mapped.get(j) || isDefinitionMoveParam(j)) {
                continue;
            }

            /*
             * If reg j doesn't interfere with the current mapping.
             * Also, if this is a pre-slotted method parameter, we
             * can't use more than the original param width.
             */
            if (!current.has(j)
                    && !(isPreslotted
                        && (maxCategory < getCategoryForSsaReg(j)))) {

                interference.mergeInterferenceSet(j, current);

                maxCategory = Math.max(maxCategory,
                        getCategoryForSsaReg(j));

                mapper.addMapping(j, newReg, maxCategory);
                mapped.set(j);
            }
        }

        mapped.set(i);
        if (!isPreslotted) {
            nextNewRegister += maxCategory;
        }
    }

    return mapper;
}
 
Example #22
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 #23
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 #24
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;
}
 
Example #25
Source File: FirstFitAllocator.java    From Box with Apache License 2.0 4 votes vote down vote up
/** {@inheritDoc} */
@Override
public RegisterMapper allocateRegisters() {
    int oldRegCount = ssaMeth.getRegCount();

    BasicRegisterMapper mapper
            = new BasicRegisterMapper(oldRegCount);

    int nextNewRegister = 0;

    if (PRESLOT_PARAMS) {
        /*
         * Reserve space for the params at the bottom of the register
         * space. Later, we'll flip the params to the end of the register
         * space.
         */

        nextNewRegister = ssaMeth.getParamWidth();
    }

    for (int i = 0; i < oldRegCount; i++) {
        if (mapped.get(i)) {
            // we already got this one
            continue;
        }

        int maxCategory = getCategoryForSsaReg(i);
        IntSet current = new BitIntSet(oldRegCount);

        interference.mergeInterferenceSet(i, current);

        boolean isPreslotted = false;
        int newReg = 0;

        if (PRESLOT_PARAMS && isDefinitionMoveParam(i)) {
            // Any move-param definition must be a NormalSsaInsn
            NormalSsaInsn defInsn = (NormalSsaInsn)
                   ssaMeth.getDefinitionForRegister(i);

            newReg = paramNumberFromMoveParam(defInsn);

            mapper.addMapping(i, newReg, maxCategory);
            isPreslotted = true;
        } else {
            mapper.addMapping(i, nextNewRegister, maxCategory);
            newReg = nextNewRegister;
        }

        for (int j = i + 1; j < oldRegCount; j++) {
            if (mapped.get(j) || isDefinitionMoveParam(j)) {
                continue;
            }

            /*
             * If reg j doesn't interfere with the current mapping.
             * Also, if this is a pre-slotted method parameter, we
             * can't use more than the original param width.
             */
            if (!current.has(j)
                    && !(isPreslotted
                        && (maxCategory < getCategoryForSsaReg(j)))) {

                interference.mergeInterferenceSet(j, current);

                maxCategory = Math.max(maxCategory,
                        getCategoryForSsaReg(j));

                mapper.addMapping(j, newReg, maxCategory);
                mapped.set(j);
            }
        }

        mapped.set(i);
        if (!isPreslotted) {
            nextNewRegister += maxCategory;
        }
    }

    return mapper;
}
 
Example #26
Source File: RegisterAllocator.java    From Box 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 #27
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 #28
Source File: FirstFitAllocator.java    From buck with Apache License 2.0 4 votes vote down vote up
/** {@inheritDoc} */
@Override
public RegisterMapper allocateRegisters() {
    int oldRegCount = ssaMeth.getRegCount();

    BasicRegisterMapper mapper
            = new BasicRegisterMapper(oldRegCount);

    int nextNewRegister = 0;

    if (PRESLOT_PARAMS) {
        /*
         * Reserve space for the params at the bottom of the register
         * space. Later, we'll flip the params to the end of the register
         * space.
         */

        nextNewRegister = ssaMeth.getParamWidth();
    }

    for (int i = 0; i < oldRegCount; i++) {
        if (mapped.get(i)) {
            // we already got this one
            continue;
        }

        int maxCategory = getCategoryForSsaReg(i);
        IntSet current = new BitIntSet(oldRegCount);

        interference.mergeInterferenceSet(i, current);

        boolean isPreslotted = false;
        int newReg = 0;

        if (PRESLOT_PARAMS && isDefinitionMoveParam(i)) {
            // Any move-param definition must be a NormalSsaInsn
            NormalSsaInsn defInsn = (NormalSsaInsn)
                   ssaMeth.getDefinitionForRegister(i);

            newReg = paramNumberFromMoveParam(defInsn);

            mapper.addMapping(i, newReg, maxCategory);
            isPreslotted = true;
        } else {
            mapper.addMapping(i, nextNewRegister, maxCategory);
            newReg = nextNewRegister;
        }

        for (int j = i + 1; j < oldRegCount; j++) {
            if (mapped.get(j) || isDefinitionMoveParam(j)) {
                continue;
            }

            /*
             * If reg j doesn't interfere with the current mapping.
             * Also, if this is a pre-slotted method parameter, we
             * can't use more than the original param width.
             */
            if (!current.has(j)
                    && !(isPreslotted
                        && (maxCategory < getCategoryForSsaReg(j)))) {

                interference.mergeInterferenceSet(j, current);

                maxCategory = Math.max(maxCategory,
                        getCategoryForSsaReg(j));

                mapper.addMapping(j, newReg, maxCategory);
                mapped.set(j);
            }
        }

        mapped.set(i);
        if (!isPreslotted) {
            nextNewRegister += maxCategory;
        }
    }

    return mapper;
}
 
Example #29
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 #30
Source File: FirstFitAllocator.java    From Box with Apache License 2.0 4 votes vote down vote up
/** {@inheritDoc} */
@Override
public RegisterMapper allocateRegisters() {
    int oldRegCount = ssaMeth.getRegCount();

    BasicRegisterMapper mapper
            = new BasicRegisterMapper(oldRegCount);

    int nextNewRegister = 0;

    if (PRESLOT_PARAMS) {
        /*
         * Reserve space for the params at the bottom of the register
         * space. Later, we'll flip the params to the end of the register
         * space.
         */

        nextNewRegister = ssaMeth.getParamWidth();
    }

    for (int i = 0; i < oldRegCount; i++) {
        if (mapped.get(i)) {
            // we already got this one
            continue;
        }

        int maxCategory = getCategoryForSsaReg(i);
        IntSet current = new BitIntSet(oldRegCount);

        interference.mergeInterferenceSet(i, current);

        boolean isPreslotted = false;
        int newReg = 0;

        if (PRESLOT_PARAMS && isDefinitionMoveParam(i)) {
            // Any move-param definition must be a NormalSsaInsn
            NormalSsaInsn defInsn = (NormalSsaInsn)
                   ssaMeth.getDefinitionForRegister(i);

            newReg = paramNumberFromMoveParam(defInsn);

            mapper.addMapping(i, newReg, maxCategory);
            isPreslotted = true;
        } else {
            mapper.addMapping(i, nextNewRegister, maxCategory);
            newReg = nextNewRegister;
        }

        for (int j = i + 1; j < oldRegCount; j++) {
            if (mapped.get(j) || isDefinitionMoveParam(j)) {
                continue;
            }

            /*
             * If reg j doesn't interfere with the current mapping.
             * Also, if this is a pre-slotted method parameter, we
             * can't use more than the original param width.
             */
            if (!current.has(j)
                    && !(isPreslotted
                        && (maxCategory < getCategoryForSsaReg(j)))) {

                interference.mergeInterferenceSet(j, current);

                maxCategory = Math.max(maxCategory,
                        getCategoryForSsaReg(j));

                mapper.addMapping(j, newReg, maxCategory);
                mapped.set(j);
            }
        }

        mapped.set(i);
        if (!isPreslotted) {
            nextNewRegister += maxCategory;
        }
    }

    return mapper;
}