Remove EnumValueInfoMap
Bug: 172528424
Change-Id: Iea6e485809987850aac711042238f3dd87823ff1
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index dc81ff4..089c747 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -61,7 +61,6 @@
import com.android.tools.r8.ir.optimize.UnusedArgumentsCollector;
import com.android.tools.r8.ir.optimize.UnusedArgumentsCollector.UnusedArgumentsGraphLens;
import com.android.tools.r8.ir.optimize.enums.EnumUnboxingCfMethods;
-import com.android.tools.r8.ir.optimize.enums.EnumValueInfoMapCollector;
import com.android.tools.r8.ir.optimize.info.OptimizationFeedbackSimple;
import com.android.tools.r8.ir.optimize.templates.CfUtilityMethodsForCodeOptimizations;
import com.android.tools.r8.jar.CfApplicationWriter;
@@ -617,9 +616,6 @@
if (options.enableEnumSwitchMapRemoval) {
appViewWithLiveness.setAppInfo(new SwitchMapCollector(appViewWithLiveness).run());
}
- if (options.enableEnumValueOptimization || options.enableEnumUnboxing) {
- appViewWithLiveness.setAppInfo(new EnumValueInfoMapCollector(appViewWithLiveness).run());
- }
// Collect the already pruned types before creating a new app info without liveness.
// TODO: we should avoid removing liveness.
diff --git a/src/main/java/com/android/tools/r8/graph/EnumValueInfoMapCollection.java b/src/main/java/com/android/tools/r8/graph/EnumValueInfoMapCollection.java
deleted file mode 100644
index 40e6286..0000000
--- a/src/main/java/com/android/tools/r8/graph/EnumValueInfoMapCollection.java
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-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;
-import java.util.Set;
-import java.util.function.BiConsumer;
-
-public class EnumValueInfoMapCollection {
-
- public static EnumValueInfoMapCollection empty() {
- return new EnumValueInfoMapCollection(ImmutableMap.of());
- }
-
- private final Map<DexType, EnumValueInfoMap> maps;
-
- private EnumValueInfoMapCollection(Map<DexType, EnumValueInfoMap> maps) {
- this.maps = maps;
- }
-
- public EnumValueInfoMap getEnumValueInfoMap(DexType type) {
- return maps.get(type);
- }
-
- public boolean isEmpty() {
- return maps.isEmpty();
- }
-
- public boolean containsEnum(DexType type) {
- return maps.containsKey(type);
- }
-
- public Set<DexType> enumSet() {
- return maps.keySet();
- }
-
- public EnumValueInfoMapCollection rewrittenWithLens(GraphLens lens) {
- Builder builder = builder();
- maps.forEach(
- (type, map) -> {
- DexType dexType = lens.lookupType(type);
- // Enum unboxing may have changed the type to int type.
- // Do not keep the map for such enums.
- if (!dexType.isPrimitiveType()) {
- builder.put(dexType, map.rewrittenWithLens(lens));
- }
- });
- return builder.build();
- }
-
- public static Builder builder() {
- return new Builder();
- }
-
- public static class Builder {
-
- private ImmutableMap.Builder<DexType, EnumValueInfoMap> builder;
-
- public Builder put(DexType type, EnumValueInfoMap map) {
- if (builder == null) {
- builder = ImmutableMap.builder();
- }
- builder.put(type, map);
- return this;
- }
-
- public EnumValueInfoMapCollection build() {
- if (builder == null) {
- return empty();
- }
- return new EnumValueInfoMapCollection(builder.build());
- }
- }
-
- public static final class EnumValueInfoMap {
-
- private final LinkedHashMap<DexField, EnumValueInfo> map;
-
- public EnumValueInfoMap(LinkedHashMap<DexField, EnumValueInfo> map) {
- this.map = map;
- }
-
- public Set<DexField> enumValues() {
- return map.keySet();
- }
-
- public int size() {
- return map.size();
- }
-
- public boolean hasEnumValueInfo(DexField field) {
- return map.containsKey(field);
- }
-
- public EnumValueInfo getEnumValueInfo(DexField field) {
- return map.get(field);
- }
-
- public void forEach(BiConsumer<DexField, EnumValueInfo> consumer) {
- map.forEach(consumer);
- }
-
- EnumValueInfoMap rewrittenWithLens(GraphLens lens) {
- LinkedHashMap<DexField, EnumValueInfo> rewritten = new LinkedHashMap<>();
- map.forEach(
- (field, valueInfo) ->
- rewritten.put(lens.lookupField(field), valueInfo.rewrittenWithLens(lens)));
- return new EnumValueInfoMap(rewritten);
- }
- }
-
- public static final class EnumValueInfo {
-
- // The anonymous subtype of this specific value or the enum type.
- public final DexType type;
- public final int ordinal;
-
- public EnumValueInfo(DexType type, int ordinal) {
- this.type = type;
- this.ordinal = ordinal;
- }
-
- public int convertToInt() {
- return EnumUnboxer.ordinalToUnboxedInt(ordinal);
- }
-
- EnumValueInfo rewrittenWithLens(GraphLens lens) {
- DexType newType = lens.lookupType(type);
- if (type == newType) {
- return this;
- }
- return new EnumValueInfo(newType, ordinal);
- }
- }
-}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumValueInfoMapCollector.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumValueInfoMapCollector.java
deleted file mode 100644
index c94be2e..0000000
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumValueInfoMapCollector.java
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.android.tools.r8.ir.optimize.enums;
-
-import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexField;
-import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.EnumValueInfoMapCollection;
-import com.android.tools.r8.graph.EnumValueInfoMapCollection.EnumValueInfo;
-import com.android.tools.r8.graph.EnumValueInfoMapCollection.EnumValueInfoMap;
-import com.android.tools.r8.graph.ProgramMethod;
-import com.android.tools.r8.ir.code.IRCode;
-import com.android.tools.r8.ir.code.Instruction;
-import com.android.tools.r8.ir.code.InvokeDirect;
-import com.android.tools.r8.ir.code.StaticPut;
-import com.android.tools.r8.shaking.AppInfoWithLiveness;
-import java.util.LinkedHashMap;
-
-/**
- * Extracts the ordinal values and any anonymous subtypes for all Enum classes from their static
- * initializer.
- *
- * <p>An Enum class has a field for each value. In the class initializer, each field is initialized
- * to a singleton object that represents the value. This code matches on the corresponding call to
- * the constructor (instance initializer) and extracts the value of the second argument, which is
- * the ordinal and the holder which is the concrete type.
- */
-public class EnumValueInfoMapCollector {
-
- private final AppView<AppInfoWithLiveness> appView;
-
- private final EnumValueInfoMapCollection.Builder valueInfoMapsBuilder =
- EnumValueInfoMapCollection.builder();
-
- public EnumValueInfoMapCollector(AppView<AppInfoWithLiveness> appView) {
- this.appView = appView;
- }
-
- public AppInfoWithLiveness run() {
- for (DexProgramClass clazz : appView.appInfo().classes()) {
- processClasses(clazz);
- }
- EnumValueInfoMapCollection valueInfoMaps = valueInfoMapsBuilder.build();
- if (!valueInfoMaps.isEmpty()) {
- return appView.appInfo().withEnumValueInfoMaps(valueInfoMaps);
- }
- return appView.appInfo();
- }
-
- private void processClasses(DexProgramClass clazz) {
- // Enum classes are flagged as such. Also, for library classes, the ordinals are not known.
- if (!clazz.accessFlags.isEnum() || clazz.isNotProgramClass() || !clazz.hasClassInitializer()) {
- return;
- }
- ProgramMethod initializer = clazz.getProgramClassInitializer();
- IRCode code = initializer.buildIR(appView);
- LinkedHashMap<DexField, EnumValueInfo> enumValueInfoMap = new LinkedHashMap<>();
- for (StaticPut staticPut : code.<StaticPut>instructions(Instruction::isStaticPut)) {
- if (staticPut.getField().type != clazz.type) {
- continue;
- }
- Instruction newInstance = staticPut.value().definition;
- if (newInstance == null || !newInstance.isNewInstance()) {
- continue;
- }
- Instruction ordinal = null;
- DexType type = null;
- for (Instruction ctorCall : newInstance.outValue().uniqueUsers()) {
- if (!ctorCall.isInvokeDirect()) {
- continue;
- }
- InvokeDirect invoke = ctorCall.asInvokeDirect();
- if (!appView.dexItemFactory().isConstructor(invoke.getInvokedMethod())
- || invoke.arguments().size() < 3) {
- continue;
- }
- ordinal = invoke.arguments().get(2).definition;
- type = invoke.getInvokedMethod().holder;
- break;
- }
- if (ordinal == null || !ordinal.isConstNumber() || type == null) {
- return;
- }
-
- EnumValueInfo info = new EnumValueInfo(type, ordinal.asConstNumber().getIntValue());
- if (enumValueInfoMap.put(staticPut.getField(), info) != null) {
- return;
- }
- }
- valueInfoMapsBuilder.put(clazz.type, new EnumValueInfoMap(enumValueInfoMap));
- }
-}
diff --git a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
index 4fc8f54..7f93d17 100644
--- a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
+++ b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
@@ -25,7 +25,6 @@
import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DirectMappedDexApplication;
-import com.android.tools.r8.graph.EnumValueInfoMapCollection;
import com.android.tools.r8.graph.FieldAccessInfo;
import com.android.tools.r8.graph.FieldAccessInfoCollection;
import com.android.tools.r8.graph.FieldAccessInfoCollectionImpl;
@@ -181,8 +180,6 @@
final Set<DexType> prunedTypes;
/** A map from switchmap class types to their corresponding switchmaps. */
final Map<DexField, Int2ReferenceMap<DexField>> switchMaps;
- /** A map from enum types to their value types and ordinals. */
- final EnumValueInfoMapCollection enumValueInfoMaps;
/* A cache to improve the lookup performance of lookupSingleVirtualTarget */
private final SingleTargetLookupCache singleTargetLookupCache = new SingleTargetLookupCache();
@@ -227,7 +224,6 @@
Object2BooleanMap<DexReference> identifierNameStrings,
Set<DexType> prunedTypes,
Map<DexField, Int2ReferenceMap<DexField>> switchMaps,
- EnumValueInfoMapCollection enumValueInfoMaps,
Set<DexType> lockCandidates,
Map<DexType, Visibility> initClassReferences) {
super(syntheticItems, classToFeatureSplitMap, mainDexClasses);
@@ -266,7 +262,6 @@
this.identifierNameStrings = identifierNameStrings;
this.prunedTypes = prunedTypes;
this.switchMaps = switchMaps;
- this.enumValueInfoMaps = enumValueInfoMaps;
this.lockCandidates = lockCandidates;
this.initClassReferences = initClassReferences;
verify();
@@ -314,7 +309,6 @@
previous.identifierNameStrings,
previous.prunedTypes,
previous.switchMaps,
- previous.enumValueInfoMaps,
previous.lockCandidates,
previous.initClassReferences);
}
@@ -363,7 +357,6 @@
? CollectionUtils.mergeSets(previous.prunedTypes, prunedItems.getRemovedClasses())
: previous.prunedTypes,
previous.switchMaps,
- previous.enumValueInfoMaps,
previous.lockCandidates,
previous.initClassReferences);
}
@@ -411,9 +404,7 @@
}
public AppInfoWithLiveness(
- AppInfoWithLiveness previous,
- Map<DexField, Int2ReferenceMap<DexField>> switchMaps,
- EnumValueInfoMapCollection enumValueInfoMaps) {
+ AppInfoWithLiveness previous, Map<DexField, Int2ReferenceMap<DexField>> switchMaps) {
super(
previous.getSyntheticItems().commit(previous.app()),
previous.getClassToFeatureSplitMap(),
@@ -453,7 +444,6 @@
this.identifierNameStrings = previous.identifierNameStrings;
this.prunedTypes = previous.prunedTypes;
this.switchMaps = switchMaps;
- this.enumValueInfoMaps = enumValueInfoMaps;
this.lockCandidates = previous.lockCandidates;
this.initClassReferences = previous.initClassReferences;
previous.markObsolete();
@@ -1006,7 +996,6 @@
// Don't rewrite pruned types - the removed types are identified by their original name.
prunedTypes,
lens.rewriteFieldKeys(switchMaps),
- enumValueInfoMaps.rewrittenWithLens(lens),
lens.rewriteTypes(lockCandidates),
lens.rewriteTypeKeys(initClassReferences));
}
@@ -1211,13 +1200,7 @@
public AppInfoWithLiveness withSwitchMaps(Map<DexField, Int2ReferenceMap<DexField>> switchMaps) {
assert checkIfObsolete();
assert this.switchMaps.isEmpty();
- return new AppInfoWithLiveness(this, switchMaps, enumValueInfoMaps);
- }
-
- public AppInfoWithLiveness withEnumValueInfoMaps(EnumValueInfoMapCollection enumValueInfoMaps) {
- assert checkIfObsolete();
- assert this.enumValueInfoMaps.isEmpty();
- return new AppInfoWithLiveness(this, switchMaps, enumValueInfoMaps);
+ return new AppInfoWithLiveness(this, switchMaps);
}
/**
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index 4b43e18..095ba07 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -47,7 +47,6 @@
import com.android.tools.r8.graph.DirectMappedDexApplication;
import com.android.tools.r8.graph.DirectMappedDexApplication.Builder;
import com.android.tools.r8.graph.EnclosingMethodAttribute;
-import com.android.tools.r8.graph.EnumValueInfoMapCollection;
import com.android.tools.r8.graph.FieldAccessInfoCollectionImpl;
import com.android.tools.r8.graph.FieldAccessInfoImpl;
import com.android.tools.r8.graph.FieldResolutionResult;
@@ -3337,7 +3336,6 @@
joinIdentifierNameStrings(rootSet.identifierNameStrings, identifierNameStrings),
Collections.emptySet(),
Collections.emptyMap(),
- EnumValueInfoMapCollection.empty(),
lockCandidates,
initClassReferences);
appInfo.markObsolete();