Logic for rewriting instance initializer info with a lens
Change-Id: Iea6881ddae03620d5a41deff8d37ef45190910fb
Bug: 150193407
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 c6a9a8b..4fd96f7 100644
--- a/src/main/java/com/android/tools/r8/graph/EnumValueInfoMapCollection.java
+++ b/src/main/java/com/android/tools/r8/graph/EnumValueInfoMapCollection.java
@@ -114,6 +114,10 @@
this.ordinal = ordinal;
}
+ public int convertToInt() {
+ return ordinal + 1;
+ }
+
EnumValueInfo rewrittenWithLens(GraphLense lens) {
DexType newType = lens.lookupType(type);
if (type == newType) {
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/AbstractFieldSet.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/AbstractFieldSet.java
index 90320b7..c6e42b6 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/AbstractFieldSet.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/AbstractFieldSet.java
@@ -4,7 +4,9 @@
package com.android.tools.r8.ir.analysis.fieldvalueanalysis;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedField;
+import com.android.tools.r8.graph.GraphLense;
/**
* Implements a lifted subset lattice for fields.
@@ -42,6 +44,8 @@
public abstract boolean contains(DexEncodedField field);
+ public abstract boolean isEmpty();
+
public boolean isBottom() {
return false;
}
@@ -65,4 +69,6 @@
public final boolean strictlyLessThan(AbstractFieldSet other) {
return lessThanOrEqual(other) && !equals(other);
}
+
+ public abstract AbstractFieldSet rewrittenWithLens(AppView<?> appView, GraphLense lens);
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/ConcreteMutableFieldSet.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/ConcreteMutableFieldSet.java
index bc13aa1..a2a932c 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/ConcreteMutableFieldSet.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/ConcreteMutableFieldSet.java
@@ -4,7 +4,9 @@
package com.android.tools.r8.ir.analysis.fieldvalueanalysis;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedField;
+import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.SetUtils;
import com.google.common.collect.Sets;
@@ -65,6 +67,26 @@
}
@Override
+ public AbstractFieldSet rewrittenWithLens(AppView<?> appView, GraphLense lens) {
+ assert !isEmpty();
+ ConcreteMutableFieldSet rewrittenSet = new ConcreteMutableFieldSet();
+ for (DexEncodedField field : fields) {
+ DexEncodedField rewrittenField = appView.definitionFor(lens.lookupField(field.field));
+ if (rewrittenField == null) {
+ assert false;
+ continue;
+ }
+ rewrittenSet.add(field);
+ }
+ return rewrittenSet;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return fields.isEmpty();
+ }
+
+ @Override
public int size() {
return fields.size();
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/EmptyFieldSet.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/EmptyFieldSet.java
index c50ded8..73559f3 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/EmptyFieldSet.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/EmptyFieldSet.java
@@ -4,7 +4,9 @@
package com.android.tools.r8.ir.analysis.fieldvalueanalysis;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedField;
+import com.android.tools.r8.graph.GraphLense;
public class EmptyFieldSet extends AbstractFieldSet implements KnownFieldSet {
@@ -37,6 +39,16 @@
}
@Override
+ public AbstractFieldSet rewrittenWithLens(AppView<?> appView, GraphLense lens) {
+ return this;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return true;
+ }
+
+ @Override
public int size() {
return 0;
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/UnknownFieldSet.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/UnknownFieldSet.java
index 9df87cc..f083438 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/UnknownFieldSet.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/UnknownFieldSet.java
@@ -4,7 +4,9 @@
package com.android.tools.r8.ir.analysis.fieldvalueanalysis;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedField;
+import com.android.tools.r8.graph.GraphLense;
public class UnknownFieldSet extends AbstractFieldSet {
@@ -22,7 +24,17 @@
}
@Override
+ public boolean isEmpty() {
+ return false;
+ }
+
+ @Override
public boolean isTop() {
return true;
}
+
+ @Override
+ public AbstractFieldSet rewrittenWithLens(AppView<?> appView, GraphLense lens) {
+ return this;
+ }
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/AbstractValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/AbstractValue.java
index 5371255..83a0525 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/AbstractValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/AbstractValue.java
@@ -4,6 +4,10 @@
package com.android.tools.r8.ir.analysis.value;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
+
public abstract class AbstractValue {
public abstract boolean isNonTrivial();
@@ -85,6 +89,9 @@
return UnknownValue.getInstance();
}
+ public abstract AbstractValue rewrittenWithLens(
+ AppView<AppInfoWithLiveness> appView, GraphLense lens);
+
@Override
public abstract boolean equals(Object o);
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/BottomValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/BottomValue.java
index ca376e7..f5b27f7 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/BottomValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/BottomValue.java
@@ -4,6 +4,10 @@
package com.android.tools.r8.ir.analysis.value;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
+
public class BottomValue extends AbstractValue {
private static final BottomValue INSTANCE = new BottomValue();
@@ -20,6 +24,11 @@
}
@Override
+ public AbstractValue rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+ return this;
+ }
+
+ @Override
public boolean isNonTrivial() {
return true;
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleConstClassValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleConstClassValue.java
index a6bf499..6261b05 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleConstClassValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleConstClassValue.java
@@ -13,12 +13,14 @@
import com.android.tools.r8.graph.DebugLocalInfo;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
import com.android.tools.r8.ir.code.ConstClass;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.TypeAndLocalInfoSupplier;
import com.android.tools.r8.ir.code.Value;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
public class SingleConstClassValue extends SingleValue {
@@ -88,4 +90,10 @@
assert baseType.isPrimitiveType();
return true;
}
+
+ @Override
+ public SingleValue rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+ assert lens.lookupType(type) == type;
+ return this;
+ }
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleEnumValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleEnumValue.java
index 313f977..4beb525 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleEnumValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleEnumValue.java
@@ -4,7 +4,11 @@
package com.android.tools.r8.ir.analysis.value;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexField;
+import com.android.tools.r8.graph.EnumValueInfoMapCollection.EnumValueInfoMap;
+import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
public class SingleEnumValue extends SingleFieldValue {
@@ -27,4 +31,18 @@
public String toString() {
return "SingleEnumValue(" + getField().toSourceString() + ")";
}
+
+ @Override
+ public SingleValue rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+ DexField field = getField();
+ EnumValueInfoMap unboxedEnumInfo = appView.unboxedEnums().getEnumValueInfoMap(field.type);
+ if (unboxedEnumInfo != null) {
+ // Return the ordinal of the unboxed enum.
+ assert unboxedEnumInfo.hasEnumValueInfo(field);
+ return appView
+ .abstractValueFactory()
+ .createSingleNumberValue(unboxedEnumInfo.getEnumValueInfo(field).convertToInt());
+ }
+ return appView.abstractValueFactory().createSingleEnumValue(lens.lookupField(field));
+ }
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleFieldValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleFieldValue.java
index 0adfe65..c549f6c 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleFieldValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleFieldValue.java
@@ -12,12 +12,14 @@
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.StaticGet;
import com.android.tools.r8.ir.code.TypeAndLocalInfoSupplier;
import com.android.tools.r8.ir.code.Value;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
public class SingleFieldValue extends SingleValue {
@@ -72,4 +74,10 @@
return isMemberVisibleFromOriginalContext(
appView, context, encodedField.field.holder, encodedField.accessFlags);
}
+
+ @Override
+ public SingleValue rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+ assert !appView.unboxedEnums().containsEnum(field.holder);
+ return appView.abstractValueFactory().createSingleFieldValue(lens.lookupField(field));
+ }
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleNumberValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleNumberValue.java
index 4a5ad60..df49b54 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleNumberValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleNumberValue.java
@@ -8,12 +8,14 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DebugLocalInfo;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
import com.android.tools.r8.ir.code.ConstNumber;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.TypeAndLocalInfoSupplier;
import com.android.tools.r8.ir.code.Value;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
public class SingleNumberValue extends SingleValue {
@@ -79,4 +81,9 @@
public boolean isMaterializableInContext(AppView<?> appView, DexType context) {
return true;
}
+
+ @Override
+ public SingleValue rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+ return this;
+ }
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleStringValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleStringValue.java
index 417fe19..9564584 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleStringValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleStringValue.java
@@ -12,6 +12,7 @@
import com.android.tools.r8.graph.DebugLocalInfo;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
import com.android.tools.r8.ir.code.BasicBlock.ThrowingInfo;
import com.android.tools.r8.ir.code.ConstString;
@@ -19,6 +20,7 @@
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.TypeAndLocalInfoSupplier;
import com.android.tools.r8.ir.code.Value;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
public class SingleStringValue extends SingleValue {
@@ -84,4 +86,9 @@
public boolean isMaterializableInContext(AppView<?> appView, DexType context) {
return true;
}
+
+ @Override
+ public SingleValue rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+ return this;
+ }
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleValue.java
index c7b249f..6bb2942 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleValue.java
@@ -7,10 +7,12 @@
import com.android.tools.r8.graph.AppInfoWithSubtyping;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.TypeAndLocalInfoSupplier;
import com.android.tools.r8.ir.optimize.info.field.InstanceFieldInitializationInfo;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
public abstract class SingleValue extends AbstractValue implements InstanceFieldInitializationInfo {
@@ -37,4 +39,8 @@
AppView<? extends AppInfoWithSubtyping> appView, IRCode code, TypeAndLocalInfoSupplier info);
public abstract boolean isMaterializableInContext(AppView<?> appView, DexType context);
+
+ @Override
+ public abstract SingleValue rewrittenWithLens(
+ AppView<AppInfoWithLiveness> appView, GraphLense lens);
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/UnknownValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/UnknownValue.java
index 216ea99..2b4f841 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/UnknownValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/UnknownValue.java
@@ -4,6 +4,10 @@
package com.android.tools.r8.ir.analysis.value;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
+
public class UnknownValue extends AbstractValue {
private static final UnknownValue INSTANCE = new UnknownValue();
@@ -25,6 +29,11 @@
}
@Override
+ public AbstractValue rewrittenWithLens(AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+ return this;
+ }
+
+ @Override
public boolean equals(Object o) {
return this == o;
}
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 9dd958f..038bc33 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
@@ -700,7 +700,7 @@
}
if (enumUnboxer != null) {
enumUnboxer.finishAnalysis();
- enumUnboxer.unboxEnums(postMethodProcessorBuilder);
+ enumUnboxer.unboxEnums(postMethodProcessorBuilder, executorService, feedback);
}
timing.begin("IR conversion phase 2");
graphLenseForIR = appView.graphLense();
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 1aa0955..e96b211 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
@@ -38,6 +38,10 @@
import com.android.tools.r8.ir.conversion.IRConverter;
import com.android.tools.r8.ir.conversion.PostMethodProcessor;
import com.android.tools.r8.ir.conversion.PostOptimization;
+import com.android.tools.r8.ir.optimize.info.FieldOptimizationInfo;
+import com.android.tools.r8.ir.optimize.info.MethodOptimizationInfo;
+import com.android.tools.r8.ir.optimize.info.OptimizationFeedback.OptimizationInfoFixer;
+import com.android.tools.r8.ir.optimize.info.OptimizationFeedbackDelayed;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.Reporter;
@@ -227,7 +231,11 @@
return Reason.ELIGIBLE;
}
- public void unboxEnums(PostMethodProcessor.Builder postBuilder) {
+ public void unboxEnums(
+ PostMethodProcessor.Builder postBuilder,
+ ExecutorService executorService,
+ OptimizationFeedbackDelayed feedback)
+ throws ExecutionException {
// At this point the enumsToUnbox are no longer candidates, they will all be unboxed.
if (enumsUnboxingCandidates.isEmpty()) {
return;
@@ -242,6 +250,37 @@
appView
.appInfo()
.rewrittenWithLens(appView.appInfo().app().asDirect(), enumUnboxingLens));
+
+ // Update optimization info.
+ feedback.fixupOptimizationInfos(
+ appView,
+ executorService,
+ new OptimizationInfoFixer() {
+ @Override
+ public void fixup(DexEncodedField field) {
+ FieldOptimizationInfo optimizationInfo = field.getOptimizationInfo();
+ if (optimizationInfo.isMutableFieldOptimizationInfo()) {
+ optimizationInfo
+ .asMutableFieldOptimizationInfo()
+ .fixupAbstractValue(appView, appView.graphLense());
+ } else {
+ assert optimizationInfo.isDefaultFieldOptimizationInfo();
+ }
+ }
+
+ @Override
+ public void fixup(DexEncodedMethod method) {
+ MethodOptimizationInfo optimizationInfo = method.getOptimizationInfo();
+ if (optimizationInfo.isUpdatableMethodOptimizationInfo()) {
+ optimizationInfo
+ .asUpdatableMethodOptimizationInfo()
+ .fixupAbstractReturnValue(appView, appView.graphLense())
+ .fixupInstanceInitializerInfo(appView, appView.graphLense());
+ } else {
+ assert optimizationInfo.isDefaultMethodOptimizationInfo();
+ }
+ }
+ });
}
postBuilder.put(this);
postBuilder.mapDexEncodedMethods(appView);
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 c05f41b..cbd3824 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
@@ -121,7 +121,7 @@
EnumValueInfo enumValueInfo = enumValueInfoMap.getEnumValueInfo(staticGet.getField());
assert enumValueInfo != null
: "Invalid read to " + staticGet.getField().name + ", error during enum analysis";
- instruction = new ConstNumber(staticGet.outValue(), enumValueInfo.ordinal + 1);
+ instruction = new ConstNumber(staticGet.outValue(), enumValueInfo.convertToInt());
staticGet
.outValue()
.setTypeLattice(PrimitiveTypeLatticeElement.fromNumericType(NumericType.INT));
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/MutableFieldOptimizationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/MutableFieldOptimizationInfo.java
index 33c7b2a..0626a7b 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/MutableFieldOptimizationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/MutableFieldOptimizationInfo.java
@@ -7,10 +7,12 @@
import com.android.tools.r8.graph.AppInfoWithSubtyping;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.analysis.type.ClassTypeLatticeElement;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
import com.android.tools.r8.ir.analysis.value.AbstractValue;
import com.android.tools.r8.ir.analysis.value.UnknownValue;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
import java.util.function.Function;
/**
@@ -64,6 +66,10 @@
this.abstractValue = abstractValue;
}
+ public void fixupAbstractValue(AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+ abstractValue = abstractValue.rewrittenWithLens(appView, lens);
+ }
+
@Override
public int getReadBits() {
return readBits;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackDelayed.java b/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackDelayed.java
index 3c689a7..c241c0a 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackDelayed.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackDelayed.java
@@ -177,13 +177,7 @@
public synchronized void methodReturnsAbstractValue(
DexEncodedMethod method, AppView<AppInfoWithLiveness> appView, AbstractValue value) {
if (appView.appInfo().mayPropagateValueFor(method.method)) {
- UpdatableMethodOptimizationInfo info = getMethodOptimizationInfoForUpdating(method);
- assert !info.getAbstractReturnValue().isSingleValue()
- || info.getAbstractReturnValue().asSingleValue() == value
- || appView.graphLense().lookupPrototypeChanges(method.method).getRewrittenReturnInfo()
- != null
- : "return single value changed from " + info.getAbstractReturnValue() + " to " + value;
- info.markReturnsAbstractValue(value);
+ getMethodOptimizationInfoForUpdating(method).markReturnsAbstractValue(value);
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/UpdatableMethodOptimizationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/UpdatableMethodOptimizationInfo.java
index 3b2a85b..366b4d2 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/UpdatableMethodOptimizationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/UpdatableMethodOptimizationInfo.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.graph.AppInfoWithSubtyping;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.analysis.type.ClassTypeLatticeElement;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
import com.android.tools.r8.ir.analysis.value.AbstractValue;
@@ -14,6 +15,7 @@
import com.android.tools.r8.ir.optimize.info.ParameterUsagesInfo.ParameterUsage;
import com.android.tools.r8.ir.optimize.info.initializer.DefaultInstanceInitializerInfo;
import com.android.tools.r8.ir.optimize.info.initializer.InstanceInitializerInfo;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.BooleanUtils;
import java.util.BitSet;
import java.util.Set;
@@ -160,6 +162,20 @@
}
}
+ public UpdatableMethodOptimizationInfo fixupAbstractReturnValue(
+ AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+ abstractReturnValue = abstractReturnValue.rewrittenWithLens(appView, lens);
+ return this;
+ }
+
+ public UpdatableMethodOptimizationInfo fixupInstanceInitializerInfo(
+ AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+ if (instanceInitializerInfo != null) {
+ instanceInitializerInfo = instanceInitializerInfo.rewrittenWithLens(appView, lens);
+ }
+ return this;
+ }
+
private void setFlag(int flag, boolean value) {
if (value) {
setFlag(flag);
@@ -384,6 +400,8 @@
}
void markReturnsAbstractValue(AbstractValue value) {
+ assert !abstractReturnValue.isSingleValue() || abstractReturnValue.asSingleValue() == value
+ : "return single value changed from " + abstractReturnValue + " to " + value;
abstractReturnValue = value;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/field/EmptyInstanceFieldInitializationInfoCollection.java b/src/main/java/com/android/tools/r8/ir/optimize/info/field/EmptyInstanceFieldInitializationInfoCollection.java
index 6b3cf4c..fd7a84f 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/field/EmptyInstanceFieldInitializationInfoCollection.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/field/EmptyInstanceFieldInitializationInfoCollection.java
@@ -4,8 +4,11 @@
package com.android.tools.r8.ir.optimize.info.field;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexEncodedField;
+import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
import java.util.function.BiConsumer;
/**
@@ -40,4 +43,10 @@
public boolean isEmpty() {
return true;
}
+
+ @Override
+ public InstanceFieldInitializationInfoCollection rewrittenWithLens(
+ AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+ return this;
+ }
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldArgumentInitializationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldArgumentInitializationInfo.java
index b9e7652..757eec8 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldArgumentInitializationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldArgumentInitializationInfo.java
@@ -4,6 +4,10 @@
package com.android.tools.r8.ir.optimize.info.field;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
+
/**
* Used to represent that a constructor initializes an instance field on the newly created instance
* with argument number {@link #argumentIndex} from the constructor's argument list.
@@ -30,4 +34,13 @@
public InstanceFieldArgumentInitializationInfo asArgumentInitializationInfo() {
return this;
}
+
+ @Override
+ public InstanceFieldInitializationInfo rewrittenWithLens(
+ AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+ // We don't have the context here to determine what should happen. It is the responsibility of
+ // optimizations that change the proto of instance initializers to update the argument
+ // initialization info.
+ return this;
+ }
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldInitializationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldInitializationInfo.java
index 2e9285a..37757f1 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldInitializationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldInitializationInfo.java
@@ -4,7 +4,10 @@
package com.android.tools.r8.ir.optimize.info.field;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.analysis.value.SingleValue;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
/**
* Information about the way a constructor initializes an instance field on the newly created
@@ -42,4 +45,7 @@
default boolean isUnknown() {
return false;
}
+
+ InstanceFieldInitializationInfo rewrittenWithLens(
+ AppView<AppInfoWithLiveness> appView, GraphLense lens);
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldInitializationInfoCollection.java b/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldInitializationInfoCollection.java
index ed1c4d3..6bf4c74 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldInitializationInfoCollection.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldInitializationInfoCollection.java
@@ -4,9 +4,12 @@
package com.android.tools.r8.ir.optimize.info.field;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexField;
+import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.function.BiConsumer;
@@ -32,6 +35,9 @@
public abstract boolean isEmpty();
+ public abstract InstanceFieldInitializationInfoCollection rewrittenWithLens(
+ AppView<AppInfoWithLiveness> appView, GraphLense lens);
+
public static class Builder {
Map<DexField, InstanceFieldInitializationInfo> infos = new IdentityHashMap<>();
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldTypeInitializationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldTypeInitializationInfo.java
index e6f84ff..91d1aef 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldTypeInitializationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/field/InstanceFieldTypeInitializationInfo.java
@@ -4,8 +4,12 @@
package com.android.tools.r8.ir.optimize.info.field;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.EnumValueInfoMapCollection;
+import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.analysis.type.ClassTypeLatticeElement;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
import java.util.Objects;
/**
@@ -43,6 +47,30 @@
}
@Override
+ public InstanceFieldInitializationInfo rewrittenWithLens(
+ AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+ EnumValueInfoMapCollection unboxedEnums = appView.unboxedEnums();
+ if (dynamicLowerBoundType != null
+ && unboxedEnums.containsEnum(dynamicLowerBoundType.getClassType())) {
+ // No point in tracking the type of primitives.
+ return UnknownInstanceFieldInitializationInfo.getInstance();
+ }
+ if (dynamicUpperBoundType.isClassType()
+ && unboxedEnums.containsEnum(
+ dynamicUpperBoundType.asClassTypeLatticeElement().getClassType())) {
+ // No point in tracking the type of primitives.
+ return UnknownInstanceFieldInitializationInfo.getInstance();
+ }
+ return new InstanceFieldTypeInitializationInfo(
+ dynamicLowerBoundType != null
+ ? dynamicLowerBoundType
+ .fixupClassTypeReferences(lens::lookupType, appView.withSubtyping())
+ .asClassTypeLatticeElement()
+ : null,
+ dynamicUpperBoundType.fixupClassTypeReferences(lens::lookupType, appView.withSubtyping()));
+ }
+
+ @Override
public int hashCode() {
return Objects.hash(dynamicLowerBoundType, dynamicUpperBoundType);
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/field/NonTrivialInstanceFieldInitializationInfoCollection.java b/src/main/java/com/android/tools/r8/ir/optimize/info/field/NonTrivialInstanceFieldInitializationInfoCollection.java
index 5883be6..7c7a563 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/field/NonTrivialInstanceFieldInitializationInfoCollection.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/field/NonTrivialInstanceFieldInitializationInfoCollection.java
@@ -4,9 +4,13 @@
package com.android.tools.r8.ir.optimize.info.field;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexField;
+import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import java.util.IdentityHashMap;
import java.util.Map;
import java.util.function.BiConsumer;
@@ -47,4 +51,17 @@
public boolean isEmpty() {
return false;
}
+
+ @Override
+ public InstanceFieldInitializationInfoCollection rewrittenWithLens(
+ AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+ Map<DexField, InstanceFieldInitializationInfo> rewrittenInfos = new IdentityHashMap<>();
+ infos.forEach(
+ (field, info) -> {
+ DexField rewrittenField = lens.lookupField(field);
+ InstanceFieldInitializationInfo rewrittenInfo = info.rewrittenWithLens(appView, lens);
+ rewrittenInfos.put(rewrittenField, rewrittenInfo);
+ });
+ return new NonTrivialInstanceFieldInitializationInfoCollection(rewrittenInfos);
+ }
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/field/UnknownInstanceFieldInitializationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/field/UnknownInstanceFieldInitializationInfo.java
index a10f045..b2b6ce9 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/field/UnknownInstanceFieldInitializationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/field/UnknownInstanceFieldInitializationInfo.java
@@ -4,6 +4,10 @@
package com.android.tools.r8.ir.optimize.info.field;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
+
/**
* Represents that no information is known about the way a particular constructor initializes an
* instance field of the newly created instance.
@@ -23,4 +27,10 @@
public boolean isUnknown() {
return true;
}
+
+ @Override
+ public InstanceFieldInitializationInfo rewrittenWithLens(
+ AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+ return this;
+ }
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/DefaultInstanceInitializerInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/DefaultInstanceInitializerInfo.java
index 20aff53..4065fb0 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/DefaultInstanceInitializerInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/DefaultInstanceInitializerInfo.java
@@ -4,11 +4,14 @@
package com.android.tools.r8.ir.optimize.info.initializer;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.analysis.fieldvalueanalysis.AbstractFieldSet;
import com.android.tools.r8.ir.analysis.fieldvalueanalysis.UnknownFieldSet;
import com.android.tools.r8.ir.optimize.info.field.EmptyInstanceFieldInitializationInfoCollection;
import com.android.tools.r8.ir.optimize.info.field.InstanceFieldInitializationInfoCollection;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
public class DefaultInstanceInitializerInfo extends InstanceInitializerInfo {
@@ -22,11 +25,6 @@
}
@Override
- public boolean isDefaultInfo() {
- return true;
- }
-
- @Override
public DexMethod getParent() {
return null;
}
@@ -55,4 +53,10 @@
public boolean receiverNeverEscapesOutsideConstructorChain() {
return false;
}
+
+ @Override
+ public InstanceInitializerInfo rewrittenWithLens(
+ AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+ return this;
+ }
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/InstanceInitializerInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/InstanceInitializerInfo.java
index b27888e..1745e7d 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/InstanceInitializerInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/InstanceInitializerInfo.java
@@ -4,9 +4,12 @@
package com.android.tools.r8.ir.optimize.info.initializer;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.analysis.fieldvalueanalysis.AbstractFieldSet;
import com.android.tools.r8.ir.optimize.info.field.InstanceFieldInitializationInfoCollection;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
public abstract class InstanceInitializerInfo {
@@ -53,7 +56,6 @@
return !receiverNeverEscapesOutsideConstructorChain();
}
- public boolean isDefaultInfo() {
- return false;
- }
+ public abstract InstanceInitializerInfo rewrittenWithLens(
+ AppView<AppInfoWithLiveness> appView, GraphLense lens);
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/NonTrivialInstanceInitializerInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/NonTrivialInstanceInitializerInfo.java
index 4e19cef..f549927 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/NonTrivialInstanceInitializerInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/initializer/NonTrivialInstanceInitializerInfo.java
@@ -4,13 +4,16 @@
package com.android.tools.r8.ir.optimize.info.initializer;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.analysis.fieldvalueanalysis.AbstractFieldSet;
import com.android.tools.r8.ir.analysis.fieldvalueanalysis.ConcreteMutableFieldSet;
import com.android.tools.r8.ir.analysis.fieldvalueanalysis.EmptyFieldSet;
import com.android.tools.r8.ir.analysis.fieldvalueanalysis.UnknownFieldSet;
import com.android.tools.r8.ir.optimize.info.field.InstanceFieldInitializationInfoCollection;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
public final class NonTrivialInstanceInitializerInfo extends InstanceInitializerInfo {
@@ -79,6 +82,16 @@
return (data & RECEIVER_NEVER_ESCAPE_OUTSIDE_CONSTRUCTOR_CHAIN) != 0;
}
+ @Override
+ public NonTrivialInstanceInitializerInfo rewrittenWithLens(
+ AppView<AppInfoWithLiveness> appView, GraphLense lens) {
+ return new NonTrivialInstanceInitializerInfo(
+ data,
+ fieldInitializationInfos.rewrittenWithLens(appView, lens),
+ readSet.rewrittenWithLens(appView, lens),
+ lens.getRenamedMethodSignature(parent));
+ }
+
public static class Builder {
private final InstanceFieldInitializationInfoCollection instanceFieldInitializationInfos;