Revert "Revert "Disallow const instructions after throwing instructions""

This reverts commit bb3572f3b2c70a23484901b143358b1451c46bd2.

Original commit was:
https://r8-review.googlesource.com/c/r8/+/33105

Change-Id: Ic1447115f522109b974e6cfd858b569569b81ee0
diff --git a/src/main/java/com/android/tools/r8/ir/code/IRCode.java b/src/main/java/com/android/tools/r8/ir/code/IRCode.java
index 773a648..cb93a5e 100644
--- a/src/main/java/com/android/tools/r8/ir/code/IRCode.java
+++ b/src/main/java/com/android/tools/r8/ir/code/IRCode.java
@@ -662,12 +662,9 @@
           }
           // After the throwing instruction only debug instructions and the final jump
           // instruction is allowed.
-          // TODO(ager): For now allow const instructions due to the way consts are pushed
-          // towards their use
           if (seenThrowing) {
             assert instruction.isDebugInstruction()
                 || instruction.isJumpInstruction()
-                || instruction.isConstInstruction()
                 || instruction.isStore()
                 || instruction.isPop();
           }
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java b/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
index 7c22bbf..fd968d6 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
@@ -210,7 +210,15 @@
             iterator.replaceCurrentInstruction(newInvoke);
 
             if (constantReturnMaterializingInstruction != null) {
-              iterator.add(constantReturnMaterializingInstruction);
+              if (block.hasCatchHandlers()) {
+                // Split the block to ensure no instructions after throwing instructions.
+                iterator
+                    .split(code, blocks)
+                    .listIterator()
+                    .add(constantReturnMaterializingInstruction);
+              } else {
+                iterator.add(constantReturnMaterializingInstruction);
+              }
             }
 
             DexType actualReturnType = actualTarget.proto.returnType;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java b/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
index 89eef31..ad3fb38 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
@@ -17,17 +17,20 @@
 import com.android.tools.r8.ir.analysis.type.Nullability;
 import com.android.tools.r8.ir.analysis.type.TypeAnalysis;
 import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
+import com.android.tools.r8.ir.code.BasicBlock;
 import com.android.tools.r8.ir.code.ConstNumber;
 import com.android.tools.r8.ir.code.FieldInstruction;
 import com.android.tools.r8.ir.code.IRCode;
 import com.android.tools.r8.ir.code.Instruction;
 import com.android.tools.r8.ir.code.InstructionIterator;
+import com.android.tools.r8.ir.code.InstructionListIterator;
 import com.android.tools.r8.ir.code.InvokeMethod;
 import com.android.tools.r8.ir.code.StaticGet;
 import com.android.tools.r8.ir.code.Value;
 import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
 import com.android.tools.r8.shaking.ProguardMemberRule;
 import com.google.common.collect.Sets;
+import java.util.ListIterator;
 import java.util.Set;
 import java.util.function.Predicate;
 
@@ -113,7 +116,8 @@
   private boolean tryConstantReplacementFromProguard(
       IRCode code,
       Set<Value> affectedValues,
-      InstructionIterator iterator,
+      ListIterator<BasicBlock> blocks,
+      InstructionListIterator iterator,
       Instruction current,
       ProguardMemberRuleLookup lookup) {
     Instruction replacement = constantReplacementFromProguardRule(lookup.rule, code, current);
@@ -132,7 +136,11 @@
         current.outValue().replaceUsers(replacement.outValue());
       }
       replacement.setPosition(current.getPosition());
-      iterator.add(replacement);
+      if (current.getBlock().hasCatchHandlers()) {
+        iterator.split(code, blocks).listIterator().add(replacement);
+      } else {
+        iterator.add(replacement);
+      }
     }
     return true;
   }
@@ -141,7 +149,8 @@
       IRCode code,
       DexType callingContext,
       Set<Value> affectedValues,
-      InstructionIterator iterator,
+      ListIterator<BasicBlock> blocks,
+      InstructionListIterator iterator,
       InvokeMethod current) {
     DexMethod invokedMethod = current.getInvokedMethod();
     DexType invokedHolder = invokedMethod.getHolder();
@@ -161,7 +170,8 @@
       } else if (!outValueNullOrNotUsed) {
         // Check to see if a constant value can be assumed.
         invokeReplaced =
-            tryConstantReplacementFromProguard(code, affectedValues, iterator, current, lookup);
+            tryConstantReplacementFromProguard(
+                code, affectedValues, blocks, iterator, current, lookup);
       }
     }
     if (invokeReplaced || current.outValue() == null) {
@@ -190,7 +200,11 @@
       current.setOutValue(null);
       replacement.setPosition(current.getPosition());
       current.moveDebugValues(replacement);
-      iterator.add(replacement);
+      if (current.getBlock().hasCatchHandlers()) {
+        iterator.split(code, blocks).listIterator().add(replacement);
+      } else {
+        iterator.add(replacement);
+      }
     }
   }
 
@@ -198,7 +212,8 @@
       IRCode code,
       Predicate<DexEncodedMethod> isProcessedConcurrently,
       Set<Value> affectedValues,
-      InstructionIterator iterator,
+      ListIterator<BasicBlock> blocks,
+      InstructionListIterator iterator,
       StaticGet current) {
     DexField field = current.getField();
     DexEncodedField target = appInfo.lookupStaticTarget(field.getHolder(), field);
@@ -215,7 +230,8 @@
     ProguardMemberRuleLookup lookup = lookupMemberRule(target);
     if (lookup != null
         && lookup.type == RuleType.ASSUME_VALUES
-        && tryConstantReplacementFromProguard(code, affectedValues, iterator, current, lookup)) {
+        && tryConstantReplacementFromProguard(
+            code, affectedValues, blocks, iterator, current, lookup)) {
       return;
     }
     if (current.dest() != null) {
@@ -275,17 +291,26 @@
   public void rewriteWithConstantValues(
       IRCode code, DexType callingContext, Predicate<DexEncodedMethod> isProcessedConcurrently) {
     Set<Value> affectedValues = Sets.newIdentityHashSet();
-    InstructionIterator iterator = code.instructionIterator();
-    while (iterator.hasNext()) {
-      Instruction current = iterator.next();
-      if (current.isInvokeMethod()) {
-        rewriteInvokeMethodWithConstantValues(
-            code, callingContext, affectedValues, iterator, current.asInvokeMethod());
-      } else if (current.isInstancePut() || current.isStaticPut()) {
-        rewritePutWithConstantValues(iterator, current.asFieldInstruction());
-      } else if (current.isStaticGet()) {
-        rewriteStaticGetWithConstantValues(
-            code, isProcessedConcurrently, affectedValues, iterator, current.asStaticGet());
+    ListIterator<BasicBlock> blocks = code.blocks.listIterator();
+    while (blocks.hasNext()) {
+      BasicBlock block = blocks.next();
+      InstructionListIterator iterator = block.listIterator();
+      while (iterator.hasNext()) {
+        Instruction current = iterator.next();
+        if (current.isInvokeMethod()) {
+          rewriteInvokeMethodWithConstantValues(
+              code, callingContext, affectedValues, blocks, iterator, current.asInvokeMethod());
+        } else if (current.isInstancePut() || current.isStaticPut()) {
+          rewritePutWithConstantValues(iterator, current.asFieldInstruction());
+        } else if (current.isStaticGet()) {
+          rewriteStaticGetWithConstantValues(
+              code,
+              isProcessedConcurrently,
+              affectedValues,
+              blocks,
+              iterator,
+              current.asStaticGet());
+        }
       }
     }
     if (!affectedValues.isEmpty()) {