// 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.analysis.sideeffect;

import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.ValueMayDependOnEnvironmentAnalysis;
import com.android.tools.r8.ir.code.ArrayPut;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.Instruction.SideEffectAssumption;
import com.android.tools.r8.ir.code.StaticPut;
import com.android.tools.r8.ir.code.Value;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.google.common.collect.Sets;
import java.util.Set;

public class ClassInitializerSideEffectAnalysis {

  public enum ClassInitializerSideEffect {
    SIDE_EFFECTS_THAT_CANNOT_BE_POSTPONED,
    SIDE_EFFECTS_THAT_CAN_BE_POSTPONED,
    NONE;

    public boolean canBePostponed() {
      return this != SIDE_EFFECTS_THAT_CANNOT_BE_POSTPONED;
    }

    public boolean isNone() {
      return this == NONE;
    }
  }

  /**
   * A class initializer cannot be postponed if it writes a static field of another class, or if any
   * non-static-put instructions may have side effects.
   */
  public static ClassInitializerSideEffect classInitializerCanBePostponed(
      AppView<AppInfoWithLiveness> appView, IRCode code) {
    ProgramMethod context = code.context();
    // Will be set to true if the control flow must be independent of the environment in order for
    // this class initializer to be postponeable.
    boolean controlFlowRequiredToBeIndependentOfControlFlow = false;
    // The set of values that must be independent of the environment in order for this class
    // initializer to be postponeable.
    Set<Value> valuesRequiredToBeIndependentOfEnvironment = Sets.newIdentityHashSet();
    for (Instruction instruction : code.instructions()) {
      // Array stores are observable if they mutate a non-local array or if they may throw.
      if (instruction.isArrayPut()) {
        ArrayPut arrayPut = instruction.asArrayPut();
        Value array = arrayPut.array().getAliasedValue();
        if (!array.isDefinedByInstructionSatisfying(Instruction::isCreatingArray)
            || arrayPut.instructionInstanceCanThrow(appView, context)) {
          return ClassInitializerSideEffect.SIDE_EFFECTS_THAT_CANNOT_BE_POSTPONED;
        }
        continue;
      }

      // Array creations are observable if they may throw.
      if (instruction.isInvokeNewArray()
          || instruction.isNewArrayEmpty()
          || instruction.isNewArrayFilledData()) {
        if (instruction.instructionInstanceCanThrow(appView, context)) {
          return ClassInitializerSideEffect.SIDE_EFFECTS_THAT_CANNOT_BE_POSTPONED;
        }
        continue;
      }

      if (instruction.isStaticPut()) {
        StaticPut staticPut = instruction.asStaticPut();
        DexEncodedField field =
            appView.appInfo().resolveField(staticPut.getField()).getResolvedField();
        if (field == null
            || field.getHolderType() != context.getHolderType()
            || instruction.instructionInstanceCanThrow(appView, context)) {
          return ClassInitializerSideEffect.SIDE_EFFECTS_THAT_CANNOT_BE_POSTPONED;
        }
        controlFlowRequiredToBeIndependentOfControlFlow = true;
        valuesRequiredToBeIndependentOfEnvironment.add(staticPut.value());
        continue;
      }

      if (instruction.isInvokeConstructor(appView.dexItemFactory())) {
        if (instruction.instructionMayHaveSideEffects(
            appView, context, SideEffectAssumption.IGNORE_RECEIVER_FIELD_ASSIGNMENTS)) {
          return ClassInitializerSideEffect.SIDE_EFFECTS_THAT_CANNOT_BE_POSTPONED;
        }
        continue;
      }

      // For other instructions, bail out if they may have side effects.
      if (instruction.instructionMayHaveSideEffects(appView, context)) {
        return ClassInitializerSideEffect.SIDE_EFFECTS_THAT_CANNOT_BE_POSTPONED;
      }
    }

    if (controlFlowRequiredToBeIndependentOfControlFlow) {
      if (code.controlFlowMayDependOnEnvironment(valuesRequiredToBeIndependentOfEnvironment::add)) {
        return ClassInitializerSideEffect.SIDE_EFFECTS_THAT_CANNOT_BE_POSTPONED;
      }
    }

    if (!valuesRequiredToBeIndependentOfEnvironment.isEmpty()) {
      ValueMayDependOnEnvironmentAnalysis environmentAnalysis =
          new ValueMayDependOnEnvironmentAnalysis(appView, code);
      if (environmentAnalysis.anyValueMayDependOnEnvironment(
          valuesRequiredToBeIndependentOfEnvironment)) {
        return ClassInitializerSideEffect.SIDE_EFFECTS_THAT_CANNOT_BE_POSTPONED;
      }
      return ClassInitializerSideEffect.SIDE_EFFECTS_THAT_CAN_BE_POSTPONED;
    }
    return ClassInitializerSideEffect.NONE;
  }
}
