Search in sources :

Example 36 with RegisterSpecList

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

the class SsaMethod method buildUseList.

/**
     * Builds useList and unmodifiableUseList.
     */
private void buildUseList() {
    if (backMode) {
        throw new RuntimeException("No use list in back mode");
    }
    useList = new ArrayList[registerCount];
    for (int i = 0; i < registerCount; i++) {
        useList[i] = new ArrayList();
    }
    forEachInsn(new SsaInsn.Visitor() {

        /** {@inheritDoc} */
        public void visitMoveInsn(NormalSsaInsn insn) {
            addToUses(insn);
        }

        /** {@inheritDoc} */
        public void visitPhiInsn(PhiInsn phi) {
            addToUses(phi);
        }

        /** {@inheritDoc} */
        public void visitNonMoveInsn(NormalSsaInsn insn) {
            addToUses(insn);
        }

        /**
             * Adds specified insn to the uses list for all of its sources.
             * @param insn {@code non-null;} insn to process
             */
        private void addToUses(SsaInsn insn) {
            RegisterSpecList rl = insn.getSources();
            int sz = rl.size();
            for (int i = 0; i < sz; i++) {
                useList[rl.get(i).getReg()].add(insn);
            }
        }
    });
    unmodifiableUseList = new List[registerCount];
    for (int i = 0; i < registerCount; i++) {
        unmodifiableUseList[i] = Collections.unmodifiableList(useList[i]);
    }
}
Also used : ArrayList(java.util.ArrayList) RegisterSpecList(com.taobao.android.dx.rop.code.RegisterSpecList)

Example 37 with RegisterSpecList

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

the class FirstFitLocalCombiningAllocator method findRangeAndAdjust.

/**
     * Find a contiguous rop register range that fits the specified
     * instruction's sources. First, try to center the range around
     * sources that have already been mapped to rop registers. If that fails,
     * just find a new contiguous range that doesn't interfere.
     *
     * @param insn {@code non-null;} the insn whose sources need to
     * fit. Must be last insn in basic block.
     * @return {@code >= 0;} rop register of start of range
     */
private int findRangeAndAdjust(NormalSsaInsn insn) {
    RegisterSpecList sources = insn.getSources();
    int szSources = sources.size();
    // the category for each source index
    int[] categoriesForIndex = new int[szSources];
    int rangeLength = 0;
    // Compute rangeLength and categoriesForIndex
    for (int i = 0; i < szSources; i++) {
        int category = sources.get(i).getCategory();
        categoriesForIndex[i] = category;
        rangeLength += categoriesForIndex[i];
    }
    // the highest score of fits tried so far
    int maxScore = Integer.MIN_VALUE;
    // the high scoring range's start
    int resultRangeStart = -1;
    // by source index: set of sources needing moves in high scoring plan
    BitSet resultMovesRequired = null;
    /*
         * First, go through each source that's already been mapped. Try
         * to center the range around the rop register this source is mapped
         * to.
         */
    int rangeStartOffset = 0;
    for (int i = 0; i < szSources; i++) {
        int ssaCenterReg = sources.get(i).getReg();
        if (i != 0) {
            rangeStartOffset -= categoriesForIndex[i - 1];
        }
        if (!ssaRegsMapped.get(ssaCenterReg)) {
            continue;
        }
        int rangeStart = mapper.oldToNew(ssaCenterReg) + rangeStartOffset;
        if (rangeStart < 0 || spansParamRange(rangeStart, rangeLength)) {
            continue;
        }
        BitSet curMovesRequired = new BitSet(szSources);
        int fitWidth = fitPlanForRange(rangeStart, insn, categoriesForIndex, curMovesRequired);
        if (fitWidth < 0) {
            continue;
        }
        int score = fitWidth - curMovesRequired.cardinality();
        if (score > maxScore) {
            maxScore = score;
            resultRangeStart = rangeStart;
            resultMovesRequired = curMovesRequired;
        }
        if (fitWidth == rangeLength) {
            // We can't do any better than this, so stop here
            break;
        }
    }
    if (resultRangeStart == -1) {
        resultMovesRequired = new BitSet(szSources);
        resultRangeStart = findAnyFittingRange(insn, rangeLength, categoriesForIndex, resultMovesRequired);
    }
    for (int i = resultMovesRequired.nextSetBit(0); i >= 0; i = resultMovesRequired.nextSetBit(i + 1)) {
        insn.changeOneSource(i, insertMoveBefore(insn, sources.get(i)));
    }
    return resultRangeStart;
}
Also used : BitSet(java.util.BitSet) RegisterSpecList(com.taobao.android.dx.rop.code.RegisterSpecList)

