// Copyright (c) 2016, 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.code;

import com.android.tools.r8.cf.LoadStoreHelper;
import com.android.tools.r8.cf.TypeVerificationHelper;
import com.android.tools.r8.errors.Unimplemented;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DebugLocalInfo;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis.AnalysisAssumption;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis.Query;
import com.android.tools.r8.ir.analysis.constant.Bottom;
import com.android.tools.r8.ir.analysis.constant.ConstRangeLatticeElement;
import com.android.tools.r8.ir.analysis.constant.LatticeElement;
import com.android.tools.r8.ir.analysis.fieldvalueanalysis.AbstractFieldSet;
import com.android.tools.r8.ir.analysis.fieldvalueanalysis.EmptyFieldSet;
import com.android.tools.r8.ir.analysis.fieldvalueanalysis.UnknownFieldSet;
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.conversion.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
import com.android.tools.r8.ir.optimize.DeadCodeRemover.DeadInstructionResult;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
import com.android.tools.r8.ir.optimize.InliningConstraints;
import com.android.tools.r8.ir.regalloc.RegisterAllocator;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.CfgPrinter;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.StringUtils.BraceType;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Predicate;

public abstract class Instruction implements InstructionOrPhi, TypeAndLocalInfoSupplier {

  protected Value outValue = null;
  protected final List<Value> inValues = new ArrayList<>();
  private BasicBlock block = null;
  private int number = -1;
  private Set<Value> debugValues = null;
  private Position position = null;

  protected Instruction(Value outValue) {
    setOutValue(outValue);
  }

  protected Instruction(Value outValue, Value inValue) {
    addInValue(inValue);
    setOutValue(outValue);
  }

  protected Instruction(Value outValue, List<? extends Value> inValues) {
    if (inValues != null) {
      for (Value v : inValues) {
        addInValue(v);
      }
    }
    setOutValue(outValue);
  }

  public abstract int opcode();

  public abstract <T> T accept(InstructionVisitor<T> visitor);

  final boolean hasPosition() {
    return position != null;
  }

  public final Position getPosition() {
    assert position != null;
    return position;
  }

  public void setPosition(Position position) {
    assert this.position == null;
    this.position = position;
  }

  public String getPositionAsString() {
    return position == null ? "???" : position.toString();
  }

  public List<Value> inValues() {
    return inValues;
  }

  protected void addInValue(Value value) {
    if (value != null) {
      inValues.add(value);
      assert value.hasUsersInfo();
      if (value.hasUsersInfo()) {
        value.addUser(this);
      }
    }
  }

  public boolean hasInValueWithLocalInfo() {
    return hasInValueThatMatches(Value::hasLocalInfo);
  }

  public boolean hasInValueThatMatches(Predicate<Value> predicate) {
    for (Value value : inValues()) {
      if (predicate.test(value)) {
        return true;
      }
    }
    return false;
  }

  public boolean hasOutValue() {
    return outValue != null;
  }

  public Value outValue() {
    return outValue;
  }

  public void setOutValue(Value value) {
    assert outValue == null || !outValue.hasUsersInfo() || !outValue.isUsed();
    outValue = value;
    if (outValue != null) {
      outValue.definition = this;
    }
  }

  public Value swapOutValue(Value newOutValue) {
    Value oldOutValue = outValue;
    outValue = null;
    setOutValue(newOutValue);
    if (oldOutValue != null) {
      oldOutValue.definition = null;
    }
    return oldOutValue;
  }

  public AbstractValue getAbstractValue(
      AppView<AppInfoWithLiveness> appView, ProgramMethod context) {
    assert hasOutValue();
    return UnknownValue.getInstance();
  }

  @Override
  public TypeElement getOutType() {
    if (hasOutValue()) {
      return outValue().getType();
    }
    return null;
  }

  public void addDebugValue(Value value) {
    assert value.hasLocalInfo();
    if (debugValues == null) {
      debugValues = Sets.newIdentityHashSet();
    }
    debugValues.add(value);
  }

  public static void clearUserInfo(Instruction instruction) {
    if (instruction.outValue != null) {
      instruction.outValue.clearUsersInfo();
    }
    instruction.inValues.forEach(Value::clearUsersInfo);
    if (instruction.debugValues != null) {
      instruction.debugValues.forEach(Value::clearUsersInfo);
      instruction.debugValues = null;
    }
  }

