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();