Declare new unused argument propagation states
An unused value state is planned to be used for a parameter P when an invoke is seen to the method of P, but where the argument to P won't be used inside the method.
After argument propagation, if a parameter P has an unused value, the parameter can be removed.
The unused states differ from the bottom states in that bottom for a parameter P encodes that the parameter does not take any value at runtime (meaning the method of P must be unreachable).
Change-Id: If7ff6966823786e917bf1d6de24a8be2dad59b79
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 19f1a3d..645d3bc 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
@@ -34,6 +34,10 @@
if (inState.isUnknown()) {
return inState;
}
+ if (inState.isUnused()) {
+ assert inState.identical(unusedArrayTypeState());
+ return inState;
+ }
assert inState.isConcrete();
assert inState.asConcrete().isReferenceState();
ConcreteReferenceTypeValueState concreteState = inState.asConcrete().asReferenceState();
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 478ec19..1019811 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
@@ -36,6 +36,10 @@
if (inState.isUnknown()) {
return inState;
}
+ if (inState.isUnused()) {
+ assert inState.identical(unusedClassTypeState());
+ return inState;
+ }
assert inState.isConcrete();
assert inState.asConcrete().isReferenceState();
ConcreteReferenceTypeValueState concreteState = inState.asConcrete().asReferenceState();
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 b429da0..08f7a1d 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
@@ -34,6 +34,10 @@
if (inState.isUnknown()) {
return inState;
}
+ if (inState.isUnused()) {
+ assert inState.identical(unusedPrimitiveTypeState());
+ return inState;
+ }
assert inState.isPrimitiveState();
return cloner.mutableCopy(inState);
}
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 8e6764e..065159e 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
@@ -145,7 +145,7 @@
DexType outStaticType,
StateCloner cloner,
Action onChangedAction) {
- if (inState.isBottom()) {
+ if (inState.isBottom() || inState.isUnused()) {
return this;
}
if (inState.isUnknown()) {
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
new file mode 100644
index 0000000..e912bca
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/UnusedArrayTypeValueState.java
@@ -0,0 +1,45 @@
+// 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.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;
+
+public class UnusedArrayTypeValueState extends UnusedValueState {
+
+ private static final UnusedArrayTypeValueState INSTANCE = new UnusedArrayTypeValueState();
+
+ private UnusedArrayTypeValueState() {}
+
+ public static UnusedArrayTypeValueState get() {
+ return INSTANCE;
+ }
+
+ @Override
+ public ValueState mutableJoin(
+ AppView<AppInfoWithLiveness> appView,
+ ValueState inState,
+ DexType inStaticType,
+ DexType outStaticType,
+ StateCloner cloner,
+ Action onChangedAction) {
+ if (inState.isBottom() || inState.isUnused()) {
+ return this;
+ }
+ if (inState.isUnknown()) {
+ return inState;
+ }
+ assert inState.isConcrete();
+ assert inState.asConcrete().isReferenceState();
+ return ValueState.bottomArrayTypeState()
+ .mutableJoin(appView, inState, inStaticType, outStaticType, cloner, onChangedAction);
+ }
+
+ @Override
+ public String toString() {
+ return "UNUSED(ARRAY)";
+ }
+}
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
new file mode 100644
index 0000000..9e55e43
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/UnusedClassTypeValueState.java
@@ -0,0 +1,45 @@
+// 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.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;
+
+public class UnusedClassTypeValueState extends UnusedValueState {
+
+ private static final UnusedClassTypeValueState INSTANCE = new UnusedClassTypeValueState();
+
+ private UnusedClassTypeValueState() {}
+
+ public static UnusedClassTypeValueState get() {
+ return INSTANCE;
+ }
+
+ @Override
+ public ValueState mutableJoin(
+ AppView<AppInfoWithLiveness> appView,
+ ValueState inState,
+ DexType inStaticType,
+ DexType outStaticType,
+ StateCloner cloner,
+ Action onChangedAction) {
+ if (inState.isBottom() || inState.isUnused()) {
+ return this;
+ }
+ if (inState.isUnknown()) {
+ return inState;
+ }
+ assert inState.isConcrete();
+ assert inState.asConcrete().isReferenceState();
+ return ValueState.bottomClassTypeState()
+ .mutableJoin(appView, inState, inStaticType, outStaticType, cloner, onChangedAction);
+ }
+
+ @Override
+ public String toString() {
+ return "UNUSED(CLASS)";
+ }
+}
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
new file mode 100644
index 0000000..1ea268a
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/UnusedPrimitiveTypeValueState.java
@@ -0,0 +1,45 @@
+// 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.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;
+
+public class UnusedPrimitiveTypeValueState extends UnusedValueState {
+
+ private static final UnusedPrimitiveTypeValueState INSTANCE = new UnusedPrimitiveTypeValueState();
+
+ private UnusedPrimitiveTypeValueState() {}
+
+ public static UnusedPrimitiveTypeValueState get() {
+ return INSTANCE;
+ }
+
+ @Override
+ public ValueState mutableJoin(
+ AppView<AppInfoWithLiveness> appView,
+ ValueState inState,
+ DexType inStaticType,
+ DexType outStaticType,
+ StateCloner cloner,
+ Action onChangedAction) {
+ if (inState.isBottom() || inState.isUnused()) {
+ return this;
+ }
+ if (inState.isUnknown()) {
+ return inState;
+ }
+ assert inState.isConcrete();
+ assert inState.asConcrete().isPrimitiveState();
+ return ValueState.bottomPrimitiveTypeState()
+ .mutableJoin(appView, inState, inStaticType, outStaticType, cloner, onChangedAction);
+ }
+
+ @Override
+ public String toString() {
+ return "UNUSED(PRIMITIVE)";
+ }
+}
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
new file mode 100644
index 0000000..e4d7a81
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/codescanner/UnusedValueState.java
@@ -0,0 +1,43 @@
+// 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.optimize.argumentpropagation.codescanner;
+
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.ir.analysis.value.AbstractValue;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
+
+public abstract class UnusedValueState extends NonEmptyValueState {
+
+ UnusedValueState() {}
+
+ @Override
+ public final AbstractValue getAbstractValue(AppView<AppInfoWithLiveness> appView) {
+ return AbstractValue.bottom();
+ }
+
+ @Override
+ public final boolean isUnused() {
+ return true;
+ }
+
+ @Override
+ public final ValueState mutableCopy() {
+ return this;
+ }
+
+ @Override
+ public ValueState mutableCopyWithoutInFlow() {
+ return this;
+ }
+
+ @Override
+ public final boolean equals(Object obj) {
+ return this == obj;
+ }
+
+ @Override
+ public final int hashCode() {
+ return System.identityHashCode(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 ac29fa6..9876db3 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
@@ -54,6 +54,29 @@
return UnknownValueState.get();
}
+ public static UnusedValueState unused(DexType type) {
+ if (type.isArrayType()) {
+ return unusedArrayTypeState();
+ } else if (type.isClassType()) {
+ return unusedClassTypeState();
+ } else {
+ assert type.isPrimitiveType();
+ return unusedPrimitiveTypeState();
+ }
+ }
+
+ public static UnusedArrayTypeValueState unusedArrayTypeState() {
+ return UnusedArrayTypeValueState.get();
+ }
+
+ public static UnusedClassTypeValueState unusedClassTypeState() {
+ return UnusedClassTypeValueState.get();
+ }
+
+ public static UnusedPrimitiveTypeValueState unusedPrimitiveTypeState() {
+ return UnusedPrimitiveTypeValueState.get();
+ }
+
public abstract AbstractValue getAbstractValue(AppView<AppInfoWithLiveness> appView);
public boolean isArrayState() {
@@ -120,6 +143,10 @@
return false;
}
+ public boolean isUnused() {
+ return false;
+ }
+
public abstract ValueState mutableCopy();
public abstract ValueState mutableCopyWithoutInFlow();