  public final ValueType outType() {
    return outValue.outType();
  }

  public abstract void buildDex(DexBuilder builder);

  public abstract void buildCf(CfBuilder builder);

  public void replaceValue(Value oldValue, Value newValue) {
    for (int i = 0; i < inValues.size(); i++) {
      if (oldValue == inValues.get(i)) {
        inValues.set(i, newValue);
        newValue.addUser(this);
      }
    }
  }

  public void replaceValue(int index, Value newValue) {
    Value oldValue = inValues.get(index);
    inValues.set(index, newValue);
    newValue.addUser(this);
    oldValue.removeUser(this);
  }

  public void replaceDebugValue(Value oldValue, Value newValue) {
    assert oldValue.hasLocalInfo();
    assert newValue.hasLocalInfo();
    assert newValue.getLocalInfo() == oldValue.getLocalInfo()
        : "Replacing debug values with inconsistent locals "
            + oldValue.getLocalInfo()
            + " and "
            + newValue.getLocalInfo()
            + ". This is likely a code transformation bug "
            + "that has not taken local information into account";
    boolean removed = debugValues.remove(oldValue);
    assert removed;
    if (removed && newValue.hasLocalInfo()) {
      newValue.addDebugLocalEnd(this);
    }
  }

  public void moveDebugValues(Instruction target) {
    if (debugValues == null) {
      return;
    }
    for (Value value : debugValues) {
      value.replaceDebugUser(this, target);
    }
    debugValues.clear();
  }

  public void removeDebugValue(Value value) {
    assert value.hasLocalInfo();
    if (debugValues != null) {
      assert debugValues.contains(value);
      if (debugValues.remove(value)) {
        value.removeDebugUser(this);
      }
      return;
    }
    assert false;
  }

  public Value removeDebugValue(DebugLocalInfo localInfo) {
    if (debugValues != null) {
      Iterator<Value> it = debugValues.iterator();
      while (it.hasNext()) {
        Value value = it.next();
        if (value.hasLocalInfo() && value.getLocalInfo() == localInfo) {
          it.remove();
          value.removeDebugUser(this);
          return value;
        }
      }
    }
    return null;
  }

  public void clearDebugValues() {
    if (debugValues != null) {
      for (Value debugValue : debugValues) {
        debugValue.removeDebugUser(this);
      }
      debugValues.clear();
    }
  }

  /**
   * Returns the basic block containing this instruction.
   */
  @Override
  public BasicBlock getBlock() {
    assert block != null;
    return block;
  }

  /**
   * Set the basic block of this instruction. See IRBuilder.
   */
  public void setBlock(BasicBlock block) {
    assert block != null;
    this.block = block;
  }

  /**
   * Clear the basic block of this instruction. Use when removing an instruction from a block.
   */
  public void clearBlock() {
    assert block != null;
    block = null;
  }

  public void removeOrReplaceByDebugLocalRead(IRCode code) {
    getBlock().listIterator(code, this).removeOrReplaceByDebugLocalRead();
  }

  public void replace(Instruction newInstruction, IRCode code) {
    getBlock().listIterator(code, this).replaceCurrentInstruction(newInstruction);
  }

  /**
   * Returns true if the instruction is in the IR and therefore has a block.
   */
  public boolean hasBlock() {
    return block != null;
  }

  public String getInstructionName() {
    return getClass().getSimpleName();
  }

  @Override
  public String toString() {
    StringBuilder builder = new StringBuilder();
    builder.append(getInstructionName());
    for (int i = builder.length(); i < 20; i++) {
      builder.append(" ");
    }
    builder.append(" ");
    if (outValue != null) {
      builder.append(outValue);
      builder.append(" <- ");
    }
    if (!inValues.isEmpty()) {
      StringUtils.append(builder, inValues, ", ", BraceType.NONE);
    }
    return builder.toString();
  }

  public void print(CfgPrinter printer) {
    int uses = 0;
    String value;
    if (outValue == null) {
      value = printer.makeUnusedValue();
    } else {
      if (outValue.hasUsersInfo()) {
        uses = outValue.uniqueUsers().size() + outValue.uniquePhiUsers().size();
      }
      value = "v" + outValue.getNumber();
    }
    printer
        .print(0)           // bci
        .sp().append(uses)  // use
        .sp().append(value) // tid
        .sp().append(getClass().getSimpleName());
    for (Value in : inValues) {
      printer.append(" v").append(in.getNumber());
    }
  }

