Cache calls to internalComputeNonReceiverValueState

Change-Id: I37907ad087bfb1ead5dce4ba53d8c153ee074b73
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorCodeScanner.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorCodeScanner.java
index b994fe4..bea4ad0 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorCodeScanner.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorCodeScanner.java
@@ -230,6 +230,7 @@
     private ComposableComputationTreeBuilder composableComputationTreeBuilder;
 
     // State used by internalComputeNonReceiverValueState.
+    private Map<Value, NonEmptyValueState> cache = new IdentityHashMap<>();
     private Value initialValue;
     private DexType staticType;
     private ProgramMember<?, ?> target;
@@ -311,17 +312,25 @@
         return ValueState.unknown();
       }
 
+      assert this.cache.isEmpty();
       assert this.initialValue == null;
+      assert this.staticType == null;
+      assert this.target == null;
       this.initialValue = value;
       this.staticType = staticType;
       this.target = target;
-      NonEmptyValueState result = internalComputeNonReceiverValueState(value);
+      NonEmptyValueState result = internalGetOrComputeNonReceiverValueState(value);
+      this.cache.clear();
       this.initialValue = null;
       this.staticType = null;
       this.target = null;
       return result;
     }
 
+    private NonEmptyValueState internalGetOrComputeNonReceiverValueState(Value value) {
+      return cache.computeIfAbsent(value, this::internalComputeNonReceiverValueState);
+    }
+
     private NonEmptyValueState internalComputeNonReceiverValueState(Value value) {
       assert value == initialValue || initialValue.getAliasedValue().isPhi();
 
@@ -469,8 +478,8 @@
       if (condition.getSingleOpenVariable() == null) {
         return null;
       }
-      NonEmptyValueState leftValue = internalComputeNonReceiverValueState(phi.getOperand(0));
-      NonEmptyValueState rightValue = internalComputeNonReceiverValueState(phi.getOperand(1));
+      NonEmptyValueState leftValue = internalGetOrComputeNonReceiverValueState(phi.getOperand(0));
+      NonEmptyValueState rightValue = internalGetOrComputeNonReceiverValueState(phi.getOperand(1));
       if (leftValue.isUnknown() && rightValue.isUnknown()) {
         return null;
       }
@@ -624,14 +633,14 @@
                   }
                 }
               });
-      NonEmptyValueState state = internalComputeNonReceiverValueState(operands.get(0));
+      NonEmptyValueState state = internalGetOrComputeNonReceiverValueState(operands.get(0));
       for (int i = 1; i < operands.size(); i++) {
         Value operand = operands.get(i);
         state =
             state.mutableJoin(
                 appView,
                 appView.getDefaultAbstractValueJoiner(),
-                internalComputeNonReceiverValueState(operand),
+                internalGetOrComputeNonReceiverValueState(operand),
                 null,
                 staticType,
                 StateCloner.getIdentity());