// 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.DexItemFactory;
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.VerifyTypesHelper;
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 void forceOverwritePosition(Position position) {
    assert position != null;
    assert this.position != null;
    this.position = position;
  }

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

  public Value getOperand(int index) {
    return inValues().get(index);
  }

  public Value getFirstOperand() {
    return getOperand(0);
  }

  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 ignoreCompatRules() {
    return false;
  }

  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 boolean hasUnusedOutValue() {
    return !hasUsedOutValue();
  }

  public boolean hasUsedOutValue() {
    return hasOutValue() && outValue().hasAnyUsers();
  }

  public Value outValue() {
    return outValue;
  }

  public Value clearOutValue() {
    return setOutValue(null);
  }

  // Returns the previous out-value, if any.
  public Value setOutValue(Value newOutValue) {
    Value previousOutValue = outValue();
    outValue = newOutValue;
    if (newOutValue != null) {
      newOutValue.definition = this;
    }
    return previousOutValue;
  }

  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);
      }
    }
    oldValue.removeUser(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) {
    replace(newInstruction, code, null);
  }

  public void replace(Instruction newInstruction, IRCode code, Set<Value> affectedValues) {
    getBlock().listIterator(code, this).replaceCurrentInstruction(newInstruction, affectedValues);
  }

  /**
   * 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 isRecordFieldValues() {
    return false;
  }

  public RecordFieldValues asRecordFieldValues() {
    return null;
  }

  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 isUnusedArgument() {
    return false;
  }

  public UnusedArgument asUnusedArgument() {
    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 isSafeCheckCast() {
    return false;
  }

  public SafeCheckCast asSafeCheckCast() {
    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 boolean isFieldGet() {
    return false;
  }

  public FieldGet asFieldGet() {
    return null;
  }

  public boolean isFieldPut() {
    return false;
  }

  public FieldPut asFieldPut() {
    return null;
  }

  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 isNewUnboxedEnumInstance() {
    return false;
  }

  public NewUnboxedEnumInstance asNewUnboxedEnumInstance() {
    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 isInvokeConstructor(DexItemFactory dexItemFactory) {
    return false;
  }

  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()
        || isRecordFieldValues();
  }

  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, VerifyTypesHelper verifyTypesHelper) {
    if (outValue != null) {
      TypeElement outTypeElement = outValue.getType();
      if (outTypeElement.isArrayType()) {
        DexType outBaseType =
            outTypeElement
                .asArrayType()
                .toDexType(appView.dexItemFactory())
                .toBaseType(appView.dexItemFactory());
        assert appView.graphLens().lookupType(outBaseType) == outBaseType;
      } else if (outTypeElement.isClassType()) {
        DexType outType = outTypeElement.asClassType().getClassType();
        assert appView.graphLens().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 IGNORE_RECEIVER_FIELD_ASSIGNMENTS =
        new SideEffectAssumption() {

          @Override
          public boolean canIgnoreInstanceFieldAssignmentsToReceiver() {
            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 canIgnoreInstanceFieldAssignmentsToReceiver() {
      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();
        }
      };
    }
  }

  public abstract static class BuilderBase<B extends BuilderBase<B, I>, I extends Instruction> {

    protected Value outValue;
    protected Position position;

    public abstract I build();

    public abstract B self();

    final I amend(I instruction) {
      if (position != null) {
        instruction.setPosition(position);
      }
      return instruction;
    }

    public B setOutValue(Value outValue) {
      this.outValue = outValue;
      return self();
    }

    public B setFreshOutValue(ValueFactory factory, TypeElement type) {
      return setFreshOutValue(factory, type, null);
    }

    public B setFreshOutValue(ValueFactory factory, TypeElement type, DebugLocalInfo localInfo) {
      return setOutValue(factory.createValue(type, localInfo));
    }

    public B setPosition(Position position) {
      this.position = position;
      return self();
    }

    public B setPosition(Instruction other) {
      return setPosition(other.getPosition());
    }
  }
}