  public void printLIR(CfgPrinter printer) {
    // TODO(ager): Improve the instruction printing. Use different name for values so that the
    // HIR and LIR values are not confused in the c1 visualizer.
    printer.print(number).sp().append(toString());
  }

  public int getNumber() {
    return number;
  }

  public void setNumber(int number) {
    assert number != -1;
    this.number = number;
  }

  public void clearNumber() {
    this.number = -1;
  }

  /**
   * Compare equality of two class-equivalent instructions modulo their values and positions.
   */
  public abstract boolean identicalNonValueNonPositionParts(Instruction other);

  public boolean identicalNonValueParts(Instruction other) {
    assert getClass() == other.getClass();
    return position.equals(other.position) && identicalNonValueNonPositionParts(other);
  }

  private boolean identicalInputAfterRegisterAllocation(
      Value a,
      int aInstrNumber,
      Instruction bInstr,
      Value b,
      int bInstrNumber,
      RegisterAllocator allocator) {
    boolean aIsStackValue = a instanceof StackValue;
    boolean aIsStackValues = a instanceof StackValues;

    if (aIsStackValue != b instanceof StackValue || aIsStackValues != b instanceof StackValues) {
      return false;
    }

    if (aIsStackValue) {
      return identicalStackValuePair((StackValue) a, (StackValue) b);
    }

    if (aIsStackValues) {
      return identicalStackValuesPair((StackValues) a, (StackValues) b);
    }

    if (needsValueInRegister(a) != bInstr.needsValueInRegister(b)) {
      return false;
    }

    // If the value is needed in a register or one of the instructions is a two-addr instruction,
    // the register for the value is used and it needs to be the same.
    if (needsValueInRegister(a) || isTwoAddr(allocator) || bInstr.isTwoAddr(allocator)) {
      // Only one of the instructions have a register assigned and one of them will use a
      // register, so the instructions are not identical.
      if (!a.needsRegister() || !b.needsRegister()) {
        return false;
      }
      // Check if the allocated registers are identical.
      if (allocator.getRegisterForValue(a, aInstrNumber)
          != allocator.getRegisterForValue(b, bInstrNumber)) {
        return false;
      }
    } else {
      ConstNumber aNum = a.getConstInstruction().asConstNumber();
      ConstNumber bNum = b.getConstInstruction().asConstNumber();
      if (!aNum.identicalNonValueNonPositionParts(bNum)) {
        return false;
      }
    }

    return a.outType() == b.outType();
  }

  private boolean identicalOutputAfterRegisterAllocation(
      Value a, int aInstrNumber, Value b, int bInstrNumber, RegisterAllocator allocator) {
    boolean aIsStackValue = a instanceof StackValue;
    boolean aIsStackValues = a instanceof StackValues;

    if (aIsStackValue != b instanceof StackValue || aIsStackValues != b instanceof StackValues) {
      return false;
    }

    if (aIsStackValue) {
      return identicalStackValuePair((StackValue) a, (StackValue) b);
    }

    if (aIsStackValues) {
      return identicalStackValuesPair((StackValues) a, (StackValues) b);
    }

    if (a.needsRegister() != b.needsRegister()) {
      return false;
    }

    if (a.needsRegister()) {
      if (allocator.getRegisterForValue(a, aInstrNumber)
          != allocator.getRegisterForValue(b, bInstrNumber)) {
        return false;
      }
    } else {
      ConstNumber aNum = a.getConstInstruction().asConstNumber();
      ConstNumber bNum = b.getConstInstruction().asConstNumber();
      if (!aNum.identicalNonValueNonPositionParts(bNum)) {
        return false;
      }
    }

    return a.outType() == b.outType();
  }

