// Copyright (c) 2017, 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.code.CfStackInstruction;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.ProgramMethod;
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.lightir.LirBuilder;
import java.util.function.BiPredicate;

public class Pop extends Instruction {

  public Pop(Value src) {
    super(null, src);
    assert src.isValueOnStack();
  }

  @Override
  public int opcode() {
    return Opcodes.POP;
  }

  @Override
  public <T> T accept(InstructionVisitor<T> visitor) {
    return visitor.visit(this);
  }

  @Override
  protected void addInValue(Value value) {
    if (value.hasUsersInfo()) {
      super.addInValue(value);
    } else {
      // Overriding IR addInValue since userinfo is cleared.
      inValues.add(value);
    }
  }

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

  @Override
  public Pop asPop() {
    return this;
  }

  @Override
  protected boolean identicalNonValueParts(Instruction other, RegisterAllocator allocator) {
    assert other.isPop();
    if (!identicalPop(
        other.asPop(),
        (initClass, otherInitClass) ->
            initClass.identicalNonValueParts(otherInitClass, allocator))) {
      return false;
    }
    assert identicalNonValueNonPositionParts(other);
    return identicalPosition(other, allocator);
  }

  @Override
  public boolean identicalNonValueNonPositionParts(Instruction other) {
    if (!other.isPop()) {
      return false;
    }
    return identicalPop(other.asPop(), InitClass::identicalNonValueNonPositionParts);
  }

  // Pops are identical except if immediately following an InitClass, in which case they are
  // identical only if the corresponding InitClass are.
  private boolean identicalPop(Pop other, BiPredicate<InitClass, InitClass> predicate) {
    if (getFirstOperand().isDefinedByInstructionSatisfying(Instruction::isInitClass)) {
      InitClass initClass = getFirstOperand().getDefinition().asInitClass();
      if (!other.getFirstOperand().isDefinedByInstructionSatisfying(Instruction::isInitClass)) {
        return false;
      }
      InitClass otherInitClass = other.getFirstOperand().getDefinition().asInitClass();
      return predicate.test(initClass, otherInitClass);
    }
    return !other.getFirstOperand().isDefinedByInstructionSatisfying(Instruction::isInitClass);
  }

  @Override
  public int maxInValueRegister() {
    throw new Unreachable();
  }

  @Override
  public int maxOutValueRegister() {
    throw new Unreachable();
  }

  @Override
  public ConstraintWithTarget inliningConstraint(
      InliningConstraints inliningConstraints, ProgramMethod context) {
    return inliningConstraints.forPop();
  }

  @Override
  public void buildLir(LirBuilder<Value, ?> builder) {
    throw new Unreachable("This classfile-specific IR should not be used in LIR.");
  }

  @Override
  public void buildDex(DexBuilder builder) {
    throw new Unreachable("This classfile-specific IR should not be inserted in the Dex backend.");
  }

  @Override
  public void buildCf(CfBuilder builder) {
    builder.add(CfStackInstruction.popType(inValues.get(0).outType()), this);
  }

  @Override
  public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
    throw new Unreachable("This IR must not be inserted before load and store insertion.");
  }

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

  @Override
  public DeadInstructionResult canBeDeadCode(AppView<?> appView, IRCode code) {
    // Pop cannot be dead code as it modifies the stack height.
    return DeadInstructionResult.notDead();
  }

  @Override
  public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
    return false;
  }
}
