Search in sources :

Example 1 with IntIterator

use of com.android.dx.util.IntIterator in project buck by facebook.

the class RegisterAllocator method insertMoveBefore.

/**
     * 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;
}
Also used : PlainInsn(com.android.dx.rop.code.PlainInsn) IntIterator(com.android.dx.util.IntIterator) IntSet(com.android.dx.util.IntSet) SsaBasicBlock(com.android.dx.ssa.SsaBasicBlock) NormalSsaInsn(com.android.dx.ssa.NormalSsaInsn) SsaInsn(com.android.dx.ssa.SsaInsn) RegisterSpecList(com.android.dx.rop.code.RegisterSpecList) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 2 with IntIterator

use of com.android.dx.util.IntIterator in project buck by facebook.

the class SsaConverter method placePhiFunctions.

/**
     * See Appel algorithm 19.6:
     *
     * Place Phi functions in appropriate locations.
     *
     * @param ssaMeth {@code non-null;} method to process.
     * Modifications are made in-place.
     * @param localInfo {@code non-null;} local variable info, used
     * when placing phis
     * @param threshold registers below this number are ignored
     */
private static void placePhiFunctions(SsaMethod ssaMeth, LocalVariableInfo localInfo, int threshold) {
    ArrayList<SsaBasicBlock> ssaBlocks;
    int regCount;
    int blockCount;
    ssaBlocks = ssaMeth.getBlocks();
    blockCount = ssaBlocks.size();
    regCount = ssaMeth.getRegCount() - threshold;
    DomFront df = new DomFront(ssaMeth);
    DomFront.DomInfo[] domInfos = df.run();
    // Bit set of registers vs block index "definition sites"
    BitSet[] defsites = new BitSet[regCount];
    // Bit set of registers vs block index "phi placement sites"
    BitSet[] phisites = new BitSet[regCount];
    for (int i = 0; i < regCount; i++) {
        defsites[i] = new BitSet(blockCount);
        phisites[i] = new BitSet(blockCount);
    }
    /*
         * For each register, build a set of all basic blocks where
         * containing an assignment to that register.
         */
    for (int bi = 0, s = ssaBlocks.size(); bi < s; bi++) {
        SsaBasicBlock b = ssaBlocks.get(bi);
        for (SsaInsn insn : b.getInsns()) {
            RegisterSpec rs = insn.getResult();
            if (rs != null && rs.getReg() - threshold >= 0) {
                defsites[rs.getReg() - threshold].set(bi);
            }
        }
    }
    if (DEBUG) {
        System.out.println("defsites");
        for (int i = 0; i < regCount; i++) {
            StringBuilder sb = new StringBuilder();
            sb.append('v').append(i).append(": ");
            sb.append(defsites[i].toString());
            System.out.println(sb);
        }
    }
    BitSet worklist;
    /*
         * For each register, compute all locations for phi placement
         * based on dominance-frontier algorithm.
         */
    for (int reg = 0, s = regCount; reg < s; reg++) {
        int workBlockIndex;
        /* Worklist set starts out with each node where reg is assigned. */
        worklist = (BitSet) (defsites[reg].clone());
        while (0 <= (workBlockIndex = worklist.nextSetBit(0))) {
            worklist.clear(workBlockIndex);
            IntIterator dfIterator = domInfos[workBlockIndex].dominanceFrontiers.iterator();
            while (dfIterator.hasNext()) {
                int dfBlockIndex = dfIterator.next();
                if (!phisites[reg].get(dfBlockIndex)) {
                    phisites[reg].set(dfBlockIndex);
                    int tReg = reg + threshold;
                    RegisterSpec rs = localInfo.getStarts(dfBlockIndex).get(tReg);
                    if (rs == null) {
                        ssaBlocks.get(dfBlockIndex).addPhiInsnForReg(tReg);
                    } else {
                        ssaBlocks.get(dfBlockIndex).addPhiInsnForReg(rs);
                    }
                    if (!defsites[reg].get(dfBlockIndex)) {
                        worklist.set(dfBlockIndex);
                    }
                }
            }
        }
    }
    if (DEBUG) {
        System.out.println("phisites");
        for (int i = 0; i < regCount; i++) {
            StringBuilder sb = new StringBuilder();
            sb.append('v').append(i).append(": ");
            sb.append(phisites[i].toString());
            System.out.println(sb);
        }
    }
}
Also used : IntIterator(com.android.dx.util.IntIterator) BitSet(java.util.BitSet) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 3 with IntIterator

use of com.android.dx.util.IntIterator in project buck by facebook.

the class FirstFitLocalCombiningAllocator method ssaSetToSpecs.

/**
     * 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;
}
Also used : IntIterator(com.android.dx.util.IntIterator) RegisterSpecList(com.android.dx.rop.code.RegisterSpecList)

Aggregations

IntIterator (com.android.dx.util.IntIterator)3 RegisterSpec (com.android.dx.rop.code.RegisterSpec)2 RegisterSpecList (com.android.dx.rop.code.RegisterSpecList)2 PlainInsn (com.android.dx.rop.code.PlainInsn)1 NormalSsaInsn (com.android.dx.ssa.NormalSsaInsn)1 SsaBasicBlock (com.android.dx.ssa.SsaBasicBlock)1 SsaInsn (com.android.dx.ssa.SsaInsn)1 IntSet (com.android.dx.util.IntSet)1 BitSet (java.util.BitSet)1