private void scheduleUseBeforeAssigned(List<SsaInsn> toSchedule) {
    BitSet regsUsedAsSources = new BitSet(parent.getRegCount());

    // TODO: Get rid of this.
    BitSet regsUsedAsResults = new BitSet(parent.getRegCount());

    int sz = toSchedule.size();

    int insertPlace = 0;

    while (insertPlace < sz) {
      int oldInsertPlace = insertPlace;

      // Record all registers used as sources in this block.
      for (int i = insertPlace; i < sz; i++) {
        setRegsUsed(regsUsedAsSources, toSchedule.get(i).getSources().get(0));

        setRegsUsed(regsUsedAsResults, toSchedule.get(i).getResult());
      }

      /*
       * If there are no circular dependencies, then there exists
       * n instructions where n > 1 whose result is not used as a source.
       */
      for (int i = insertPlace; i < sz; i++) {
        SsaInsn insn = toSchedule.get(i);

        /*
         * Move these n registers to the front, since they overwrite
         * nothing.
         */
        if (!checkRegUsed(regsUsedAsSources, insn.getResult())) {
          Collections.swap(toSchedule, i, insertPlace++);
        }
      }

      /*
       * If we've made no progress in this iteration, there's a
       * circular dependency. Split it using the temp reg.
       */
      if (oldInsertPlace == insertPlace) {

        SsaInsn insnToSplit = null;

        // Find an insn whose result is used as a source.
        for (int i = insertPlace; i < sz; i++) {
          SsaInsn insn = toSchedule.get(i);
          if (checkRegUsed(regsUsedAsSources, insn.getResult())
              && checkRegUsed(regsUsedAsResults, insn.getSources().get(0))) {

            insnToSplit = insn;
            /*
             * We're going to split this insn; move it to the
             * front.
             */
            Collections.swap(toSchedule, insertPlace, i);
            break;
          }
        }

        // At least one insn will be set above.

        RegisterSpec result = insnToSplit.getResult();
        RegisterSpec tempSpec = result.withReg(parent.borrowSpareRegister(result.getCategory()));

        NormalSsaInsn toAdd =
            new NormalSsaInsn(
                new PlainInsn(
                    Rops.opMove(result.getType()),
                    SourcePosition.NO_INFO,
                    tempSpec,
                    insnToSplit.getSources()),
                this);

        toSchedule.add(insertPlace++, toAdd);

        RegisterSpecList newSources = RegisterSpecList.make(tempSpec);

        NormalSsaInsn toReplace =
            new NormalSsaInsn(
                new PlainInsn(
                    Rops.opMove(result.getType()), SourcePosition.NO_INFO, result, newSources),
                this);

        toSchedule.set(insertPlace, toReplace);

        // The size changed.
        sz = toSchedule.size();
      }

      regsUsedAsSources.clear();
      regsUsedAsResults.clear();
    }
  }
Ensures that all move operations in this block occur such that reads of any register happen
before writes to that register. NOTE: caller is expected to returnSpareRegisters()!

<p>TODO: See Briggs, et al "Practical Improvements to the Construction and Destruction of
Static Single Assignment Form" section 5. a) This can be done in three passes.

@param toSchedule List of instructions. Must consist only of moves.
android/android_framework/dex-maker/src/main/java/com/android/dx/ssa/SsaBasicBlock.java