Remove all field states
Bug: b/296030319
Change-Id: I9f80ac358a561a4d8f7806454f30b88393d96116
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/FieldAssignmentTracker.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/FieldAssignmentTracker.java
index de3e876..2c917645 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/FieldAssignmentTracker.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/FieldAssignmentTracker.java
@@ -18,10 +18,6 @@
import com.android.tools.r8.graph.ObjectAllocationInfoCollection;
import com.android.tools.r8.graph.ProgramField;
import com.android.tools.r8.graph.ProgramMethod;
-import com.android.tools.r8.ir.analysis.fieldaccess.state.ConcreteArrayTypeFieldState;
-import com.android.tools.r8.ir.analysis.fieldaccess.state.ConcreteClassTypeFieldState;
-import com.android.tools.r8.ir.analysis.fieldaccess.state.ConcretePrimitiveTypeFieldState;
-import com.android.tools.r8.ir.analysis.fieldaccess.state.FieldState;
import com.android.tools.r8.ir.analysis.type.ClassTypeElement;
import com.android.tools.r8.ir.analysis.type.DynamicType;
import com.android.tools.r8.ir.analysis.type.DynamicTypeWithUpperBound;
@@ -40,6 +36,10 @@
import com.android.tools.r8.ir.optimize.info.field.InstanceFieldArgumentInitializationInfo;
import com.android.tools.r8.ir.optimize.info.field.InstanceFieldInitializationInfo;
import com.android.tools.r8.ir.optimize.info.field.InstanceFieldInitializationInfoCollection;
+import com.android.tools.r8.optimize.argumentpropagation.codescanner.ConcreteArrayTypeValueState;
+import com.android.tools.r8.optimize.argumentpropagation.codescanner.ConcreteClassTypeValueState;
+import com.android.tools.r8.optimize.argumentpropagation.codescanner.ConcretePrimitiveTypeValueState;
+import com.android.tools.r8.optimize.argumentpropagation.codescanner.ValueState;
import com.android.tools.r8.optimize.argumentpropagation.utils.WideningUtils;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.shaking.KeepFieldInfo;
@@ -74,7 +74,7 @@
// Information about the fields in the program. If a field is not a key in the map then no writes
// has been seen to the field.
- private final Map<DexEncodedField, FieldState> fieldStates = new ConcurrentHashMap<>();
+ private final Map<DexEncodedField, ValueState> fieldStates = new ConcurrentHashMap<>();
private final Map<DexProgramClass, ProgramFieldMap<AbstractValue>>
abstractFinalInstanceFieldValues = new ConcurrentHashMap<>();
@@ -141,7 +141,7 @@
KeepFieldInfo keepInfo = appView.getKeepInfo(field);
if (keepInfo.isPinned(appView.options())
|| (accessInfo != null && accessInfo.isWrittenFromMethodHandle())) {
- fieldStates.put(field.getDefinition(), FieldState.unknown());
+ fieldStates.put(field.getDefinition(), ValueState.unknown());
}
});
}
@@ -166,7 +166,7 @@
assert abstractValue.isSingleStringValue()
|| abstractValue.isSingleDexItemBasedStringValue();
if (fieldType == dexItemFactory.stringType) {
- return ConcreteClassTypeFieldState.create(
+ return ConcreteClassTypeValueState.create(
abstractValue, DynamicType.definitelyNotNull());
} else {
ClassTypeElement nonNullableStringType =
@@ -174,16 +174,16 @@
.stringType
.toTypeElement(appView, definitelyNotNull())
.asClassType();
- return ConcreteClassTypeFieldState.create(
+ return ConcreteClassTypeValueState.create(
abstractValue, DynamicType.createExact(nonNullableStringType));
}
} else {
assert fieldType.isPrimitiveType();
- return ConcretePrimitiveTypeFieldState.create(abstractValue);
+ return ConcretePrimitiveTypeValueState.create(abstractValue);
}
}
// If the field is already assigned outside the class initializer then just give up.
- return FieldState.unknown();
+ return ValueState.unknown();
});
});
}
@@ -202,16 +202,17 @@
value.isZero()
? abstractValueFactory.createDefaultValue(field.getType())
: AbstractValue.unknown();
+ Nullability nullability = value.getType().nullability();
fieldStates.compute(
field.getDefinition(),
(f, fieldState) -> {
if (fieldState == null || fieldState.isBottom()) {
DexType fieldType = field.getType();
if (fieldType.isArrayType()) {
- return ConcreteArrayTypeFieldState.create(abstractValue);
+ return ConcreteArrayTypeValueState.create(nullability);
}
if (fieldType.isPrimitiveType()) {
- return ConcretePrimitiveTypeFieldState.create(abstractValue);
+ return ConcretePrimitiveTypeValueState.create(abstractValue);
}
assert fieldType.isClassType();
DynamicType dynamicType =
@@ -219,7 +220,7 @@
appView,
value.getDynamicType(appView).withNullability(Nullability.maybeNull()),
field.getType());
- return ConcreteClassTypeFieldState.create(abstractValue, dynamicType);
+ return ConcreteClassTypeValueState.create(abstractValue, dynamicType);
}
if (fieldState.isUnknown()) {
@@ -228,19 +229,19 @@
assert fieldState.isConcrete();
- if (fieldState.isArray()) {
- ConcreteArrayTypeFieldState arrayFieldState = fieldState.asArray();
- return arrayFieldState.mutableJoin(appView, field, abstractValue);
+ if (fieldState.isArrayState()) {
+ ConcreteArrayTypeValueState arrayFieldState = fieldState.asArrayState();
+ return arrayFieldState.mutableJoin(appView, field, nullability);
}
- if (fieldState.isPrimitive()) {
- ConcretePrimitiveTypeFieldState primitiveFieldState = fieldState.asPrimitive();
+ if (fieldState.isPrimitiveState()) {
+ ConcretePrimitiveTypeValueState primitiveFieldState = fieldState.asPrimitiveState();
return primitiveFieldState.mutableJoin(appView, field, abstractValue);
}
- assert fieldState.isClass();
+ assert fieldState.isClassState();
- ConcreteClassTypeFieldState classFieldState = fieldState.asClass();
+ ConcreteClassTypeValueState classFieldState = fieldState.asClassState();
return classFieldState.mutableJoin(
appView, abstractValue, value.getDynamicType(appView), field);
});
@@ -316,15 +317,18 @@
@SuppressWarnings("ReferenceEquality")
private void recordAllFieldPutsProcessed(
ProgramField field, OptimizationFeedbackDelayed feedback) {
- FieldState fieldState = fieldStates.getOrDefault(field.getDefinition(), FieldState.bottom());
+ ValueState fieldState =
+ fieldStates.getOrDefault(field.getDefinition(), ValueState.bottom(field));
AbstractValue abstractValue =
- fieldState.getAbstractValue(appView.abstractValueFactory(), field);
+ fieldState.isBottom()
+ ? appView.abstractValueFactory().createDefaultValue(field.getType())
+ : fieldState.getAbstractValue(appView);
if (abstractValue.isNonTrivial()) {
feedback.recordFieldHasAbstractValue(field.getDefinition(), appView, abstractValue);
}
- if (fieldState.isClass() && field.getOptimizationInfo().getDynamicType().isUnknown()) {
- ConcreteClassTypeFieldState classFieldState = fieldState.asClass();
+ if (fieldState.isClassState() && field.getOptimizationInfo().getDynamicType().isUnknown()) {
+ ConcreteClassTypeValueState classFieldState = fieldState.asClassState();
DynamicType dynamicType = classFieldState.getDynamicType();
if (!dynamicType.isUnknown()) {
assert WideningUtils.widenDynamicNonReceiverType(appView, dynamicType, field.getType())
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/state/BottomFieldState.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/state/BottomFieldState.java
deleted file mode 100644
index f71be76..0000000
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/state/BottomFieldState.java
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 2021, 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.analysis.fieldaccess.state;
-
-import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.ProgramField;
-import com.android.tools.r8.ir.analysis.value.AbstractValue;
-import com.android.tools.r8.ir.analysis.value.AbstractValueFactory;
-import com.android.tools.r8.optimize.argumentpropagation.codescanner.ConcreteValueState;
-import com.android.tools.r8.optimize.argumentpropagation.codescanner.NonEmptyValueState;
-import com.android.tools.r8.shaking.AppInfoWithLiveness;
-import com.android.tools.r8.utils.Action;
-
-/** Used to represent the state for fields that have never been assigned in the program. */
-public class BottomFieldState extends FieldState {
-
- private static final BottomFieldState INSTANCE = new BottomFieldState();
-
- private BottomFieldState() {}
-
- public static BottomFieldState getInstance() {
- return INSTANCE;
- }
-
- @Override
- public AbstractValue getAbstractValue(
- AbstractValueFactory abstractValueFactory, ProgramField field) {
- return abstractValueFactory.createDefaultValue(field.getType());
- }
-
- @Override
- public boolean isBottom() {
- return true;
- }
-
- @Override
- public FieldState mutableCopy() {
- return this;
- }
-
- @Override
- public FieldState mutableJoin(
- AppView<AppInfoWithLiveness> appView,
- ProgramField field,
- NonEmptyFieldState fieldState,
- Action onChangedAction) {
- return fieldState.mutableCopy();
- }
-
- @Override
- public FieldState mutableJoin(
- AppView<AppInfoWithLiveness> appView,
- ProgramField field,
- NonEmptyValueState parameterState,
- Action onChangedAction) {
- if (parameterState.isUnknown()) {
- return unknown();
- }
- ConcreteValueState concreteParameterState = parameterState.asConcrete();
- if (field.getType().isArrayType()) {
- return ConcreteArrayTypeFieldState.create(
- concreteParameterState.getAbstractValue(appView), concreteParameterState.copyInFlow());
- } else if (field.getType().isReferenceType()) {
- return ConcreteClassTypeFieldState.create(
- concreteParameterState.getAbstractValue(appView),
- concreteParameterState.asReferenceParameter().getDynamicType(),
- concreteParameterState.copyInFlow());
- } else {
- assert field.getType().isPrimitiveType();
- return ConcretePrimitiveTypeFieldState.create(
- concreteParameterState.getAbstractValue(appView), concreteParameterState.copyInFlow());
- }
- }
-}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/state/ConcreteArrayTypeFieldState.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/state/ConcreteArrayTypeFieldState.java
deleted file mode 100644
index d8b4587..0000000
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/state/ConcreteArrayTypeFieldState.java
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright (c) 2021, 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.analysis.fieldaccess.state;
-
-import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.ProgramField;
-import com.android.tools.r8.ir.analysis.value.AbstractValue;
-import com.android.tools.r8.optimize.argumentpropagation.codescanner.ConcreteReferenceTypeValueState;
-import com.android.tools.r8.optimize.argumentpropagation.codescanner.InFlow;
-import com.android.tools.r8.shaking.AppInfoWithLiveness;
-import com.android.tools.r8.utils.Action;
-import com.android.tools.r8.utils.SetUtils;
-import java.util.Collections;
-import java.util.Set;
-
-/**
- * The information that we track for fields with an array type.
- *
- * <p>Since we don't gain much from tracking the dynamic types of arrays, this is only tracking the
- * abstract value.
- */
-public class ConcreteArrayTypeFieldState extends ConcreteReferenceTypeFieldState {
-
- public ConcreteArrayTypeFieldState(InFlow inFlow) {
- this(SetUtils.newHashSet(inFlow));
- }
-
- private ConcreteArrayTypeFieldState(Set<InFlow> inFlow) {
- this(AbstractValue.bottom(), inFlow);
- }
-
- @SuppressWarnings("InconsistentOverloads")
- private ConcreteArrayTypeFieldState(AbstractValue abstractValue, Set<InFlow> inFlow) {
- super(abstractValue, inFlow);
- }
-
- public static NonEmptyFieldState create(AbstractValue abstractValue) {
- return create(abstractValue, Collections.emptySet());
- }
-
- public static NonEmptyFieldState create(AbstractValue abstractValue, Set<InFlow> inFlow) {
- return abstractValue.isUnknown()
- ? FieldState.unknown()
- : new ConcreteArrayTypeFieldState(abstractValue, inFlow);
- }
-
- @Override
- public boolean isArray() {
- return true;
- }
-
- @Override
- public ConcreteArrayTypeFieldState asArray() {
- return this;
- }
-
- @Override
- public FieldState mutableCopy() {
- return new ConcreteArrayTypeFieldState(getAbstractValue(), copyInFlow());
- }
-
- public FieldState mutableJoin(
- AppView<AppInfoWithLiveness> appView, ProgramField field, AbstractValue abstractValue) {
- mutableJoinAbstractValue(appView, field, abstractValue);
- if (isEffectivelyUnknown()) {
- return unknown();
- }
- return this;
- }
-
- @Override
- public FieldState mutableJoin(
- AppView<AppInfoWithLiveness> appView,
- ProgramField field,
- ConcreteReferenceTypeFieldState fieldState,
- Action onChangedAction) {
- boolean abstractValueChanged = mutableJoinAbstractValue(appView, field, fieldState);
- if (isEffectivelyUnknown()) {
- return unknown();
- }
- boolean inFlowChanged = mutableJoinInFlow(fieldState);
- if (widenInFlow(appView)) {
- return unknown();
- }
- if (abstractValueChanged || inFlowChanged) {
- onChangedAction.execute();
- }
- return this;
- }
-
- @Override
- public FieldState mutableJoin(
- AppView<AppInfoWithLiveness> appView,
- ProgramField field,
- ConcreteReferenceTypeValueState parameterState,
- Action onChangedAction) {
- boolean abstractValueChanged =
- mutableJoinAbstractValue(appView, field, parameterState.getAbstractValue(appView));
- if (isEffectivelyUnknown()) {
- return unknown();
- }
- boolean inFlowChanged = mutableJoinInFlow(parameterState.getInFlow());
- if (widenInFlow(appView)) {
- return unknown();
- }
- if (abstractValueChanged || inFlowChanged) {
- onChangedAction.execute();
- }
- return this;
- }
-}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/state/ConcreteClassTypeFieldState.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/state/ConcreteClassTypeFieldState.java
deleted file mode 100644
index 4217f4c..0000000
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/state/ConcreteClassTypeFieldState.java
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright (c) 2021, 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.analysis.fieldaccess.state;
-
-import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.ProgramField;
-import com.android.tools.r8.ir.analysis.type.DynamicType;
-import com.android.tools.r8.ir.analysis.value.AbstractValue;
-import com.android.tools.r8.optimize.argumentpropagation.codescanner.ConcreteReferenceTypeValueState;
-import com.android.tools.r8.optimize.argumentpropagation.codescanner.InFlow;
-import com.android.tools.r8.optimize.argumentpropagation.utils.WideningUtils;
-import com.android.tools.r8.shaking.AppInfoWithLiveness;
-import com.android.tools.r8.utils.Action;
-import com.android.tools.r8.utils.SetUtils;
-import java.util.Collections;
-import java.util.Set;
-
-/** The information that we track for fields whose type is a class type. */
-public class ConcreteClassTypeFieldState extends ConcreteReferenceTypeFieldState {
-
- private DynamicType dynamicType;
-
- public ConcreteClassTypeFieldState(InFlow inFlow) {
- this(SetUtils.newHashSet(inFlow));
- }
-
- private ConcreteClassTypeFieldState(Set<InFlow> inFlow) {
- this(AbstractValue.bottom(), DynamicType.bottom(), inFlow);
- }
-
- @SuppressWarnings("InconsistentOverloads")
- private ConcreteClassTypeFieldState(
- AbstractValue abstractValue, DynamicType dynamicType, Set<InFlow> inFlow) {
- super(abstractValue, inFlow);
- this.dynamicType = dynamicType;
- }
-
- public static NonEmptyFieldState create(AbstractValue abstractValue, DynamicType dynamicType) {
- return create(abstractValue, dynamicType, Collections.emptySet());
- }
-
- public static NonEmptyFieldState create(
- AbstractValue abstractValue, DynamicType dynamicType, Set<InFlow> inFlow) {
- return abstractValue.isUnknown() && dynamicType.isUnknown()
- ? FieldState.unknown()
- : new ConcreteClassTypeFieldState(abstractValue, dynamicType, inFlow);
- }
-
- @Override
- public DynamicType getDynamicType() {
- return dynamicType;
- }
-
- @Override
- public boolean isClass() {
- return true;
- }
-
- @Override
- public ConcreteClassTypeFieldState asClass() {
- return this;
- }
-
- @Override
- public boolean isEffectivelyBottom() {
- return super.isEffectivelyBottom() && dynamicType.isBottom();
- }
-
- @Override
- public boolean isEffectivelyUnknown() {
- return super.isEffectivelyUnknown() && dynamicType.isUnknown();
- }
-
- @Override
- public FieldState mutableCopy() {
- return new ConcreteClassTypeFieldState(getAbstractValue(), getDynamicType(), copyInFlow());
- }
-
- public FieldState mutableJoin(
- AppView<AppInfoWithLiveness> appView,
- AbstractValue abstractValue,
- DynamicType dynamicType,
- ProgramField field) {
- assert field.getType().isClassType();
- mutableJoinAbstractValue(appView, field, abstractValue);
- mutableJoinDynamicType(appView, field, dynamicType);
- if (isEffectivelyUnknown()) {
- return unknown();
- }
- return this;
- }
-
- @Override
- public FieldState mutableJoin(
- AppView<AppInfoWithLiveness> appView,
- ProgramField field,
- ConcreteReferenceTypeFieldState fieldState,
- Action onChangedAction) {
- boolean abstractValueChanged = mutableJoinAbstractValue(appView, field, fieldState);
- boolean dynamicTypeChanged = mutableJoinDynamicType(appView, field, fieldState);
- if (isEffectivelyUnknown()) {
- return unknown();
- }
- boolean inFlowChanged = mutableJoinInFlow(fieldState);
- if (widenInFlow(appView)) {
- return unknown();
- }
- if (abstractValueChanged || dynamicTypeChanged || inFlowChanged) {
- onChangedAction.execute();
- }
- return this;
- }
-
- @Override
- public FieldState mutableJoin(
- AppView<AppInfoWithLiveness> appView,
- ProgramField field,
- ConcreteReferenceTypeValueState parameterState,
- Action onChangedAction) {
- boolean abstractValueChanged =
- mutableJoinAbstractValue(appView, field, parameterState.getAbstractValue(appView));
- boolean dynamicTypeChanged =
- mutableJoinDynamicType(appView, field, parameterState.getDynamicType());
- if (isEffectivelyUnknown()) {
- return unknown();
- }
- boolean inFlowChanged = mutableJoinInFlow(parameterState.getInFlow());
- if (widenInFlow(appView)) {
- return unknown();
- }
- if (abstractValueChanged || dynamicTypeChanged || inFlowChanged) {
- onChangedAction.execute();
- }
- return this;
- }
-
- private boolean mutableJoinDynamicType(
- AppView<AppInfoWithLiveness> appView,
- ProgramField field,
- ConcreteReferenceTypeFieldState fieldState) {
- return mutableJoinDynamicType(
- appView,
- field,
- fieldState.isClass() ? fieldState.asClass().getDynamicType() : DynamicType.unknown());
- }
-
- private boolean mutableJoinDynamicType(
- AppView<AppInfoWithLiveness> appView, ProgramField field, DynamicType otherDynamicType) {
- DynamicType oldDynamicType = dynamicType;
- DynamicType joinedDynamicType = dynamicType.join(appView, otherDynamicType);
- DynamicType widenedDynamicType =
- WideningUtils.widenDynamicNonReceiverType(appView, joinedDynamicType, field.getType());
- dynamicType = widenedDynamicType;
- return !dynamicType.equals(oldDynamicType);
- }
-}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/state/ConcreteFieldState.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/state/ConcreteFieldState.java
deleted file mode 100644
index 1605e9f..0000000
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/state/ConcreteFieldState.java
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright (c) 2021, 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.analysis.fieldaccess.state;
-
-import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.ProgramField;
-import com.android.tools.r8.ir.analysis.value.AbstractValue;
-import com.android.tools.r8.optimize.argumentpropagation.codescanner.ConcreteValueState;
-import com.android.tools.r8.optimize.argumentpropagation.codescanner.InFlow;
-import com.android.tools.r8.optimize.argumentpropagation.codescanner.NonEmptyValueState;
-import com.android.tools.r8.shaking.AppInfoWithLiveness;
-import com.android.tools.r8.utils.Action;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.function.Function;
-
-/** A shared base class for non-trivial field information (neither bottom nor top). */
-public abstract class ConcreteFieldState extends NonEmptyFieldState {
-
- private AbstractValue abstractValue;
- private Set<InFlow> inFlow;
-
- ConcreteFieldState(AbstractValue abstractValue, Set<InFlow> inFlow) {
- this.abstractValue = abstractValue;
- this.inFlow = inFlow;
- }
-
- @Override
- public AbstractValue getAbstractValue() {
- return abstractValue;
- }
-
- public boolean hasInFlow() {
- return !inFlow.isEmpty();
- }
-
- public Set<InFlow> getInFlow() {
- assert inFlow.isEmpty() || inFlow instanceof HashSet<?>;
- return inFlow;
- }
-
- public FieldState clearInFlow() {
- if (hasInFlow()) {
- inFlow = Collections.emptySet();
- if (isEffectivelyBottom()) {
- return bottom();
- }
- }
- assert !isEffectivelyBottom();
- return this;
- }
-
- public Set<InFlow> copyInFlow() {
- if (inFlow.isEmpty()) {
- assert inFlow == Collections.<InFlow>emptySet();
- return inFlow;
- }
- return new HashSet<>(inFlow);
- }
-
- @Override
- public boolean isConcrete() {
- return true;
- }
-
- @Override
- public ConcreteFieldState asConcrete() {
- return this;
- }
-
- public boolean isEffectivelyBottom() {
- return abstractValue.isBottom() && !hasInFlow();
- }
-
- public boolean isEffectivelyUnknown() {
- return abstractValue.isUnknown();
- }
-
- @Override
- public final FieldState mutableJoin(
- AppView<AppInfoWithLiveness> appView,
- ProgramField field,
- NonEmptyFieldState fieldState,
- Action onChangedAction) {
- if (fieldState.isUnknown()) {
- return fieldState;
- }
- ConcreteFieldState concreteFieldState = fieldState.asConcrete();
- if (isReference()) {
- assert concreteFieldState.isReference();
- return asReference()
- .mutableJoin(appView, field, concreteFieldState.asReference(), onChangedAction);
- }
- return asPrimitive()
- .mutableJoin(appView, field, concreteFieldState.asPrimitive(), onChangedAction);
- }
-
- @Override
- public FieldState mutableJoin(
- AppView<AppInfoWithLiveness> appView,
- ProgramField field,
- NonEmptyValueState parameterState,
- Action onChangedAction) {
- if (parameterState.isUnknown()) {
- return unknown();
- }
- ConcreteValueState concreteParameterState = parameterState.asConcrete();
- if (isReference()) {
- assert concreteParameterState.isReferenceParameter();
- return asReference()
- .mutableJoin(
- appView, field, concreteParameterState.asReferenceParameter(), onChangedAction);
- }
- return asPrimitive()
- .mutableJoin(
- appView, field, concreteParameterState.asPrimitiveParameter(), onChangedAction);
- }
-
- @Override
- public final FieldState mutableJoin(
- AppView<AppInfoWithLiveness> appView,
- ProgramField field,
- Function<FieldState, NonEmptyFieldState> fieldStateSupplier) {
- return mutableJoin(appView, field, fieldStateSupplier.apply(this));
- }
-
- final boolean mutableJoinAbstractValue(
- AppView<AppInfoWithLiveness> appView, ProgramField field, ConcreteFieldState fieldState) {
- return mutableJoinAbstractValue(appView, field, fieldState.abstractValue);
- }
-
- final boolean mutableJoinAbstractValue(
- AppView<AppInfoWithLiveness> appView, ProgramField field, AbstractValue otherAbstractValue) {
- AbstractValue oldAbstractValue = abstractValue;
- abstractValue =
- appView.getAbstractValueFieldJoiner().join(abstractValue, otherAbstractValue, field);
- return !abstractValue.equals(oldAbstractValue);
- }
-
- final boolean mutableJoinInFlow(ConcreteFieldState fieldState) {
- return mutableJoinInFlow(fieldState.inFlow);
- }
-
- final boolean mutableJoinInFlow(Set<InFlow> otherInFlow) {
- if (otherInFlow.isEmpty()) {
- return false;
- }
- if (inFlow.isEmpty()) {
- assert inFlow == Collections.<InFlow>emptySet();
- inFlow = new HashSet<>();
- }
- return inFlow.addAll(otherInFlow);
- }
-
- /**
- * Returns true if the in-parameters set should be widened to unknown, in which case the entire
- * parameter state must be widened to unknown.
- */
- boolean widenInFlow(AppView<AppInfoWithLiveness> appView) {
- return inFlow != null
- && inFlow.size() > appView.options().callSiteOptimizationOptions().getMaxInFlowSize();
- }
-}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/state/ConcretePrimitiveTypeFieldState.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/state/ConcretePrimitiveTypeFieldState.java
deleted file mode 100644
index 68e767e..0000000
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/state/ConcretePrimitiveTypeFieldState.java
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright (c) 2021, 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.analysis.fieldaccess.state;
-
-import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.ProgramField;
-import com.android.tools.r8.ir.analysis.value.AbstractValue;
-import com.android.tools.r8.optimize.argumentpropagation.codescanner.ConcretePrimitiveTypeValueState;
-import com.android.tools.r8.optimize.argumentpropagation.codescanner.InFlow;
-import com.android.tools.r8.shaking.AppInfoWithLiveness;
-import com.android.tools.r8.utils.Action;
-import com.android.tools.r8.utils.SetUtils;
-import java.util.Collections;
-import java.util.Set;
-
-/** The information that we track for fields whose type is a primitive type. */
-public class ConcretePrimitiveTypeFieldState extends ConcreteFieldState {
-
- public ConcretePrimitiveTypeFieldState(InFlow inFlow) {
- this(SetUtils.newHashSet(inFlow));
- }
-
- private ConcretePrimitiveTypeFieldState(Set<InFlow> inFlow) {
- this(AbstractValue.bottom(), inFlow);
- }
-
- @SuppressWarnings("InconsistentOverloads")
- private ConcretePrimitiveTypeFieldState(AbstractValue abstractValue, Set<InFlow> inFlow) {
- super(abstractValue, inFlow);
- }
-
- public static NonEmptyFieldState create(AbstractValue abstractValue) {
- return create(abstractValue, Collections.emptySet());
- }
-
- public static NonEmptyFieldState create(AbstractValue abstractValue, Set<InFlow> inFlow) {
- return abstractValue.isUnknown()
- ? FieldState.unknown()
- : new ConcretePrimitiveTypeFieldState(abstractValue, inFlow);
- }
-
- @Override
- public boolean isPrimitive() {
- return true;
- }
-
- @Override
- public ConcretePrimitiveTypeFieldState asPrimitive() {
- return this;
- }
-
- @Override
- public FieldState mutableCopy() {
- return new ConcretePrimitiveTypeFieldState(getAbstractValue(), copyInFlow());
- }
-
- public FieldState mutableJoin(
- AppView<AppInfoWithLiveness> appView, ProgramField field, AbstractValue abstractValue) {
- mutableJoinAbstractValue(appView, field, abstractValue);
- if (isEffectivelyUnknown()) {
- return FieldState.unknown();
- }
- return this;
- }
-
- public FieldState mutableJoin(
- AppView<AppInfoWithLiveness> appView,
- ProgramField field,
- ConcretePrimitiveTypeFieldState fieldState,
- Action onChangedAction) {
- assert field.getType().isPrimitiveType();
- boolean abstractValueChanged = mutableJoinAbstractValue(appView, field, fieldState);
- if (isEffectivelyUnknown()) {
- return unknown();
- }
- boolean inFlowChanged = mutableJoinInFlow(fieldState);
- if (widenInFlow(appView)) {
- return unknown();
- }
- if (abstractValueChanged || inFlowChanged) {
- onChangedAction.execute();
- }
- return this;
- }
-
- public FieldState mutableJoin(
- AppView<AppInfoWithLiveness> appView,
- ProgramField field,
- ConcretePrimitiveTypeValueState parameterState,
- Action onChangedAction) {
- assert field.getType().isPrimitiveType();
- boolean abstractValueChanged =
- mutableJoinAbstractValue(appView, field, parameterState.getAbstractValue());
- if (isEffectivelyUnknown()) {
- return unknown();
- }
- boolean inFlowChanged = mutableJoinInFlow(parameterState.getInFlow());
- if (widenInFlow(appView)) {
- return unknown();
- }
- if (abstractValueChanged || inFlowChanged) {
- onChangedAction.execute();
- }
- return this;
- }
-}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/state/ConcreteReferenceTypeFieldState.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/state/ConcreteReferenceTypeFieldState.java
deleted file mode 100644
index f7c99bd..0000000
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/state/ConcreteReferenceTypeFieldState.java
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2021, 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.analysis.fieldaccess.state;
-
-import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.ProgramField;
-import com.android.tools.r8.ir.analysis.type.DynamicType;
-import com.android.tools.r8.ir.analysis.value.AbstractValue;
-import com.android.tools.r8.optimize.argumentpropagation.codescanner.ConcreteReferenceTypeValueState;
-import com.android.tools.r8.optimize.argumentpropagation.codescanner.InFlow;
-import com.android.tools.r8.shaking.AppInfoWithLiveness;
-import com.android.tools.r8.utils.Action;
-import java.util.Set;
-
-/** The information that we track for fields whose type is a reference type. */
-public abstract class ConcreteReferenceTypeFieldState extends ConcreteFieldState {
-
- ConcreteReferenceTypeFieldState(AbstractValue abstractValue, Set<InFlow> inFlow) {
- super(abstractValue, inFlow);
- }
-
- // TODO(b/296030319): Consider leveraging the static field type here. This type may be more
- // precise than that of a parameter, for example, unlike the unknown type.
- public DynamicType getDynamicType() {
- return DynamicType.unknown();
- }
-
- @Override
- public boolean isReference() {
- return true;
- }
-
- @Override
- public ConcreteReferenceTypeFieldState asReference() {
- return this;
- }
-
- public abstract FieldState mutableJoin(
- AppView<AppInfoWithLiveness> appView,
- ProgramField field,
- ConcreteReferenceTypeFieldState fieldState,
- Action onChangedAction);
-
- public abstract FieldState mutableJoin(
- AppView<AppInfoWithLiveness> appView,
- ProgramField field,
- ConcreteReferenceTypeValueState parameterState,
- Action onChangedAction);
-}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/state/FieldState.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/state/FieldState.java
deleted file mode 100644
index 7fee282..0000000
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/state/FieldState.java
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright (c) 2021, 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.analysis.fieldaccess.state;
-
-import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.ProgramField;
-import com.android.tools.r8.ir.analysis.value.AbstractValue;
-import com.android.tools.r8.ir.analysis.value.AbstractValueFactory;
-import com.android.tools.r8.optimize.argumentpropagation.codescanner.NonEmptyValueState;
-import com.android.tools.r8.shaking.AppInfoWithLiveness;
-import com.android.tools.r8.utils.Action;
-
-/** An abstraction of the runtime values that may flow into each field. */
-public abstract class FieldState {
-
- public static BottomFieldState bottom() {
- return BottomFieldState.getInstance();
- }
-
- public static UnknownFieldState unknown() {
- return UnknownFieldState.getInstance();
- }
-
- public abstract AbstractValue getAbstractValue(
- AbstractValueFactory abstractValueFactory, ProgramField field);
-
- public boolean isArray() {
- return false;
- }
-
- public ConcreteArrayTypeFieldState asArray() {
- return null;
- }
-
- public boolean isBottom() {
- return false;
- }
-
- public boolean isClass() {
- return false;
- }
-
- public ConcreteClassTypeFieldState asClass() {
- return null;
- }
-
- public boolean isConcrete() {
- return false;
- }
-
- public ConcreteFieldState asConcrete() {
- return null;
- }
-
- public NonEmptyFieldState asNonEmpty() {
- return null;
- }
-
- public boolean isPrimitive() {
- return false;
- }
-
- public ConcretePrimitiveTypeFieldState asPrimitive() {
- return null;
- }
-
- public boolean isReference() {
- return false;
- }
-
- public ConcreteReferenceTypeFieldState asReference() {
- return null;
- }
-
- public boolean isUnknown() {
- return false;
- }
-
- public abstract FieldState mutableCopy();
-
- public final FieldState mutableJoin(
- AppView<AppInfoWithLiveness> appView, ProgramField field, NonEmptyFieldState fieldState) {
- return mutableJoin(appView, field, fieldState, Action.empty());
- }
-
- public abstract FieldState mutableJoin(
- AppView<AppInfoWithLiveness> appView,
- ProgramField field,
- NonEmptyFieldState fieldState,
- Action onChangedAction);
-
- public abstract FieldState mutableJoin(
- AppView<AppInfoWithLiveness> appView,
- ProgramField field,
- NonEmptyValueState parameterState,
- Action onChangedAction);
-}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/state/NonEmptyFieldState.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/state/NonEmptyFieldState.java
deleted file mode 100644
index e6bf253..0000000
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/state/NonEmptyFieldState.java
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2024, 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.analysis.fieldaccess.state;
-
-import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.ProgramField;
-import com.android.tools.r8.ir.analysis.value.AbstractValue;
-import com.android.tools.r8.ir.analysis.value.AbstractValueFactory;
-import com.android.tools.r8.shaking.AppInfoWithLiveness;
-import java.util.function.Function;
-
-public abstract class NonEmptyFieldState extends FieldState {
-
- @Override
- public NonEmptyFieldState asNonEmpty() {
- return this;
- }
-
- public abstract AbstractValue getAbstractValue();
-
- @Override
- public final AbstractValue getAbstractValue(
- AbstractValueFactory abstractValueFactory, ProgramField field) {
- return getAbstractValue();
- }
-
- public abstract FieldState mutableJoin(
- AppView<AppInfoWithLiveness> appView,
- ProgramField field,
- Function<FieldState, NonEmptyFieldState> fieldStateSupplier);
-}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/state/UnknownFieldState.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/state/UnknownFieldState.java
deleted file mode 100644
index b4f2743..0000000
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/state/UnknownFieldState.java
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 2021, 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.analysis.fieldaccess.state;
-
-import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.ProgramField;
-import com.android.tools.r8.ir.analysis.value.AbstractValue;
-import com.android.tools.r8.optimize.argumentpropagation.codescanner.NonEmptyValueState;
-import com.android.tools.r8.shaking.AppInfoWithLiveness;
-import com.android.tools.r8.utils.Action;
-import java.util.function.Function;
-
-/** Represents that nothing is known about the values that may flow into a given field. */
-public class UnknownFieldState extends NonEmptyFieldState {
-
- private static final UnknownFieldState INSTANCE = new UnknownFieldState();
-
- private UnknownFieldState() {}
-
- public static UnknownFieldState getInstance() {
- return INSTANCE;
- }
-
- @Override
- public AbstractValue getAbstractValue() {
- return AbstractValue.unknown();
- }
-
- @Override
- public boolean isUnknown() {
- return true;
- }
-
- @Override
- public FieldState mutableCopy() {
- return this;
- }
-
- @Override
- public FieldState mutableJoin(
- AppView<AppInfoWithLiveness> appView,
- ProgramField field,
- NonEmptyFieldState fieldState,
- Action onChangedAction) {
- return this;
- }
-
- @Override
- public FieldState mutableJoin(
- AppView<AppInfoWithLiveness> appView,
- ProgramField field,
- NonEmptyValueState parameterState,
- Action onChangedAction) {
- return this;
- }
-
- @Override
- public FieldState mutableJoin(
- AppView<AppInfoWithLiveness> appView,
- ProgramField field,
- Function<FieldState, NonEmptyFieldState> fieldStateSupplier) {
- return this;
- }
-}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/ConcreteCallSiteOptimizationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/ConcreteCallSiteOptimizationInfo.java
index 0e24e5d..1ea06bf 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/ConcreteCallSiteOptimizationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/ConcreteCallSiteOptimizationInfo.java
@@ -160,7 +160,7 @@
if (staticType.isReferenceType()) {
DynamicTypeWithUpperBound staticTypeElement = staticType.toDynamicType(appView);
if (staticType.isArrayType()) {
- Nullability nullability = concreteParameterState.asArrayParameter().getNullability();
+ Nullability nullability = concreteParameterState.asArrayState().getNullability();
if (nullability.isDefinitelyNull()) {
newCallSiteInfo.constants.put(
argumentIndex, appView.abstractValueFactory().createNullValue(staticType));
@@ -176,7 +176,7 @@
assert false;
}
} else if (staticType.isClassType()) {
- DynamicType dynamicType = concreteParameterState.asReferenceParameter().getDynamicType();
+ DynamicType dynamicType = concreteParameterState.asReferenceState().getDynamicType();
if (!dynamicType.isUnknown()) {
newCallSiteInfo.dynamicTypes.put(argumentIndex, dynamicType);
isTop = false;
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorOptimizationInfoPopulator.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorOptimizationInfoPopulator.java
index fbe7a42..e4181f2 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorOptimizationInfoPopulator.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorOptimizationInfoPopulator.java
@@ -236,10 +236,10 @@
argumentIndex < methodState.getParameterStates().size();
argumentIndex++) {
ConcreteValueState parameterState = methodState.getParameterState(argumentIndex).asConcrete();
- if (parameterState == null || !parameterState.isClassParameter()) {
+ if (parameterState == null || !parameterState.isClassState()) {
continue;
}
- DynamicType dynamicType = parameterState.asClassParameter().getDynamicType();
+ DynamicType dynamicType = parameterState.asClassState().getDynamicType();
DexType staticType = method.getArgumentType(argumentIndex);
if (shouldWidenDynamicTypeToUnknown(dynamicType, staticType)) {
methodState.setParameterState(
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/BottomArrayTypeValueState.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/BottomArrayTypeValueState.java
index bf1ba8b..98e6bfc 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/BottomArrayTypeValueState.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/BottomArrayTypeValueState.java
@@ -6,8 +6,6 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.ir.analysis.fieldaccess.state.ConcreteClassTypeFieldState;
-import com.android.tools.r8.ir.analysis.fieldaccess.state.ConcreteFieldState;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.Action;
@@ -25,45 +23,26 @@
@Override
public ValueState mutableJoin(
AppView<AppInfoWithLiveness> appView,
- ValueState parameterState,
- DexType parameterType,
+ ValueState state,
+ DexType staticType,
StateCloner cloner,
Action onChangedAction) {
- if (parameterState.isBottom()) {
+ if (state.isBottom()) {
return this;
}
- if (parameterState.isUnknown()) {
- return parameterState;
+ if (state.isUnknown()) {
+ return state;
}
- assert parameterState.isConcrete();
- assert parameterState.asConcrete().isReferenceParameter();
- ConcreteReferenceTypeValueState concreteParameterState =
- parameterState.asConcrete().asReferenceParameter();
- if (concreteParameterState.isArrayParameter()) {
- return cloner.mutableCopy(concreteParameterState);
+ assert state.isConcrete();
+ assert state.asConcrete().isReferenceState();
+ ConcreteReferenceTypeValueState concreteState = state.asConcrete().asReferenceState();
+ if (concreteState.isArrayState()) {
+ return cloner.mutableCopy(concreteState);
}
- Nullability nullability = concreteParameterState.getNullability();
+ Nullability nullability = concreteState.getNullability();
if (nullability.isMaybeNull()) {
return unknown();
}
- return new ConcreteArrayTypeValueState(nullability, concreteParameterState.copyInFlow());
- }
-
- @Override
- public ValueState mutableJoin(
- AppView<AppInfoWithLiveness> appView,
- ConcreteFieldState fieldState,
- DexType parameterType,
- Action onChangedAction) {
- // We only track nullability for class type fields.
- if (fieldState.isClass()) {
- ConcreteClassTypeFieldState classFieldState = fieldState.asClass();
- Nullability nullability = classFieldState.getDynamicType().getNullability();
- if (nullability.isUnknown()) {
- return unknown();
- }
- return new ConcreteArrayTypeValueState(nullability, classFieldState.copyInFlow());
- }
- return unknown();
+ return new ConcreteArrayTypeValueState(nullability, concreteState.copyInFlow());
}
}
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/BottomClassTypeValueState.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/BottomClassTypeValueState.java
index df28567..f8745d8 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/BottomClassTypeValueState.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/BottomClassTypeValueState.java
@@ -6,8 +6,6 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.ir.analysis.fieldaccess.state.ConcreteFieldState;
-import com.android.tools.r8.ir.analysis.fieldaccess.state.ConcreteReferenceTypeFieldState;
import com.android.tools.r8.ir.analysis.type.DynamicType;
import com.android.tools.r8.ir.analysis.value.AbstractValue;
import com.android.tools.r8.optimize.argumentpropagation.utils.WideningUtils;
@@ -27,43 +25,29 @@
@Override
public ValueState mutableJoin(
AppView<AppInfoWithLiveness> appView,
- ValueState parameterState,
- DexType parameterType,
+ ValueState state,
+ DexType staticType,
StateCloner cloner,
Action onChangedAction) {
- if (parameterState.isBottom()) {
+ if (state.isBottom()) {
return this;
}
- if (parameterState.isUnknown()) {
- return parameterState;
+ if (state.isUnknown()) {
+ return state;
}
- assert parameterState.isConcrete();
- assert parameterState.asConcrete().isReferenceParameter();
- ConcreteReferenceTypeValueState concreteParameterState =
- parameterState.asConcrete().asReferenceParameter();
- AbstractValue abstractValue = concreteParameterState.getAbstractValue(appView);
- DynamicType dynamicType = concreteParameterState.getDynamicType();
+ assert state.isConcrete();
+ assert state.asConcrete().isReferenceState();
+ ConcreteReferenceTypeValueState concreteState = state.asConcrete().asReferenceState();
+ AbstractValue abstractValue = concreteState.getAbstractValue(appView);
+ DynamicType dynamicType = concreteState.getDynamicType();
DynamicType widenedDynamicType =
- WideningUtils.widenDynamicNonReceiverType(appView, dynamicType, parameterType);
- if (concreteParameterState.isClassParameter() && !widenedDynamicType.isUnknown()) {
- return cloner.mutableCopy(concreteParameterState);
+ WideningUtils.widenDynamicNonReceiverType(appView, dynamicType, staticType);
+ if (concreteState.isClassState() && !widenedDynamicType.isUnknown()) {
+ return cloner.mutableCopy(concreteState);
}
return abstractValue.isUnknown() && widenedDynamicType.isUnknown()
? unknown()
: new ConcreteClassTypeValueState(
- abstractValue, widenedDynamicType, concreteParameterState.copyInFlow());
- }
-
- @Override
- public ValueState mutableJoin(
- AppView<AppInfoWithLiveness> appView,
- ConcreteFieldState fieldState,
- DexType parameterType,
- Action onChangedAction) {
- ConcreteReferenceTypeFieldState referenceFieldState = fieldState.asReference();
- AbstractValue abstractValue = referenceFieldState.getAbstractValue();
- DynamicType dynamicType = referenceFieldState.getDynamicType();
- return new ConcreteClassTypeValueState(
- abstractValue, dynamicType, referenceFieldState.copyInFlow());
+ abstractValue, widenedDynamicType, concreteState.copyInFlow());
}
}
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/BottomPrimitiveTypeValueState.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/BottomPrimitiveTypeValueState.java
index e1da2ea..f325f4a 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/BottomPrimitiveTypeValueState.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/BottomPrimitiveTypeValueState.java
@@ -6,7 +6,6 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.ir.analysis.fieldaccess.state.ConcreteFieldState;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.Action;
@@ -23,29 +22,18 @@
@Override
public ValueState mutableJoin(
AppView<AppInfoWithLiveness> appView,
- ValueState parameterState,
- DexType parameterType,
+ ValueState state,
+ DexType staticType,
StateCloner cloner,
Action onChangedAction) {
- if (parameterState.isBottom()) {
- assert parameterState == bottomPrimitiveTypeParameter();
+ if (state.isBottom()) {
+ assert state == bottomPrimitiveTypeParameter();
return this;
}
- if (parameterState.isUnknown()) {
- return parameterState;
+ if (state.isUnknown()) {
+ return state;
}
- assert parameterState.isConcrete();
- assert parameterState.asConcrete().isPrimitiveParameter();
- return cloner.mutableCopy(parameterState);
- }
-
- @Override
- public ValueState mutableJoin(
- AppView<AppInfoWithLiveness> appView,
- ConcreteFieldState fieldState,
- DexType parameterType,
- Action onChangedAction) {
- return new ConcretePrimitiveTypeValueState(
- fieldState.getAbstractValue(), fieldState.copyInFlow());
+ assert state.isPrimitiveState();
+ return cloner.mutableCopy(state);
}
}
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/BottomReceiverValueState.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/BottomReceiverValueState.java
index de17523..b8eb62e 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/BottomReceiverValueState.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/BottomReceiverValueState.java
@@ -6,10 +6,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.ir.analysis.fieldaccess.state.ConcreteClassTypeFieldState;
-import com.android.tools.r8.ir.analysis.fieldaccess.state.ConcreteFieldState;
import com.android.tools.r8.ir.analysis.type.DynamicType;
-import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.Action;
@@ -26,46 +23,26 @@
@Override
public ValueState mutableJoin(
AppView<AppInfoWithLiveness> appView,
- ValueState parameterState,
- DexType parameterType,
+ ValueState state,
+ DexType staticType,
StateCloner cloner,
Action onChangedAction) {
- if (parameterState.isBottom()) {
+ if (state.isBottom()) {
return this;
}
- if (parameterState.isUnknown()) {
- return parameterState;
+ if (state.isUnknown()) {
+ return state;
}
- assert parameterState.isConcrete();
- assert parameterState.asConcrete().isReferenceParameter();
- ConcreteReferenceTypeValueState concreteParameterState =
- parameterState.asConcrete().asReferenceParameter();
- if (concreteParameterState.isReceiverParameter()) {
- return cloner.mutableCopy(concreteParameterState);
+ assert state.isConcrete();
+ assert state.asConcrete().isReferenceState();
+ ConcreteReferenceTypeValueState concreteState = state.asConcrete().asReferenceState();
+ if (concreteState.isReceiverState()) {
+ return cloner.mutableCopy(concreteState);
}
- DynamicType dynamicType = concreteParameterState.getDynamicType();
+ DynamicType dynamicType = concreteState.getDynamicType();
if (dynamicType.isUnknown()) {
return unknown();
}
- return new ConcreteReceiverValueState(dynamicType, concreteParameterState.copyInFlow());
- }
-
- @Override
- public ValueState mutableJoin(
- AppView<AppInfoWithLiveness> appView,
- ConcreteFieldState fieldState,
- DexType parameterType,
- Action onChangedAction) {
- // We only track the dynamic type for class type fields.
- if (fieldState.isClass()) {
- ConcreteClassTypeFieldState classFieldState = fieldState.asClass();
- DynamicType dynamicType = classFieldState.getDynamicType();
- if (dynamicType.isNotNullType() || dynamicType.isUnknown()) {
- return unknown();
- }
- DynamicType nonNullDynamicType = dynamicType.withNullability(Nullability.definitelyNotNull());
- return new ConcreteReceiverValueState(nonNullDynamicType, classFieldState.copyInFlow());
- }
- return unknown();
+ return new ConcreteReceiverValueState(dynamicType, concreteState.copyInFlow());
}
}
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ConcreteArrayTypeValueState.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ConcreteArrayTypeValueState.java
index 6775bf4..46a26d7 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ConcreteArrayTypeValueState.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ConcreteArrayTypeValueState.java
@@ -6,7 +6,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.ir.analysis.fieldaccess.state.ConcreteReferenceTypeFieldState;
+import com.android.tools.r8.graph.ProgramField;
import com.android.tools.r8.ir.analysis.type.DynamicType;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.analysis.value.AbstractValue;
@@ -35,6 +35,10 @@
assert !isEffectivelyUnknown() : "Must use UnknownParameterState instead";
}
+ public static NonEmptyValueState create(Nullability nullability) {
+ return nullability.isUnknown() ? unknown() : new ConcreteArrayTypeValueState(nullability);
+ }
+
@Override
public ValueState clearInFlow() {
if (hasInFlow()) {
@@ -71,12 +75,12 @@
}
@Override
- public boolean isArrayParameter() {
+ public boolean isArrayState() {
return true;
}
@Override
- public ConcreteArrayTypeValueState asArrayParameter() {
+ public ConcreteArrayTypeValueState asArrayState() {
return this;
}
@@ -95,19 +99,27 @@
return new ConcreteArrayTypeValueState(nullability, copyInFlow());
}
- @Override
- public ValueState mutableJoin(
- AppView<AppInfoWithLiveness> appView,
- ConcreteReferenceTypeValueState parameterState,
- DexType parameterType,
- Action onChangedAction) {
- assert parameterType.isArrayType();
- assert !nullability.isUnknown();
- boolean nullabilityChanged = mutableJoinNullability(parameterState.getNullability());
+ public NonEmptyValueState mutableJoin(
+ AppView<AppInfoWithLiveness> appView, ProgramField field, Nullability nullability) {
+ mutableJoinNullability(nullability);
if (isEffectivelyUnknown()) {
return unknown();
}
- boolean inFlowChanged = mutableJoinInFlow(parameterState);
+ return this;
+ }
+
+ @Override
+ public NonEmptyValueState mutableJoin(
+ AppView<AppInfoWithLiveness> appView,
+ ConcreteReferenceTypeValueState state,
+ DexType staticType,
+ Action onChangedAction) {
+ assert staticType.isArrayType();
+ boolean nullabilityChanged = mutableJoinNullability(state.getNullability());
+ if (isEffectivelyUnknown()) {
+ return unknown();
+ }
+ boolean inFlowChanged = mutableJoinInFlow(state);
if (widenInFlow(appView)) {
return unknown();
}
@@ -117,17 +129,6 @@
return this;
}
- @Override
- public ValueState mutableJoin(
- AppView<AppInfoWithLiveness> appView,
- ConcreteReferenceTypeFieldState fieldState,
- DexType parameterType,
- Action onChangedAction) {
- assert fieldState.isArray();
- // We do not track the nullability of array fields.
- return unknown();
- }
-
private boolean mutableJoinNullability(Nullability otherNullability) {
Nullability oldNullability = nullability;
nullability = nullability.join(otherNullability);
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ConcreteClassTypeValueState.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ConcreteClassTypeValueState.java
index 4366388..bf3d1f9 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ConcreteClassTypeValueState.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ConcreteClassTypeValueState.java
@@ -6,7 +6,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.ir.analysis.fieldaccess.state.ConcreteReferenceTypeFieldState;
+import com.android.tools.r8.graph.ProgramField;
import com.android.tools.r8.ir.analysis.type.DynamicType;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.analysis.value.AbstractValue;
@@ -39,6 +39,12 @@
assert !isEffectivelyUnknown() : "Must use UnknownParameterState instead";
}
+ public static NonEmptyValueState create(AbstractValue abstractValue, DynamicType dynamicType) {
+ return abstractValue.isUnknown() && dynamicType.isUnknown()
+ ? ValueState.unknown()
+ : new ConcreteClassTypeValueState(abstractValue, dynamicType);
+ }
+
@Override
public ValueState clearInFlow() {
if (hasInFlow()) {
@@ -77,12 +83,12 @@
}
@Override
- public boolean isClassParameter() {
+ public boolean isClassState() {
return true;
}
@Override
- public ConcreteClassTypeValueState asClassParameter() {
+ public ConcreteClassTypeValueState asClassState() {
return this;
}
@@ -101,45 +107,35 @@
return new ConcreteClassTypeValueState(abstractValue, dynamicType, copyInFlow());
}
- @Override
- public ValueState mutableJoin(
+ public NonEmptyValueState mutableJoin(
AppView<AppInfoWithLiveness> appView,
- ConcreteReferenceTypeValueState parameterState,
- DexType parameterType,
- Action onChangedAction) {
- assert parameterType.isClassType();
- boolean abstractValueChanged =
- mutableJoinAbstractValue(appView, parameterState.getAbstractValue(appView), parameterType);
- boolean dynamicTypeChanged =
- mutableJoinDynamicType(appView, parameterState.getDynamicType(), parameterType);
+ AbstractValue abstractValue,
+ DynamicType dynamicType,
+ ProgramField field) {
+ assert field.getType().isClassType();
+ mutableJoinAbstractValue(appView, abstractValue, field.getType());
+ mutableJoinDynamicType(appView, dynamicType, field.getType());
if (isEffectivelyUnknown()) {
return unknown();
}
- boolean inFlowChanged = mutableJoinInFlow(parameterState);
- if (widenInFlow(appView)) {
- return unknown();
- }
- if (abstractValueChanged || dynamicTypeChanged || inFlowChanged) {
- onChangedAction.execute();
- }
return this;
}
@Override
- public ValueState mutableJoin(
+ public NonEmptyValueState mutableJoin(
AppView<AppInfoWithLiveness> appView,
- ConcreteReferenceTypeFieldState fieldState,
- DexType parameterType,
+ ConcreteReferenceTypeValueState state,
+ DexType staticType,
Action onChangedAction) {
- assert parameterType.isClassType();
+ assert staticType.isClassType();
boolean abstractValueChanged =
- mutableJoinAbstractValue(appView, fieldState.getAbstractValue(), parameterType);
+ mutableJoinAbstractValue(appView, state.getAbstractValue(appView), staticType);
boolean dynamicTypeChanged =
- mutableJoinDynamicType(appView, fieldState.getDynamicType(), parameterType);
+ mutableJoinDynamicType(appView, state.getDynamicType(), staticType);
if (isEffectivelyUnknown()) {
return unknown();
}
- boolean inFlowChanged = mutableJoinInFlow(fieldState.getInFlow());
+ boolean inFlowChanged = mutableJoinInFlow(state);
if (widenInFlow(appView)) {
return unknown();
}
@@ -150,23 +146,21 @@
}
private boolean mutableJoinAbstractValue(
- AppView<AppInfoWithLiveness> appView,
- AbstractValue otherAbstractValue,
- DexType parameterType) {
+ AppView<AppInfoWithLiveness> appView, AbstractValue otherAbstractValue, DexType staticType) {
AbstractValue oldAbstractValue = abstractValue;
abstractValue =
appView
.getAbstractValueParameterJoiner()
- .join(abstractValue, otherAbstractValue, parameterType);
+ .join(abstractValue, otherAbstractValue, staticType);
return !abstractValue.equals(oldAbstractValue);
}
private boolean mutableJoinDynamicType(
- AppView<AppInfoWithLiveness> appView, DynamicType otherDynamicType, DexType parameterType) {
+ AppView<AppInfoWithLiveness> appView, DynamicType otherDynamicType, DexType staticType) {
DynamicType oldDynamicType = dynamicType;
DynamicType joinedDynamicType = dynamicType.join(appView, otherDynamicType);
DynamicType widenedDynamicType =
- WideningUtils.widenDynamicNonReceiverType(appView, joinedDynamicType, parameterType);
+ WideningUtils.widenDynamicNonReceiverType(appView, joinedDynamicType, staticType);
dynamicType = widenedDynamicType;
return !dynamicType.equals(oldDynamicType);
}
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ConcreteMonomorphicMethodState.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ConcreteMonomorphicMethodState.java
index 7f0b954..b2b1862 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ConcreteMonomorphicMethodState.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ConcreteMonomorphicMethodState.java
@@ -22,7 +22,7 @@
public ConcreteMonomorphicMethodState(
boolean isReturnValueUsed, List<ValueState> parameterStates) {
assert Streams.stream(Iterables.skip(parameterStates, 1))
- .noneMatch(x -> x.isConcrete() && x.asConcrete().isReceiverParameter());
+ .noneMatch(x -> x.isConcrete() && x.asConcrete().isReceiverState());
this.isReturnValueUsed = isReturnValueUsed;
this.parameterStates = parameterStates;
assert !isEffectivelyUnknown() : "Must use UnknownMethodState instead";
@@ -102,7 +102,7 @@
argumentIndex,
parameterState.mutableJoin(appView, otherParameterState, parameterType, cloner));
assert !parameterStates.get(argumentIndex).isConcrete()
- || !parameterStates.get(argumentIndex).asConcrete().isReceiverParameter();
+ || !parameterStates.get(argumentIndex).asConcrete().isReceiverState();
}
return isEffectivelyUnknown() ? unknown() : this;
@@ -126,7 +126,7 @@
public void setParameterState(int index, ValueState parameterState) {
assert index == 0
|| !parameterState.isConcrete()
- || !parameterState.asConcrete().isReceiverParameter();
+ || !parameterState.asConcrete().isReceiverState();
parameterStates.set(index, parameterState);
}
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ConcretePrimitiveTypeValueState.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ConcretePrimitiveTypeValueState.java
index 37686ed..2d53523 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ConcretePrimitiveTypeValueState.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ConcretePrimitiveTypeValueState.java
@@ -6,7 +6,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.ir.analysis.fieldaccess.state.ConcretePrimitiveTypeFieldState;
+import com.android.tools.r8.graph.ProgramField;
import com.android.tools.r8.ir.analysis.value.AbstractValue;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.Action;
@@ -29,6 +29,12 @@
assert !isEffectivelyUnknown() : "Must use UnknownParameterState instead";
}
+ public static NonEmptyValueState create(AbstractValue abstractValue) {
+ return abstractValue.isUnknown()
+ ? ValueState.unknown()
+ : new ConcretePrimitiveTypeValueState(abstractValue);
+ }
+
public ConcretePrimitiveTypeValueState(InFlow inFlow) {
this(AbstractValue.bottom(), SetUtils.newHashSet(inFlow));
}
@@ -50,39 +56,27 @@
return new ConcretePrimitiveTypeValueState(abstractValue, copyInFlow());
}
- public ValueState mutableJoin(
- AppView<AppInfoWithLiveness> appView,
- ConcretePrimitiveTypeValueState parameterState,
- DexType parameterType,
- Action onChangedAction) {
- assert parameterType.isPrimitiveType();
- boolean abstractValueChanged =
- mutableJoinAbstractValue(appView, parameterState.getAbstractValue(), parameterType);
+ public NonEmptyValueState mutableJoin(
+ AppView<AppInfoWithLiveness> appView, ProgramField field, AbstractValue abstractValue) {
+ mutableJoinAbstractValue(appView, abstractValue, field.getType());
if (isEffectivelyUnknown()) {
return unknown();
}
- boolean inFlowChanged = mutableJoinInFlow(parameterState);
- if (widenInFlow(appView)) {
- return unknown();
- }
- if (abstractValueChanged || inFlowChanged) {
- onChangedAction.execute();
- }
return this;
}
- public ValueState mutableJoin(
+ public NonEmptyValueState mutableJoin(
AppView<AppInfoWithLiveness> appView,
- ConcretePrimitiveTypeFieldState fieldState,
- DexType parameterType,
+ ConcretePrimitiveTypeValueState state,
+ DexType staticType,
Action onChangedAction) {
- assert parameterType.isPrimitiveType();
+ assert staticType.isPrimitiveType();
boolean abstractValueChanged =
- mutableJoinAbstractValue(appView, fieldState.getAbstractValue(), parameterType);
+ mutableJoinAbstractValue(appView, state.getAbstractValue(), staticType);
if (isEffectivelyUnknown()) {
return unknown();
}
- boolean inFlowChanged = mutableJoinInFlow(fieldState.getInFlow());
+ boolean inFlowChanged = mutableJoinInFlow(state);
if (widenInFlow(appView)) {
return unknown();
}
@@ -93,14 +87,12 @@
}
private boolean mutableJoinAbstractValue(
- AppView<AppInfoWithLiveness> appView,
- AbstractValue otherAbstractValue,
- DexType parameterType) {
+ AppView<AppInfoWithLiveness> appView, AbstractValue otherAbstractValue, DexType staticType) {
AbstractValue oldAbstractValue = abstractValue;
abstractValue =
appView
.getAbstractValueParameterJoiner()
- .join(abstractValue, otherAbstractValue, parameterType);
+ .join(abstractValue, otherAbstractValue, staticType);
return !abstractValue.equals(oldAbstractValue);
}
@@ -129,12 +121,12 @@
}
@Override
- public boolean isPrimitiveParameter() {
+ public boolean isPrimitiveState() {
return true;
}
@Override
- public ConcretePrimitiveTypeValueState asPrimitiveParameter() {
+ public ConcretePrimitiveTypeValueState asPrimitiveState() {
return this;
}
}
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ConcreteReceiverValueState.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ConcreteReceiverValueState.java
index d5721d9..186dae0 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ConcreteReceiverValueState.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ConcreteReceiverValueState.java
@@ -6,7 +6,6 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.ir.analysis.fieldaccess.state.ConcreteReferenceTypeFieldState;
import com.android.tools.r8.ir.analysis.type.DynamicType;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.analysis.value.AbstractValue;
@@ -74,12 +73,12 @@
}
@Override
- public boolean isReceiverParameter() {
+ public boolean isReceiverState() {
return true;
}
@Override
- public ConcreteReceiverValueState asReceiverParameter() {
+ public ConcreteReceiverValueState asReceiverState() {
return this;
}
@@ -89,41 +88,20 @@
}
@Override
- public ValueState mutableJoin(
+ public NonEmptyValueState mutableJoin(
AppView<AppInfoWithLiveness> appView,
- ConcreteReferenceTypeValueState parameterState,
- DexType parameterType,
+ ConcreteReferenceTypeValueState state,
+ DexType staticType,
Action onChangedAction) {
// TODO(b/190154391): Always take in the static type as an argument, and unset the dynamic type
// if it equals the static type.
- assert parameterType == null || parameterType.isClassType();
+ assert staticType == null || staticType.isClassType();
boolean dynamicTypeChanged =
- mutableJoinDynamicType(appView, parameterState.getDynamicType(), parameterType);
+ mutableJoinDynamicType(appView, state.getDynamicType(), staticType);
if (isEffectivelyUnknown()) {
return unknown();
}
- boolean inFlowChanged = mutableJoinInFlow(parameterState);
- if (widenInFlow(appView)) {
- return unknown();
- }
- if (dynamicTypeChanged || inFlowChanged) {
- onChangedAction.execute();
- }
- return this;
- }
-
- @Override
- public ValueState mutableJoin(
- AppView<AppInfoWithLiveness> appView,
- ConcreteReferenceTypeFieldState fieldState,
- DexType parameterType,
- Action onChangedAction) {
- boolean dynamicTypeChanged =
- mutableJoinDynamicType(appView, fieldState.getDynamicType(), parameterType);
- if (isEffectivelyUnknown()) {
- return unknown();
- }
- boolean inFlowChanged = mutableJoinInFlow(fieldState.getInFlow());
+ boolean inFlowChanged = mutableJoinInFlow(state);
if (widenInFlow(appView)) {
return unknown();
}
@@ -134,12 +112,12 @@
}
private boolean mutableJoinDynamicType(
- AppView<AppInfoWithLiveness> appView, DynamicType otherDynamicType, DexType parameterType) {
+ AppView<AppInfoWithLiveness> appView, DynamicType otherDynamicType, DexType staticType) {
DynamicType oldDynamicType = dynamicType;
DynamicType joinedDynamicType = dynamicType.join(appView, otherDynamicType);
- if (parameterType != null) {
+ if (staticType != null) {
DynamicType widenedDynamicType =
- WideningUtils.widenDynamicNonReceiverType(appView, joinedDynamicType, parameterType);
+ WideningUtils.widenDynamicNonReceiverType(appView, joinedDynamicType, staticType);
dynamicType = widenedDynamicType;
} else {
dynamicType = joinedDynamicType;
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ConcreteReferenceTypeValueState.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ConcreteReferenceTypeValueState.java
index dd23935..4dc4202 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ConcreteReferenceTypeValueState.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ConcreteReferenceTypeValueState.java
@@ -6,7 +6,6 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.ir.analysis.fieldaccess.state.ConcreteReferenceTypeFieldState;
import com.android.tools.r8.ir.analysis.type.DynamicType;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
@@ -24,24 +23,18 @@
public abstract Nullability getNullability();
@Override
- public boolean isReferenceParameter() {
+ public boolean isReferenceState() {
return true;
}
@Override
- public ConcreteReferenceTypeValueState asReferenceParameter() {
+ public ConcreteReferenceTypeValueState asReferenceState() {
return this;
}
- public abstract ValueState mutableJoin(
+ public abstract NonEmptyValueState mutableJoin(
AppView<AppInfoWithLiveness> appView,
- ConcreteReferenceTypeValueState parameterState,
- DexType parameterType,
- Action onChangedAction);
-
- public abstract ValueState mutableJoin(
- AppView<AppInfoWithLiveness> appView,
- ConcreteReferenceTypeFieldState fieldState,
- DexType parameterType,
+ ConcreteReferenceTypeValueState state,
+ DexType staticType,
Action onChangedAction);
}
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ConcreteValueState.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ConcreteValueState.java
index 2c7e129..f05f9e6 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ConcreteValueState.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ConcreteValueState.java
@@ -6,12 +6,12 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.ir.analysis.fieldaccess.state.ConcreteFieldState;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.Action;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
+import java.util.function.Function;
public abstract class ConcreteValueState extends NonEmptyValueState {
@@ -53,50 +53,10 @@
public abstract ConcreteParameterStateKind getKind();
- public boolean isArrayParameter() {
- return false;
- }
-
- public ConcreteArrayTypeValueState asArrayParameter() {
- return null;
- }
-
- public boolean isClassParameter() {
- return false;
- }
-
- public ConcreteClassTypeValueState asClassParameter() {
- return null;
- }
-
public abstract boolean isEffectivelyBottom();
public abstract boolean isEffectivelyUnknown();
- public boolean isPrimitiveParameter() {
- return false;
- }
-
- public ConcretePrimitiveTypeValueState asPrimitiveParameter() {
- return null;
- }
-
- public boolean isReceiverParameter() {
- return false;
- }
-
- public ConcreteReceiverValueState asReceiverParameter() {
- return null;
- }
-
- public boolean isReferenceParameter() {
- return false;
- }
-
- public ConcreteReferenceTypeValueState asReferenceParameter() {
- return null;
- }
-
@Override
public boolean isConcrete() {
return true;
@@ -108,50 +68,40 @@
}
@Override
- public final ValueState mutableJoin(
+ public NonEmptyValueState mutableJoin(
AppView<AppInfoWithLiveness> appView,
- ValueState parameterState,
- DexType parameterType,
+ Function<ValueState, NonEmptyValueState> stateSupplier,
+ DexType staticType,
StateCloner cloner,
Action onChangedAction) {
- if (parameterState.isBottom()) {
- return this;
- }
- if (parameterState.isUnknown()) {
- return parameterState;
- }
- ConcreteValueState concreteParameterState = parameterState.asConcrete();
- if (isReferenceParameter()) {
- assert concreteParameterState.isReferenceParameter();
- return asReferenceParameter()
- .mutableJoin(
- appView,
- concreteParameterState.asReferenceParameter(),
- parameterType,
- onChangedAction);
- }
- return asPrimitiveParameter()
- .mutableJoin(
- appView, concreteParameterState.asPrimitiveParameter(), parameterType, onChangedAction);
+ return mutableJoin(appView, stateSupplier.apply(this), staticType, cloner, onChangedAction);
}
@Override
- public final ValueState mutableJoin(
+ public final NonEmptyValueState mutableJoin(
AppView<AppInfoWithLiveness> appView,
- ConcreteFieldState fieldState,
- DexType parameterType,
+ ValueState state,
+ DexType staticType,
+ StateCloner cloner,
Action onChangedAction) {
- if (isReferenceParameter()) {
- assert fieldState.isReference();
- return asReferenceParameter()
- .mutableJoin(appView, fieldState.asReference(), parameterType, onChangedAction);
+ if (state.isBottom()) {
+ return this;
}
- return asPrimitiveParameter()
- .mutableJoin(appView, fieldState.asPrimitive(), parameterType, onChangedAction);
+ if (state.isUnknown()) {
+ return unknown();
+ }
+ ConcreteValueState concreteState = state.asConcrete();
+ if (isReferenceState()) {
+ assert concreteState.isReferenceState();
+ return asReferenceState()
+ .mutableJoin(appView, concreteState.asReferenceState(), staticType, onChangedAction);
+ }
+ return asPrimitiveState()
+ .mutableJoin(appView, concreteState.asPrimitiveState(), staticType, onChangedAction);
}
- boolean mutableJoinInFlow(ConcreteValueState parameterState) {
- return mutableJoinInFlow(parameterState.getInFlow());
+ boolean mutableJoinInFlow(ConcreteValueState state) {
+ return mutableJoinInFlow(state.getInFlow());
}
boolean mutableJoinInFlow(Set<InFlow> otherInFlow) {
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/NonEmptyValueState.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/NonEmptyValueState.java
index 4d03f35..19bc95a 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/NonEmptyValueState.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/NonEmptyValueState.java
@@ -4,10 +4,36 @@
package com.android.tools.r8.optimize.argumentpropagation.codescanner;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import com.android.tools.r8.utils.Action;
+import java.util.function.Function;
+
public abstract class NonEmptyValueState extends ValueState {
@Override
+ public boolean isNonEmpty() {
+ return true;
+ }
+
+ @Override
public NonEmptyValueState asNonEmpty() {
return this;
}
+
+ public final NonEmptyValueState mutableJoin(
+ AppView<AppInfoWithLiveness> appView,
+ Function<ValueState, NonEmptyValueState> stateSupplier,
+ DexType staticType,
+ StateCloner cloner) {
+ return mutableJoin(appView, stateSupplier, staticType, cloner, Action.empty());
+ }
+
+ public abstract NonEmptyValueState mutableJoin(
+ AppView<AppInfoWithLiveness> appView,
+ Function<ValueState, NonEmptyValueState> stateSupplier,
+ DexType staticType,
+ StateCloner cloner,
+ Action onChangedAction);
}
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/UnknownValueState.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/UnknownValueState.java
index eb59e78..f9e7a1d 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/UnknownValueState.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/UnknownValueState.java
@@ -6,10 +6,10 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.ir.analysis.fieldaccess.state.ConcreteFieldState;
import com.android.tools.r8.ir.analysis.value.AbstractValue;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.Action;
+import java.util.function.Function;
public class UnknownValueState extends NonEmptyValueState {
@@ -47,10 +47,11 @@
}
@Override
- public ValueState mutableJoin(
+ public NonEmptyValueState mutableJoin(
AppView<AppInfoWithLiveness> appView,
- ConcreteFieldState fieldState,
- DexType parameterType,
+ Function<ValueState, NonEmptyValueState> stateSupplier,
+ DexType staticType,
+ StateCloner cloner,
Action onChangedAction) {
return this;
}
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ValueState.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ValueState.java
index 1a6e570..4cb4c2b 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ValueState.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/ValueState.java
@@ -6,13 +6,25 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.ir.analysis.fieldaccess.state.ConcreteFieldState;
+import com.android.tools.r8.graph.ProgramField;
import com.android.tools.r8.ir.analysis.value.AbstractValue;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.Action;
public abstract class ValueState {
+ public static BottomValueState bottom(ProgramField field) {
+ DexType fieldType = field.getType();
+ if (fieldType.isArrayType()) {
+ return bottomArrayTypeParameter();
+ } else if (fieldType.isClassType()) {
+ return bottomClassTypeParameter();
+ } else {
+ assert fieldType.isPrimitiveType();
+ return bottomPrimitiveTypeParameter();
+ }
+ }
+
public static BottomValueState bottomArrayTypeParameter() {
return BottomArrayTypeValueState.get();
}
@@ -35,10 +47,26 @@
public abstract AbstractValue getAbstractValue(AppView<AppInfoWithLiveness> appView);
+ public boolean isArrayState() {
+ return false;
+ }
+
+ public ConcreteArrayTypeValueState asArrayState() {
+ return null;
+ }
+
public boolean isBottom() {
return false;
}
+ public boolean isClassState() {
+ return false;
+ }
+
+ public ConcreteClassTypeValueState asClassState() {
+ return null;
+ }
+
public boolean isConcrete() {
return false;
}
@@ -47,10 +75,38 @@
return null;
}
+ public boolean isNonEmpty() {
+ return false;
+ }
+
public NonEmptyValueState asNonEmpty() {
return null;
}
+ public boolean isPrimitiveState() {
+ return false;
+ }
+
+ public ConcretePrimitiveTypeValueState asPrimitiveState() {
+ return null;
+ }
+
+ public boolean isReceiverState() {
+ return false;
+ }
+
+ public ConcreteReceiverValueState asReceiverState() {
+ return null;
+ }
+
+ public boolean isReferenceState() {
+ return false;
+ }
+
+ public ConcreteReferenceTypeValueState asReferenceState() {
+ return null;
+ }
+
public boolean isUnknown() {
return false;
}
@@ -59,22 +115,16 @@
public final ValueState mutableJoin(
AppView<AppInfoWithLiveness> appView,
- ValueState parameterState,
+ ValueState state,
DexType parameterType,
StateCloner cloner) {
- return mutableJoin(appView, parameterState, parameterType, cloner, Action.empty());
+ return mutableJoin(appView, state, parameterType, cloner, Action.empty());
}
public abstract ValueState mutableJoin(
AppView<AppInfoWithLiveness> appView,
- ValueState parameterState,
- DexType parameterType,
+ ValueState state,
+ DexType staticType,
StateCloner cloner,
Action onChangedAction);
-
- public abstract ValueState mutableJoin(
- AppView<AppInfoWithLiveness> appView,
- ConcreteFieldState fieldState,
- DexType parameterType,
- Action onChangedAction);
}