@Override
    public void visitMoveInsn(NormalSsaInsn insn) {
      /*
       * For moves: copy propogate the move if we can, but don't
       * if we need to preserve local variable info and the
       * result has a different name than the source.
       */

      RegisterSpec ropResult = insn.getResult();
      int ropResultReg = ropResult.getReg();
      int ropSourceReg = insn.getSources().get(0).getReg();

      insn.mapSourceRegisters(mapper);
      int ssaSourceReg = insn.getSources().get(0).getReg();

      LocalItem sourceLocal = currentMapping[ropSourceReg].getLocalItem();
      LocalItem resultLocal = ropResult.getLocalItem();

      /*
       * A move from a register that's currently associated with a local
       * to one that will not be associated with a local does not need
       * to be preserved, but the local association should remain.
       * Hence, we inherit the sourceLocal where the resultLocal is null.
       */

      LocalItem newLocal = (resultLocal == null) ? sourceLocal : resultLocal;
      LocalItem associatedLocal = getLocalForNewReg(ssaSourceReg);

      /*
       * If we take the new local, will only one local have ever
       * been associated with this SSA reg?
       */
      boolean onlyOneAssociatedLocal =
          associatedLocal == null || newLocal == null || newLocal.equals(associatedLocal);

      /*
       * If we're going to copy-propogate, then the ssa register
       * spec that's going to go into the mapping is made up of
       * the source register number mapped from above, the type
       * of the result, and the name either from the result (if
       * specified) or inherited from the existing mapping.
       *
       * The move source has incomplete type information in null
       * object cases, so the result type is used.
       */
      RegisterSpec ssaReg =
          RegisterSpec.makeLocalOptional(ssaSourceReg, ropResult.getType(), newLocal);

      if (!Optimizer.getPreserveLocals()
          || (onlyOneAssociatedLocal && equalsHandlesNulls(newLocal, sourceLocal))
              && threshold == 0) {
        /*
         * We don't have to keep this move to preserve local
         * information. Either the name is the same, or the result
         * register spec is unnamed.
         */

        addMapping(ropResultReg, ssaReg);
      } else if (onlyOneAssociatedLocal && sourceLocal == null && threshold == 0) {
        /*
         * The register was previously unnamed. This means that a
         * local starts after it's first assignment in SSA form
         */

        RegisterSpecList ssaSources =
            RegisterSpecList.make(RegisterSpec.make(ssaReg.getReg(), ssaReg.getType(), newLocal));

        SsaInsn newInsn =
            SsaInsn.makeFromRop(
                new PlainInsn(Rops.opMarkLocal(ssaReg), SourcePosition.NO_INFO, null, ssaSources),
                block);

        insnsToReplace.put(insn, newInsn);

        // Just map as above.
        addMapping(ropResultReg, ssaReg);
      } else {
        /*
         * Do not copy-propogate, since the two registers have
         * two different local-variable names.
         */
        processResultReg(insn);

        movesToKeep.add(insn);
      }
    }
{@inheritDoc}

<p>Move insns are treated as a simple mapping operation, and will later be removed unless
they represent a local variable assignment. If they represent a local variable assignement,
they are preserved.
android/android_framework/dex-maker/src/main/java/com/android/dx/ssa/SsaRenamer.java