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 4f374e6..8b19ac3 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
@@ -211,644 +211,610 @@
       IRCode code,
       AbstractValueSupplier abstractValueSupplier,
       Timing timing) {
-    timing.begin("Argument propagation scanner");
-    for (Instruction instruction : code.instructions()) {
-      if (instruction.isFieldPut()) {
-        scan(instruction.asFieldPut(), abstractValueSupplier, method, timing);
-      } else if (instruction.isInvokeMethod()) {
-        scan(instruction.asInvokeMethod(), abstractValueSupplier, method, timing);
-      } else if (instruction.isInvokeCustom()) {
-        scan(instruction.asInvokeCustom());
-      }
-    }
-    timing.end();
+    new CodeScanner(abstractValueSupplier, code, method).scan(timing);
   }
 
-  private void scan(
-      FieldPut fieldPut,
-      AbstractValueSupplier abstractValueSupplier,
-      ProgramMethod context,
-      Timing timing) {
-    ProgramField field = fieldPut.resolveField(appView, context).getProgramField();
-    if (field == null) {
-      // Nothing to propagate.
-      return;
-    }
-    addTemporaryFieldState(fieldPut, field, abstractValueSupplier, context, timing);
-  }
+  protected class CodeScanner {
 
-  private void addTemporaryFieldState(
-      FieldPut fieldPut,
-      ProgramField field,
-      AbstractValueSupplier abstractValueSupplier,
-      ProgramMethod context,
-      Timing timing) {
-    timing.begin("Add field state");
-    fieldStates.addTemporaryFieldState(
-        field,
-        () -> computeFieldState(fieldPut, field, abstractValueSupplier, context, timing),
-        timing,
-        (existingFieldState, fieldStateToAdd) -> {
-          DexType inStaticType = null;
-          NonEmptyValueState newFieldState =
-              existingFieldState.mutableJoin(
-                  appView,
-                  fieldStateToAdd,
-                  inStaticType,
-                  field.getType(),
-                  StateCloner.getCloner(),
-                  Action.empty());
-          return narrowFieldState(field, newFieldState);
-        });
-    timing.end();
-  }
+    protected final AbstractValueSupplier abstractValueSupplier;
+    protected final IRCode code;
+    protected final ProgramMethod context;
 
-  private NonEmptyValueState computeFieldState(
-      FieldPut fieldPut,
-      ProgramField resolvedField,
-      AbstractValueSupplier abstractValueSupplier,
-      ProgramMethod context,
-      Timing timing) {
-    timing.begin("Compute field state for field-put");
-    NonEmptyValueState result =
-        computeFieldState(fieldPut, resolvedField, abstractValueSupplier, context);
-    timing.end();
-    return result;
-  }
-
-  private NonEmptyValueState computeFieldState(
-      FieldPut fieldPut,
-      ProgramField field,
-      AbstractValueSupplier abstractValueSupplier,
-      ProgramMethod context) {
-    TypeElement fieldType = field.getType().toTypeElement(appView);
-    if (!fieldPut.value().getType().lessThanOrEqual(fieldType, appView)) {
-      return ValueState.unknown();
+    protected CodeScanner(
+        AbstractValueSupplier abstractValueSupplier, IRCode code, ProgramMethod method) {
+      this.abstractValueSupplier = abstractValueSupplier;
+      this.code = code;
+      this.context = method;
     }
 
-    NonEmptyValueState inFlowState = computeInFlowState(field.getType(), fieldPut.value(), context);
-    if (inFlowState != null) {
-      return inFlowState;
-    }
-
-    if (field.getType().isArrayType()) {
-      Nullability nullability = fieldPut.value().getType().nullability();
-      return ConcreteArrayTypeValueState.create(nullability);
-    }
-
-    AbstractValue abstractValue = abstractValueSupplier.getAbstractValue(fieldPut.value());
-    if (abstractValue.isUnknown()) {
-      abstractValue =
-          getFallbackAbstractValueForField(
-              field,
-              () -> ObjectStateAnalysis.computeObjectState(fieldPut.value(), appView, context));
-    }
-    if (field.getType().isClassType()) {
-      DynamicType dynamicType =
-          WideningUtils.widenDynamicNonReceiverType(
-              appView, fieldPut.value().getDynamicType(appView), field.getType());
-      return ConcreteClassTypeValueState.create(abstractValue, dynamicType);
-    } else {
-      assert field.getType().isPrimitiveType();
-      return ConcretePrimitiveTypeValueState.create(abstractValue);
-    }
-  }
-
-  // If the value is an argument of the enclosing method or defined by a field-get, then clearly we
-  // have no information about its abstract value (yet). Instead of treating this as having an
-  // unknown runtime value, we instead record a flow constraint.
-  private InFlow computeInFlow(DexType staticType, Value value, ProgramMethod context) {
-    Value valueRoot = value.getAliasedValue(aliasedValueConfiguration);
-    if (valueRoot.isArgument()) {
-      MethodParameter inParameter =
-          methodParameterFactory.create(context, valueRoot.getDefinition().asArgument().getIndex());
-      return castBaseInFlow(widenBaseInFlow(staticType, inParameter, context), value);
-    } else if (valueRoot.isDefinedByInstructionSatisfying(Instruction::isFieldGet)) {
-      FieldGet fieldGet = valueRoot.getDefinition().asFieldGet();
-      ProgramField field = fieldGet.resolveField(appView, context).getProgramField();
-      if (field == null) {
-        return null;
-      }
-      if (fieldGet.isInstanceGet()) {
-        Value receiverValue = fieldGet.asInstanceGet().object();
-        BaseInFlow receiverInFlow =
-            asBaseInFlowOrNull(computeInFlow(staticType, receiverValue, context));
-        if (receiverInFlow != null
-            && receiverInFlow.equals(widenBaseInFlow(staticType, receiverInFlow, context))) {
-          return new InstanceFieldReadAbstractFunction(receiverInFlow, field.getReference());
+    public void scan(Timing timing) {
+      timing.begin("Argument propagation scanner");
+      for (Instruction instruction : code.instructions()) {
+        if (instruction.isFieldPut()) {
+          scanFieldPut(instruction.asFieldPut(), timing);
+        } else if (instruction.isInvokeMethod()) {
+          scanInvoke(instruction.asInvokeMethod(), timing);
+        } else if (instruction.isInvokeCustom()) {
+          scanInvokeCustom(instruction.asInvokeCustom());
         }
       }
-      return castBaseInFlow(
-          widenBaseInFlow(staticType, fieldValueFactory.create(field), context), value);
+      timing.end();
     }
-    return null;
-  }
 
-  private InFlow castBaseInFlow(InFlow inFlow, Value value) {
-    if (inFlow.isUnknownAbstractFunction()) {
-      return inFlow;
-    }
-    assert inFlow.isBaseInFlow();
-    Value valueRoot = value.getAliasedValue();
-    if (!valueRoot.isDefinedByInstructionSatisfying(Instruction::isCheckCast)) {
-      return inFlow;
-    }
-    CheckCast checkCast = valueRoot.getDefinition().asCheckCast();
-    return new CastAbstractFunction(inFlow.asBaseInFlow(), checkCast.getType());
-  }
-
-  private InFlow widenBaseInFlow(DexType staticType, BaseInFlow inFlow, ProgramMethod context) {
-    if (inFlow.isFieldValue()) {
-      if (isFieldValueAlreadyUnknown(staticType, inFlow.asFieldValue().getField())) {
-        return AbstractFunction.unknown();
+    private void scanFieldPut(FieldPut fieldPut, Timing timing) {
+      ProgramField field = fieldPut.resolveField(appView, context).getProgramField();
+      if (field == null) {
+        // Nothing to propagate.
+        return;
       }
-    } else {
-      assert inFlow.isMethodParameter();
-      if (isMethodParameterAlreadyUnknown(staticType, inFlow.asMethodParameter(), context)) {
-        return AbstractFunction.unknown();
-      }
+      addTemporaryFieldState(fieldPut, field, timing);
     }
-    return inFlow;
-  }
 
-  private NonEmptyValueState computeInFlowState(
-      DexType staticType, Value value, ProgramMethod context) {
-    InFlow inFlow = computeInFlow(staticType, value, context);
-    if (inFlow == null) {
-      return null;
+    private void addTemporaryFieldState(FieldPut fieldPut, ProgramField field, Timing timing) {
+      timing.begin("Add field state");
+      fieldStates.addTemporaryFieldState(
+          field,
+          () -> computeFieldState(fieldPut, field, timing),
+          timing,
+          (existingFieldState, fieldStateToAdd) -> {
+            DexType inStaticType = null;
+            NonEmptyValueState newFieldState =
+                existingFieldState.mutableJoin(
+                    appView,
+                    fieldStateToAdd,
+                    inStaticType,
+                    field.getType(),
+                    StateCloner.getCloner(),
+                    Action.empty());
+            return narrowFieldState(field, newFieldState);
+          });
+      timing.end();
     }
-    if (inFlow.isUnknownAbstractFunction()) {
-      return ValueState.unknown();
-    }
-    assert inFlow.isBaseInFlow()
-        || inFlow.isCastAbstractFunction()
-        || inFlow.isInstanceFieldReadAbstractFunction();
-    return ConcreteValueState.create(staticType, inFlow);
-  }
 
-  // Strengthens the abstract value of static final fields to a (self-)SingleFieldValue when the
-  // abstract value is unknown. The soundness of this is based on the fact that static final fields
-  // will never have their value changed after the <clinit> finishes, so value in a static final
-  // field can always be rematerialized by reading the field.
-  private NonEmptyValueState narrowFieldState(ProgramField field, NonEmptyValueState fieldState) {
-    AbstractValue fallbackAbstractValue =
-        getFallbackAbstractValueForField(field, ObjectState::empty);
-    if (!fallbackAbstractValue.isUnknown()) {
-      AbstractValue abstractValue = fieldState.getAbstractValue(appView);
-      if (!abstractValue.isUnknown()) {
-        return fieldState;
+    private NonEmptyValueState computeFieldState(
+        FieldPut fieldPut, ProgramField resolvedField, Timing timing) {
+      timing.begin("Compute field state for field-put");
+      NonEmptyValueState result = computeFieldState(fieldPut, resolvedField);
+      timing.end();
+      return result;
+    }
+
+    private NonEmptyValueState computeFieldState(FieldPut fieldPut, ProgramField field) {
+      TypeElement fieldType = field.getType().toTypeElement(appView);
+      if (!fieldPut.value().getType().lessThanOrEqual(fieldType, appView)) {
+        return ValueState.unknown();
       }
+
+      NonEmptyValueState inFlowState =
+          computeInFlowState(field.getType(), fieldPut.value(), context);
+      if (inFlowState != null) {
+        return inFlowState;
+      }
+
       if (field.getType().isArrayType()) {
-        // We do not track an abstract value for array types.
-        return fieldState;
+        Nullability nullability = fieldPut.value().getType().nullability();
+        return ConcreteArrayTypeValueState.create(nullability);
+      }
+
+      AbstractValue abstractValue = abstractValueSupplier.getAbstractValue(fieldPut.value());
+      if (abstractValue.isUnknown()) {
+        abstractValue =
+            getFallbackAbstractValueForField(
+                field,
+                () -> ObjectStateAnalysis.computeObjectState(fieldPut.value(), appView, context));
       }
       if (field.getType().isClassType()) {
         DynamicType dynamicType =
-            fieldState.isReferenceState()
-                ? fieldState.asReferenceState().getDynamicType()
-                : DynamicType.unknown();
-        return new ConcreteClassTypeValueState(fallbackAbstractValue, dynamicType);
+            WideningUtils.widenDynamicNonReceiverType(
+                appView, fieldPut.value().getDynamicType(appView), field.getType());
+        return ConcreteClassTypeValueState.create(abstractValue, dynamicType);
       } else {
         assert field.getType().isPrimitiveType();
-        return new ConcretePrimitiveTypeValueState(fallbackAbstractValue);
+        return ConcretePrimitiveTypeValueState.create(abstractValue);
       }
     }
-    return fieldState;
-  }
 
-  private AbstractValue getFallbackAbstractValueForField(
-      ProgramField field, Supplier<ObjectState> objectStateSupplier) {
-    if (field.isFinalOrEffectivelyFinal(appView) && field.getAccessFlags().isStatic()) {
-      return appView
-          .abstractValueFactory()
-          .createSingleFieldValue(field.getReference(), objectStateSupplier.get());
-    }
-    return AbstractValue.unknown();
-  }
-
-  private void scan(
-      InvokeMethod invoke,
-      AbstractValueSupplier abstractValueSupplier,
-      ProgramMethod context,
-      Timing timing) {
-    DexMethod invokedMethod = invoke.getInvokedMethod();
-    if (invokedMethod.getHolderType().isArrayType()) {
-      // Nothing to propagate; the targeted method is not a program method.
-      return;
+    // If the value is an argument of the enclosing method or defined by a field-get, then clearly
+    // we have no information about its abstract value (yet). Instead of treating this as having an
+    // unknown runtime value, we instead record a flow constraint.
+    private InFlow computeInFlow(DexType staticType, Value value, ProgramMethod context) {
+      Value valueRoot = value.getAliasedValue(aliasedValueConfiguration);
+      if (valueRoot.isArgument()) {
+        MethodParameter inParameter =
+            methodParameterFactory.create(
+                context, valueRoot.getDefinition().asArgument().getIndex());
+        return castBaseInFlow(widenBaseInFlow(staticType, inParameter, context), value);
+      } else if (valueRoot.isDefinedByInstructionSatisfying(Instruction::isFieldGet)) {
+        FieldGet fieldGet = valueRoot.getDefinition().asFieldGet();
+        ProgramField field = fieldGet.resolveField(appView, context).getProgramField();
+        if (field == null) {
+          return null;
+        }
+        if (fieldGet.isInstanceGet()) {
+          Value receiverValue = fieldGet.asInstanceGet().object();
+          BaseInFlow receiverInFlow =
+              asBaseInFlowOrNull(computeInFlow(staticType, receiverValue, context));
+          if (receiverInFlow != null
+              && receiverInFlow.equals(widenBaseInFlow(staticType, receiverInFlow, context))) {
+            return new InstanceFieldReadAbstractFunction(receiverInFlow, field.getReference());
+          }
+        }
+        return castBaseInFlow(
+            widenBaseInFlow(staticType, fieldValueFactory.create(field), context), value);
+      }
+      return null;
     }
 
-    if (appView.options().testing.checkReceiverAlwaysNullInCallSiteOptimization
-        && invoke.isInvokeMethodWithReceiver()
-        && invoke.asInvokeMethodWithReceiver().getReceiver().isAlwaysNull(appView)) {
-      // Nothing to propagate; the invoke instruction always fails.
-      return;
+    private InFlow castBaseInFlow(InFlow inFlow, Value value) {
+      if (inFlow.isUnknownAbstractFunction()) {
+        return inFlow;
+      }
+      assert inFlow.isBaseInFlow();
+      Value valueRoot = value.getAliasedValue();
+      if (!valueRoot.isDefinedByInstructionSatisfying(Instruction::isCheckCast)) {
+        return inFlow;
+      }
+      CheckCast checkCast = valueRoot.getDefinition().asCheckCast();
+      return new CastAbstractFunction(inFlow.asBaseInFlow(), checkCast.getType());
     }
 
-    SingleResolutionResult<?> resolutionResult =
-        invoke.resolveMethod(appView, context).asSingleResolution();
-    if (resolutionResult == null) {
-      // Nothing to propagate; the invoke instruction fails.
-      return;
+    private InFlow widenBaseInFlow(DexType staticType, BaseInFlow inFlow, ProgramMethod context) {
+      if (inFlow.isFieldValue()) {
+        if (isFieldValueAlreadyUnknown(staticType, inFlow.asFieldValue().getField())) {
+          return AbstractFunction.unknown();
+        }
+      } else {
+        assert inFlow.isMethodParameter();
+        if (isMethodParameterAlreadyUnknown(staticType, inFlow.asMethodParameter(), context)) {
+          return AbstractFunction.unknown();
+        }
+      }
+      return inFlow;
     }
 
-    if (!resolutionResult.getResolvedHolder().isProgramClass()) {
-      // Nothing to propagate; this could dispatch to a program method, but we cannot optimize
-      // methods that override non-program methods.
-      return;
+    private NonEmptyValueState computeInFlowState(
+        DexType staticType, Value value, ProgramMethod context) {
+      InFlow inFlow = computeInFlow(staticType, value, context);
+      if (inFlow == null) {
+        return null;
+      }
+      if (inFlow.isUnknownAbstractFunction()) {
+        return ValueState.unknown();
+      }
+      assert inFlow.isBaseInFlow()
+          || inFlow.isCastAbstractFunction()
+          || inFlow.isInstanceFieldReadAbstractFunction();
+      return ConcreteValueState.create(staticType, inFlow);
     }
 
-    ProgramMethod resolvedMethod = resolutionResult.getResolvedProgramMethod();
-    if (resolvedMethod.getDefinition().isLibraryMethodOverride().isPossiblyTrue()) {
-      assert resolvedMethod.getDefinition().isLibraryMethodOverride().isTrue();
-      // Nothing to propagate; we don't know anything about methods that can be called from outside
-      // the program.
-      return;
+    // Strengthens the abstract value of static final fields to a (self-)SingleFieldValue when the
+    // abstract value is unknown. The soundness of this is based on the fact that static final
+    // fields will never have their value changed after the <clinit> finishes, so value in a static
+    // final field can always be rematerialized by reading the field.
+    private NonEmptyValueState narrowFieldState(ProgramField field, NonEmptyValueState fieldState) {
+      AbstractValue fallbackAbstractValue =
+          getFallbackAbstractValueForField(field, ObjectState::empty);
+      if (!fallbackAbstractValue.isUnknown()) {
+        AbstractValue abstractValue = fieldState.getAbstractValue(appView);
+        if (!abstractValue.isUnknown()) {
+          return fieldState;
+        }
+        if (field.getType().isArrayType()) {
+          // We do not track an abstract value for array types.
+          return fieldState;
+        }
+        if (field.getType().isClassType()) {
+          DynamicType dynamicType =
+              fieldState.isReferenceState()
+                  ? fieldState.asReferenceState().getDynamicType()
+                  : DynamicType.unknown();
+          return new ConcreteClassTypeValueState(fallbackAbstractValue, dynamicType);
+        } else {
+          assert field.getType().isPrimitiveType();
+          return new ConcretePrimitiveTypeValueState(fallbackAbstractValue);
+        }
+      }
+      return fieldState;
     }
 
-    if (invoke.arguments().size() != resolvedMethod.getDefinition().getNumberOfArguments()
-        || invoke.isInvokeStatic() != resolvedMethod.getAccessFlags().isStatic()) {
-      // Nothing to propagate; the invoke instruction fails.
-      return;
+    private AbstractValue getFallbackAbstractValueForField(
+        ProgramField field, Supplier<ObjectState> objectStateSupplier) {
+      if (field.isFinalOrEffectivelyFinal(appView) && field.getAccessFlags().isStatic()) {
+        return appView
+            .abstractValueFactory()
+            .createSingleFieldValue(field.getReference(), objectStateSupplier.get());
+      }
+      return AbstractValue.unknown();
     }
 
-    if (invoke.isInvokeInterface()) {
-      if (!resolutionResult.getInitialResolutionHolder().isInterface()) {
+    private void scanInvoke(InvokeMethod invoke, Timing timing) {
+      DexMethod invokedMethod = invoke.getInvokedMethod();
+      if (invokedMethod.getHolderType().isArrayType()) {
+        // Nothing to propagate; the targeted method is not a program method.
+        return;
+      }
+
+      if (appView.options().testing.checkReceiverAlwaysNullInCallSiteOptimization
+          && invoke.isInvokeMethodWithReceiver()
+          && invoke.asInvokeMethodWithReceiver().getReceiver().isAlwaysNull(appView)) {
+        // Nothing to propagate; the invoke instruction always fails.
+        return;
+      }
+
+      SingleResolutionResult<?> resolutionResult =
+          invoke.resolveMethod(appView, context).asSingleResolution();
+      if (resolutionResult == null) {
         // Nothing to propagate; the invoke instruction fails.
         return;
       }
-    }
 
-    if (invoke.isInvokeSuper()) {
-      // Use the super target instead of the resolved method to ensure that we propagate the
-      // argument information to the targeted method.
-      DexClassAndMethod target =
-          resolutionResult.lookupInvokeSuperTarget(context.getHolder(), appView);
-      if (target == null) {
+      if (!resolutionResult.getResolvedHolder().isProgramClass()) {
+        // Nothing to propagate; this could dispatch to a program method, but we cannot optimize
+        // methods that override non-program methods.
+        return;
+      }
+
+      ProgramMethod resolvedMethod = resolutionResult.getResolvedProgramMethod();
+      if (resolvedMethod.getDefinition().isLibraryMethodOverride().isPossiblyTrue()) {
+        assert resolvedMethod.getDefinition().isLibraryMethodOverride().isTrue();
+        // Nothing to propagate; we don't know anything about methods that can be called from
+        // outside the program.
+        return;
+      }
+
+      if (invoke.arguments().size() != resolvedMethod.getDefinition().getNumberOfArguments()
+          || invoke.isInvokeStatic() != resolvedMethod.getAccessFlags().isStatic()) {
         // Nothing to propagate; the invoke instruction fails.
         return;
       }
-      if (!target.isProgramMethod()) {
-        throw new Unreachable(
-            "Expected super target of a non-library override to be a program method ("
-                + "resolved program method: "
-                + resolvedMethod
-                + ", "
-                + "super non-program method: "
-                + target
-                + ")");
+
+      if (invoke.isInvokeInterface()) {
+        if (!resolutionResult.getInitialResolutionHolder().isInterface()) {
+          // Nothing to propagate; the invoke instruction fails.
+          return;
+        }
       }
-      resolvedMethod = target.asProgramMethod();
+
+      if (invoke.isInvokeSuper()) {
+        // Use the super target instead of the resolved method to ensure that we propagate the
+        // argument information to the targeted method.
+        DexClassAndMethod target =
+            resolutionResult.lookupInvokeSuperTarget(context.getHolder(), appView);
+        if (target == null) {
+          // Nothing to propagate; the invoke instruction fails.
+          return;
+        }
+        if (!target.isProgramMethod()) {
+          throw new Unreachable(
+              "Expected super target of a non-library override to be a program method ("
+                  + "resolved program method: "
+                  + resolvedMethod
+                  + ", "
+                  + "super non-program method: "
+                  + target
+                  + ")");
+        }
+        resolvedMethod = target.asProgramMethod();
+      }
+
+      // Find the method where to store the information about the arguments from this invoke.
+      // If the invoke may dispatch to more than one method, we intentionally do not compute all
+      // possible dispatch targets and propagate the information to these methods (this is
+      // expensive). Instead we record the information in one place and then later propagate the
+      // information to all dispatch targets.
+      addTemporaryMethodState(invoke, resolvedMethod, timing);
     }
 
-    // Find the method where to store the information about the arguments from this invoke.
-    // If the invoke may dispatch to more than one method, we intentionally do not compute all
-    // possible dispatch targets and propagate the information to these methods (this is expensive).
-    // Instead we record the information in one place and then later propagate the information to
-    // all dispatch targets.
-    addTemporaryMethodState(invoke, resolvedMethod, abstractValueSupplier, context, timing);
-  }
+    protected void addTemporaryMethodState(
+        InvokeMethod invoke, ProgramMethod resolvedMethod, Timing timing) {
+      timing.begin("Add method state");
+      methodStates.addTemporaryMethodState(
+          appView,
+          getRepresentative(invoke, resolvedMethod),
+          existingMethodState ->
+              computeMethodState(invoke, resolvedMethod, existingMethodState, timing),
+          timing);
+      timing.end();
+    }
 
-  protected void addTemporaryMethodState(
-      InvokeMethod invoke,
-      ProgramMethod resolvedMethod,
-      AbstractValueSupplier abstractValueSupplier,
-      ProgramMethod context,
-      Timing timing) {
-    timing.begin("Add method state");
-    methodStates.addTemporaryMethodState(
-        appView,
-        getRepresentative(invoke, resolvedMethod),
-        existingMethodState ->
-            computeMethodState(
+    private MethodState computeMethodState(
+        InvokeMethod invoke,
+        ProgramMethod resolvedMethod,
+        MethodState existingMethodState,
+        Timing timing) {
+      assert !existingMethodState.isUnknown();
+
+      // If this invoke may target at most one method, then we compute a state that maps each
+      // parameter to the abstract value and dynamic type provided by this call site. Otherwise, we
+      // compute a polymorphic method state, which includes information about the receiver's dynamic
+      // type bounds.
+      timing.begin("Compute method state for invoke");
+      MethodState result;
+      if (shouldUsePolymorphicMethodState(invoke, resolvedMethod)) {
+        assert existingMethodState.isBottom() || existingMethodState.isPolymorphic();
+        result =
+            computePolymorphicMethodState(
+                invoke.asInvokeMethodWithReceiver(),
+                resolvedMethod,
+                existingMethodState.asPolymorphicOrBottom());
+      } else {
+        assert existingMethodState.isBottom() || existingMethodState.isMonomorphic();
+        result =
+            computeMonomorphicMethodState(
                 invoke,
                 resolvedMethod,
-                abstractValueSupplier,
-                context,
-                existingMethodState,
-                timing),
-        timing);
-    timing.end();
-  }
+                invoke.lookupSingleProgramTarget(appView, context),
+                existingMethodState.asMonomorphicOrBottom());
+      }
+      timing.end();
+      return result;
+    }
 
-  private MethodState computeMethodState(
-      InvokeMethod invoke,
-      ProgramMethod resolvedMethod,
-      AbstractValueSupplier abstractValueSupplier,
-      ProgramMethod context,
-      MethodState existingMethodState,
-      Timing timing) {
-    assert !existingMethodState.isUnknown();
+    // TODO(b/190154391): Add a strategy that widens the dynamic receiver type to allow easily
+    //  experimenting with the performance/size trade-off between precise/imprecise handling of
+    //  dynamic dispatch.
+    private MethodState computePolymorphicMethodState(
+        InvokeMethodWithReceiver invoke,
+        ProgramMethod resolvedMethod,
+        ConcretePolymorphicMethodStateOrBottom existingMethodState) {
+      DynamicTypeWithUpperBound dynamicReceiverType = invoke.getReceiver().getDynamicType(appView);
+      // TODO(b/331587404): Investigate if we can replace the receiver by null before entering this
+      //  pass, so that this special case is not needed.
+      if (dynamicReceiverType.isNullType()) {
+        assert appView.testing().allowNullDynamicTypeInCodeScanner : "b/250634405";
+        // This can happen if we were unable to determine that the receiver is a phi value where
+        // null information has not been propagated down. Ideally this case would never happen as it
+        // should be possible to replace the receiver by the null constant in this case. Since the
+        // receiver is known to be null, no argument information should be propagated to the
+        // callees, so we return bottom here.
+        return MethodState.bottom();
+      }
 
-    // If this invoke may target at most one method, then we compute a state that maps each
-    // parameter to the abstract value and dynamic type provided by this call site. Otherwise, we
-    // compute a polymorphic method state, which includes information about the receiver's dynamic
-    // type bounds.
-    timing.begin("Compute method state for invoke");
-    MethodState result;
-    if (shouldUsePolymorphicMethodState(invoke, resolvedMethod)) {
-      assert existingMethodState.isBottom() || existingMethodState.isPolymorphic();
-      result =
-          computePolymorphicMethodState(
-              invoke.asInvokeMethodWithReceiver(),
-              resolvedMethod,
-              abstractValueSupplier,
-              context,
-              existingMethodState.asPolymorphicOrBottom());
-    } else {
-      assert existingMethodState.isBottom() || existingMethodState.isMonomorphic();
-      result =
+      ProgramMethod singleTarget = invoke.lookupSingleProgramTarget(appView, context);
+      DynamicTypeWithUpperBound bounds =
+          computeBoundsForPolymorphicMethodState(resolvedMethod, singleTarget, dynamicReceiverType);
+      MethodState existingMethodStateForBounds =
+          existingMethodState.isPolymorphic()
+              ? existingMethodState.asPolymorphic().getMethodStateForBounds(bounds)
+              : MethodState.bottom();
+
+      if (existingMethodStateForBounds.isPolymorphic()) {
+        assert false;
+        return MethodState.unknown();
+      }
+
+      // If we already don't know anything about the parameters for the given type bounds, then
+      // don't compute a method state.
+      if (existingMethodStateForBounds.isUnknown()) {
+        return MethodState.bottom();
+      }
+
+      ConcreteMonomorphicMethodStateOrUnknown methodStateForBounds =
           computeMonomorphicMethodState(
               invoke,
               resolvedMethod,
-              invoke.lookupSingleProgramTarget(appView, context),
-              abstractValueSupplier,
-              context,
-              existingMethodState.asMonomorphicOrBottom());
-    }
-    timing.end();
-    return result;
-  }
-
-  // TODO(b/190154391): Add a strategy that widens the dynamic receiver type to allow easily
-  //  experimenting with the performance/size trade-off between precise/imprecise handling of
-  //  dynamic dispatch.
-  private MethodState computePolymorphicMethodState(
-      InvokeMethodWithReceiver invoke,
-      ProgramMethod resolvedMethod,
-      AbstractValueSupplier abstractValueSupplier,
-      ProgramMethod context,
-      ConcretePolymorphicMethodStateOrBottom existingMethodState) {
-    DynamicTypeWithUpperBound dynamicReceiverType = invoke.getReceiver().getDynamicType(appView);
-    // TODO(b/331587404): Investigate if we can replace the receiver by null before entering this
-    //  pass, so that this special case is not needed.
-    if (dynamicReceiverType.isNullType()) {
-      assert appView.testing().allowNullDynamicTypeInCodeScanner : "b/250634405";
-      // This can happen if we were unable to determine that the receiver is a phi value where null
-      // information has not been propagated down. Ideally this case would never happen as it should
-      // be possible to replace the receiver by the null constant in this case.
-      //
-      // Since the receiver is known to be null, no argument information should be propagated to the
-      // callees, so we return bottom here.
-      return MethodState.bottom();
+              singleTarget,
+              existingMethodStateForBounds.asMonomorphicOrBottom(),
+              dynamicReceiverType);
+      return ConcretePolymorphicMethodState.create(bounds, methodStateForBounds);
     }
 
-    ProgramMethod singleTarget = invoke.lookupSingleProgramTarget(appView, context);
-    DynamicTypeWithUpperBound bounds =
-        computeBoundsForPolymorphicMethodState(resolvedMethod, singleTarget, dynamicReceiverType);
-    MethodState existingMethodStateForBounds =
-        existingMethodState.isPolymorphic()
-            ? existingMethodState.asPolymorphic().getMethodStateForBounds(bounds)
-            : MethodState.bottom();
+    private DynamicTypeWithUpperBound computeBoundsForPolymorphicMethodState(
+        ProgramMethod resolvedMethod,
+        ProgramMethod singleTarget,
+        DynamicTypeWithUpperBound dynamicReceiverType) {
+      DynamicTypeWithUpperBound bounds =
+          singleTarget != null
+              ? DynamicType.createExact(
+                  singleTarget.getHolderType().toTypeElement(appView).asClassType())
+              : dynamicReceiverType.withNullability(Nullability.maybeNull());
 
-    if (existingMethodStateForBounds.isPolymorphic()) {
-      assert false;
-      return MethodState.unknown();
-    }
+      // We intentionally drop the nullability for the type bounds. This increases the number of
+      // collisions in the polymorphic method states, which does not change the precision (since the
+      // nullability does not have any impact on the possible dispatch targets) and is good for
+      // state pruning.
+      assert bounds.getDynamicUpperBoundType().nullability().isMaybeNull();
 
-    // If we already don't know anything about the parameters for the given type bounds, then don't
-    // compute a method state.
-    if (existingMethodStateForBounds.isUnknown()) {
-      return MethodState.bottom();
-    }
+      // If the bounds are trivial (i.e., the upper bound is equal to the holder of the virtual root
+      // method), then widen the type bounds to 'unknown'.
+      DexMethod virtualRootMethod = getVirtualRootMethod(resolvedMethod);
+      if (virtualRootMethod == null) {
+        assert false : "Unexpected virtual method without root: " + resolvedMethod;
+        return bounds;
+      }
 
-    ConcreteMonomorphicMethodStateOrUnknown methodStateForBounds =
-        computeMonomorphicMethodState(
-            invoke,
-            resolvedMethod,
-            singleTarget,
-            abstractValueSupplier,
-            context,
-            existingMethodStateForBounds.asMonomorphicOrBottom(),
-            dynamicReceiverType);
-    return ConcretePolymorphicMethodState.create(bounds, methodStateForBounds);
-  }
-
-  private DynamicTypeWithUpperBound computeBoundsForPolymorphicMethodState(
-      ProgramMethod resolvedMethod,
-      ProgramMethod singleTarget,
-      DynamicTypeWithUpperBound dynamicReceiverType) {
-    DynamicTypeWithUpperBound bounds =
-        singleTarget != null
-            ? DynamicType.createExact(
-                singleTarget.getHolderType().toTypeElement(appView).asClassType())
-            : dynamicReceiverType.withNullability(Nullability.maybeNull());
-
-    // We intentionally drop the nullability for the type bounds. This increases the number of
-    // collisions in the polymorphic method states, which does not change the precision (since the
-    // nullability does not have any impact on the possible dispatch targets) and is good for state
-    // pruning.
-    assert bounds.getDynamicUpperBoundType().nullability().isMaybeNull();
-
-    // If the bounds are trivial (i.e., the upper bound is equal to the holder of the virtual root
-    // method), then widen the type bounds to 'unknown'.
-    DexMethod virtualRootMethod = getVirtualRootMethod(resolvedMethod);
-    if (virtualRootMethod == null) {
-      assert false : "Unexpected virtual method without root: " + resolvedMethod;
+      DynamicType trivialBounds =
+          DynamicType.create(
+              appView, virtualRootMethod.getHolderType().toTypeElement(appView).asClassType());
+      if (bounds.equals(trivialBounds)) {
+        return DynamicType.unknown();
+      }
       return bounds;
     }
 
-    DynamicType trivialBounds =
-        DynamicType.create(
-            appView, virtualRootMethod.getHolderType().toTypeElement(appView).asClassType());
-    if (bounds.equals(trivialBounds)) {
-      return DynamicType.unknown();
-    }
-    return bounds;
-  }
-
-  private ConcreteMonomorphicMethodStateOrUnknown computeMonomorphicMethodState(
-      InvokeMethod invoke,
-      ProgramMethod resolvedMethod,
-      ProgramMethod singleTarget,
-      AbstractValueSupplier abstractValueSupplier,
-      ProgramMethod context,
-      ConcreteMonomorphicMethodStateOrBottom existingMethodState) {
-    return computeMonomorphicMethodState(
-        invoke,
-        resolvedMethod,
-        singleTarget,
-        abstractValueSupplier,
-        context,
-        existingMethodState,
-        invoke.isInvokeMethodWithReceiver()
-            ? invoke.getFirstArgument().getDynamicType(appView)
-            : null);
-  }
-
-  @SuppressWarnings("UnusedVariable")
-  private ConcreteMonomorphicMethodStateOrUnknown computeMonomorphicMethodState(
-      InvokeMethod invoke,
-      ProgramMethod resolvedMethod,
-      ProgramMethod singleTarget,
-      AbstractValueSupplier abstractValueSupplier,
-      ProgramMethod context,
-      ConcreteMonomorphicMethodStateOrBottom existingMethodState,
-      DynamicType dynamicReceiverType) {
-    List<ValueState> parameterStates = new ArrayList<>(invoke.arguments().size());
-
-    MethodReprocessingCriteria methodReprocessingCriteria =
-        singleTarget != null
-            ? reprocessingCriteriaCollection.getReprocessingCriteria(singleTarget)
-            : MethodReprocessingCriteria.alwaysReprocess();
-
-    int argumentIndex = 0;
-    if (invoke.isInvokeMethodWithReceiver()) {
-      assert dynamicReceiverType != null;
-      parameterStates.add(
-          computeParameterStateForReceiver(
-              resolvedMethod,
-              dynamicReceiverType,
-              existingMethodState,
-              methodReprocessingCriteria.getParameterReprocessingCriteria(0)));
-      argumentIndex++;
+    private ConcreteMonomorphicMethodStateOrUnknown computeMonomorphicMethodState(
+        InvokeMethod invoke,
+        ProgramMethod resolvedMethod,
+        ProgramMethod singleTarget,
+        ConcreteMonomorphicMethodStateOrBottom existingMethodState) {
+      return computeMonomorphicMethodState(
+          invoke,
+          resolvedMethod,
+          singleTarget,
+          existingMethodState,
+          invoke.isInvokeMethodWithReceiver()
+              ? invoke.getFirstArgument().getDynamicType(appView)
+              : null);
     }
 
-    for (; argumentIndex < invoke.arguments().size(); argumentIndex++) {
-      parameterStates.add(
-          computeParameterStateForNonReceiver(
-              invoke,
-              singleTarget,
-              argumentIndex,
-              invoke.getArgument(argumentIndex),
-              abstractValueSupplier,
-              context,
-              existingMethodState));
+    @SuppressWarnings("UnusedVariable")
+    private ConcreteMonomorphicMethodStateOrUnknown computeMonomorphicMethodState(
+        InvokeMethod invoke,
+        ProgramMethod resolvedMethod,
+        ProgramMethod singleTarget,
+        ConcreteMonomorphicMethodStateOrBottom existingMethodState,
+        DynamicType dynamicReceiverType) {
+      List<ValueState> parameterStates = new ArrayList<>(invoke.arguments().size());
+
+      MethodReprocessingCriteria methodReprocessingCriteria =
+          singleTarget != null
+              ? reprocessingCriteriaCollection.getReprocessingCriteria(singleTarget)
+              : MethodReprocessingCriteria.alwaysReprocess();
+
+      int argumentIndex = 0;
+      if (invoke.isInvokeMethodWithReceiver()) {
+        assert dynamicReceiverType != null;
+        parameterStates.add(
+            computeParameterStateForReceiver(
+                resolvedMethod,
+                dynamicReceiverType,
+                existingMethodState,
+                methodReprocessingCriteria.getParameterReprocessingCriteria(0)));
+        argumentIndex++;
+      }
+
+      for (; argumentIndex < invoke.arguments().size(); argumentIndex++) {
+        parameterStates.add(
+            computeParameterStateForNonReceiver(
+                invoke,
+                singleTarget,
+                argumentIndex,
+                invoke.getArgument(argumentIndex),
+                existingMethodState));
+      }
+
+      // We simulate that the return value is used for methods with void return type. This ensures
+      // that we will widen the method state to unknown if/when all parameter states become unknown.
+      boolean isReturnValueUsed = invoke.getReturnType().isVoidType() || invoke.hasUsedOutValue();
+      return ConcreteMonomorphicMethodState.create(isReturnValueUsed, parameterStates);
     }
 
-    // We simulate that the return value is used for methods with void return type. This ensures
-    // that we will widen the method state to unknown if/when all parameter states become unknown.
-    boolean isReturnValueUsed = invoke.getReturnType().isVoidType() || invoke.hasUsedOutValue();
-    return ConcreteMonomorphicMethodState.create(isReturnValueUsed, parameterStates);
-  }
+    // For receivers there is not much point in trying to track an abstract value. Therefore we only
+    // track the dynamic type for receivers.
+    // TODO(b/190154391): Consider validating the above hypothesis by using
+    //  computeParameterStateForNonReceiver() for receivers.
+    private ValueState computeParameterStateForReceiver(
+        ProgramMethod resolvedMethod,
+        DynamicType dynamicReceiverType,
+        ConcreteMonomorphicMethodStateOrBottom existingMethodState,
+        ParameterReprocessingCriteria parameterReprocessingCriteria) {
+      // Don't compute a state for this parameter if the stored state is already unknown.
+      if (existingMethodState.isMonomorphic()
+          && existingMethodState.asMonomorphic().getParameterState(0).isUnknown()) {
+        return ValueState.unknown();
+      }
 
-  // For receivers there is not much point in trying to track an abstract value. Therefore we only
-  // track the dynamic type for receivers.
-  // TODO(b/190154391): Consider validating the above hypothesis by using
-  //  computeParameterStateForNonReceiver() for receivers.
-  private ValueState computeParameterStateForReceiver(
-      ProgramMethod resolvedMethod,
-      DynamicType dynamicReceiverType,
-      ConcreteMonomorphicMethodStateOrBottom existingMethodState,
-      ParameterReprocessingCriteria parameterReprocessingCriteria) {
-    // Don't compute a state for this parameter if the stored state is already unknown.
-    if (existingMethodState.isMonomorphic()
-        && existingMethodState.asMonomorphic().getParameterState(0).isUnknown()) {
-      return ValueState.unknown();
+      // For receivers we only track the dynamic type. Therefore, if there is no need to track the
+      // dynamic type of the receiver of the targeted method, then just return unknown.
+      if (!parameterReprocessingCriteria.shouldReprocessDueToDynamicType()) {
+        return ValueState.unknown();
+      }
+
+      DynamicType widenedDynamicReceiverType =
+          WideningUtils.widenDynamicReceiverType(appView, resolvedMethod, dynamicReceiverType);
+      return widenedDynamicReceiverType.isUnknown()
+          ? ValueState.unknown()
+          : new ConcreteReceiverValueState(dynamicReceiverType);
     }
 
-    // For receivers we only track the dynamic type. Therefore, if there is no need to track the
-    // dynamic type of the receiver of the targeted method, then just return unknown.
-    if (!parameterReprocessingCriteria.shouldReprocessDueToDynamicType()) {
-      return ValueState.unknown();
+    @SuppressWarnings("UnusedVariable")
+    private ValueState computeParameterStateForNonReceiver(
+        InvokeMethod invoke,
+        ProgramMethod singleTarget,
+        int argumentIndex,
+        Value argument,
+        ConcreteMonomorphicMethodStateOrBottom existingMethodState) {
+      ValueState modeledState =
+          modeling.modelParameterStateForArgumentToFunction(
+              invoke, singleTarget, argumentIndex, argument, context);
+      if (modeledState != null) {
+        return modeledState;
+      }
+
+      // Don't compute a state for this parameter if the stored state is already unknown.
+      if (existingMethodState.isMonomorphic()
+          && existingMethodState.asMonomorphic().getParameterState(argumentIndex).isUnknown()) {
+        return ValueState.unknown();
+      }
+
+      DexType parameterType =
+          invoke.getInvokedMethod().getArgumentType(argumentIndex, invoke.isInvokeStatic());
+
+      // If the value is an argument of the enclosing method, then clearly we have no information
+      // about its abstract value. Instead of treating this as having an unknown runtime value, we
+      // instead record a flow constraint that specifies that all values that flow into the
+      // parameter of this enclosing method also flows into the corresponding parameter of the
+      // methods potentially called from this invoke instruction.
+      NonEmptyValueState inFlowState = computeInFlowState(parameterType, argument, context);
+      if (inFlowState != null) {
+        return inFlowState;
+      }
+
+      // Only track the nullability for array types.
+      if (parameterType.isArrayType()) {
+        Nullability nullability = argument.getType().nullability();
+        return ConcreteArrayTypeValueState.create(nullability);
+      }
+
+      AbstractValue abstractValue = abstractValueSupplier.getAbstractValue(argument);
+
+      // For class types, we track both the abstract value and the dynamic type. If both are
+      // unknown, then use UnknownParameterState.
+      if (parameterType.isClassType()) {
+        DynamicType dynamicType = argument.getDynamicType(appView);
+        DynamicType widenedDynamicType =
+            WideningUtils.widenDynamicNonReceiverType(appView, dynamicType, parameterType);
+        return ConcreteClassTypeValueState.create(abstractValue, widenedDynamicType);
+      } else {
+        // For primitive types, we only track the abstract value, thus if the abstract value is
+        // unknown, we use UnknownParameterState.
+        assert parameterType.isPrimitiveType();
+        return ConcretePrimitiveTypeValueState.create(abstractValue);
+      }
     }
 
-    DynamicType widenedDynamicReceiverType =
-        WideningUtils.widenDynamicReceiverType(appView, resolvedMethod, dynamicReceiverType);
-    return widenedDynamicReceiverType.isUnknown()
-        ? ValueState.unknown()
-        : new ConcreteReceiverValueState(dynamicReceiverType);
-  }
+    @SuppressWarnings("ReferenceEquality")
+    private DexMethod getRepresentative(InvokeMethod invoke, ProgramMethod resolvedMethod) {
+      if (resolvedMethod.getDefinition().belongsToDirectPool()) {
+        return resolvedMethod.getReference();
+      }
 
-  @SuppressWarnings("UnusedVariable")
-  private ValueState computeParameterStateForNonReceiver(
-      InvokeMethod invoke,
-      ProgramMethod singleTarget,
-      int argumentIndex,
-      Value argument,
-      AbstractValueSupplier abstractValueSupplier,
-      ProgramMethod context,
-      ConcreteMonomorphicMethodStateOrBottom existingMethodState) {
-    ValueState modeledState =
-        modeling.modelParameterStateForArgumentToFunction(
-            invoke, singleTarget, argumentIndex, argument, context);
-    if (modeledState != null) {
-      return modeledState;
+      if (isMonomorphicVirtualMethod(resolvedMethod)) {
+        return resolvedMethod.getReference();
+      }
+
+      if (invoke.isInvokeInterface()) {
+        assert !isMonomorphicVirtualMethod(resolvedMethod);
+        return getVirtualRootMethod(resolvedMethod);
+      }
+
+      assert invoke.isInvokeSuper() || invoke.isInvokeVirtual();
+
+      DexMethod rootMethod = getVirtualRootMethod(resolvedMethod);
+      assert rootMethod != null;
+      assert !isMonomorphicVirtualMethod(resolvedMethod)
+          || rootMethod == resolvedMethod.getReference();
+      return rootMethod;
     }
 
-    // Don't compute a state for this parameter if the stored state is already unknown.
-    if (existingMethodState.isMonomorphic()
-        && existingMethodState.asMonomorphic().getParameterState(argumentIndex).isUnknown()) {
-      return ValueState.unknown();
+    private boolean shouldUsePolymorphicMethodState(
+        InvokeMethod invoke, ProgramMethod resolvedMethod) {
+      return !resolvedMethod.getDefinition().belongsToDirectPool()
+          && !isMonomorphicVirtualMethod(getRepresentative(invoke, resolvedMethod));
     }
 
-    DexType parameterType =
-        invoke.getInvokedMethod().getArgumentType(argumentIndex, invoke.isInvokeStatic());
-
-    // If the value is an argument of the enclosing method, then clearly we have no information
-    // about its abstract value. Instead of treating this as having an unknown runtime value, we
-    // instead record a flow constraint that specifies that all values that flow into the parameter
-    // of this enclosing method also flows into the corresponding parameter of the methods
-    // potentially called from this invoke instruction.
-    NonEmptyValueState inFlowState = computeInFlowState(parameterType, argument, context);
-    if (inFlowState != null) {
-      return inFlowState;
-    }
-
-    // Only track the nullability for array types.
-    if (parameterType.isArrayType()) {
-      Nullability nullability = argument.getType().nullability();
-      return ConcreteArrayTypeValueState.create(nullability);
-    }
-
-    AbstractValue abstractValue = abstractValueSupplier.getAbstractValue(argument);
-
-    // For class types, we track both the abstract value and the dynamic type. If both are unknown,
-    // then use UnknownParameterState.
-    if (parameterType.isClassType()) {
-      DynamicType dynamicType = argument.getDynamicType(appView);
-      DynamicType widenedDynamicType =
-          WideningUtils.widenDynamicNonReceiverType(appView, dynamicType, parameterType);
-      return ConcreteClassTypeValueState.create(abstractValue, widenedDynamicType);
-    } else {
-      // For primitive types, we only track the abstract value, thus if the abstract value is
-      // unknown,
-      // we use UnknownParameterState.
-      assert parameterType.isPrimitiveType();
-      return ConcretePrimitiveTypeValueState.create(abstractValue);
-    }
-  }
-
-  @SuppressWarnings("ReferenceEquality")
-  private DexMethod getRepresentative(InvokeMethod invoke, ProgramMethod resolvedMethod) {
-    if (resolvedMethod.getDefinition().belongsToDirectPool()) {
-      return resolvedMethod.getReference();
-    }
-
-    if (isMonomorphicVirtualMethod(resolvedMethod)) {
-      return resolvedMethod.getReference();
-    }
-
-    if (invoke.isInvokeInterface()) {
-      assert !isMonomorphicVirtualMethod(resolvedMethod);
-      return getVirtualRootMethod(resolvedMethod);
-    }
-
-    assert invoke.isInvokeSuper() || invoke.isInvokeVirtual();
-
-    DexMethod rootMethod = getVirtualRootMethod(resolvedMethod);
-    assert rootMethod != null;
-    assert !isMonomorphicVirtualMethod(resolvedMethod)
-        || rootMethod == resolvedMethod.getReference();
-    return rootMethod;
-  }
-
-  private boolean shouldUsePolymorphicMethodState(
-      InvokeMethod invoke, ProgramMethod resolvedMethod) {
-    return !resolvedMethod.getDefinition().belongsToDirectPool()
-        && !isMonomorphicVirtualMethod(getRepresentative(invoke, resolvedMethod));
-  }
-
-  private void scan(InvokeCustom invoke) {
-    // If the bootstrap method is program declared it will be called. The call is with runtime
-    // provided arguments so ensure that the argument information is unknown.
-    DexMethodHandle bootstrapMethod = invoke.getCallSite().bootstrapMethod;
-    SingleResolutionResult<?> resolution =
-        appView
-            .appInfo()
-            .resolveMethodLegacy(bootstrapMethod.asMethod(), bootstrapMethod.isInterface)
-            .asSingleResolution();
-    if (resolution != null && resolution.getResolvedHolder().isProgramClass()) {
-      methodStates.set(resolution.getResolvedProgramMethod(), UnknownMethodState.get());
+    private void scanInvokeCustom(InvokeCustom invoke) {
+      // If the bootstrap method is program declared it will be called. The call is with runtime
+      // provided arguments so ensure that the argument information is unknown.
+      DexMethodHandle bootstrapMethod = invoke.getCallSite().bootstrapMethod;
+      SingleResolutionResult<?> resolution =
+          appView
+              .appInfo()
+              .resolveMethodLegacy(bootstrapMethod.asMethod(), bootstrapMethod.isInterface)
+              .asSingleResolution();
+      if (resolution != null && resolution.getResolvedHolder().isProgramClass()) {
+        methodStates.set(resolution.getResolvedProgramMethod(), UnknownMethodState.get());
+      }
     }
   }
 
diff --git a/src/main/java/com/android/tools/r8/optimize/compose/ArgumentPropagatorCodeScannerForComposableFunctions.java b/src/main/java/com/android/tools/r8/optimize/compose/ArgumentPropagatorCodeScannerForComposableFunctions.java
index 174e8ba..2116f3a 100644
--- a/src/main/java/com/android/tools/r8/optimize/compose/ArgumentPropagatorCodeScannerForComposableFunctions.java
+++ b/src/main/java/com/android/tools/r8/optimize/compose/ArgumentPropagatorCodeScannerForComposableFunctions.java
@@ -7,6 +7,7 @@
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.ir.code.AbstractValueSupplier;
+import com.android.tools.r8.ir.code.IRCode;
 import com.android.tools.r8.ir.code.InvokeMethod;
 import com.android.tools.r8.optimize.argumentpropagation.ArgumentPropagatorCodeScanner;
 import com.android.tools.r8.optimize.argumentpropagation.codescanner.MethodParameter;
@@ -25,16 +26,12 @@
   }
 
   @Override
-  protected void addTemporaryMethodState(
-      InvokeMethod invoke,
-      ProgramMethod resolvedMethod,
+  public void scan(
+      ProgramMethod method,
+      IRCode code,
       AbstractValueSupplier abstractValueSupplier,
-      ProgramMethod context,
       Timing timing) {
-    ComposableCallGraphNode node = callGraph.getNodes().get(resolvedMethod);
-    if (node != null && node.isComposable()) {
-      super.addTemporaryMethodState(invoke, resolvedMethod, abstractValueSupplier, context, timing);
-    }
+    new CodeScanner(abstractValueSupplier, code, method).scan(timing);
   }
 
   @Override
@@ -43,4 +40,21 @@
     // We haven't defined the virtual root mapping, so we can't tell.
     return false;
   }
+
+  private class CodeScanner extends ArgumentPropagatorCodeScanner.CodeScanner {
+
+    protected CodeScanner(
+        AbstractValueSupplier abstractValueSupplier, IRCode code, ProgramMethod method) {
+      super(abstractValueSupplier, code, method);
+    }
+
+    @Override
+    protected void addTemporaryMethodState(
+        InvokeMethod invoke, ProgramMethod resolvedMethod, Timing timing) {
+      ComposableCallGraphNode node = callGraph.getNodes().get(resolvedMethod);
+      if (node != null && node.isComposable()) {
+        super.addTemporaryMethodState(invoke, resolvedMethod, timing);
+      }
+    }
+  }
 }
