Merge "Avoid duplicate debug positions for exception targets."
diff --git a/src/main/java/com/android/tools/r8/ir/code/DebugPosition.java b/src/main/java/com/android/tools/r8/ir/code/DebugPosition.java
index 9a8f8a5..d6063f3 100644
--- a/src/main/java/com/android/tools/r8/ir/code/DebugPosition.java
+++ b/src/main/java/com/android/tools/r8/ir/code/DebugPosition.java
@@ -50,6 +50,15 @@
   }
 
   @Override
+  public boolean equals(Object other) {
+    if (other instanceof DebugPosition) {
+      DebugPosition o = (DebugPosition) other;
+      return line == o.line && file == o.file;
+    }
+    return false;
+  }
+
+  @Override
   public int maxInValueRegister() {
     throw new Unreachable();
   }
diff --git a/src/main/java/com/android/tools/r8/ir/code/Instruction.java b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
index 466a455..eb8c972 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Instruction.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
@@ -86,6 +86,7 @@
     instruction.inValues.forEach(Value::clearUsersInfo);
     if (instruction.debugValues != null) {
       instruction.debugValues.forEach(Value::clearUsersInfo);
+      instruction.debugValues = null;
     }
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/DexBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/DexBuilder.java
index 18bbe0e..cbd8941 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/DexBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/DexBuilder.java
@@ -150,6 +150,11 @@
 
       // Populate the builder info objects.
       numberOfInstructions = 0;
+
+      // Remove redundant debug position instructions. They would otherwise materialize as
+      // unnecessary nops.
+      removeRedundantDebugPositions();
+
       ListIterator<BasicBlock> iterator = ir.listIterator();
       assert iterator.hasNext();
       BasicBlock block = iterator.next();
@@ -237,6 +242,26 @@
     return code;
   }
 
+  private void removeRedundantDebugPositions() {
+    ListIterator<BasicBlock> iterator = ir.listIterator();
+    DebugPosition lastMoveExceptionPosition = null;
+    while (iterator.hasNext()) {
+      BasicBlock next = iterator.next();
+      InstructionListIterator it = next.listIterator();
+      while (it.hasNext()) {
+        com.android.tools.r8.ir.code.Instruction instruction = it.next();
+        if (instruction.isDebugPosition()) {
+          if (instruction.asDebugPosition().equals(lastMoveExceptionPosition)) {
+            it.remove();
+          }
+          lastMoveExceptionPosition = null;
+        } else if (instruction.isMoveException()) {
+          lastMoveExceptionPosition = instruction.asMoveException().getPosition();
+        }
+      }
+    }
+  }
+
   // Rewrite ifs with offsets that are too large for the if encoding. The rewriting transforms:
   //
   //
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
index 245a75a..8670b31 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
@@ -5,7 +5,6 @@
 package com.android.tools.r8.ir.conversion;
 
 import com.android.tools.r8.ApiLevelException;
-import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.errors.CompilationError;
 import com.android.tools.r8.errors.InternalCompilerError;
 import com.android.tools.r8.errors.InvalidDebugInfoException;