Search in sources :

Example 41 with RegisterSpec

use of com.taobao.android.dx.rop.code.RegisterSpec in project atlas by alibaba.

the class SCCP method replaceConstants.

/**
     * 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);
        }
    }
}
Also used : TypedConstant(com.taobao.android.dx.rop.cst.TypedConstant) TypeBearer(com.taobao.android.dx.rop.type.TypeBearer) RegisterSpecList(com.taobao.android.dx.rop.code.RegisterSpecList) RegisterSpec(com.taobao.android.dx.rop.code.RegisterSpec)

Example 42 with RegisterSpec

use of com.taobao.android.dx.rop.code.RegisterSpec in project atlas by alibaba.

the class SsaBasicBlock method scheduleMovesFromPhis.

/**
     * Sorts move instructions added via {@code addMoveToEnd} during
     * phi removal so that results don't overwrite sources that are used.
     * For use after all phis have been removed and all calls to
     * addMoveToEnd() have been made.<p>
     *
     * This is necessary because copy-propogation may have left us in a state
     * where the same basic block has the same register as a phi operand
     * and a result. In this case, the register in the phi operand always
     * refers value before any other phis have executed.
     */
public void scheduleMovesFromPhis() {
    if (movesFromPhisAtBeginning > 1) {
        List<SsaInsn> toSchedule;
        toSchedule = insns.subList(0, movesFromPhisAtBeginning);
        scheduleUseBeforeAssigned(toSchedule);
        SsaInsn firstNonPhiMoveInsn = insns.get(movesFromPhisAtBeginning);
        /*
             * TODO: It's actually possible that this case never happens,
             * because a move-exception block, having only one predecessor
             * in SSA form, perhaps is never on a dominance frontier.
             */
        if (firstNonPhiMoveInsn.isMoveException()) {
            if (true) {
                /*
                     * We've yet to observe this case, and if it can
                     * occur the code written to handle it probably
                     * does not work.
                     */
                throw new RuntimeException("Unexpected: moves from " + "phis before move-exception");
            } else {
                /*
                     * A move-exception insn must be placed first in this block
                     * We need to move it there, and deal with possible
                     * interference.
                     */
                boolean moveExceptionInterferes = false;
                int moveExceptionResult = firstNonPhiMoveInsn.getResult().getReg();
                /*
                     * Does the move-exception result reg interfere with the
                     * phi moves?
                     */
                for (SsaInsn insn : toSchedule) {
                    if (insn.isResultReg(moveExceptionResult) || insn.isRegASource(moveExceptionResult)) {
                        moveExceptionInterferes = true;
                        break;
                    }
                }
                if (!moveExceptionInterferes) {
                    // This is the easy case.
                    insns.remove(movesFromPhisAtBeginning);
                    insns.add(0, firstNonPhiMoveInsn);
                } else {
                    /*
                         * We need to move the result to a spare reg
                         * and move it back.
                         */
                    RegisterSpec originalResultSpec = firstNonPhiMoveInsn.getResult();
                    int spareRegister = parent.borrowSpareRegister(originalResultSpec.getCategory());
                    // We now move it to a spare register.
                    firstNonPhiMoveInsn.changeResultReg(spareRegister);
                    RegisterSpec tempSpec = firstNonPhiMoveInsn.getResult();
                    insns.add(0, firstNonPhiMoveInsn);
                    // And here we move it back.
                    NormalSsaInsn toAdd = new NormalSsaInsn(new PlainInsn(Rops.opMove(tempSpec.getType()), SourcePosition.NO_INFO, originalResultSpec, RegisterSpecList.make(tempSpec)), this);
                    /*
                         * Place it immediately after the phi-moves,
                         * overwriting the move-exception that was there.
                         */
                    insns.set(movesFromPhisAtBeginning + 1, toAdd);
                }
            }
        }
    }
    if (movesFromPhisAtEnd > 1) {
        scheduleUseBeforeAssigned(insns.subList(insns.size() - movesFromPhisAtEnd - 1, insns.size() - 1));
    }
    // Return registers borrowed here and in scheduleUseBeforeAssigned().
    parent.returnSpareRegisters();
}
Also used : PlainInsn(com.taobao.android.dx.rop.code.PlainInsn) RegisterSpec(com.taobao.android.dx.rop.code.RegisterSpec)

Example 43 with RegisterSpec

use of com.taobao.android.dx.rop.code.RegisterSpec in project atlas by alibaba.

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.taobao.android.dx.util.IntIterator) BitSet(java.util.BitSet) RegisterSpec(com.taobao.android.dx.rop.code.RegisterSpec)

Example 44 with RegisterSpec

use of com.taobao.android.dx.rop.code.RegisterSpec in project atlas by alibaba.

the class SsaInsn method mapRegisters.

/**
     * Map registers after register allocation.
     *
     * @param mapper {@code non-null;} mapping from old to new registers
     */
public final void mapRegisters(RegisterMapper mapper) {
    RegisterSpec oldResult = result;
    result = mapper.map(result);
    block.getParent().updateOneDefinition(this, oldResult);
    mapSourceRegisters(mapper);
}
Also used : RegisterSpec(com.taobao.android.dx.rop.code.RegisterSpec)

Example 45 with RegisterSpec

use of com.taobao.android.dx.rop.code.RegisterSpec in project atlas by alibaba.

the class LivenessAnalyzer method liveOutAtStatement.

/**
     * "v is live-out at s."
     */
private void liveOutAtStatement() {
    SsaInsn statement = blockN.getInsns().get(statementIndex);
    RegisterSpec rs = statement.getResult();
    if (!statement.isResultReg(regV)) {
        if (rs != null) {
            interference.add(regV, rs.getReg());
        }
        nextFunction = NextFunction.LIVE_IN_AT_STATEMENT;
    }
}
Also used : SsaInsn(com.taobao.android.dx.ssa.SsaInsn) RegisterSpec(com.taobao.android.dx.rop.code.RegisterSpec)

Aggregations

RegisterSpec (com.taobao.android.dx.rop.code.RegisterSpec)66 RegisterSpecList (com.taobao.android.dx.rop.code.RegisterSpecList)24 PlainInsn (com.taobao.android.dx.rop.code.PlainInsn)12 Constant (com.taobao.android.dx.rop.cst.Constant)10 TypedConstant (com.taobao.android.dx.rop.cst.TypedConstant)8 ArrayList (java.util.ArrayList)8 Insn (com.taobao.android.dx.rop.code.Insn)7 PlainCstInsn (com.taobao.android.dx.rop.code.PlainCstInsn)7 Rop (com.taobao.android.dx.rop.code.Rop)7 ThrowingCstInsn (com.taobao.android.dx.rop.code.ThrowingCstInsn)7 CstType (com.taobao.android.dx.rop.cst.CstType)7 TypeBearer (com.taobao.android.dx.rop.type.TypeBearer)7 LocalItem (com.taobao.android.dx.rop.code.LocalItem)5 RegisterSpecSet (com.taobao.android.dx.rop.code.RegisterSpecSet)5 ThrowingInsn (com.taobao.android.dx.rop.code.ThrowingInsn)5 CstString (com.taobao.android.dx.rop.cst.CstString)5 BitSet (java.util.BitSet)5 HashSet (java.util.HashSet)5 SourcePosition (com.taobao.android.dx.rop.code.SourcePosition)4 CstFieldRef (com.taobao.android.dx.rop.cst.CstFieldRef)4