  public boolean identicalAfterRegisterAllocation(Instruction other, RegisterAllocator allocator) {
    if (other.getClass() != getClass()) {
      return false;
    }
    // In debug mode or if the instruction can throw we must account for positions, in release mode
    // we do want to share non-throwing instructions even if their positions differ.
    if (instructionTypeCanThrow() || allocator.options().debug) {
      if (!identicalNonValueParts(other)) {
        return false;
      }
    } else if (!identicalNonValueNonPositionParts(other)) {
      return false;
    }
    if (isInvokeDirect() && !asInvokeDirect().sameConstructorReceiverValue(other.asInvoke())) {
      return false;
    }
    if (outValue != null) {
      if (other.outValue == null) {
        return false;
      }
      if (!identicalOutputAfterRegisterAllocation(
          outValue, getNumber(), other.outValue, other.getNumber(), allocator)) {
        return false;
      }
    } else if (other.outValue != null) {
      return false;
    }
    // Check that all input values have the same type and allocated registers.
    if (inValues.size() != other.inValues.size()) {
      return false;
    }
    for (int j = 0; j < inValues.size(); j++) {
      Value in0 = inValues.get(j);
      Value in1 = other.inValues.get(j);
      if (!identicalInputAfterRegisterAllocation(in0, getNumber(), other, in1, other.getNumber(),
          allocator)) {
        return false;
      }
    }
    // Finally check that the dex instructions for the generated code actually are the same.
    if (allocator.options().isGeneratingDex()
        && !DexBuilder.identicalInstructionsAfterBuildingDexCode(this, other, allocator)) {
      return false;
    }
    return true;
  }

  private boolean identicalStackValuePair(StackValue a, StackValue b) {
    return a.getHeight() == b.getHeight() && a.outType() == b.outType();
  }

  private boolean identicalStackValuesPair(StackValues a, StackValues b) {
    StackValue[] aStackValues = a.getStackValues();
    StackValue[] bStackValues = b.getStackValues();
    if (aStackValues.length != bStackValues.length) {
      return false;
    }
    for (int i = 0; i < aStackValues.length; ++i) {
      if (!identicalStackValuePair(aStackValues[i], bStackValues[i])) {
        return false;
      }
    }
    return true;
  }

  public boolean isAllowedAfterThrowingInstruction() {
    return false;
  }

  public boolean isBlockLocalInstructionWithoutSideEffects(
      AppView<?> appView, ProgramMethod context) {
    return definesBlockLocalValue() && !instructionMayHaveSideEffects(appView, context);
  }

  private boolean definesBlockLocalValue() {
    return !definesValueWithNonLocalUsages();
  }

  private boolean definesValueWithNonLocalUsages() {
    if (hasOutValue()) {
      Value outValue = outValue();
      if (outValue.numberOfPhiUsers() > 0) {
        return true;
      }
      for (Instruction user : outValue.uniqueUsers()) {
        if (user.getBlock() != getBlock()) {
          return true;
        }
      }
    }
    return false;
  }

  public boolean instructionTypeCanBeCanonicalized() {
    return false;
  }

  /**
   * Returns true if this instruction may throw an exception.
   */
  public boolean instructionTypeCanThrow() {
    return false;
  }

  public boolean instructionInstanceCanThrow() {
    return instructionTypeCanThrow();
  }

  public boolean instructionMayHaveSideEffects(AppView<?> appView, ProgramMethod context) {
    return instructionMayHaveSideEffects(appView, context, SideEffectAssumption.NONE);
  }

  public boolean instructionMayHaveSideEffects(
      AppView<?> appView, ProgramMethod context, SideEffectAssumption assumption) {
    return instructionInstanceCanThrow();
  }

  /**
   * Returns true if this instruction may trigger another method to execute either directly or
   * indirectly (e.g., via class initialization).
   */
  public abstract boolean instructionMayTriggerMethodInvocation(
      AppView<?> appView, ProgramMethod context);

  public boolean instructionInstanceCanThrow(AppView<?> appView, ProgramMethod context) {
    return instructionInstanceCanThrow();
  }

  /** Returns true is this instruction can be treated as dead code if its outputs are not used. */
  public DeadInstructionResult canBeDeadCode(AppView<?> appView, IRCode code) {
    return instructionMayHaveSideEffects(appView, code.context())
        ? DeadInstructionResult.notDead()
        : DeadInstructionResult.deadIfOutValueIsDead();
  }

  /**
   * Returns an abstraction of the set of fields that may possibly be read as a result of executing
   * this instruction.
   */
  public AbstractFieldSet readSet(AppView<AppInfoWithLiveness> appView, ProgramMethod context) {
    if (instructionMayTriggerMethodInvocation(appView, context)
        && instructionMayHaveSideEffects(appView, context)) {
      return UnknownFieldSet.getInstance();
    }
    return EmptyFieldSet.getInstance();
  }

  /**
   * Returns true if this instruction need this value in a register.
   */
  public boolean needsValueInRegister(Value value) {
    return true;
  }

  public boolean isTwoAddr(RegisterAllocator allocator) {
    return false;
  }

