public void addMoveToEnd(RegisterSpec result, RegisterSpec source) {
    /*
     * Check that there are no other successors otherwise we may
     * insert a move that affects those (b/69128828).
     */
    if (successors.cardinality() > 1) {
      throw new IllegalStateException("Inserting a move to a block with multiple successors");
    }

    if (result.getReg() == source.getReg()) {
      // Sometimes we end up with no-op moves. Ignore them here.
      return;
    }

    /*
     * The last Insn has to be a normal SSA insn: a phi can't branch
     * or return or cause an exception, etc.
     */
    NormalSsaInsn lastInsn;
    lastInsn = (NormalSsaInsn) insns.get(insns.size() - 1);

    if (lastInsn.getResult() != null || lastInsn.getSources().size() > 0) {
      /*
       * The final insn in this block has a source or result
       * register, and the moves we may need to place and
       * schedule may interfere. We need to insert this
       * instruction at the beginning of the primary successor
       * block instead. We know this is safe, because when we
       * edge-split earlier, we ensured that each successor has
       * only us as a predecessor.
       */

      for (int i = successors.nextSetBit(0); i >= 0; i = successors.nextSetBit(i + 1)) {

        SsaBasicBlock succ;

        succ = parent.getBlocks().get(i);
        succ.addMoveToBeginning(result, source);
      }
    } else {
      /*
       * We can safely add a move to the end of the block just
       * before the last instruction, because the final insn does
       * not assign to anything.
       */
      RegisterSpecList sources = RegisterSpecList.make(source);
      NormalSsaInsn toAdd =
          new NormalSsaInsn(
              new PlainInsn(Rops.opMove(result.getType()), SourcePosition.NO_INFO, result, sources),
              this);

      insns.add(insns.size() - 1, toAdd);

      movesFromPhisAtEnd++;
    }
  }
Adds a move instruction to the end of this basic block, just before the last instruction. If
the result of the final instruction is the source in question, then the move is placed at the
beginning of the primary successor block. This is for unversioned registers.

@param result move destination
@param source move source
android/android_framework/dex-maker/src/main/java/com/android/dx/ssa/SsaBasicBlock.java