Merge "Make Instruction.buildCf()+buildDex() abstract"
diff --git a/src/main/java/com/android/tools/r8/ir/code/DebugLocalRead.java b/src/main/java/com/android/tools/r8/ir/code/DebugLocalRead.java
index d8e78e5..747f912 100644
--- a/src/main/java/com/android/tools/r8/ir/code/DebugLocalRead.java
+++ b/src/main/java/com/android/tools/r8/ir/code/DebugLocalRead.java
@@ -6,12 +6,14 @@
 import com.android.tools.r8.cf.LoadStoreHelper;
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.ir.conversion.CfBuilder;
 import com.android.tools.r8.ir.conversion.DexBuilder;
 import com.android.tools.r8.ir.optimize.Inliner.Constraint;
 import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
 import com.android.tools.r8.utils.InternalOptions;
 
 public class DebugLocalRead extends Instruction {
+  private static final String ERROR_MESSAGE = "Unexpected attempt to emit debug-local read.";
 
   public DebugLocalRead() {
     super(null);
@@ -29,7 +31,12 @@
 
   @Override
   public void buildDex(DexBuilder builder) {
-    throw new Unreachable("Unexpected attempt to emit debug-local read.");
+    throw new Unreachable(ERROR_MESSAGE);
+  }
+
+  @Override
+  public void buildCf(CfBuilder builder) {
+    throw new Unreachable(ERROR_MESSAGE);
   }
 
   @Override
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 c47dc54..68253c6 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
@@ -138,13 +138,9 @@
     return outValue.outType();
   }
 
-  public void buildDex(DexBuilder builder) {
-    throw new Unreachable("Unexpected instruction when converting to DEX: " + getInstructionName());
-  }
+  public abstract void buildDex(DexBuilder builder);
 
-  public void buildCf(CfBuilder builder) {
-    throw new Unimplemented("No support for building CF instructions for: " + getInstructionName());
-  }
+  public abstract void buildCf(CfBuilder builder);
 
   public void replaceValue(Value oldValue, Value newValue) {
     for (int i = 0; i < inValues.size(); i++) {
@@ -1021,12 +1017,11 @@
   public abstract Constraint inliningConstraint(AppInfoWithLiveness info,
       DexType invocationContext);
 
-  public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
-    throw new Unimplemented("Implement load/store insertion for: " + getInstructionName());
-  }
+  public abstract void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper);
 
   public DexType computeVerificationType(TypeVerificationHelper helper) {
-    throw new Unimplemented("Implement verification type computation for: " + getInstructionName());
+    assert outValue == null || !outValue.type.isObject();
+    throw new Unreachable("Instruction without object outValue cannot compute verification type");
   }
 
   public boolean hasInvariantVerificationType() {
diff --git a/src/main/java/com/android/tools/r8/ir/code/Load.java b/src/main/java/com/android/tools/r8/ir/code/Load.java
index 91526dd..e194d32 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Load.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Load.java
@@ -10,6 +10,7 @@
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.ir.conversion.CfBuilder;
+import com.android.tools.r8.ir.conversion.DexBuilder;
 import com.android.tools.r8.ir.optimize.Inliner.Constraint;
 import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
 
@@ -55,6 +56,11 @@
   }
 
   @Override
+  public void buildDex(DexBuilder builder) {
+    throw new Unreachable("This classfile-specific IR should not be inserted in the Dex backend.");
+  }
+
+  @Override
   public void buildCf(CfBuilder builder) {
     Value value = inValues.get(0);
     builder.add(new CfLoad(value.outType(), builder.getLocalRegister(value)));
diff --git a/src/main/java/com/android/tools/r8/ir/code/Move.java b/src/main/java/com/android/tools/r8/ir/code/Move.java
index 48fa364..9ee9684 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Move.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Move.java
@@ -4,16 +4,21 @@
 
 package com.android.tools.r8.ir.code;
 
+import com.android.tools.r8.cf.LoadStoreHelper;
 import com.android.tools.r8.dex.Constants;
+import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.AppInfo;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
+import com.android.tools.r8.ir.conversion.CfBuilder;
 import com.android.tools.r8.ir.conversion.DexBuilder;
 import com.android.tools.r8.ir.optimize.Inliner.Constraint;
 import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
 import java.util.function.Function;
 
 public class Move extends Instruction {
+  private static final String ERROR_MESSAGE =
+      "This DEX-specific instruction should not be seen in the CF backend";
 
   public Move(Value dest, Value src) {
     super(dest, src);
@@ -36,6 +41,11 @@
   }
 
   @Override
+  public void buildCf(CfBuilder builder) {
+    throw new Unreachable(ERROR_MESSAGE);
+  }
+
+  @Override
   public int maxInValueRegister() {
     return Constants.U16BIT_MAX;
   }
@@ -93,4 +103,9 @@
       AppInfo appInfo, Function<Value, TypeLatticeElement> getLatticeElement) {
     return getLatticeElement.apply(src());
   }
+
+  @Override
+  public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
+    throw new Unreachable(ERROR_MESSAGE);
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/code/NewArrayFilledData.java b/src/main/java/com/android/tools/r8/ir/code/NewArrayFilledData.java
index 7a7566d..799c528 100644
--- a/src/main/java/com/android/tools/r8/ir/code/NewArrayFilledData.java
+++ b/src/main/java/com/android/tools/r8/ir/code/NewArrayFilledData.java
@@ -3,10 +3,13 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.ir.code;
 
+import com.android.tools.r8.cf.LoadStoreHelper;
 import com.android.tools.r8.code.FillArrayData;
 import com.android.tools.r8.code.FillArrayDataPayload;
 import com.android.tools.r8.dex.Constants;
+import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.ir.conversion.CfBuilder;
 import com.android.tools.r8.ir.conversion.DexBuilder;
 import com.android.tools.r8.ir.optimize.Inliner.Constraint;
 import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
@@ -14,6 +17,8 @@
 import java.util.Arrays;
 
 public class NewArrayFilledData extends Instruction {
+  private static final String ERROR_MESSAGE =
+      "Conversion from DEX to classfile not supported for NewArrayFilledData";
 
   public final int element_width;
   public final long size;
@@ -42,6 +47,11 @@
   }
 
   @Override
+  public void buildCf(CfBuilder builder) {
+    throw new Unreachable(ERROR_MESSAGE);
+  }
+
+  @Override
   public boolean identicalNonValueNonPositionParts(Instruction other) {
     NewArrayFilledData o = other.asNewArrayFilledData();
     return o.element_width == element_width
@@ -102,4 +112,9 @@
   public Constraint inliningConstraint(AppInfoWithLiveness info, DexType invocationContext) {
     return Constraint.ALWAYS;
   }
+
+  @Override
+  public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
+    throw new Unreachable(ERROR_MESSAGE);
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/code/NonNull.java b/src/main/java/com/android/tools/r8/ir/code/NonNull.java
index 51ef234..8da9903 100644
--- a/src/main/java/com/android/tools/r8/ir/code/NonNull.java
+++ b/src/main/java/com/android/tools/r8/ir/code/NonNull.java
@@ -3,10 +3,12 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.ir.code;
 
+import com.android.tools.r8.cf.LoadStoreHelper;
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.AppInfo;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
+import com.android.tools.r8.ir.conversion.CfBuilder;
 import com.android.tools.r8.ir.conversion.DexBuilder;
 import com.android.tools.r8.ir.optimize.Inliner.Constraint;
 import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
@@ -52,6 +54,11 @@
   }
 
   @Override
+  public void buildCf(CfBuilder builder) {
+    throw new Unreachable(ERROR_MESSAGE);
+  }
+
+  @Override
   public int maxInValueRegister() {
     throw new Unreachable(ERROR_MESSAGE);
   }
@@ -92,4 +99,9 @@
     }
     return l;
   }
