Remove EnumValueInfo from CfCodeProvider

Bug: 172528424
Change-Id: I9e9c467a4365e6171f3da396ec2380f3afd8a3a2
diff --git a/src/main/java/com/android/tools/r8/graph/EnumValueInfoMapCollection.java b/src/main/java/com/android/tools/r8/graph/EnumValueInfoMapCollection.java
index 362ff7c..40e6286 100644
--- a/src/main/java/com/android/tools/r8/graph/EnumValueInfoMapCollection.java
+++ b/src/main/java/com/android/tools/r8/graph/EnumValueInfoMapCollection.java
@@ -4,6 +4,7 @@
 
 package com.android.tools.r8.graph;
 
+import com.android.tools.r8.ir.optimize.enums.EnumUnboxer;
 import com.google.common.collect.ImmutableMap;
 import java.util.LinkedHashMap;
 import java.util.Map;
@@ -125,7 +126,7 @@
     }
 
     public int convertToInt() {
-      return ordinal + 1;
+      return EnumUnboxer.ordinalToUnboxedInt(ordinal);
     }
 
     EnumValueInfo rewrittenWithLens(GraphLens lens) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumInstanceFieldData.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumInstanceFieldData.java
index 4f4dea9..69a5179 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumInstanceFieldData.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumInstanceFieldData.java
@@ -4,9 +4,9 @@
 
 package com.android.tools.r8.ir.optimize.enums;
 
-import com.android.tools.r8.graph.DexField;
 import com.android.tools.r8.ir.analysis.value.AbstractValue;
