Never run removeRedundantDebugPositions in release mode

The mayHaveDebugPosition() check may conservatively return true even if the given piece of code does not have any debug positions. This typically only happens if we use IRMetadata.unknown() for handcrafted LIR code.

When removeRedundantDebugPositions() is run in release mode it may fail due to non-throwing instructions not having any positions.

Change-Id: I9cccdf3a0da117e59f009d8b55c20508898415af
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
index c03f772..813132c 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
@@ -212,7 +212,7 @@
 
     trivialGotosCollapser.run(code, timing);
     timing.begin("Remove redundant debug positions");
-    DexBuilder.removeRedundantDebugPositions(code);
+    DexBuilder.removeRedundantDebugPositions(appView, code);
     timing.end();
     timing.begin("Build CF Code");
     CfCode code = buildCfCode();
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 3c9c7f3..8c6c16a 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
@@ -220,7 +220,7 @@
 
       // Remove redundant debug position instructions. They would otherwise materialize as
       // unnecessary nops.
-      removeRedundantDebugPositions(ir);
+      removeRedundantDebugPositions(appView, ir);
 
       // Reset the state of the builder to start from scratch.
       reset();
@@ -440,8 +440,9 @@
   //
   // After this pass all remaining debug positions mark places where we must ensure a materializing
   // instruction, eg, for two successive lines without intermediate instructions.
-  public static void removeRedundantDebugPositions(IRCode code) {
-    if (!code.metadata().mayHaveDebugPosition()) {
+  public static void removeRedundantDebugPositions(AppView<?> appView, IRCode code) {
+    if (appView.options().shouldCompileMethodInReleaseMode(appView, code.context())
+        || !code.metadata().mayHaveDebugPosition()) {
       return;
     }
 
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index f116aef..222ab99 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -924,6 +924,14 @@
 
   public boolean debug = false;
 
+  public boolean shouldCompileMethodInDebugMode(AppView<?> appView, ProgramMethod method) {
+    return debug || method.getOrComputeReachabilitySensitive(appView);
+  }
+
+  public boolean shouldCompileMethodInReleaseMode(AppView<?> appView, ProgramMethod method) {
+    return !shouldCompileMethodInDebugMode(appView, method);
+  }
+
   private final AccessModifierOptions accessModifierOptions = new AccessModifierOptions(this);
   private final RewriteArrayOptions rewriteArrayOptions = new RewriteArrayOptions();
   private final CallSiteOptimizationOptions callSiteOptimizationOptions =