+
+  @Override
+  public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
+    throw new Unreachable(ERROR_MESSAGE);
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/code/Pop.java b/src/main/java/com/android/tools/r8/ir/code/Pop.java
index c991ffc..d2e47fb 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Pop.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Pop.java
@@ -3,10 +3,12 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.ir.code;
 
+import com.android.tools.r8.cf.LoadStoreHelper;
 import com.android.tools.r8.cf.code.CfPop;
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.ir.conversion.CfBuilder;
+import com.android.tools.r8.ir.conversion.DexBuilder;
 import com.android.tools.r8.ir.optimize.Inliner.Constraint;
 import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
 import com.android.tools.r8.utils.InternalOptions;
@@ -53,11 +55,21 @@
   }
 
   @Override
+  public void buildDex(DexBuilder builder) {
+    throw new Unreachable("This classfile-specific IR should not be inserted in the Dex backend.");
+  }
+
+  @Override
   public void buildCf(CfBuilder builder) {
     builder.add(new CfPop(inValues.get(0).type));
   }
 
   @Override
+  public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
+    throw new Unreachable("This IR must not be inserted before load and store insertion.");
+  }
+
+  @Override
   public boolean canBeDeadCode(IRCode code, InternalOptions options) {
     // Pop cannot be dead code as it modifies the stack height.
     return false;
diff --git a/src/main/java/com/android/tools/r8/ir/code/Store.java b/src/main/java/com/android/tools/r8/ir/code/Store.java
index 0963b03..82c0eeb 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Store.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Store.java
@@ -11,6 +11,7 @@
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.ir.conversion.CfBuilder;
+import com.android.tools.r8.ir.conversion.DexBuilder;
 import com.android.tools.r8.ir.optimize.Inliner.Constraint;
 import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
 import com.android.tools.r8.utils.InternalOptions;
@@ -57,6 +58,11 @@
   }
 
   @Override
+  public void buildDex(DexBuilder builder) {
+    throw new Unreachable("This classfile-specific IR should not be inserted in the Dex backend.");
+  }
+
+  @Override
   public void buildCf(CfBuilder builder) {
     builder.add(new CfStore(outType(), builder.getLocalRegister(outValue)));
   }