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;
  }
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"
android/android_framework/dex-maker/src/main/java/com/android/dx/ssa/back/FirstFitLocalCombiningAllocator.java