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()));