Support for running throw block outliner on SystemUI benchmark

Bug: b/434769547
Change-Id: I8f630f3c258c6e6869270a384384c6fcd3204a67
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/type/TypeUtils.java b/src/main/java/com/android/tools/r8/ir/analysis/type/TypeUtils.java
index 4471bf8..8b7b5a8 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/type/TypeUtils.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/type/TypeUtils.java
@@ -19,7 +19,7 @@
 
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexField;
-import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.ir.code.Assume;
 import com.android.tools.r8.ir.code.InstanceGet;
 import com.android.tools.r8.ir.code.InstancePut;
@@ -29,7 +29,6 @@
 import com.android.tools.r8.ir.code.Phi;
 import com.android.tools.r8.ir.code.StaticPut;
 import com.android.tools.r8.ir.code.Value;
-import com.android.tools.r8.shaking.AppInfoWithLiveness;
 import com.android.tools.r8.utils.WorkList;
 import java.util.Objects;
 
@@ -68,8 +67,7 @@
    * Returns the "use type" of a given value {@link Value}, i.e., the weakest static type that this
    * value must have in order for the program to type check.
    */
-  public static TypeElement computeUseType(
-      AppView<AppInfoWithLiveness> appView, ProgramMethod method, Value value) {
+  public static TypeElement computeUseType(AppView<?> appView, DexType returnType, Value value) {
     TypeElement staticType = value.getType();
     TypeElement useType = TypeElement.getBottom();
     WorkList<UserAndValuePair> users = WorkList.newEqualityWorkList();
@@ -82,7 +80,7 @@
       } else {
         Instruction instruction = user.asInstruction();
         TypeElement instructionUseType =
-            computeUseTypeForInstruction(appView, method, instruction, item.value, users);
+            computeUseTypeForInstruction(appView, returnType, instruction, item.value, users);
         useType = useType.join(instructionUseType, appView);
         if (useType.isTop() || useType.equalUpToNullability(staticType)) {
           // Bail-out.
@@ -103,8 +101,8 @@
   }
 
   private static TypeElement computeUseTypeForInstruction(
-      AppView<AppInfoWithLiveness> appView,
-      ProgramMethod method,
+      AppView<?> appView,
+      DexType returnType,
       Instruction instruction,
       Value value,
       WorkList<UserAndValuePair> users) {
@@ -125,7 +123,7 @@
       case INVOKE_VIRTUAL:
         return computeUseTypeForInvoke(appView, instruction.asInvokeMethod(), value);
       case RETURN:
-        return computeUseTypeForReturn(appView, method);
+        return computeUseTypeForReturn(appView, returnType);
       case STATIC_PUT:
         return computeUseTypeForStaticPut(appView, instruction.asStaticPut());
       default:
@@ -141,12 +139,12 @@
   }
 
   private static TypeElement computeUseTypeForInstanceGet(
-      AppView<AppInfoWithLiveness> appView, InstanceGet instanceGet) {
+      AppView<?> appView, InstanceGet instanceGet) {
     return instanceGet.getField().getHolderType().toTypeElement(appView);
   }
 
   private static TypeElement computeUseTypeForInstancePut(
-      AppView<AppInfoWithLiveness> appView, InstancePut instancePut, Value value) {
+      AppView<?> appView, InstancePut instancePut, Value value) {
     DexField field = instancePut.getField();
     TypeElement useType = TypeElement.getBottom();
     if (instancePut.object() == value) {
@@ -159,7 +157,7 @@
   }
 
   private static TypeElement computeUseTypeForInvoke(
-      AppView<AppInfoWithLiveness> appView, InvokeMethod invoke, Value value) {
+      AppView<?> appView, InvokeMethod invoke, Value value) {
     TypeElement useType = TypeElement.getBottom();
     for (int argumentIndex = 0; argumentIndex < invoke.arguments().size(); argumentIndex++) {
       Value argument = invoke.getArgument(argumentIndex);
@@ -177,19 +175,11 @@
     return useType;
   }
 
-  private static TypeElement computeUseTypeForReturn(
-      AppView<AppInfoWithLiveness> appView, ProgramMethod method) {
-    return method.getReturnType().toTypeElement(appView);
+  private static TypeElement computeUseTypeForReturn(AppView<?> appView, DexType returnType) {
+    return returnType.toTypeElement(appView);
   }
 
-  private static TypeElement computeUseTypeForStaticPut(
-      AppView<AppInfoWithLiveness> appView, StaticPut staticPut) {
+  private static TypeElement computeUseTypeForStaticPut(AppView<?> appView, StaticPut staticPut) {
     return staticPut.getField().getType().toTypeElement(appView);
   }
-
-  @SuppressWarnings("ReferenceEquality")
-  public static boolean isNullPointerException(TypeElement type, AppView<?> appView) {
-    return type.isClassType()
-        && type.asClassType().getClassType() == appView.dexItemFactory().npeType;
-  }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/passes/TrivialCheckCastAndInstanceOfRemover.java b/src/main/java/com/android/tools/r8/ir/conversion/passes/TrivialCheckCastAndInstanceOfRemover.java
index afd13f5..01ffc31 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/passes/TrivialCheckCastAndInstanceOfRemover.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/passes/TrivialCheckCastAndInstanceOfRemover.java
@@ -297,7 +297,8 @@
             .getDynamicUpperBoundType(appViewWithLiveness)
             .lessThanOrEqualUpToNullability(castTypeLattice, appView)) {
       TypeElement useType =
-          TypeUtils.computeUseType(appViewWithLiveness, context, checkCast.outValue());
+          TypeUtils.computeUseType(
+              appViewWithLiveness, context.getReturnType(), checkCast.outValue());
       if (inTypeLattice.lessThanOrEqualUpToNullability(useType, appView)) {
         return RemoveCheckCastInstructionIfTrivialResult.REMOVED_CAST_DO_NARROW;
       }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/outliner/exceptions/ThrowBlockOutlineMarkerRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/outliner/exceptions/ThrowBlockOutlineMarkerRewriter.java
index d375841..0ccaf37 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/outliner/exceptions/ThrowBlockOutlineMarkerRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/outliner/exceptions/ThrowBlockOutlineMarkerRewriter.java
@@ -87,6 +87,10 @@
 
   private void removeConstantArgumentsFromOutline(
       ProgramMethod method, IRCode code, ThrowBlockOutline outline) {
+    if (!outline.hasConstantArgument()) {
+      return;
+    }
+
     Set<Phi> affectedPhis = Collections.emptySet();
     Set<UnusedArgument> unusedArguments = Collections.emptySet();
     new LensCodeArgumentRewriter(appView)
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/outliner/exceptions/ThrowBlockOutlinerScanner.java b/src/main/java/com/android/tools/r8/ir/optimize/outliner/exceptions/ThrowBlockOutlinerScanner.java
index 1dab9c4..fe43436 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/outliner/exceptions/ThrowBlockOutlinerScanner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/outliner/exceptions/ThrowBlockOutlinerScanner.java
@@ -14,9 +14,12 @@
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexProto;
+import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.DexTypeUtils;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.graph.bytecodemetadata.BytecodeMetadataProvider;
+import com.android.tools.r8.ir.analysis.type.TypeElement;
+import com.android.tools.r8.ir.analysis.type.TypeUtils;
 import com.android.tools.r8.ir.analysis.value.AbstractValueFactory;
 import com.android.tools.r8.ir.code.Argument;
 import com.android.tools.r8.ir.code.BasicBlock;
@@ -127,11 +130,10 @@
             LirCode<?> lirCode = outlineBuilder.buildLirCode(appView, code.context());
             Wrapper<LirCode<?>> lirCodeWrapper =
                 ThrowBlockOutlinerLirCodeEquivalence.get().wrap(lirCode);
-            DexProto proto = outlineBuilder.getProto(factory);
+            DexProto proto = outlineBuilder.getProto(appView);
             ThrowBlockOutline outline =
                 outlines.computeIfAbsent(
                     lirCodeWrapper, w -> new ThrowBlockOutline(w.get(), proto));
-            // TODO(b/434769547): This may not hold. We should compute the join.
             assert proto.isIdenticalTo(outline.getProto());
             List<Value> arguments = outlineBuilder.buildArguments();
             outline.addUser(code.reference(), arguments, getAbstractValueFactory());
@@ -402,12 +404,19 @@
       return addArgument(value).outValue();
     }
 
-    DexProto getProto(DexItemFactory factory) {
+    DexProto getProto(AppView<?> appView) {
+      DexItemFactory factory = appView.dexItemFactory();
+      DexType returnType = factory.voidType;
       return factory.createProto(
-          factory.voidType,
+          returnType,
           ListUtils.map(
               outlinedArguments,
-              outlinedArgument -> DexTypeUtils.toDexType(factory, outlinedArgument.getOutType())));
+              outlinedArgument -> {
+                TypeElement useType =
+                    TypeUtils.computeUseType(
+                        appView, factory.voidType, outlinedArgument.outValue());
+                return DexTypeUtils.toDexType(factory, useType);
+              }));
     }
 
     List<Value> buildArguments() {