Extend completeness checking for tivi to enum unboxing

Fixes: b/267592755
Change-Id: Icb83c1b92ddb5116f30a9c91036922129f4d6c11
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 6301054..97467f1 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import static com.android.tools.r8.profile.art.ArtProfileCompletenessChecker.CompletenessExceptions.ALLOW_MISSING_ENUM_UNBOXING_UTILITY_METHODS;
 import static com.android.tools.r8.utils.AssertionUtils.forTesting;
 import static com.android.tools.r8.utils.ExceptionUtils.unwrapExecutionException;
 
@@ -533,7 +534,8 @@
       new PrimaryR8IRConverter(appViewWithLiveness, timing)
           .optimize(appViewWithLiveness, executorService);
 
-      assert ArtProfileCompletenessChecker.verify(appView);
+      assert ArtProfileCompletenessChecker.verify(
+          appView, ALLOW_MISSING_ENUM_UNBOXING_UTILITY_METHODS);
 
       // Clear the reference type lattice element cache to reduce memory pressure.
       appView.dexItemFactory().clearTypeElementsCache();
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileCompletenessChecker.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileCompletenessChecker.java
index 581db1b..21a7635 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileCompletenessChecker.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileCompletenessChecker.java
@@ -4,39 +4,56 @@
 
 package com.android.tools.r8.profile.art;
 
+import static com.android.tools.r8.profile.art.ArtProfileCompletenessChecker.CompletenessExceptions.ALLOW_MISSING_ENUM_UNBOXING_UTILITY_METHODS;
+
 import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexReference;
+import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramDefinition;
+import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.synthesis.SyntheticItems;
 import com.android.tools.r8.utils.StringUtils;
+import com.google.common.collect.Sets;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Set;
 
 public class ArtProfileCompletenessChecker {
 
-  public static boolean verify(AppView<?> appView) {
+  public enum CompletenessExceptions {
+    ALLOW_MISSING_ENUM_UNBOXING_UTILITY_METHODS
+  }
+
+  public static boolean verify(
+      AppView<?> appView, CompletenessExceptions... completenessExceptions) {
     if (appView.options().getArtProfileOptions().isCompletenessCheckForTestingEnabled()) {
       ArtProfile completeArtProfile = appView.getArtProfileCollection().asNonEmpty().getLast();
-      assert verifyProfileIsComplete(appView, completeArtProfile);
+      assert verifyProfileIsComplete(
+          appView, completeArtProfile, Sets.newHashSet(completenessExceptions));
     }
     return true;
   }
 
-  private static boolean verifyProfileIsComplete(AppView<?> appView, ArtProfile artProfile) {
+  private static boolean verifyProfileIsComplete(
+      AppView<?> appView,
+      ArtProfile artProfile,
+      Set<CompletenessExceptions> completenessExceptions) {
     assert !appView.getSyntheticItems().hasPendingSyntheticClasses();
     List<DexReference> missing = new ArrayList<>();
     for (DexProgramClass clazz : appView.appInfo().classesWithDeterministicOrder()) {
       if (appView.horizontallyMergedClasses().hasBeenMergedIntoDifferentType(clazz.getType())
           || (appView.hasVerticallyMergedClasses()
-              && appView.verticallyMergedClasses().hasBeenMergedIntoSubtype(clazz.getType()))) {
+              && appView.verticallyMergedClasses().hasBeenMergedIntoSubtype(clazz.getType()))
+          || appView.unboxedEnums().isUnboxedEnum(clazz)) {
         continue;
       }
       if (!artProfile.containsClassRule(clazz.getType())) {
-        missing.add(clazz.getType());
+        recordMissingDefinition(appView, clazz, completenessExceptions, missing);
       }
-      for (DexEncodedMethod method : clazz.methods()) {
+      for (ProgramMethod method : clazz.programMethods()) {
         if (!artProfile.containsMethodRule(method.getReference())) {
-          missing.add(method.getReference());
+          recordMissingDefinition(appView, method, completenessExceptions, missing);
         }
       }
     }
@@ -47,4 +64,26 @@
     }
     return true;
   }
+
+  private static void recordMissingDefinition(
+      AppView<?> appView,
+      ProgramDefinition definition,
+      Set<CompletenessExceptions> completenessExceptions,
+      List<DexReference> missing) {
+    if (completenessExceptions.contains(ALLOW_MISSING_ENUM_UNBOXING_UTILITY_METHODS)) {
+      DexType contextType = definition.getContextType();
+      SyntheticItems syntheticItems = appView.getSyntheticItems();
+      if (syntheticItems.isSynthetic(contextType)) {
+        if (syntheticItems.isSyntheticOfKind(
+                contextType, naming -> naming.ENUM_UNBOXING_CHECK_NOT_ZERO_METHOD)
+            || syntheticItems.isSyntheticOfKind(
+                contextType, naming -> naming.ENUM_UNBOXING_LOCAL_UTILITY_CLASS)
+            || syntheticItems.isSyntheticOfKind(
+                contextType, naming -> naming.ENUM_UNBOXING_SHARED_UTILITY_CLASS)) {
+          return;
+        }
+      }
+    }
+    missing.add(definition.getReference());
+  }
 }
diff --git a/src/test/java/com/android/tools/r8/internal/opensourceapps/TiviTest.java b/src/test/java/com/android/tools/r8/internal/opensourceapps/TiviTest.java
index fa4833f..c2d3a03 100644
--- a/src/test/java/com/android/tools/r8/internal/opensourceapps/TiviTest.java
+++ b/src/test/java/com/android/tools/r8/internal/opensourceapps/TiviTest.java
@@ -48,7 +48,6 @@
   public void testR8() throws Exception {
     testForR8(Backend.DEX)
         .addProgramFiles(outDirectory.resolve("program.jar"))
-        .addOptionsModification(options -> options.enableEnumUnboxing = false)
         .addOptionsModification(
             options -> options.getArtProfileOptions().setEnableCompletenessCheckForTesting(true))
         .apply(this::configure)