  /**
   * Returns true if the out value of this instruction is a constant.
   *
   * @return whether the out value of this instruction is a constant.
   */
  public boolean isOutConstant() {
    return false;
  }

  /**
   * Returns the ConstInstruction defining the constant out value if the out value is constant.
   *
   * @return ConstInstruction or null.
   */
  public ConstInstruction getOutConstantConstInstruction() {
    return null;
  }

  public abstract int maxInValueRegister();

  public abstract int maxOutValueRegister();

  @Override
  public DebugLocalInfo getLocalInfo() {
    return outValue == null ? null : outValue.getLocalInfo();
  }

  public Set<Value> getDebugValues() {
    return debugValues != null ? debugValues : ImmutableSet.of();
  }

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

  @Override
  public Instruction asInstruction() {
    return this;
  }

  public boolean isArrayAccess() {
    return false;
  }

  public ArrayAccess asArrayAccess() {
    return null;
  }

  public boolean isArrayGet() {
    return false;
  }

  public ArrayGet asArrayGet() {
    return null;
  }

  public boolean isArrayLength() {
    return false;
  }

  public ArrayLength asArrayLength() {
    return null;
  }

  public boolean isArrayPut() {
    return false;
  }

  public ArrayPut asArrayPut() {
    return null;
  }

  public boolean isArgument() {
    return false;
  }

  public Argument asArgument() {
    return null;
  }

  public boolean isArithmeticBinop() {
    return false;
  }

  public ArithmeticBinop asArithmeticBinop() {
    return null;
  }

  public boolean isAssume() {
    return false;
  }

  public Assume asAssume() {
    return null;
  }

  public final boolean isAssumeWithDynamicTypeAssumption() {
    return isAssume() && asAssume().hasDynamicTypeAssumption();
  }

  public final boolean isAssumeWithNonNullAssumption() {
    return isAssume() && asAssume().hasNonNullAssumption();
  }

  public boolean isBinop() {
    return false;
  }

  public Binop asBinop() {
    return null;
  }

  public boolean isUnop() {
    return false;
  }

  public Unop asUnop() {
    return null;
  }

  public boolean isCheckCast() {
    return false;
  }

  public CheckCast asCheckCast() {
    return null;
  }

  public boolean isConstNumber() {
    return false;
  }

  public ConstNumber asConstNumber() {
    return null;
  }

  public boolean isConstInstruction() {
    return false;
  }

  public ConstInstruction asConstInstruction() {
    return null;
  }

  public boolean isConstClass() {
    return false;
  }

  public ConstClass asConstClass() {
    return null;
  }

  public boolean isConstMethodHandle() {
    return false;
  }

  public ConstMethodHandle asConstMethodHandle() {
    return null;
  }

  public boolean isConstMethodType() {
    return false;
  }

  public ConstMethodType asConstMethodType() {
    return null;
  }

  public boolean isConstString() {
    return false;
  }

  public ConstString asConstString() {
    return null;
  }

  public boolean isDexItemBasedConstString() {
    return false;
  }

  public DexItemBasedConstString asDexItemBasedConstString() {
    return null;
  }

  public boolean isCmp() {
    return false;
  }

  public Cmp asCmp() {
    return null;
  }

  public boolean isDup() {
    return false;
  }

  public Dup asDup() {
    return null;
  }

  public boolean isDup2() {
    return false;
  }

  public Dup2 asDup2() {
    return null;
  }

  public boolean isJumpInstruction() {
    return false;
  }

  public JumpInstruction asJumpInstruction() {
    return null;
  }

  public boolean isFieldInstruction() {
    return false;
  }

  public FieldInstruction asFieldInstruction() {
    return null;
  }

  public boolean isGoto() {
    return false;
  }

  public Goto asGoto() {
    return null;
  }

  public boolean isIf() {
    return false;
  }

  public If asIf() {
    return null;
  }

  public boolean isSwitch() {
    return false;
  }

  public Switch asSwitch() {
    return null;
  }

  public boolean isIntSwitch() {
    return false;
  }

  public IntSwitch asIntSwitch() {
    return null;
  }

  public boolean isStringSwitch() {
    return false;
  }

  public StringSwitch asStringSwitch() {
    return null;
  }

  public boolean isInstanceFieldInstruction() {
    return false;
  }

  public InstanceFieldInstruction asInstanceFieldInstruction() {
    return null;
  }

