Postpone enum unboxing candidate removal

This allows to deterministically choose the number of
methods where peephole optimizations are not applied in
IR processing round 1, and therefore make the compilation
deterministic again.

Bug: 191157574
Change-Id: I99222b00c54d7734a437be5432e05f839ecc6864
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 577f154..a99c921 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
@@ -883,6 +883,9 @@
     if (appView.options().protoShrinking().enableRemoveProtoEnumSwitchMap()) {
       appView.protoShrinker().protoEnumSwitchMapRemover.updateVisibleStaticFieldValues();
     }
+    if (enumUnboxer != null) {
+      enumUnboxer.updateEnumUnboxingCandidatesInfo();
+    }
     assert delayedOptimizationFeedback.noUpdatesLeft();
     onWaveDoneActions.forEach(com.android.tools.r8.utils.Action::execute);
     onWaveDoneActions = null;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxer.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxer.java
index 31f7131..71d5f33 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxer.java
@@ -130,6 +130,7 @@
   private final EnumUnboxingCandidateInfoCollection enumUnboxingCandidatesInfo;
   private final ProgramPackageCollection enumsToUnboxWithPackageRequirement =
       ProgramPackageCollection.createEmpty();
+  private final Set<DexProgramClass> candidatesToRemoveInWave = Sets.newConcurrentHashSet();
   private final Map<DexType, EnumStaticFieldValues> staticFieldValuesMap =
       new ConcurrentHashMap<>();
   private final ProgramMethodSet methodsDependingOnLibraryModelisation =
@@ -168,6 +169,13 @@
     return ordinal + 1;
   }
 
+  public void updateEnumUnboxingCandidatesInfo() {
+    for (DexProgramClass candidate : candidatesToRemoveInWave) {
+      enumUnboxingCandidatesInfo.removeCandidate(candidate);
+    }
+    candidatesToRemoveInWave.clear();
+  }
+
   /**
    * Returns true if {@param enumClass} was marked as being unboxable.
    *
@@ -178,7 +186,7 @@
     assert enumClass.isEnum();
     if (!reportFailure(enumClass, reason)) {
       // The failure was not reported, meaning debug logging is disabled.
-      enumUnboxingCandidatesInfo.removeCandidate(enumClass);
+      candidatesToRemoveInWave.add(enumClass);
       return true;
     }
     return false;
@@ -464,7 +472,9 @@
       ExecutorService executorService,
       OptimizationFeedbackDelayed feedback)
       throws ExecutionException {
+    assert candidatesToRemoveInWave.isEmpty();
     EnumDataMap enumDataMap = finishAnalysis();
+    assert candidatesToRemoveInWave.isEmpty();
     // At this point the enum unboxing candidates are no longer candidates, they will all be
     // unboxed. We extract the now immutable enums to unbox information and clear the candidate
     // info.
@@ -540,6 +550,7 @@
   public EnumDataMap finishAnalysis() {
     analyzeInitializers();
     analyzeAccessibility();
+    updateEnumUnboxingCandidatesInfo();
     EnumDataMap enumDataMap = analyzeEnumInstances();
     if (debugLogEnabled) {
       // Remove all enums that have been reported as being unboxable.