Search in sources :

Example 1 with NormalSsaInsn

use of com.android.dx.ssa.NormalSsaInsn in project buck by facebook.

the class FirstFitLocalCombiningAllocator method handleCheckCastResults.

/**
     * Handles check cast results to reuse the same source register.
     * Inserts a move if it can't map the same register to both and the
     * check cast is not caught.
     */
private void handleCheckCastResults() {
    for (NormalSsaInsn insn : moveResultPseudoInsns) {
        RegisterSpec moveRegSpec = insn.getResult();
        int moveReg = moveRegSpec.getReg();
        BitSet predBlocks = insn.getBlock().getPredecessors();
        // Expect one predecessor block only
        if (predBlocks.cardinality() != 1) {
            continue;
        }
        SsaBasicBlock predBlock = ssaMeth.getBlocks().get(predBlocks.nextSetBit(0));
        ArrayList<SsaInsn> insnList = predBlock.getInsns();
        /**
             * If the predecessor block has a check-cast, it will be the last
             * instruction
             */
        SsaInsn checkCastInsn = insnList.get(insnList.size() - 1);
        if (checkCastInsn.getOpcode().getOpcode() != RegOps.CHECK_CAST) {
            continue;
        }
        RegisterSpec checkRegSpec = checkCastInsn.getSources().get(0);
        int checkReg = checkRegSpec.getReg();
        /**
             * See if either register is already mapped. Most likely the move
             * result will be mapped already since the cast result is stored
             * in a local variable.
             */
        int category = checkRegSpec.getCategory();
        boolean moveMapped = ssaRegsMapped.get(moveReg);
        boolean checkMapped = ssaRegsMapped.get(checkReg);
        if (moveMapped & !checkMapped) {
            int moveRopReg = mapper.oldToNew(moveReg);
            checkMapped = tryMapReg(checkRegSpec, moveRopReg, category);
        }
        if (checkMapped & !moveMapped) {
            int checkRopReg = mapper.oldToNew(checkReg);
            moveMapped = tryMapReg(moveRegSpec, checkRopReg, category);
        }
        // Map any unmapped registers to anything available
        if (!moveMapped || !checkMapped) {
            int ropReg = findNextUnreservedRopReg(paramRangeEnd, category);
            ArrayList<RegisterSpec> ssaRegs = new ArrayList<RegisterSpec>(2);
            ssaRegs.add(moveRegSpec);
            ssaRegs.add(checkRegSpec);
            while (!tryMapRegs(ssaRegs, ropReg, category, false)) {
                ropReg = findNextUnreservedRopReg(ropReg + 1, category);
            }
        }
        /*
             * If source and result have a different mapping, insert a move so
             * they can have the same mapping. Don't do this if the check cast
             * is caught, since it will overwrite a potentially live value.
             */
        boolean hasExceptionHandlers = checkCastInsn.getOriginalRopInsn().getCatches().size() != 0;
        int moveRopReg = mapper.oldToNew(moveReg);
        int checkRopReg = mapper.oldToNew(checkReg);
        if (moveRopReg != checkRopReg && !hasExceptionHandlers) {
            ((NormalSsaInsn) checkCastInsn).changeOneSource(0, insertMoveBefore(checkCastInsn, checkRegSpec));
            addMapping(checkCastInsn.getSources().get(0), moveRopReg);
        }
    }
}
Also used : NormalSsaInsn(com.android.dx.ssa.NormalSsaInsn) SsaBasicBlock(com.android.dx.ssa.SsaBasicBlock) BitSet(java.util.BitSet) ArrayList(java.util.ArrayList) NormalSsaInsn(com.android.dx.ssa.NormalSsaInsn) SsaInsn(com.android.dx.ssa.SsaInsn) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 2 with NormalSsaInsn

use of com.android.dx.ssa.NormalSsaInsn in project J2ME-Loader by nikita36078.

the class FirstFitLocalCombiningAllocator method handleCheckCastResults.

/**
 * Handles check cast results to reuse the same source register.
 * Inserts a move if it can't map the same register to both and the
 * check cast is not caught.
 */