  public boolean isInstanceGet() {
    return false;
  }

  public InstanceGet asInstanceGet() {
    return null;
  }

  public boolean isInstanceOf() {
    return false;
  }

  public InstanceOf asInstanceOf() {
    return null;
  }

  public final boolean isFieldGet() {
    return isInstanceGet() || isStaticGet();
  }

  public final boolean isFieldPut() {
    return isInstancePut() || isStaticPut();
  }

  public boolean isInstancePut() {
    return false;
  }

  public InstancePut asInstancePut() {
    return null;
  }

  public boolean isInvoke() {
    return false;
  }

  public Invoke asInvoke() {
    return null;
  }

  public boolean isMonitor() {
    return false;
  }

  public boolean isMonitorEnter() {
    return false;
  }

  public Monitor asMonitor() {
    return null;
  }

  public boolean isMove() {
    return false;
  }

  public Move asMove() {
    return null;
  }

  public boolean isNewArrayEmpty() {
    return false;
  }

  public NewArrayEmpty asNewArrayEmpty() {
    return null;
  }

  public boolean isNewArrayFilledData() {
    return false;
  }

  public NewArrayFilledData asNewArrayFilledData() {
    return null;
  }

  public boolean isNeg() {
    return false;
  }

  public Neg asNeg() {
    return null;
  }

  public boolean isNewInstance() {
    return false;
  }

  public NewInstance asNewInstance() {
    return null;
  }

  public boolean isNot() {
    return false;
  }

  public Not asNot() {
    return null;
  }

  public boolean isNumberConversion() {
    return false;
  }

  public NumberConversion asNumberConversion() {
    return null;
  }

  public boolean isReturn() {
    return false;
  }

  public Return asReturn() {
    return null;
  }

  public boolean isThrow() {
    return false;
  }

  public Throw asThrow() {
    return null;
  }

  public boolean isStaticFieldInstruction() {
    return false;
  }

  public boolean isStaticGet() {
    return false;
  }

  public StaticGet asStaticGet() {
    return null;
  }

  public boolean isStaticPut() {
    return false;
  }

  public StaticPut asStaticPut() {
    return null;
  }

  public boolean isInitClass() {
    return false;
  }

  public InitClass asInitClass() {
    return null;
  }

  public boolean isAdd() {
    return false;
  }

  public Add asAdd() {
    return null;
  }

  public boolean isSub() {
    return false;
  }

  public Sub asSub() {
    return null;
  }

  public boolean isMul() {
    return false;
  }

  public Mul asMul() {
    return null;
  }

  public boolean isDiv() {
    return false;
  }

  public Div asDiv() {
    return null;
  }

  public boolean isRem() {
    return false;
  }

  public Rem asRem() {
    return null;
  }

  public boolean isLogicalBinop() {
    return false;
  }

  public LogicalBinop asLogicalBinop() {
    return null;
  }

  public boolean isShl() {
    return false;
  }

  public Shl asShl() {
    return null;
  }

  public boolean isShr() {
    return false;
  }

  public Shr asShr() {
    return null;
  }

  public boolean isUshr() {
    return false;
  }

  public Ushr asUshr() {
    return null;
  }

  public boolean isAnd() {
    return false;
  }

  public And asAnd() {
    return null;
  }

  public boolean isOr() {
    return false;
  }

  public Or asOr() {
    return null;
  }

  public boolean isXor() {
    return false;
  }

  public Xor asXor() {
    return null;
  }

  public boolean isMoveException() {
    return false;
  }

  public MoveException asMoveException() {
    return null;
  }

  public boolean isDebugInstruction() {
    return isDebugPosition()
        || isDebugLocalsChange()
        || isDebugLocalRead()
        || isDebugLocalWrite()
        || isDebugLocalUninitialized();
  }

  public boolean isDebugPosition() {
    return false;
  }

  public DebugPosition asDebugPosition() {
    return null;
  }

  public boolean isDebugLocalsChange() {
    return false;
  }

  public DebugLocalsChange asDebugLocalsChange() {
    return null;
  }

  public boolean isDebugLocalUninitialized() {
    return false;
  }

  public DebugLocalUninitialized asDebugLocalUninitialized() {
    return null;
  }

  public boolean isDebugLocalWrite() {
    return false;
  }

  public DebugLocalWrite asDebugLocalWrite() {
    return null;
  }

