Revert "Avoid wrapping/unwrapping array object state"
This reverts commit a7406a58f4d7dedbdc6ac1018d60b5ebdc904a0b.
Reason for revert: Breaks build
Change-Id: Ia413a58f2cff6ca6948cdb5b1ed1e59f7e8b247f
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/StaticFieldValueAnalysis.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/StaticFieldValueAnalysis.java
index 21c51a6..80a4124 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/StaticFieldValueAnalysis.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/StaticFieldValueAnalysis.java
@@ -26,6 +26,7 @@
import com.android.tools.r8.ir.analysis.value.UnknownValue;
import com.android.tools.r8.ir.analysis.value.objectstate.EnumValuesObjectState;
import com.android.tools.r8.ir.analysis.value.objectstate.ObjectState;
+import com.android.tools.r8.ir.analysis.value.objectstate.ObjectStateAnalysis;
import com.android.tools.r8.ir.code.ArrayPut;
import com.android.tools.r8.ir.code.FieldInstruction;
import com.android.tools.r8.ir.code.IRCode;
@@ -195,7 +196,7 @@
}
return appView
.abstractValueFactory()
- .createSingleFieldValue(field.getReference(), value.computeObjectState(appView, context));
+ .createSingleFieldValue(field.getReference(), computeObjectState(value));
}
/**
@@ -351,8 +352,9 @@
// TODO(b/169050248): We could consider analysing these to answer the object state here.
return false;
}
- ObjectState objectState = root.computeObjectState(appView, context);
- if (objectState.isEmpty()) {
+ ObjectState objectState =
+ definition.isNewInstance() ? computeObjectState(definition.outValue()) : null;
+ if (objectState == null || objectState.isEmpty()) {
// We need the state of all fields for the analysis to be valuable.
return false;
}
@@ -444,8 +446,12 @@
return appView
.abstractValueFactory()
- .createSingleFieldValue(
- enumField.getReference(), value.computeObjectState(appView, context));
+ .createSingleFieldValue(enumField.getReference(), computeObjectState(value));
+ }
+
+ private ObjectState computeObjectState(Value value) {
+ // TODO(b/204159267): Move this logic into Instruction#getAbstractValue in NewInstance.
+ return ObjectStateAnalysis.computeObjectState(value, appView, context);
}
private boolean isEnumValuesArray(Value value) {
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/objectstate/ObjectStateNewInstanceAnalysis.java b/src/main/java/com/android/tools/r8/ir/analysis/value/objectstate/ObjectStateAnalysis.java
similarity index 66%
rename from src/main/java/com/android/tools/r8/ir/analysis/value/objectstate/ObjectStateNewInstanceAnalysis.java
rename to src/main/java/com/android/tools/r8/ir/analysis/value/objectstate/ObjectStateAnalysis.java
index df44057..f694589 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/objectstate/ObjectStateNewInstanceAnalysis.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/objectstate/ObjectStateAnalysis.java
@@ -7,7 +7,8 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.ProgramMethod;
-import com.android.tools.r8.ir.code.AbstractValueSupplier;
+import com.android.tools.r8.ir.analysis.value.AbstractValue;
+import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InvokeDirect;
import com.android.tools.r8.ir.code.NewInstance;
import com.android.tools.r8.ir.code.Value;
@@ -15,13 +16,34 @@
import com.android.tools.r8.ir.optimize.info.field.InstanceFieldInitializationInfoCollection;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
-public class ObjectStateNewInstanceAnalysis {
+public class ObjectStateAnalysis {
- public static ObjectState computeNewInstanceObjectState(
- NewInstance newInstance,
- AppView<AppInfoWithLiveness> appView,
- ProgramMethod context,
- AbstractValueSupplier abstractValueSupplier) {
+ public static ObjectState computeObjectState(
+ Value value, AppView<AppInfoWithLiveness> appView, ProgramMethod context) {
+ Value valueRoot = value.getAliasedValue();
+ if (valueRoot.isDefinedByInstructionSatisfying(
+ i -> i.isNewArrayEmpty() || i.isNewArrayFilledData() || i.isNewArrayFilled())) {
+ return computeNewArrayObjectState(valueRoot, appView, context);
+ }
+ if (valueRoot.isDefinedByInstructionSatisfying(Instruction::isNewInstance)) {
+ return computeNewInstanceObjectState(valueRoot, appView, context);
+ }
+ return ObjectState.empty();
+ }
+
+ private static ObjectState computeNewArrayObjectState(
+ Value value, AppView<AppInfoWithLiveness> appView, ProgramMethod context) {
+ AbstractValue abstractValue = value.getAbstractValue(appView, context);
+ if (abstractValue.isStatefulObjectValue()) {
+ // TODO(b/204272377): Avoid wrapping and unwrapping the object state.
+ return abstractValue.asStatefulObjectValue().getObjectState();
+ }
+ return ObjectState.empty();
+ }
+
+ private static ObjectState computeNewInstanceObjectState(
+ Value value, AppView<AppInfoWithLiveness> appView, ProgramMethod context) {
+ NewInstance newInstance = value.definition.asNewInstance();
InvokeDirect uniqueConstructorInvoke =
newInstance.getUniqueConstructorInvoke(appView.dexItemFactory());
if (uniqueConstructorInvoke == null) {
@@ -62,8 +84,7 @@
initializationInfo.asArgumentInitializationInfo();
Value argument =
uniqueConstructorInvoke.getArgument(argumentInitializationInfo.getArgumentIndex());
- builder.recordFieldHasValue(
- field, abstractValueSupplier.getAbstractValue(argument, appView, context));
+ builder.recordFieldHasValue(field, argument.getAbstractValue(appView, context));
} else if (initializationInfo.isSingleValue()) {
builder.recordFieldHasValue(field, initializationInfo.asSingleValue());
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Assume.java b/src/main/java/com/android/tools/r8/ir/code/Assume.java
index 0a55c89..e29df9f 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Assume.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Assume.java
@@ -14,13 +14,11 @@
import com.android.tools.r8.ir.analysis.type.DynamicTypeWithUpperBound;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.analysis.type.TypeElement;
-import com.android.tools.r8.ir.analysis.value.objectstate.ObjectState;
import com.android.tools.r8.ir.conversion.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
import com.android.tools.r8.ir.optimize.InliningConstraints;
import com.android.tools.r8.lightir.LirBuilder;
-import com.android.tools.r8.shaking.AppInfoWithLiveness;
import java.util.Set;
public class Assume extends Instruction {
@@ -116,14 +114,6 @@
}
@Override
- public ObjectState computeObjectState(
- AppView<AppInfoWithLiveness> appView,
- ProgramMethod context,
- AbstractValueSupplier abstractValueSupplier) {
- return src().computeObjectState(appView, context, abstractValueSupplier);
- }
-
- @Override
public boolean couldIntroduceAnAlias(AppView<?> appView, Value root) {
assert root != null && root.getType().isReferenceType();
assert outValue != null;
diff --git a/src/main/java/com/android/tools/r8/ir/code/Instruction.java b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
index e410c59..565e62f 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Instruction.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
@@ -25,7 +25,6 @@
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.analysis.value.AbstractValue;
import com.android.tools.r8.ir.analysis.value.UnknownValue;
-import com.android.tools.r8.ir.analysis.value.objectstate.ObjectState;
import com.android.tools.r8.ir.conversion.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
import com.android.tools.r8.ir.conversion.MethodConversionOptions;
@@ -207,13 +206,6 @@
return oldOutValue;
}
- public ObjectState computeObjectState(
- AppView<AppInfoWithLiveness> appView,
- ProgramMethod context,
- AbstractValueSupplier abstractValueSupplier) {
- return ObjectState.empty();
- }
-
public AbstractValue getAbstractValue(
AppView<?> appView, ProgramMethod context, AbstractValueSupplier abstractValueSupplier) {
assert hasOutValue();
diff --git a/src/main/java/com/android/tools/r8/ir/code/NewArrayEmpty.java b/src/main/java/com/android/tools/r8/ir/code/NewArrayEmpty.java
index de0aa46..0eb198e 100644
--- a/src/main/java/com/android/tools/r8/ir/code/NewArrayEmpty.java
+++ b/src/main/java/com/android/tools/r8/ir/code/NewArrayEmpty.java
@@ -18,14 +18,13 @@
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.analysis.value.AbstractValue;
import com.android.tools.r8.ir.analysis.value.StatefulObjectValue;
-import com.android.tools.r8.ir.analysis.value.objectstate.ObjectState;
+import com.android.tools.r8.ir.analysis.value.UnknownValue;
import com.android.tools.r8.ir.conversion.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
import com.android.tools.r8.ir.optimize.DeadCodeRemover.DeadInstructionResult;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
import com.android.tools.r8.ir.optimize.InliningConstraints;
import com.android.tools.r8.lightir.LirBuilder;
-import com.android.tools.r8.shaking.AppInfoWithLiveness;
public class NewArrayEmpty extends Instruction {
@@ -101,31 +100,18 @@
return sizeIfConst() < 0;
}
- private ObjectState internalComputeObjectState(
+ @Override
+ public AbstractValue getAbstractValue(
AppView<?> appView, ProgramMethod context, AbstractValueSupplier abstractValueSupplier) {
if (!instructionMayHaveSideEffects(appView, context, abstractValueSupplier)
&& size().getType().isInt()) {
assert !instructionInstanceCanThrow(appView, context, abstractValueSupplier);
- return appView
- .abstractValueFactory()
- .createKnownLengthArrayState(size().definition.asConstNumber().getIntValue());
+ return StatefulObjectValue.create(
+ appView
+ .abstractValueFactory()
+ .createKnownLengthArrayState(size().definition.asConstNumber().getIntValue()));
}
- return ObjectState.empty();
- }
-
- @Override
- public ObjectState computeObjectState(
- AppView<AppInfoWithLiveness> appView,
- ProgramMethod context,
- AbstractValueSupplier abstractValueSupplier) {
- return internalComputeObjectState(appView, context, abstractValueSupplier);
- }
-
- @Override
- public AbstractValue getAbstractValue(
- AppView<?> appView, ProgramMethod context, AbstractValueSupplier abstractValueSupplier) {
- return StatefulObjectValue.create(
- internalComputeObjectState(appView, context, abstractValueSupplier));
+ return UnknownValue.getInstance();
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/NewArrayFilled.java b/src/main/java/com/android/tools/r8/ir/code/NewArrayFilled.java
index 01855e3..bdaeb21 100644
--- a/src/main/java/com/android/tools/r8/ir/code/NewArrayFilled.java
+++ b/src/main/java/com/android/tools/r8/ir/code/NewArrayFilled.java
@@ -21,13 +21,12 @@
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.analysis.value.AbstractValue;
import com.android.tools.r8.ir.analysis.value.StatefulObjectValue;
-import com.android.tools.r8.ir.analysis.value.objectstate.ObjectState;
+import com.android.tools.r8.ir.analysis.value.UnknownValue;
import com.android.tools.r8.ir.conversion.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
import com.android.tools.r8.ir.optimize.InliningConstraints;
import com.android.tools.r8.lightir.LirBuilder;
-import com.android.tools.r8.shaking.AppInfoWithLiveness;
import java.util.List;
public class NewArrayFilled extends Invoke {
@@ -153,28 +152,15 @@
throw new Unreachable("InvokeNewArray (non-empty) not supported when compiling to classfiles.");
}
- private ObjectState internalComputeObjectState(
- AppView<?> appView, ProgramMethod context, AbstractValueSupplier abstractValueSupplier) {
- if (!instructionMayHaveSideEffects(appView, context, abstractValueSupplier)) {
- int size = inValues.size();
- return appView.abstractValueFactory().createKnownLengthArrayState(size);
- }
- return ObjectState.empty();
- }
-
- @Override
- public ObjectState computeObjectState(
- AppView<AppInfoWithLiveness> appView,
- ProgramMethod context,
- AbstractValueSupplier abstractValueSupplier) {
- return internalComputeObjectState(appView, context, abstractValueSupplier);
- }
-
@Override
public AbstractValue getAbstractValue(
AppView<?> appView, ProgramMethod context, AbstractValueSupplier abstractValueSupplier) {
- return StatefulObjectValue.create(
- internalComputeObjectState(appView, context, abstractValueSupplier));
+ if (!instructionMayHaveSideEffects(appView, context, abstractValueSupplier)) {
+ int size = inValues.size();
+ return StatefulObjectValue.create(
+ appView.abstractValueFactory().createKnownLengthArrayState(size));
+ }
+ return UnknownValue.getInstance();
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/NewArrayFilledData.java b/src/main/java/com/android/tools/r8/ir/code/NewArrayFilledData.java
index c2b38ed..33a0b7d 100644
--- a/src/main/java/com/android/tools/r8/ir/code/NewArrayFilledData.java
+++ b/src/main/java/com/android/tools/r8/ir/code/NewArrayFilledData.java
@@ -12,13 +12,12 @@
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.value.AbstractValue;
import com.android.tools.r8.ir.analysis.value.StatefulObjectValue;
-import com.android.tools.r8.ir.analysis.value.objectstate.ObjectState;
+import com.android.tools.r8.ir.analysis.value.UnknownValue;
import com.android.tools.r8.ir.conversion.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
import com.android.tools.r8.ir.optimize.InliningConstraints;
import com.android.tools.r8.lightir.LirBuilder;
-import com.android.tools.r8.shaking.AppInfoWithLiveness;
import java.util.Arrays;
public class NewArrayFilledData extends Instruction {
@@ -133,29 +132,16 @@
return appView.options().debug || src().getType().isNullable();
}
- private ObjectState internalComputeObjectState(
+ @Override
+ public AbstractValue getAbstractValue(
AppView<?> appView, ProgramMethod context, AbstractValueSupplier abstractValueSupplier) {
if (!instructionMayHaveSideEffects(appView, context, abstractValueSupplier)
&& size <= Integer.MAX_VALUE) {
assert !instructionInstanceCanThrow(appView, context, abstractValueSupplier);
- return appView.abstractValueFactory().createKnownLengthArrayState((int) size);
+ return StatefulObjectValue.create(
+ appView.abstractValueFactory().createKnownLengthArrayState((int) size));
}
- return ObjectState.empty();
- }
-
- @Override
- public ObjectState computeObjectState(
- AppView<AppInfoWithLiveness> appView,
- ProgramMethod context,
- AbstractValueSupplier abstractValueSupplier) {
- return internalComputeObjectState(appView, context, abstractValueSupplier);
- }
-
- @Override
- public AbstractValue getAbstractValue(
- AppView<?> appView, ProgramMethod context, AbstractValueSupplier abstractValueSupplier) {
- return StatefulObjectValue.create(
- internalComputeObjectState(appView, context, abstractValueSupplier));
+ return UnknownValue.getInstance();
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/NewInstance.java b/src/main/java/com/android/tools/r8/ir/code/NewInstance.java
index 9c6416c..a3f05e0 100644
--- a/src/main/java/com/android/tools/r8/ir/code/NewInstance.java
+++ b/src/main/java/com/android/tools/r8/ir/code/NewInstance.java
@@ -25,8 +25,6 @@
import com.android.tools.r8.ir.analysis.VerifyTypesHelper;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.analysis.type.TypeElement;
-import com.android.tools.r8.ir.analysis.value.objectstate.ObjectState;
-import com.android.tools.r8.ir.analysis.value.objectstate.ObjectStateNewInstanceAnalysis;
import com.android.tools.r8.ir.conversion.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
@@ -247,15 +245,6 @@
}
@Override
- public ObjectState computeObjectState(
- AppView<AppInfoWithLiveness> appView,
- ProgramMethod context,
- AbstractValueSupplier abstractValueSupplier) {
- return ObjectStateNewInstanceAnalysis.computeNewInstanceObjectState(
- this, appView, context, abstractValueSupplier);
- }
-
- @Override
void internalRegisterUse(UseRegistry<?> registry, DexClassAndMethod context) {
registry.registerNewInstance(clazz);
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Phi.java b/src/main/java/com/android/tools/r8/ir/code/Phi.java
index 0e0c86e..7bafe1b 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Phi.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Phi.java
@@ -16,12 +16,10 @@
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.analysis.type.TypeElement;
-import com.android.tools.r8.ir.analysis.value.objectstate.ObjectState;
import com.android.tools.r8.ir.code.BasicBlock.EdgeType;
import com.android.tools.r8.ir.conversion.IRBuilder;
import com.android.tools.r8.ir.conversion.TypeConstraintResolver;
import com.android.tools.r8.ir.optimize.AffectedValues;
-import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.DequeUtils;
import com.android.tools.r8.utils.ListUtils;
import com.android.tools.r8.utils.Reporter;
@@ -101,13 +99,6 @@
setBlock(null);
}
- public ObjectState computeObjectState(
- AppView<AppInfoWithLiveness> appView,
- ProgramMethod context,
- AbstractValueSupplier abstractValueSupplier) {
- return ObjectState.empty();
- }
-
@Override
public void constrainType(
ValueTypeConstraint constraint, ProgramMethod method, Reporter reporter) {
diff --git a/src/main/java/com/android/tools/r8/ir/code/Value.java b/src/main/java/com/android/tools/r8/ir/code/Value.java
index 193874e..d782e2b 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Value.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Value.java
@@ -28,7 +28,6 @@
import com.android.tools.r8.ir.analysis.value.AbstractValue;
import com.android.tools.r8.ir.analysis.value.NumberFromIntervalValue;
import com.android.tools.r8.ir.analysis.value.UnknownValue;
-import com.android.tools.r8.ir.analysis.value.objectstate.ObjectState;
import com.android.tools.r8.ir.optimize.AffectedValues;
import com.android.tools.r8.ir.regalloc.LiveIntervals;
import com.android.tools.r8.position.MethodPosition;
@@ -880,18 +879,6 @@
return definition.isOutConstant() && !hasLocalInfo();
}
- public final ObjectState computeObjectState(
- AppView<AppInfoWithLiveness> appView, ProgramMethod context) {
- return definition.computeObjectState(appView, context, AbstractValueSupplier.shallow());
- }
-
- public ObjectState computeObjectState(
- AppView<AppInfoWithLiveness> appView,
- ProgramMethod context,
- AbstractValueSupplier abstractValueSupplier) {
- return definition.computeObjectState(appView, context, abstractValueSupplier);
- }
-
public final AbstractValue getAbstractValue(AppView<?> appView, ProgramMethod context) {
return getAbstractValue(appView, context, AbstractValueSupplier.unknown());
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
index 415e7bf..fd48de4 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
@@ -66,6 +66,7 @@
import com.android.tools.r8.ir.analysis.value.AbstractValue;
import com.android.tools.r8.ir.analysis.value.StatefulObjectValue;
import com.android.tools.r8.ir.analysis.value.objectstate.ObjectState;
+import com.android.tools.r8.ir.analysis.value.objectstate.ObjectStateAnalysis;
import com.android.tools.r8.ir.code.AbstractValueSupplier;
import com.android.tools.r8.ir.code.AliasedValueConfiguration;
import com.android.tools.r8.ir.code.Argument;
@@ -221,7 +222,9 @@
}
} else if (returnValue.getType().isReferenceType()) {
// TODO(b/204159267): Move this logic into Instruction#getAbstractValue in NewInstance.
- ObjectState objectState = aliasedValue.computeObjectState(appView, context);
+ ObjectState objectState =
+ ObjectStateAnalysis.computeObjectState(aliasedValue, appView, context);
+ // TODO(b/204272377): Avoid wrapping and unwrapping the object state.
feedback.methodReturnsAbstractValue(
method, appView, StatefulObjectValue.create(objectState));
}
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorCodeScanner.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorCodeScanner.java
index 5012849..5f33057 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorCodeScanner.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorCodeScanner.java
@@ -23,6 +23,7 @@
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.analysis.value.AbstractValue;
import com.android.tools.r8.ir.analysis.value.objectstate.ObjectState;
+import com.android.tools.r8.ir.analysis.value.objectstate.ObjectStateAnalysis;
import com.android.tools.r8.ir.code.AbstractValueSupplier;
import com.android.tools.r8.ir.code.AliasedValueConfiguration;
import com.android.tools.r8.ir.code.Argument;
@@ -372,7 +373,7 @@
if (abstractValue.isUnknown()) {
abstractValue =
getFallbackAbstractValueForField(
- field, () -> value.computeObjectState(appView, context));
+ field, () -> ObjectStateAnalysis.computeObjectState(value, appView, context));
}
if (field.getType().isClassType()) {
DynamicType dynamicType =