private void handleCheckCastResults() {
    for (NormalSsaInsn insn : moveResultPseudoInsns) {
        RegisterSpec moveRegSpec = insn.getResult();
        int moveReg = moveRegSpec.getReg();
        BitSet predBlocks = insn.getBlock().getPredecessors();
        // Expect one predecessor block only
        if (predBlocks.cardinality() != 1) {
            continue;
        }
        SsaBasicBlock predBlock = ssaMeth.getBlocks().get(predBlocks.nextSetBit(0));
        ArrayList<SsaInsn> insnList = predBlock.getInsns();
        /**
         * If the predecessor block has a check-cast, it will be the last
         * instruction
         */
        SsaInsn checkCastInsn = insnList.get(insnList.size() - 1);
        if (checkCastInsn.getOpcode().getOpcode() != RegOps.CHECK_CAST) {
            continue;
        }
        RegisterSpec checkRegSpec = checkCastInsn.getSources().get(0);
        int checkReg = checkRegSpec.getReg();
        /**
         * See if either register is already mapped. Most likely the move
         * result will be mapped already since the cast result is stored
         * in a local variable.
         */
        int category = checkRegSpec.getCategory();
        boolean moveMapped = ssaRegsMapped.get(moveReg);
        boolean checkMapped = ssaRegsMapped.get(checkReg);
        if (moveMapped & !checkMapped) {
            int moveRopReg = mapper.oldToNew(moveReg);
            checkMapped = tryMapReg(checkRegSpec, moveRopReg, category);
        }
        if (checkMapped & !moveMapped) {
            int checkRopReg = mapper.oldToNew(checkReg);
            moveMapped = tryMapReg(moveRegSpec, checkRopReg, category);
        }
        // Map any unmapped registers to anything available
        if (!moveMapped || !checkMapped) {
            int ropReg = findNextUnreservedRopReg(paramRangeEnd, category);
            ArrayList<RegisterSpec> ssaRegs = new ArrayList<RegisterSpec>(2);
            ssaRegs.add(moveRegSpec);
            ssaRegs.add(checkRegSpec);
            while (!tryMapRegs(ssaRegs, ropReg, category, false)) {
                ropReg = findNextUnreservedRopReg(ropReg + 1, category);
            }
        }
        /*
             * If source and result have a different mapping, insert a move so
             * they can have the same mapping. Don't do this if the check cast
             * is caught, since it will overwrite a potentially live value.
             */
        boolean hasExceptionHandlers = checkCastInsn.getOriginalRopInsn().getCatches().size() != 0;
        int moveRopReg = mapper.oldToNew(moveReg);
        int checkRopReg = mapper.oldToNew(checkReg);
        if (moveRopReg != checkRopReg && !hasExceptionHandlers) {
            ((NormalSsaInsn) checkCastInsn).changeOneSource(0, insertMoveBefore(checkCastInsn, checkRegSpec));
            addMapping(checkCastInsn.getSources().get(0), moveRopReg);
        }
    }
}
Also used : NormalSsaInsn(com.android.dx.ssa.NormalSsaInsn) SsaBasicBlock(com.android.dx.ssa.SsaBasicBlock) BitSet(java.util.BitSet) ArrayList(java.util.ArrayList) NormalSsaInsn(com.android.dx.ssa.NormalSsaInsn) SsaInsn(com.android.dx.ssa.SsaInsn) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 3 with NormalSsaInsn

use of com.android.dx.ssa.NormalSsaInsn in project buck by facebook.

the class FirstFitAllocator method allocateRegisters.

/** {@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;
}
Also used : NormalSsaInsn(com.android.dx.ssa.NormalSsaInsn) BasicRegisterMapper(com.android.dx.ssa.BasicRegisterMapper) IntSet(com.android.dx.util.IntSet) BitIntSet(com.android.dx.util.BitIntSet) BitIntSet(com.android.dx.util.BitIntSet)

Example 4 with NormalSsaInsn

use of com.android.dx.ssa.NormalSsaInsn in project J2ME-Loader by nikita36078.

the class FirstFitAllocator method allocateRegisters.

/**
 * {@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;
}
Also used : NormalSsaInsn(com.android.dx.ssa.NormalSsaInsn) BasicRegisterMapper(com.android.dx.ssa.BasicRegisterMapper) IntSet(com.android.dx.util.IntSet) BitIntSet(com.android.dx.util.BitIntSet) BitIntSet(com.android.dx.util.BitIntSet)

Aggregations

NormalSsaInsn (com.android.dx.ssa.NormalSsaInsn)4 RegisterSpec (com.android.dx.rop.code.RegisterSpec)2 BasicRegisterMapper (com.android.dx.ssa.BasicRegisterMapper)2 SsaBasicBlock (com.android.dx.ssa.SsaBasicBlock)2 SsaInsn (com.android.dx.ssa.SsaInsn)2 BitIntSet (com.android.dx.util.BitIntSet)2 IntSet (com.android.dx.util.IntSet)2 ArrayList (java.util.ArrayList)2 BitSet (java.util.BitSet)2