  public boolean isInvokeMethodWithDynamicDispatch() {
    return isInvokeInterface() || isInvokeVirtual();
  }

  public boolean isInvokeMethod() {
    return false;
  }

  public InvokeMethod asInvokeMethod() {
    return null;
  }

  public boolean isInvokeMethodWithReceiver() {
    return false;
  }

  public InvokeMethodWithReceiver asInvokeMethodWithReceiver() {
    return null;
  }

  public boolean isInvokeNewArray() {
    return false;
  }

  public InvokeNewArray asInvokeNewArray() {
    return null;
  }

  public boolean isInvokeMultiNewArray() {
    return false;
  }

  public InvokeMultiNewArray asInvokeMultiNewArray() {
    return null;
  }

  public boolean isInvokeCustom() {
    return false;
  }

  public InvokeCustom asInvokeCustom() {
    return null;
  }

  public boolean isInvokeDirect() {
    return false;
  }

  public InvokeDirect asInvokeDirect() {
    return null;
  }

  public boolean isInvokeInterface() {
    return false;
  }

  public InvokeInterface asInvokeInterface() {
    return null;
  }

  public boolean isInvokeStatic() {
    return false;
  }

  public InvokeStatic asInvokeStatic() {
    return null;
  }

  public boolean isInvokeSuper() {
    return false;
  }

  public InvokeSuper asInvokeSuper() {
    return null;
  }

  public boolean isInvokeVirtual() {
    return false;
  }

  public InvokeVirtual asInvokeVirtual() {
    return null;
  }

  public boolean isInvokePolymorphic() {
    return false;
  }

  public InvokePolymorphic asInvokePolymorphic() {
    return null;
  }

  public boolean isDebugLocalRead() {
    return false;
  }

  public DebugLocalRead asDebugLocalRead() {
    return null;
  }

  public boolean isPop() {
    return false;
  }

  public Pop asPop() {
    return null;
  }

  public boolean isStore() {
    return false;
  }

  public Store asStore() {
    return null;
  }

  public boolean isSwap() {
    return false;
  }

  public Swap asSwap() {
    return null;
  }

  public boolean isLoad() {
    return false;
  }

  public Load asLoad() {
    return null;
  }

  public boolean canBeFolded() {
    return false;
  }

  /** Returns true if the out-value could be an alias of an in-value.
   *
   * <p>This is a conservative version of {@link #isIntroducingAnAlias()} so that other analyses,
   * e.g., escape analysis, can propagate or track aliased values in a conservative manner.
   */
  public boolean couldIntroduceAnAlias(AppView<?> appView, Value root) {
    return false;
  }

  /** Returns true if the out-value is an alias of an in-value. */
  public boolean isIntroducingAnAlias() {
    return false;
  }

  /** Returns the in-value that is an alias for the out-value. */
  public Value getAliasForOutValue() {
    assert isIntroducingAnAlias();
    return null;
  }

  public boolean isCreatingArray() {
    return isNewArrayEmpty()
        || isNewArrayFilledData()
        || isInvokeNewArray()
        || isInvokeMultiNewArray();
  }

  public boolean isCreatingInstanceOrArray() {
    return isNewInstance() || isCreatingArray();
  }

  /**
   * Returns the inlining constraint for this method when used in the context of the given type.
   *
   * <p>The type is used to judge visibility constraints and also for dispatch decisions.
   */
  public abstract ConstraintWithTarget inliningConstraint(
      InliningConstraints inliningConstraints, ProgramMethod context);

