// Copyright (c) 2019, 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.ir.optimize.info;

import static java.util.Collections.emptySet;

import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.PrunedItems;
import com.android.tools.r8.ir.analysis.inlining.NeverSimpleInliningConstraint;
import com.android.tools.r8.ir.analysis.inlining.SimpleInliningConstraint;
import com.android.tools.r8.ir.analysis.type.DynamicType;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.analysis.value.AbstractValue;
import com.android.tools.r8.ir.analysis.value.UnknownValue;
import com.android.tools.r8.ir.code.InvokeDirect;
import com.android.tools.r8.ir.code.InvokeMethod;
import com.android.tools.r8.ir.optimize.classinliner.constraint.ClassInlinerMethodConstraint;
import com.android.tools.r8.ir.optimize.enums.classification.EnumUnboxerMethodClassification;
import com.android.tools.r8.ir.optimize.info.bridge.BridgeInfo;
import com.android.tools.r8.ir.optimize.info.initializer.InstanceInitializerInfo;
import com.android.tools.r8.ir.optimize.info.initializer.InstanceInitializerInfoCollection;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.BitSetUtils;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.OptionalBool;
import java.util.BitSet;
import java.util.Collections;
import java.util.Set;

public class MutableMethodOptimizationInfo extends MethodOptimizationInfo
    implements MutableOptimizationInfo {

  private CallSiteOptimizationInfo argumentInfos = CallSiteOptimizationInfo.top();
  private Set<DexType> initializedClassesOnNormalExit =
      DefaultMethodOptimizationInfo.UNKNOWN_INITIALIZED_CLASSES_ON_NORMAL_EXIT;
  private int returnedArgument = DefaultMethodOptimizationInfo.UNKNOWN_RETURNED_ARGUMENT;
  private AbstractValue abstractReturnValue =
      DefaultMethodOptimizationInfo.UNKNOWN_ABSTRACT_RETURN_VALUE;
  private ClassInlinerMethodConstraint classInlinerConstraint =
      ClassInlinerMethodConstraint.alwaysFalse();
  private EnumUnboxerMethodClassification enumUnboxerMethodClassification =
      EnumUnboxerMethodClassification.unknown();
  private DynamicType dynamicType = DynamicType.unknown();
  private InlinePreference inlining = InlinePreference.Default;
  private OptionalBool isReturnValueUsed = OptionalBool.unknown();
  // Stores information about instance methods and constructors for
  // class inliner, null value indicates that the method is not eligible.
  private BridgeInfo bridgeInfo = null;
  private InstanceInitializerInfoCollection instanceInitializerInfoCollection =
      InstanceInitializerInfoCollection.empty();
  // Stores information about nullability hint per parameter. If set, that means, the method
  // somehow (e.g., null check, such as arg != null, or using checkParameterIsNotNull) ensures
  // the corresponding parameter is not null, or throws NPE before any other side effects.
  // This info is used by {@link UninstantiatedTypeOptimization#rewriteInvoke} that replaces an
  // invocation with null throwing code if an always-null argument is passed. Also used by Inliner
  // to give a credit to null-safe code, e.g., Kotlin's null safe argument.
  // Note that this bit set takes into account the receiver for instance methods.
  private BitSet nonNullParamOrThrow =
      DefaultMethodOptimizationInfo.NO_NULL_PARAMETER_OR_THROW_FACTS;
  // Stores information about nullability facts per parameter. If set, that means, the method
  // somehow (e.g., null check, such as arg != null, or NPE-throwing instructions such as array
  // access or another invocation) ensures the corresponding parameter is not null, and that is
  // guaranteed until the normal exits. That is, if the invocation of this method is finished
  // normally, the recorded parameter is definitely not null. These facts are used to propagate
  // non-null information through {@link NonNullTracker}.
  // Note that this bit set takes into account the receiver for instance methods.
  private BitSet nonNullParamOnNormalExits =
      DefaultMethodOptimizationInfo.NO_NULL_PARAMETER_ON_NORMAL_EXITS_FACTS;

  private SimpleInliningConstraint simpleInliningConstraint =
      NeverSimpleInliningConstraint.getInstance();

  private BitSet unusedArguments = null;

  // To reduce the memory footprint of UpdatableMethodOptimizationInfo, all the boolean fields are
  // merged into a flag int field. The various static final FLAG fields indicate which bit is
  // used by each boolean. DEFAULT_FLAGS encodes the default value for efficient instantiation and
  // is computed during class initialization from the default method optimization info. The
  // methods setFlag, clearFlag and isFlagSet are used to access the booleans.
  private static final int CANNOT_BE_KEPT_FLAG = 0x1;
  private static final int CLASS_INITIALIZER_MAY_BE_POSTPONED_FLAG = 0x2;
  private static final int HAS_BEEN_INLINED_INTO_SINGLE_CALL_SITE_FLAG = 0x4;
  private static final int MAY_HAVE_SIDE_EFFECT_FLAG = 0x8;
  private static final int RETURN_VALUE_ONLY_DEPENDS_ON_ARGUMENTS_FLAG = 0x10;
  private static final int UNUSED_FLAG_1 = 0x20;
  private static final int NEVER_RETURNS_NORMALLY_FLAG = 0x40;
  private static final int UNUSED_FLAG_2 = 0x80;
  private static final int UNUSED_FLAG_3 = 0x100;
  private static final int UNUSED_FLAG_4 = 0x200;
  private static final int INITIALIZER_ENABLING_JAVA_ASSERTIONS_FLAG = 0x400;
  private static final int REACHABILITY_SENSITIVE_FLAG = 0x800;
  private static final int RETURN_VALUE_HAS_BEEN_PROPAGATED_FLAG = 0x1000;

  private static final int DEFAULT_FLAGS;

  static {
    int defaultFlags = 0;
    MethodOptimizationInfo defaultOptInfo = DefaultMethodOptimizationInfo.DEFAULT_INSTANCE;
    defaultFlags |= BooleanUtils.intValue(defaultOptInfo.cannotBeKept()) * CANNOT_BE_KEPT_FLAG;
    defaultFlags |=
        BooleanUtils.intValue(defaultOptInfo.classInitializerMayBePostponed())
            * CLASS_INITIALIZER_MAY_BE_POSTPONED_FLAG;
    defaultFlags |=
        BooleanUtils.intValue(defaultOptInfo.hasBeenInlinedIntoSingleCallSite())
            * HAS_BEEN_INLINED_INTO_SINGLE_CALL_SITE_FLAG;
    defaultFlags |=
        BooleanUtils.intValue(defaultOptInfo.mayHaveSideEffects()) * MAY_HAVE_SIDE_EFFECT_FLAG;
    defaultFlags |=
        BooleanUtils.intValue(defaultOptInfo.returnValueOnlyDependsOnArguments())
            * RETURN_VALUE_ONLY_DEPENDS_ON_ARGUMENTS_FLAG;
    defaultFlags |= 0 * UNUSED_FLAG_1;
    defaultFlags |=
        BooleanUtils.intValue(defaultOptInfo.neverReturnsNormally()) * NEVER_RETURNS_NORMALLY_FLAG;
    defaultFlags |= 0 * UNUSED_FLAG_2;
    defaultFlags |= 0 * UNUSED_FLAG_3;
    defaultFlags |= 0 * UNUSED_FLAG_4;
    defaultFlags |=
        BooleanUtils.intValue(defaultOptInfo.isInitializerEnablingJavaVmAssertions())
            * INITIALIZER_ENABLING_JAVA_ASSERTIONS_FLAG;
    defaultFlags |=
        BooleanUtils.intValue(defaultOptInfo.isReachabilitySensitive())
            * REACHABILITY_SENSITIVE_FLAG;
    defaultFlags |=
        BooleanUtils.intValue(defaultOptInfo.returnValueHasBeenPropagated())
            * RETURN_VALUE_HAS_BEEN_PROPAGATED_FLAG;
    DEFAULT_FLAGS = defaultFlags;
  }

  private int flags = DEFAULT_FLAGS;

  MutableMethodOptimizationInfo() {
    // Intentionally left empty, just use the default values.
  }

  // Copy constructor used to create a mutable copy. Do not forget to copy from template when a new
  // field is added.
  private MutableMethodOptimizationInfo(MutableMethodOptimizationInfo template) {
    argumentInfos = template.argumentInfos;
    flags = template.flags;
    initializedClassesOnNormalExit = template.initializedClassesOnNormalExit;
    returnedArgument = template.returnedArgument;
    abstractReturnValue = template.abstractReturnValue;
    dynamicType = template.dynamicType;
    inlining = template.inlining;
    simpleInliningConstraint = template.simpleInliningConstraint;
    bridgeInfo = template.bridgeInfo;
    instanceInitializerInfoCollection = template.instanceInitializerInfoCollection;
    nonNullParamOrThrow = template.nonNullParamOrThrow;
    nonNullParamOnNormalExits = template.nonNullParamOnNormalExits;
    classInlinerConstraint = template.classInlinerConstraint;
    enumUnboxerMethodClassification = template.enumUnboxerMethodClassification;
  }

  public MutableMethodOptimizationInfo fixup(
      AppView<AppInfoWithLiveness> appView, MethodOptimizationInfoFixer fixer) {
    return fixupArgumentInfos(fixer)
        .fixupBridgeInfo(fixer)
        .fixupClassInlinerMethodConstraint(appView, fixer)
        .fixupEnumUnboxerMethodClassification(fixer)
        .fixupInstanceInitializerInfo(appView, fixer)
        .fixupNonNullParamOnNormalExits(fixer)
        .fixupNonNullParamOrThrow(fixer)
        .fixupReturnedArgumentIndex(fixer)
        .fixupSimpleInliningConstraint(appView, fixer)
        .fixupUnusedArguments(fixer);
  }

  public MutableMethodOptimizationInfo fixupClassTypeReferences(
      AppView<AppInfoWithLiveness> appView, GraphLens lens) {
    return fixupClassTypeReferences(appView, lens, emptySet());
  }

  public MutableMethodOptimizationInfo fixupClassTypeReferences(
      AppView<AppInfoWithLiveness> appView, GraphLens lens, Set<DexType> prunedTypes) {
    dynamicType = dynamicType.rewrittenWithLens(appView, lens, prunedTypes);
    return this;
  }

  public MutableMethodOptimizationInfo fixupAbstractReturnValue(
      AppView<AppInfoWithLiveness> appView, GraphLens lens, GraphLens codeLens) {
    abstractReturnValue = abstractReturnValue.rewrittenWithLens(appView, lens, codeLens);
    return this;
  }

  public MutableMethodOptimizationInfo fixupInstanceInitializerInfo(
      AppView<AppInfoWithLiveness> appView,
      GraphLens lens,
      GraphLens codeLens,
      PrunedItems prunedItems) {
    instanceInitializerInfoCollection =
        instanceInitializerInfoCollection.rewrittenWithLens(appView, lens, codeLens, prunedItems);
    return this;
  }

  private void setFlag(int flag, boolean value) {
    if (value) {
      setFlag(flag);
    } else {
      clearFlag(flag);
    }
  }

  private void setFlag(int flag) {
    flags |= flag;
  }

  private void clearFlag(int flag) {
    flags &= ~flag;
  }

  private boolean isFlagSet(int flag) {
    return (flags & flag) != 0;
  }

  @Override
  public boolean cannotBeKept() {
    return isFlagSet(CANNOT_BE_KEPT_FLAG);
  }

  // TODO(b/140214568): Should be package-private.
  public void markCannotBeKept() {
    setFlag(CANNOT_BE_KEPT_FLAG);
  }

  @Override
  public boolean classInitializerMayBePostponed() {
    return isFlagSet(CLASS_INITIALIZER_MAY_BE_POSTPONED_FLAG);
  }

  void markClassInitializerMayBePostponed() {
    setFlag(CLASS_INITIALIZER_MAY_BE_POSTPONED_FLAG);
  }

  void unsetClassInitializerMayBePostponed() {
    clearFlag(CLASS_INITIALIZER_MAY_BE_POSTPONED_FLAG);
  }

  @Override
  public CallSiteOptimizationInfo getArgumentInfos() {
    return argumentInfos;
  }

  public MutableMethodOptimizationInfo fixupArgumentInfos(MethodOptimizationInfoFixer fixer) {
    if (argumentInfos.isConcreteCallSiteOptimizationInfo()) {
      argumentInfos =
          fixer.fixupCallSiteOptimizationInfo(argumentInfos.asConcreteCallSiteOptimizationInfo());
    }
    return this;
  }

  void setArgumentInfos(CallSiteOptimizationInfo argumentInfos) {
    this.argumentInfos = argumentInfos;
  }

  @Override
  public ClassInlinerMethodConstraint getClassInlinerMethodConstraint() {
    return classInlinerConstraint;
  }

  public MutableMethodOptimizationInfo fixupClassInlinerMethodConstraint(
      AppView<AppInfoWithLiveness> appView, MethodOptimizationInfoFixer fixer) {
    classInlinerConstraint =
        fixer.fixupClassInlinerMethodConstraint(appView, classInlinerConstraint);
    return this;
  }

  void setClassInlinerMethodConstraint(ClassInlinerMethodConstraint classInlinerConstraint) {
    this.classInlinerConstraint = classInlinerConstraint;
  }

  void unsetClassInlinerMethodConstraint() {
    this.classInlinerConstraint = ClassInlinerMethodConstraint.alwaysFalse();
  }

  @Override
  public EnumUnboxerMethodClassification getEnumUnboxerMethodClassification() {
    return enumUnboxerMethodClassification;
  }

  public MutableMethodOptimizationInfo setEnumUnboxerMethodClassification(
      EnumUnboxerMethodClassification enumUnboxerMethodClassification) {
    // Check monotonicity.
    assert !this.enumUnboxerMethodClassification.isCheckNotNullClassification()
        || enumUnboxerMethodClassification.isCheckNotNullClassification();
    this.enumUnboxerMethodClassification = enumUnboxerMethodClassification;
    return this;
  }

  public void unsetEnumUnboxerMethodClassification() {
    this.enumUnboxerMethodClassification = EnumUnboxerMethodClassification.unknown();
  }

  public MutableMethodOptimizationInfo fixupEnumUnboxerMethodClassification(
      MethodOptimizationInfoFixer fixer) {
    enumUnboxerMethodClassification =
        fixer.fixupEnumUnboxerMethodClassification(enumUnboxerMethodClassification);
    return this;
  }

  @Override
  public DynamicType getDynamicType() {
    return dynamicType;
  }

  @Override
  public Set<DexType> getInitializedClassesOnNormalExit() {
    return initializedClassesOnNormalExit;
  }

  @Override
  public InstanceInitializerInfo getContextInsensitiveInstanceInitializerInfo() {
    return instanceInitializerInfoCollection.getContextInsensitive();
  }

  @Override
  public InstanceInitializerInfo getInstanceInitializerInfo(InvokeDirect invoke) {
    return instanceInitializerInfoCollection.get(invoke);
  }

  public MutableMethodOptimizationInfo fixupInstanceInitializerInfo(
      AppView<AppInfoWithLiveness> appView, MethodOptimizationInfoFixer fixer) {
    instanceInitializerInfoCollection =
        fixer.fixupInstanceInitializerInfo(appView, instanceInitializerInfoCollection);
    return this;
  }

  @Override
  public BitSet getNonNullParamOrThrow() {
    return nonNullParamOrThrow;
  }

  public MutableMethodOptimizationInfo fixupNonNullParamOrThrow(MethodOptimizationInfoFixer fixer) {
    nonNullParamOrThrow = fixer.fixupNonNullParamOrThrow(nonNullParamOrThrow);
    return this;
  }

  void setNonNullParamOrThrow(BitSet facts) {
    this.nonNullParamOrThrow = facts;
  }

  void unsetNonNullParamOrThrow() {
    this.nonNullParamOrThrow = null;
  }

  @Override
  public BitSet getNonNullParamOnNormalExits() {
    return nonNullParamOnNormalExits;
  }

  public MutableMethodOptimizationInfo fixupNonNullParamOnNormalExits(
      MethodOptimizationInfoFixer fixer) {
    nonNullParamOnNormalExits = fixer.fixupNonNullParamOnNormalExits(nonNullParamOnNormalExits);
    return this;
  }

  void setNonNullParamOnNormalExits(BitSet facts) {
    this.nonNullParamOnNormalExits = facts;
  }

  void unsetNonNullParamOnNormalExits() {
    nonNullParamOnNormalExits = null;
  }

  @Override
  public boolean hasBeenInlinedIntoSingleCallSite() {
    return isFlagSet(HAS_BEEN_INLINED_INTO_SINGLE_CALL_SITE_FLAG);
  }

  void markInlinedIntoSingleCallSite() {
    setFlag(HAS_BEEN_INLINED_INTO_SINGLE_CALL_SITE_FLAG);
  }

  void unsetInlinedIntoSingleCallSite() {
    clearFlag(HAS_BEEN_INLINED_INTO_SINGLE_CALL_SITE_FLAG);
  }

  @Override
  public boolean isReachabilitySensitive() {
    return isFlagSet(REACHABILITY_SENSITIVE_FLAG);
  }

  @Override
  public boolean returnsArgument() {
    return returnedArgument != -1;
  }

  @Override
  public int getReturnedArgument() {
    assert returnsArgument();
    return returnedArgument;
  }

  @Override
  public boolean neverReturnsNormally() {
    return isFlagSet(NEVER_RETURNS_NORMALLY_FLAG);
  }

  @Override
  public BridgeInfo getBridgeInfo() {
    return bridgeInfo;
  }

  public MutableMethodOptimizationInfo fixupBridgeInfo(MethodOptimizationInfoFixer fixer) {
    if (bridgeInfo != null) {
      assert bridgeInfo.isVirtualBridgeInfo();
      bridgeInfo = fixer.fixupBridgeInfo(bridgeInfo.asVirtualBridgeInfo());
    }
    return this;
  }

  void setBridgeInfo(BridgeInfo bridgeInfo) {
    this.bridgeInfo = bridgeInfo;
  }

  void unsetBridgeInfo() {
    this.bridgeInfo = null;
  }

  @Override
  public AbstractValue getAbstractReturnValue() {
    return abstractReturnValue;
  }

  @Override
  public SimpleInliningConstraint getNopInliningConstraint(InternalOptions options) {
    // We currently require that having a simple inlining constraint implies that the method becomes
    // empty after inlining. Therefore, an invoke is a nop if the simple inlining constraint is
    // satisfied (if the invoke does not trigger other side effects, such as class initialization).
    assert options.simpleInliningConstraintThreshold == 0;
    return getSimpleInliningConstraint();
  }

  @Override
  public SimpleInliningConstraint getSimpleInliningConstraint() {
    return simpleInliningConstraint;
  }

  @Override
  public BitSet getUnusedArguments() {
    return unusedArguments;
  }

  public MutableMethodOptimizationInfo fixupUnusedArguments(MethodOptimizationInfoFixer fixer) {
    fixupUnusedArguments(fixer.fixupUnusedArguments(unusedArguments));
    return this;
  }

  public MutableMethodOptimizationInfo fixupUnusedArguments(BitSet unusedArguments) {
    this.unusedArguments =
        unusedArguments != null && !unusedArguments.isEmpty() ? unusedArguments : null;
    return this;
  }

  void setUnusedArguments(BitSet unusedArguments) {
    // Verify monotonicity (i.e., unused arguments should never become used).
    assert !hasUnusedArguments() || unusedArguments != null;
    assert !hasUnusedArguments()
        || BitSetUtils.verifyLessThanOrEqualTo(getUnusedArguments(), unusedArguments);
    this.unusedArguments =
        unusedArguments != null && !unusedArguments.isEmpty() ? unusedArguments : null;
  }

  void unsetUnusedArguments() {
    unusedArguments = null;
  }

  @Override
  public boolean isInitializerEnablingJavaVmAssertions() {
    return isFlagSet(INITIALIZER_ENABLING_JAVA_ASSERTIONS_FLAG);
  }

  @Override
  public boolean isMultiCallerMethod() {
    return inlining == InlinePreference.MultiCallerInline;
  }

  @Override
  public OptionalBool isReturnValueUsed() {
    return isReturnValueUsed;
  }

  void setIsReturnValueUsed(OptionalBool isReturnValueUsed) {
    this.isReturnValueUsed = isReturnValueUsed;
  }

  @Override
  public boolean forceInline() {
    return inlining == InlinePreference.ForceInline;
  }

  @Override
  public boolean mayHaveSideEffects() {
    return isFlagSet(MAY_HAVE_SIDE_EFFECT_FLAG);
  }

  @Override
  public boolean mayHaveSideEffects(InvokeMethod invoke, InternalOptions options) {
    if (!mayHaveSideEffects()) {
      return false;
    }
    if (getNopInliningConstraint(options).isSatisfied(invoke)) {
      return false;
    }
    return true;
  }

  @Override
  public boolean returnValueOnlyDependsOnArguments() {
    return isFlagSet(RETURN_VALUE_ONLY_DEPENDS_ON_ARGUMENTS_FLAG);
  }

  public void setReachabilitySensitive(boolean reachabilitySensitive) {
    setFlag(REACHABILITY_SENSITIVE_FLAG, reachabilitySensitive);
  }

  void unsetReachabilitySensitive() {
    clearFlag(REACHABILITY_SENSITIVE_FLAG);
  }

  void setSimpleInliningConstraint(SimpleInliningConstraint constraint) {
    this.simpleInliningConstraint = constraint;
  }

  void unsetSimpleInliningConstraint() {
    simpleInliningConstraint = NeverSimpleInliningConstraint.getInstance();
  }

  public MutableMethodOptimizationInfo fixupSimpleInliningConstraint(
      AppView<AppInfoWithLiveness> appView, MethodOptimizationInfoFixer fixer) {
    simpleInliningConstraint =
        fixer.fixupSimpleInliningConstraint(
            appView, simpleInliningConstraint, appView.simpleInliningConstraintFactory());
    return this;
  }

  void setInstanceInitializerInfoCollection(
      InstanceInitializerInfoCollection instanceInitializerInfoCollection) {
    this.instanceInitializerInfoCollection = instanceInitializerInfoCollection;
  }

  void unsetInstanceInitializerInfoCollection() {
    instanceInitializerInfoCollection = InstanceInitializerInfoCollection.empty();
  }

  void setInitializerEnablingJavaAssertions() {
    setFlag(INITIALIZER_ENABLING_JAVA_ASSERTIONS_FLAG);
  }

  void unsetInitializerEnablingJavaVmAssertions() {
    clearFlag(INITIALIZER_ENABLING_JAVA_ASSERTIONS_FLAG);
  }

  void markInitializesClassesOnNormalExit(Set<DexType> initializedClassesOnNormalExit) {
    this.initializedClassesOnNormalExit = initializedClassesOnNormalExit;
  }

  void unsetInitializedClassesOnNormalExit() {
    initializedClassesOnNormalExit = Collections.emptySet();
  }

  void markReturnsArgument(int returnedArgumentIndex) {
    assert returnedArgumentIndex >= 0;
    assert returnedArgument == -1 || returnedArgument == returnedArgumentIndex;
    returnedArgument = returnedArgumentIndex;
  }

  void unsetReturnedArgument() {
    returnedArgument = -1;
  }

  public MutableMethodOptimizationInfo fixupReturnedArgumentIndex(
      MethodOptimizationInfoFixer fixer) {
    returnedArgument = fixer.fixupReturnedArgumentIndex(returnedArgument);
    return this;
  }

  void markMayNotHaveSideEffects() {
    clearFlag(MAY_HAVE_SIDE_EFFECT_FLAG);
  }

  void unsetMayNotHaveSideEffects() {
    setFlag(MAY_HAVE_SIDE_EFFECT_FLAG);
  }

  void markReturnValueOnlyDependsOnArguments() {
    setFlag(RETURN_VALUE_ONLY_DEPENDS_ON_ARGUMENTS_FLAG);
  }

  void unsetReturnValueOnlyDependsOnArguments() {
    clearFlag(RETURN_VALUE_ONLY_DEPENDS_ON_ARGUMENTS_FLAG);
  }

  void markNeverReturnsNormally() {
    setFlag(NEVER_RETURNS_NORMALLY_FLAG);
  }

  void unsetNeverReturnsNormally() {
    clearFlag(NEVER_RETURNS_NORMALLY_FLAG);
  }

  void markReturnsAbstractValue(AbstractValue value) {
    assert !abstractReturnValue.isSingleValue() || abstractReturnValue.equals(value)
        : "return single value changed from " + abstractReturnValue + " to " + value;
    abstractReturnValue = value;
  }

  void unsetAbstractReturnValue() {
    abstractReturnValue = UnknownValue.getInstance();
  }

  void setDynamicType(AppView<?> appView, DynamicType newDynamicType, DexEncodedMethod method) {
    assert newDynamicType != null;
    // We may get more precise type information if the method is reprocessed (e.g., due to
    // optimization info collected from all call sites), and hence the
    // `returnsObjectWithUpperBoundType` is allowed to become more precise.
    // TODO(b/142559221): non-materializable assume instructions?
    // Nullability could be less precise, though. For example, suppose a value is known to be
    // non-null after a safe invocation, hence recorded with the non-null variant. If that call is
    // inlined and the method is reprocessed, such non-null assumption cannot be made again.
    assert verifyDynamicType(appView, newDynamicType, method);
    dynamicType = newDynamicType;
  }

  private boolean verifyDynamicType(
      AppView<?> appView, DynamicType newDynamicType, DexEncodedMethod method) {
    if (appView.enableWholeProgramOptimizations()) {
      TypeElement staticReturnType = method.getReturnType().toTypeElement(appView);
      TypeElement previousDynamicUpperBoundType =
          dynamicType.getDynamicUpperBoundType(staticReturnType);
      TypeElement newDynamicUpperBoundType =
          newDynamicType.getDynamicUpperBoundType(staticReturnType);
      assert newDynamicUpperBoundType.lessThanOrEqualUpToNullability(
              previousDynamicUpperBoundType, appView)
          : "upper bound type changed from "
              + previousDynamicUpperBoundType
              + " to "
              + newDynamicUpperBoundType;
    }
    return true;
  }

  void unsetDynamicType() {
    dynamicType = DynamicType.unknown();
  }

  // TODO(b/140214568): Should be package-private.
  public void markForceInline() {
    // For concurrent scenarios we should allow the flag to be already set
    assert inlining == InlinePreference.Default || inlining == InlinePreference.ForceInline;
    inlining = InlinePreference.ForceInline;
  }

  void unsetForceInline() {
    inlining = InlinePreference.Default;
  }

  void setMultiCallerMethod() {
    if (inlining == InlinePreference.Default) {
      inlining = InlinePreference.MultiCallerInline;
    } else {
      assert inlining == InlinePreference.ForceInline;
    }
  }

  // TODO(b/140214568): Should be package-private.
  public void markAsPropagated() {
    setFlag(RETURN_VALUE_HAS_BEEN_PROPAGATED_FLAG);
  }

  @Override
  public boolean returnValueHasBeenPropagated() {
    return isFlagSet(RETURN_VALUE_HAS_BEEN_PROPAGATED_FLAG);
  }

  @Override
  public boolean isMutableOptimizationInfo() {
    return true;
  }

  @Override
  public MutableMethodOptimizationInfo toMutableOptimizationInfo() {
    return this;
  }

  @Override
  public MutableMethodOptimizationInfo asMutableMethodOptimizationInfo() {
    return this;
  }

  public MutableMethodOptimizationInfo mutableCopy() {
    return new MutableMethodOptimizationInfo(this);
  }
}
