Fix join of concrete and unused value state
Change-Id: I6be651ea3dbd5863fb89dc900a82a938440ccbd9
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 ca98915..91fbd6d 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
@@ -65,6 +65,11 @@
}
@Override
+ public UnusedValueState getCorrespondingUnused() {
+ return unusedArrayTypeState();
+ }
+
+ @Override
public ConcreteParameterStateKind getKind() {
return ConcreteParameterStateKind.ARRAY;
}
@@ -124,7 +129,8 @@
if (widenInFlow(appView)) {
return unknown();
}
- if (nullabilityChanged || inFlowChanged) {
+ boolean unusedChanged = mutableJoinUnused(inState);
+ if (nullabilityChanged || inFlowChanged || unusedChanged) {
onChangedAction.execute();
}
return this;
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 96e476b..4bbc3ff 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
@@ -82,6 +82,11 @@
}
@Override
+ public UnusedValueState getCorrespondingUnused() {
+ return unusedClassTypeState();
+ }
+
+ @Override
public DynamicType getDynamicType() {
return dynamicType;
}
@@ -155,7 +160,8 @@
if (widenInFlow(appView)) {
return unknown();
}
- if (abstractValueChanged || dynamicTypeChanged || inFlowChanged) {
+ boolean unusedChanged = mutableJoinUnused(inState);
+ if (abstractValueChanged || dynamicTypeChanged || inFlowChanged || unusedChanged) {
onChangedAction.execute();
}
return this;
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 118c05d..4283477 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
@@ -74,7 +74,8 @@
if (widenInFlow(appView)) {
return unknown();
}
- if (abstractValueChanged || inFlowChanged) {
+ boolean unusedChanged = mutableJoinUnused(state);
+ if (abstractValueChanged || inFlowChanged || unusedChanged) {
onChangedAction.execute();
}
return this;
@@ -105,6 +106,11 @@
}
@Override
+ public UnusedValueState getCorrespondingUnused() {
+ return unusedPrimitiveTypeState();
+ }
+
+ @Override
public ConcreteParameterStateKind getKind() {
return ConcreteParameterStateKind.PRIMITIVE;
}
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 04711fe..b7bf979 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
@@ -4,6 +4,7 @@
package com.android.tools.r8.optimize.argumentpropagation.codescanner;
+import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.analysis.type.DynamicType;
@@ -57,6 +58,12 @@
}
@Override
+ public UnusedValueState getCorrespondingUnused() {
+ // We currently don't generate unused states for receivers.
+ throw new Unreachable();
+ }
+
+ @Override
public DynamicType getDynamicType() {
assert !dynamicType.isUnknown();
return dynamicType;
@@ -117,7 +124,8 @@
if (widenInFlow(appView)) {
return unknown();
}
- if (dynamicTypeChanged || inFlowChanged) {
+ boolean unusedChanged = mutableJoinUnused(inState);
+ if (dynamicTypeChanged || inFlowChanged || unusedChanged) {
onChangedAction.execute();
}
return this;
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 065159e..9833d99 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
@@ -27,6 +27,7 @@
}
private Set<InFlow> inFlow;
+ private boolean unused;
ConcreteValueState(Set<InFlow> inFlow) {
this.inFlow = inFlow;
@@ -60,6 +61,9 @@
if (isEffectivelyBottom()) {
return getCorrespondingBottom();
}
+ if (isEffectivelyUnused()) {
+ return getCorrespondingUnused();
+ }
}
assert !isEffectivelyBottom();
return this;
@@ -98,12 +102,22 @@
return traversalContinuation;
}
+ public boolean hasSeenUnused() {
+ return unused;
+ }
+
public abstract BottomValueState getCorrespondingBottom();
+ public abstract UnusedValueState getCorrespondingUnused();
+
public abstract ConcreteParameterStateKind getKind();
public final boolean isEffectivelyBottom() {
- return isEffectivelyBottomIgnoringInFlow() && !hasInFlow();
+ return !hasInFlow() && isEffectivelyBottomIgnoringInFlow() && !hasSeenUnused();
+ }
+
+ public final boolean isEffectivelyUnused() {
+ return !hasInFlow() && isEffectivelyBottomIgnoringInFlow() && hasSeenUnused();
}
public abstract boolean isEffectivelyBottomIgnoringInFlow();
@@ -145,12 +159,15 @@
DexType outStaticType,
StateCloner cloner,
Action onChangedAction) {
- if (inState.isBottom() || inState.isUnused()) {
+ if (inState.isBottom()) {
return this;
}
if (inState.isUnknown()) {
return unknown();
}
+ if (inState.isUnused()) {
+ return mutableJoinUnused(inState.asUnused());
+ }
ConcreteValueState concreteState = inState.asConcrete();
if (isReferenceState()) {
assert concreteState.isReferenceState();
@@ -181,6 +198,20 @@
return inFlow.addAll(otherInFlow);
}
+ public boolean mutableJoinUnused(ConcreteValueState other) {
+ if (!unused && other.unused) {
+ unused = true;
+ return true;
+ }
+ return false;
+ }
+
+ public ConcreteValueState mutableJoinUnused(UnusedValueState witness) {
+ assert witness != null;
+ unused = true;
+ return this;
+ }
+
/**
* Returns true if the in-parameters set should be widened to unknown, in which case the entire
* parameter state must be widened to unknown.
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/StateCloner.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/StateCloner.java
index 6843b58..0359b74 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/StateCloner.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/StateCloner.java
@@ -27,9 +27,10 @@
return methodState.mutableCopy();
}
+ @SuppressWarnings("unchecked")
@Override
- public ValueState mutableCopy(ValueState parameterState) {
- return parameterState.mutableCopy();
+ public <T extends ValueState> T mutableCopy(T parameterState) {
+ return (T) parameterState.mutableCopy();
}
};
@@ -41,7 +42,7 @@
}
@Override
- public ValueState mutableCopy(ValueState parameterState) {
+ public <T extends ValueState> T mutableCopy(T parameterState) {
return parameterState;
}
};
@@ -56,5 +57,5 @@
public abstract MethodState mutableCopy(MethodState methodState);
- public abstract ValueState mutableCopy(ValueState parameterState);
+ public abstract <T extends ValueState> T mutableCopy(T parameterState);
}
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/UnusedArrayTypeValueState.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/UnusedArrayTypeValueState.java
index e912bca..237b053 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/UnusedArrayTypeValueState.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/UnusedArrayTypeValueState.java
@@ -34,8 +34,15 @@
}
assert inState.isConcrete();
assert inState.asConcrete().isReferenceState();
- return ValueState.bottomArrayTypeState()
- .mutableJoin(appView, inState, inStaticType, outStaticType, cloner, onChangedAction);
+ ValueState result =
+ bottomArrayTypeState()
+ .mutableJoin(appView, inState, inStaticType, outStaticType, cloner, onChangedAction);
+ if (result.isConcrete()) {
+ return result.asConcrete().mutableJoinUnused(this);
+ } else {
+ assert result.isUnknown();
+ return result;
+ }
}
@Override
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/UnusedClassTypeValueState.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/UnusedClassTypeValueState.java
index 9e55e43..77b8e6d 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/UnusedClassTypeValueState.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/UnusedClassTypeValueState.java
@@ -34,8 +34,15 @@
}
assert inState.isConcrete();
assert inState.asConcrete().isReferenceState();
- return ValueState.bottomClassTypeState()
- .mutableJoin(appView, inState, inStaticType, outStaticType, cloner, onChangedAction);
+ ValueState result =
+ bottomClassTypeState()
+ .mutableJoin(appView, inState, inStaticType, outStaticType, cloner, onChangedAction);
+ if (result.isConcrete()) {
+ return result.asConcrete().mutableJoinUnused(this);
+ } else {
+ assert result.isUnknown();
+ return result;
+ }
}
@Override
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/UnusedPrimitiveTypeValueState.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/UnusedPrimitiveTypeValueState.java
index 1ea268a..b61b267 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/UnusedPrimitiveTypeValueState.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/UnusedPrimitiveTypeValueState.java
@@ -34,8 +34,7 @@
}
assert inState.isConcrete();
assert inState.asConcrete().isPrimitiveState();
- return ValueState.bottomPrimitiveTypeState()
- .mutableJoin(appView, inState, inStaticType, outStaticType, cloner, onChangedAction);
+ return cloner.mutableCopy(inState.asPrimitiveState()).mutableJoinUnused(this);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/UnusedValueState.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/UnusedValueState.java
index e4d7a81..26560ff 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/UnusedValueState.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/UnusedValueState.java
@@ -22,6 +22,11 @@
}
@Override
+ public final UnusedValueState asUnused() {
+ return this;
+ }
+
+ @Override
public final ValueState mutableCopy() {
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 9876db3..215b468 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
@@ -147,6 +147,10 @@
return false;
}
+ public UnusedValueState asUnused() {
+ return null;
+ }
+
public abstract ValueState mutableCopy();
public abstract ValueState mutableCopyWithoutInFlow();
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/propagation/InFlowPropagator.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/propagation/InFlowPropagator.java
index 840297c..752e59d 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/propagation/InFlowPropagator.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/propagation/InFlowPropagator.java
@@ -258,7 +258,7 @@
appView, flowGraphStateProvider, stateToPropagate, successorNode.getStaticType());
ValueState oldSuccessorStateForDebugging =
successorNode.getDebug() ? successorNode.getState().mutableCopy() : null;
- if (transferState.isBottom()) {
+ if (transferState.isBottom() || transferState.isUnused()) {
// Nothing to propagate.
} else if (transferState.isUnknown()) {
successorNode.setStateToUnknown();
@@ -359,6 +359,8 @@
appView.abstractValueFactory().createZeroValue());
}
monomorphicMethodState.setParameterState(i, replacement);
+ } else {
+ assert !parameterState.isConcrete() || !parameterState.asConcrete().isEffectivelyUnused();
}
}
}