-import java.util.Map;
+import com.android.tools.r8.utils.collections.ImmutableInt2ReferenceSortedMap;
+import java.util.function.BiConsumer;
 
 /*
  * My instances represent the values of an enum field for each of the enum instance.
@@ -83,9 +83,9 @@
   }
 
   public static class EnumInstanceFieldMappingData extends EnumInstanceFieldKnownData {
-    private final Map<DexField, AbstractValue> mapping;
+    private final ImmutableInt2ReferenceSortedMap<AbstractValue> mapping;
 
-    public EnumInstanceFieldMappingData(Map<DexField, AbstractValue> mapping) {
+    public EnumInstanceFieldMappingData(ImmutableInt2ReferenceSortedMap<AbstractValue> mapping) {
       this.mapping = mapping;
     }
 
@@ -104,8 +104,12 @@
       return this;
     }
 
-    public AbstractValue getData(DexField field) {
-      return mapping.get(field);
+    public AbstractValue getData(int unboxedEnumValue) {
+      return mapping.get(unboxedEnumValue);
+    }
+
+    public void forEach(BiConsumer<? super Integer, ? super AbstractValue> consumer) {
+      mapping.forEach(consumer);
     }
   }
 }
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 2d436ad..9e95486 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
@@ -66,12 +66,12 @@
 import com.android.tools.r8.utils.BooleanUtils;
 import com.android.tools.r8.utils.Reporter;
 import com.android.tools.r8.utils.StringDiagnostic;
+import com.android.tools.r8.utils.collections.ImmutableInt2ReferenceSortedMap;
 import com.android.tools.r8.utils.collections.ProgramMethodSet;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
 import java.util.Arrays;
-import java.util.IdentityHashMap;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
@@ -110,6 +110,10 @@
     enumUnboxingCandidatesInfo = new EnumUnboxingCandidateAnalysis(appView, this).findCandidates();
   }
 
+  public static int ordinalToUnboxedInt(int ordinal) {
+    return ordinal + 1;
+  }
+
   private void markEnumAsUnboxable(Reason reason, DexProgramClass enumClass) {
     assert enumClass.isEnum();
     reportFailure(enumClass.type, reason);
@@ -445,22 +449,31 @@
         ImmutableMap.builder();
     enumUnboxingCandidatesInfo.forEachCandidateAndRequiredInstanceFieldData(
         (enumClass, fields) -> {
-          ImmutableMap.Builder<DexField, EnumInstanceFieldKnownData> typeBuilder =
-              ImmutableMap.builder();
-          for (DexField field : fields) {
-            EnumInstanceFieldData enumInstanceFieldData = computeEnumFieldData(field, enumClass);
-            if (enumInstanceFieldData.isUnknown()) {
-              markEnumAsUnboxable(Reason.MISSING_INSTANCE_FIELD_DATA, enumClass);
-              return;
-            }
-            typeBuilder.put(field, enumInstanceFieldData.asEnumFieldKnownData());
+          ImmutableMap<DexField, EnumInstanceFieldKnownData> data =
+              buildEnumInstanceFieldData(enumClass, fields);
+          if (data == null) {
+            markEnumAsUnboxable(Reason.MISSING_INSTANCE_FIELD_DATA, enumClass);
+            return;
           }
-          builder.put(enumClass.type, typeBuilder.build());
+          builder.put(enumClass.type, data);
         });
     staticFieldValuesMap.clear();
     return new EnumInstanceFieldDataMap(builder.build());
   }
 
+  private ImmutableMap<DexField, EnumInstanceFieldKnownData> buildEnumInstanceFieldData(
+      DexProgramClass enumClass, Set<DexField> fields) {
+    ImmutableMap.Builder<DexField, EnumInstanceFieldKnownData> typeBuilder = ImmutableMap.builder();
+    for (DexField field : fields) {
+      EnumInstanceFieldData enumInstanceFieldData = computeEnumFieldData(field, enumClass);
+      if (enumInstanceFieldData.isUnknown()) {
+        return null;
+      }
+      typeBuilder.put(field, enumInstanceFieldData.asEnumFieldKnownData());
+    }
+    return typeBuilder.build();
+  }
+
   private void analyzeAccessibility() {
     // Unboxing an enum will require to move its methods to a different class, which may impact
     // accessibility. For a quick analysis we simply reuse the inliner analysis.
@@ -951,7 +964,8 @@
         appView.appInfo().resolveFieldOn(enumClass, instanceField).getResolvedField();
     assert encodedInstanceField != null;
     boolean canBeOrdinal = instanceField.type.isIntType();
-    Map<DexField, AbstractValue> data = new IdentityHashMap<>();
+    ImmutableInt2ReferenceSortedMap.Builder<AbstractValue> data =
+        ImmutableInt2ReferenceSortedMap.builder();
     EnumValueInfoMapCollection.EnumValueInfoMap enumValueInfoMap =
         appView.appInfo().getEnumValueInfoMap(enumClass.type);
     for (DexField staticField : enumValueInfoMap.enumValues()) {
@@ -970,7 +984,7 @@
         if (!(fieldValue.isSingleNumberValue() || fieldValue.isSingleStringValue())) {
           return EnumInstanceFieldUnknownData.getInstance();
         }
-        data.put(staticField, fieldValue);
+        data.put(enumValueInfoMap.getEnumValueInfo(staticField).convertToInt(), fieldValue);
         if (canBeOrdinal) {
           int ordinalValue = enumValueInfoMap.getEnumValueInfo(staticField).ordinal;
           assert fieldValue.isSingleNumberValue();
@@ -984,7 +998,7 @@
     if (canBeOrdinal) {
       return new EnumInstanceFieldOrdinalData();
     }
-    return new EnumInstanceFieldMappingData(data);
+    return new EnumInstanceFieldMappingData(data.build());
   }
 
   private void reportEnumsAnalysis() {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingRewriter.java
index c456bd0..c0b1831 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingRewriter.java
@@ -599,7 +599,6 @@
                 appView,
                 method.holder,
                 field.type,
-                enumsToUnbox.getEnumValueInfoMap(enumType),
                 unboxedEnumsInstanceFieldData
                     .getInstanceFieldData(enumType, field)
                     .asEnumFieldMappingData(),
@@ -618,7 +617,6 @@
                 appView,
                 method.holder,
                 enumType,
-                enumsToUnbox.getEnumValueInfoMap(enumType),
                 unboxedEnumsInstanceFieldData
                     .getInstanceFieldData(enumType, factory.enumMembers.nameField)
                     .asEnumFieldMappingData())
diff --git a/src/main/java/com/android/tools/r8/ir/synthetic/EnumUnboxingCfCodeProvider.java b/src/main/java/com/android/tools/r8/ir/synthetic/EnumUnboxingCfCodeProvider.java
index 75358f7..d21c6d9 100644
--- a/src/main/java/com/android/tools/r8/ir/synthetic/EnumUnboxingCfCodeProvider.java
+++ b/src/main/java/com/android/tools/r8/ir/synthetic/EnumUnboxingCfCodeProvider.java
@@ -28,7 +28,6 @@
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.EnumValueInfoMapCollection.EnumValueInfoMap;
 import com.android.tools.r8.ir.analysis.value.AbstractValue;
 import com.android.tools.r8.ir.code.If;
 import com.android.tools.r8.ir.code.ValueType;
@@ -64,7 +63,6 @@
   public static class EnumUnboxingInstanceFieldCfCodeProvider extends EnumUnboxingCfCodeProvider {
 
     private final DexType returnType;
-    private final EnumValueInfoMap enumValueInfoMap;
     private final EnumInstanceFieldMappingData fieldDataMap;
     private final AbstractValue nullValue;
 
@@ -72,12 +70,10 @@
         AppView<?> appView,
         DexType holder,
         DexType returnType,
-        EnumValueInfoMap enumValueInfoMap,
         EnumInstanceFieldMappingData fieldDataMap,
         AbstractValue nullValue) {
       super(appView, holder);
       this.returnType = returnType;
-      this.enumValueInfoMap = enumValueInfoMap;
       this.fieldDataMap = fieldDataMap;
       this.nullValue = nullValue;
     }
@@ -101,19 +97,16 @@
 
       // if (i == 1) { return 10;}
       // if (i == 2) { return 20;}
-      enumValueInfoMap.forEach(
-          (field, enumValueInfo) -> {
-            AbstractValue value = fieldDataMap.getData(field);
-            if (value != null) {
-              CfLabel dest = new CfLabel();
-              instructions.add(new CfLoad(ValueType.fromDexType(factory.intType), 0));
-              instructions.add(new CfConstNumber(enumValueInfo.convertToInt(), ValueType.INT));
-              instructions.add(new CfIfCmp(If.Type.NE, ValueType.INT, dest));
-              addCfInstructionsForAbstractValue(instructions, value, returnType);
-              instructions.add(new CfReturn(ValueType.fromDexType(returnType)));
-              instructions.add(dest);
-              instructions.add(new CfFrame(locals, ImmutableDeque.of()));
-            }
+      fieldDataMap.forEach(
+          (unboxedEnumValue, value) -> {
+            CfLabel dest = new CfLabel();
+            instructions.add(new CfLoad(ValueType.fromDexType(factory.intType), 0));
+            instructions.add(new CfConstNumber(unboxedEnumValue, ValueType.INT));
+            instructions.add(new CfIfCmp(If.Type.NE, ValueType.INT, dest));
+            addCfInstructionsForAbstractValue(instructions, value, returnType);
+            instructions.add(new CfReturn(ValueType.fromDexType(returnType)));
+            instructions.add(dest);
+            instructions.add(new CfFrame(locals, ImmutableDeque.of()));
           });
 
       if (nullValue != null) {
@@ -132,19 +125,16 @@
 
   public static class EnumUnboxingValueOfCfCodeProvider extends EnumUnboxingCfCodeProvider {
 
-    private DexType enumType;
-    private EnumValueInfoMap map;
+    private final DexType enumType;
     private final EnumInstanceFieldMappingData fieldDataMap;
 
     public EnumUnboxingValueOfCfCodeProvider(
         AppView<?> appView,
         DexType holder,
         DexType enumType,
-        EnumValueInfoMap map,
         EnumInstanceFieldMappingData fieldDataMap) {
       super(appView, holder);
       this.enumType = enumType;
-      this.map = map;
       this.fieldDataMap = fieldDataMap;
     }
 
@@ -180,16 +170,15 @@
 
       // if (s.equals("A")) { return 1;}
       // if (s.equals("B")) { return 2;}
-      map.forEach(
-          (field, enumValueInfo) -> {
+      fieldDataMap.forEach(
+          (unboxedEnumValue, value) -> {
             CfLabel dest = new CfLabel();
             instructions.add(new CfLoad(ValueType.fromDexType(factory.stringType), 0));
-            AbstractValue value = fieldDataMap.getData(field);
             addCfInstructionsForAbstractValue(instructions, value, factory.stringType);
             instructions.add(
                 new CfInvoke(Opcodes.INVOKEVIRTUAL, factory.stringMembers.equals, false));
             instructions.add(new CfIf(If.Type.EQ, ValueType.INT, dest));
-            instructions.add(new CfConstNumber(enumValueInfo.convertToInt(), ValueType.INT));
+            instructions.add(new CfConstNumber(unboxedEnumValue, ValueType.INT));
             instructions.add(new CfReturn(ValueType.INT));
             instructions.add(dest);
             instructions.add(new CfFrame(locals, ImmutableDeque.of()));