  public abstract void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper);

  public DexType computeVerificationType(AppView<?> appView, TypeVerificationHelper helper) {
    assert outValue == null || !outValue.getType().isReferenceType();
    throw new Unreachable("Instruction without object outValue cannot compute verification type");
  }

  public abstract boolean hasInvariantOutType();

  public LatticeElement evaluate(IRCode code, Function<Value, LatticeElement> getLatticeElement) {
    if (outValue.hasValueRange()) {
      return new ConstRangeLatticeElement(outValue);
    }
    return Bottom.getInstance();
  }

  // TODO(b/72693244): maybe rename to computeOutType once TypeVerificationHelper is gone?
  public TypeElement evaluate(AppView<?> appView) {
    assert outValue == null;
    throw new Unimplemented(
        "Implement type lattice evaluation for: " + getInstructionName());
  }

  public boolean verifyTypes(AppView<?> appView) {
    // TODO(b/72693244): for instructions with invariant out type, we can verify type directly here.
    if (outValue != null) {
      TypeElement outTypeElement = outValue.getType();
      if (outTypeElement.isArrayType()) {
        DexType outBaseType =
            outTypeElement
                .asArrayType()
                .toDexType(appView.dexItemFactory())
                .toBaseType(appView.dexItemFactory());
        assert appView.graphLense().lookupType(outBaseType) == outBaseType;
      } else if (outTypeElement.isClassType()) {
        DexType outType = outTypeElement.asClassType().getClassType();
        assert appView.graphLense().lookupType(outType) == outType;
      }
    }
    return true;
  }

  /**
   * Indicates whether the instruction throws a NullPointerException if the object denoted by the
   * given value is null at runtime execution.
   *
   * @param value the value representing an object that may be null at runtime execution.
   * @param appView where pre-defined descriptors are retrieved
   * @param context
   * @return true if the instruction throws NullPointerException if value is null at runtime, false
   *     otherwise.
   */
  public boolean throwsNpeIfValueIsNull(Value value, AppView<?> appView, ProgramMethod context) {
    return false;
  }

  // Any instructions that override `throwsNpeIfValueIsNull` should override this too.
  // `throw` instruction is also throwing if the input is null. However, this util and the below
  // one are used to insert Assume instruction if input is known to be non-null or replace the
  // instruction with `throw null`. In either case, nullability of `throw` does not add anything
  // new: `throw X` with null reference X has the same effect as `throw null`; `throw X` with
  // non-null reference X ends, hence having non-null X after that instruction is non-sense.
  public boolean throwsOnNullInput() {
    return false;
  }

  // Any instructions that override `throwsOnNullInput` should override this too.
  public Value getNonNullInput() {
    throw new Unreachable("Should conform to throwsOnNullInput.");
  }

  /**
   * Indicates whether the instruction triggers the class initialization (i.e. the <clinit> method)
   * of the given class at runtime execution.
   *
   * @return true if the instruction triggers intialization of the class at runtime, false
   *     otherwise.
   */
  public boolean definitelyTriggersClassInitialization(
      DexType clazz,
      ProgramMethod context,
      AppView<AppInfoWithLiveness> appView,
      Query mode,
      AnalysisAssumption assumption) {
    return false;
  }

  public boolean verifyValidPositionInfo(boolean debug) {
    assert position != null;
    assert !debug || getPosition().isSome();
    assert !instructionTypeCanThrow()
        || isConstString()
        || isDexItemBasedConstString()
        || getPosition().isSome()
        || getPosition().isSyntheticNone();
    return true;
  }

  public boolean outTypeKnownToBeBoolean(Set<Phi> seen) {
    return false;
  }

  public static class SideEffectAssumption {

    public static final SideEffectAssumption NONE = new SideEffectAssumption();

    public static final SideEffectAssumption CLASS_ALREADY_INITIALIZED =
        new SideEffectAssumption() {

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

    public static final SideEffectAssumption INVOKED_METHOD_DOES_NOT_HAVE_SIDE_EFFECTS =
        new SideEffectAssumption() {

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

    public static final SideEffectAssumption RECEIVER_NOT_NULL =
        new SideEffectAssumption() {

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

    public boolean canAssumeClassIsAlreadyInitialized() {
      return false;
    }

    public boolean canAssumeInvokedMethodDoesNotHaveSideEffects() {
      return false;
    }

    public boolean canAssumeReceiverIsNotNull() {
      return false;
    }

    public SideEffectAssumption join(SideEffectAssumption other) {
      return new SideEffectAssumption() {

        @Override
        public boolean canAssumeClassIsAlreadyInitialized() {
          return SideEffectAssumption.this.canAssumeClassIsAlreadyInitialized()
              || other.canAssumeClassIsAlreadyInitialized();
        }

        @Override
        public boolean canAssumeInvokedMethodDoesNotHaveSideEffects() {
          return SideEffectAssumption.this.canAssumeInvokedMethodDoesNotHaveSideEffects()
              || other.canAssumeInvokedMethodDoesNotHaveSideEffects();
        }

        @Override
        public boolean canAssumeReceiverIsNotNull() {
          return SideEffectAssumption.this.canAssumeInvokedMethodDoesNotHaveSideEffects()
              || other.canAssumeInvokedMethodDoesNotHaveSideEffects();
        }
      };
    }
  }
}