Example 38 with RegisterSpecList

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

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

Example 39 with RegisterSpecList

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

the class FirstFitLocalCombiningAllocator method fitPlanForRange.

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

Example 40 with RegisterSpecList

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

the class LiteralOpUpgrader method run.

/**
     * Run the literal op upgrader
     */
private void run() {
    final TranslationAdvice advice = optimizer.getAdvice();
    ssaMeth.forEachInsn(new SsaInsn.Visitor() {

        public void visitMoveInsn(NormalSsaInsn insn) {
        // do nothing
        }

        public void visitPhiInsn(PhiInsn insn) {
        // do nothing
        }

        public void visitNonMoveInsn(NormalSsaInsn insn) {
            Insn originalRopInsn = insn.getOriginalRopInsn();
            Rop opcode = originalRopInsn.getOpcode();
            RegisterSpecList sources = insn.getSources();
            // Replace insns with constant results with const insns
            if (tryReplacingWithConstant(insn))
                return;
            if (sources.size() != 2) {
                // We're only dealing with two-source insns here.
                return;
            }
            if (opcode.getBranchingness() == Rop.BRANCH_IF) {
                /*
                     * An if instruction can become an if-*z instruction.
                     */
                if (isConstIntZeroOrKnownNull(sources.get(0))) {
                    replacePlainInsn(insn, sources.withoutFirst(), RegOps.flippedIfOpcode(opcode.getOpcode()), null);
                } else if (isConstIntZeroOrKnownNull(sources.get(1))) {
                    replacePlainInsn(insn, sources.withoutLast(), opcode.getOpcode(), null);
                }
            } else if (advice.hasConstantOperation(opcode, sources.get(0), sources.get(1))) {
                insn.upgradeToLiteral();
            } else if (opcode.isCommutative() && advice.hasConstantOperation(opcode, sources.get(1), sources.get(0))) {
                /*
                     * An instruction can be commuted to a literal operation
                     */
                insn.setNewSources(RegisterSpecList.make(sources.get(1), sources.get(0)));
                insn.upgradeToLiteral();
            }
        }
    });
}
Also used : Insn(com.taobao.android.dx.rop.code.Insn) PlainCstInsn(com.taobao.android.dx.rop.code.PlainCstInsn) PlainInsn(com.taobao.android.dx.rop.code.PlainInsn) Rop(com.taobao.android.dx.rop.code.Rop) TranslationAdvice(com.taobao.android.dx.rop.code.TranslationAdvice) RegisterSpecList(com.taobao.android.dx.rop.code.RegisterSpecList)

Aggregations

RegisterSpecList (com.taobao.android.dx.rop.code.RegisterSpecList)98 RegisterSpec (com.taobao.android.dx.rop.code.RegisterSpec)24 BitSet (java.util.BitSet)22 CstLiteralBits (com.taobao.android.dx.rop.cst.CstLiteralBits)21 CstInsn (com.taobao.android.dx.dex.code.CstInsn)17 Constant (com.taobao.android.dx.rop.cst.Constant)17 PlainInsn (com.taobao.android.dx.rop.code.PlainInsn)9 CstType (com.taobao.android.dx.rop.cst.CstType)6 TargetInsn (com.taobao.android.dx.dex.code.TargetInsn)5 Insn (com.taobao.android.dx.rop.code.Insn)5 TypedConstant (com.taobao.android.dx.rop.cst.TypedConstant)5 PlainCstInsn (com.taobao.android.dx.rop.code.PlainCstInsn)4 Rop (com.taobao.android.dx.rop.code.Rop)4 CstFieldRef (com.taobao.android.dx.rop.cst.CstFieldRef)4 ThrowingCstInsn (com.taobao.android.dx.rop.code.ThrowingCstInsn)3 ThrowingInsn (com.taobao.android.dx.rop.code.ThrowingInsn)3 CstInteger (com.taobao.android.dx.rop.cst.CstInteger)3 CstMethodRef (com.taobao.android.dx.rop.cst.CstMethodRef)3 TypeBearer (com.taobao.android.dx.rop.type.TypeBearer)3 FillArrayDataInsn (com.taobao.android.dx.rop.code.FillArrayDataInsn)2