Insert assume instructions during StaticizingProcessor's reprocessing.

Bug: 143733090, 140767158
Change-Id: I959b197f32f99e8037c8e47c6f5370f586939194
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index 0552b9f..358a7fe 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -48,6 +48,7 @@
 import com.android.tools.r8.ir.desugar.StringConcatRewriter;
 import com.android.tools.r8.ir.desugar.TwrCloseResourceRewriter;
 import com.android.tools.r8.ir.optimize.AliasIntroducer;
+import com.android.tools.r8.ir.optimize.Assumer;
 import com.android.tools.r8.ir.optimize.ClassInitializerDefaultsOptimization;
 import com.android.tools.r8.ir.optimize.CodeRewriter;
 import com.android.tools.r8.ir.optimize.ConstantCanonicalizer;
@@ -155,13 +156,12 @@
   private final ServiceLoaderRewriter serviceLoaderRewriter;
 
   // Assumers that will insert Assume instructions.
-  private final AliasIntroducer aliasIntroducer;
+  public final Collection<Assumer> assumers = new ArrayList<>();
   private final DynamicTypeOptimization dynamicTypeOptimization;
-  private final NonNullTracker nonNullTracker;
 
   final DeadCodeRemover deadCodeRemover;
 
-  final MethodOptimizationInfoCollector methodOptimizationInfoCollector;
+  private final MethodOptimizationInfoCollector methodOptimizationInfoCollector;
 
   private final OptimizationFeedbackDelayed delayedOptimizationFeedback =
       new OptimizationFeedbackDelayed();
@@ -219,8 +219,6 @@
       this.twrCloseResourceRewriter = null;
       this.lambdaMerger = null;
       this.covariantReturnTypeAnnotationTransformer = null;
-      this.aliasIntroducer = null;
-      this.nonNullTracker = null;
       this.dynamicTypeOptimization = null;
       this.classInliner = null;
       this.classStaticizer = null;
@@ -258,9 +256,12 @@
         options.processCovariantReturnTypeAnnotations
             ? new CovariantReturnTypeAnnotationTransformer(this, appView.dexItemFactory())
             : null;
-    this.aliasIntroducer =
-        options.testing.forceAssumeNoneInsertion ? new AliasIntroducer(appView) : null;
-    this.nonNullTracker = options.enableNonNullTracking ? new NonNullTracker(appView) : null;
+    if (options.testing.forceAssumeNoneInsertion) {
+      assumers.add(new AliasIntroducer(appView));
+    }
+    if (options.enableNonNullTracking) {
+      assumers.add(new NonNullTracker(appView));
+    }
     this.desugaredLibraryAPIConverter =
         appView.rewritePrefix.isRewriting() ? new DesugaredLibraryAPIConverter(appView) : null;
     if (appView.enableWholeProgramOptimizations()) {
@@ -277,6 +278,9 @@
           options.enableDynamicTypeOptimization
               ? new DynamicTypeOptimization(appViewWithLiveness)
               : null;
+      if (dynamicTypeOptimization != null) {
+        assumers.add(dynamicTypeOptimization);
+      }
       this.fieldBitAccessAnalysis =
           options.enableFieldBitAccessAnalysis
               ? new FieldBitAccessAnalysis(appViewWithLiveness)
@@ -1146,25 +1150,13 @@
 
     previous = printMethod(code, "IR after disable assertions (SSA)", previous);
 
-    if (aliasIntroducer != null) {
-      aliasIntroducer.insertAssumeInstructions(code);
-      assert code.isConsistentSSA();
-    }
+    CodeRewriter.insertAssumeInstructions(code, assumers);
 
-    if (nonNullTracker != null) {
-      nonNullTracker.insertAssumeInstructions(code);
-      assert code.isConsistentSSA();
-    }
-
-    if (dynamicTypeOptimization != null) {
-      assert appView.enableWholeProgramOptimizations();
-      dynamicTypeOptimization.insertAssumeInstructions(code);
-      assert code.isConsistentSSA();
-    }
+    previous = printMethod(code, "IR after inserting assume instructions (SSA)", previous);
 
     appView.withGeneratedMessageLiteShrinker(shrinker -> shrinker.run(method, code));
 
-    previous = printMethod(code, "IR after null tracking (SSA)", previous);
+    previous = printMethod(code, "IR after generated message lite shrinking (SSA)", previous);
 
     if (!isDebugMode && options.enableInlining && inliner != null) {
       inliner.performInlining(method, code, feedback, methodProcessor);
@@ -1393,7 +1385,7 @@
       collectOptimizationInfo(code, feedback);
     }
 
-    if (aliasIntroducer != null || nonNullTracker != null || dynamicTypeOptimization != null) {
+    if (!assumers.isEmpty()) {
       CodeRewriter.removeAssumeInstructions(appView, code);
       assert code.isConsistentSSA();
     }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Assumer.java b/src/main/java/com/android/tools/r8/ir/optimize/Assumer.java
index 10e7314..dfabec5 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Assumer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Assumer.java
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.ir.optimize;
 
+import com.android.tools.r8.Keep;
 import com.android.tools.r8.ir.code.Assume;
 import com.android.tools.r8.ir.code.BasicBlock;
 import com.android.tools.r8.ir.code.IRCode;
@@ -13,10 +14,14 @@
 /**
  * One that assumes. Inherited tracker/optimization insert necessary variants of {@link Assume}.
  */
-interface Assumer {
+// TODO(b/143590191): should not need an explicit keep annotation to prevent the default interface
+//  method from being shrunk.
+@Keep
+public interface Assumer {
   default void insertAssumeInstructions(IRCode code) {
     insertAssumeInstructionsInBlocks(code, code.listIterator(), Predicates.alwaysTrue());
   }
+
   void insertAssumeInstructionsInBlocks(
       IRCode code, ListIterator<BasicBlock> blockIterator, Predicate<BasicBlock> blockTester);
 }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
index f6fba1d..8925262 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
@@ -159,6 +159,13 @@
     this.dexItemFactory = appView.dexItemFactory();
   }
 
+  public static void insertAssumeInstructions(IRCode code, Collection<Assumer> assumers) {
+    for (Assumer assumer : assumers) {
+      assumer.insertAssumeInstructions(code);
+      assert code.isConsistentSSA();
+    }
+  }
+
   public static void removeAssumeInstructions(AppView<?> appView, IRCode code) {
     // We need to update the types of all values whose definitions depend on a non-null value.
     // This is needed to preserve soundness of the types after the Assume<NonNullAssumption>
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/staticizer/StaticizingProcessor.java b/src/main/java/com/android/tools/r8/ir/optimize/staticizer/StaticizingProcessor.java
index 158fd9c..b98cff8 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/staticizer/StaticizingProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/staticizer/StaticizingProcessor.java
@@ -289,6 +289,7 @@
     Origin origin = appView.appInfo().originFor(method.method.holder);
     IRCode code = method.buildIR(appView, origin);
     codeOptimizations.forEach(codeOptimization -> codeOptimization.accept(code));
+    CodeRewriter.insertAssumeInstructions(code, converter.assumers);
     converter.collectOptimizationInfo(code, feedback);
     CodeRewriter.removeAssumeInstructions(appView, code);
     converter.finalizeIR(method, code, feedback);