//===---------------- llvm/CodeGen/MatchContext.h  --------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file declares the EmptyMatchContext class and VPMatchContext class.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_CODEGEN_SELECTIONDAG_MATCHCONTEXT_H
#define LLVM_LIB_CODEGEN_SELECTIONDAG_MATCHCONTEXT_H

#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/TargetLowering.h"

namespace llvm {

class EmptyMatchContext {
  SelectionDAG &DAG;
  const TargetLowering &TLI;
  SDNode *Root;

public:
  EmptyMatchContext(SelectionDAG &DAG, const TargetLowering &TLI, SDNode *Root)
      : DAG(DAG), TLI(TLI), Root(Root) {}

  unsigned getRootBaseOpcode() { return Root->getOpcode(); }
  bool match(SDValue OpN, unsigned Opcode) const {
    return Opcode == OpN->getOpcode();
  }

  // Same as SelectionDAG::getNode().
  template <typename... ArgT> SDValue getNode(ArgT &&...Args) {
    return DAG.getNode(std::forward<ArgT>(Args)...);
  }

  bool isOperationLegal(unsigned Op, EVT VT) const {
    return TLI.isOperationLegal(Op, VT);
  }

  bool isOperationLegalOrCustom(unsigned Op, EVT VT,
                                bool LegalOnly = false) const {
    return TLI.isOperationLegalOrCustom(Op, VT, LegalOnly);
  }

  unsigned getNumOperands(SDValue N) const { return N->getNumOperands(); }
};

class VPMatchContext {
  SelectionDAG &DAG;
  const TargetLowering &TLI;
  SDValue RootMaskOp;
  SDValue RootVectorLenOp;
  SDNode *Root;

public:
  VPMatchContext(SelectionDAG &DAG, const TargetLowering &TLI, SDNode *_Root)
      : DAG(DAG), TLI(TLI), RootMaskOp(), RootVectorLenOp() {
    Root = _Root;
    assert(Root->isVPOpcode());
    if (auto RootMaskPos = ISD::getVPMaskIdx(Root->getOpcode()))
      RootMaskOp = Root->getOperand(*RootMaskPos);
    else if (Root->getOpcode() == ISD::VP_SELECT)
      RootMaskOp = DAG.getAllOnesConstant(SDLoc(Root),
                                          Root->getOperand(0).getValueType());

    if (auto RootVLenPos = ISD::getVPExplicitVectorLengthIdx(Root->getOpcode()))
      RootVectorLenOp = Root->getOperand(*RootVLenPos);
  }

  unsigned getRootBaseOpcode() {
    std::optional<unsigned> Opcode = ISD::getBaseOpcodeForVP(
        Root->getOpcode(), !Root->getFlags().hasNoFPExcept());
    assert(Opcode.has_value());
    return *Opcode;
  }

  /// whether \p OpVal is a node that is functionally compatible with the
  /// NodeType \p Opc
  bool match(SDValue OpVal, unsigned Opc) const {
    if (!OpVal->isVPOpcode())
      return OpVal->getOpcode() == Opc;

    auto BaseOpc = ISD::getBaseOpcodeForVP(OpVal->getOpcode(),
                                           !OpVal->getFlags().hasNoFPExcept());
    if (BaseOpc != Opc)
      return false;

    // Make sure the mask of OpVal is true mask or is same as Root's.
    unsigned VPOpcode = OpVal->getOpcode();
    if (auto MaskPos = ISD::getVPMaskIdx(VPOpcode)) {
      SDValue MaskOp = OpVal.getOperand(*MaskPos);
      if (RootMaskOp != MaskOp &&
          !ISD::isConstantSplatVectorAllOnes(MaskOp.getNode()))
        return false;
    }

    // Make sure the EVL of OpVal is same as Root's.
    if (auto VLenPos = ISD::getVPExplicitVectorLengthIdx(VPOpcode))
      if (RootVectorLenOp != OpVal.getOperand(*VLenPos))
        return false;
    return true;
  }

  // Specialize based on number of operands.
  // TODO emit VP intrinsics where MaskOp/VectorLenOp != null
  // SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT) { return
  // DAG.getNode(Opcode, DL, VT); }
  SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue Operand) {
    unsigned VPOpcode = *ISD::getVPForBaseOpcode(Opcode);
    assert(ISD::getVPMaskIdx(VPOpcode) == 1 &&
           ISD::getVPExplicitVectorLengthIdx(VPOpcode) == 2);
    return DAG.getNode(VPOpcode, DL, VT,
                       {Operand, RootMaskOp, RootVectorLenOp});
  }

  SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
                  SDValue N2) {
    unsigned VPOpcode = *ISD::getVPForBaseOpcode(Opcode);
    assert(ISD::getVPMaskIdx(VPOpcode) == 2 &&
           ISD::getVPExplicitVectorLengthIdx(VPOpcode) == 3);
    return DAG.getNode(VPOpcode, DL, VT, {N1, N2, RootMaskOp, RootVectorLenOp});
  }

  SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
                  SDValue N2, SDValue N3) {
    unsigned VPOpcode = *ISD::getVPForBaseOpcode(Opcode);
    assert(ISD::getVPMaskIdx(VPOpcode) == 3 &&
           ISD::getVPExplicitVectorLengthIdx(VPOpcode) == 4);
    return DAG.getNode(VPOpcode, DL, VT,
                       {N1, N2, N3, RootMaskOp, RootVectorLenOp});
  }

  SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue Operand,
                  SDNodeFlags Flags) {
    unsigned VPOpcode = *ISD::getVPForBaseOpcode(Opcode);
    assert(ISD::getVPMaskIdx(VPOpcode) == 1 &&
           ISD::getVPExplicitVectorLengthIdx(VPOpcode) == 2);
    return DAG.getNode(VPOpcode, DL, VT, {Operand, RootMaskOp, RootVectorLenOp},
                       Flags);
  }

  SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
                  SDValue N2, SDNodeFlags Flags) {
    unsigned VPOpcode = *ISD::getVPForBaseOpcode(Opcode);
    assert(ISD::getVPMaskIdx(VPOpcode) == 2 &&
           ISD::getVPExplicitVectorLengthIdx(VPOpcode) == 3);
    return DAG.getNode(VPOpcode, DL, VT, {N1, N2, RootMaskOp, RootVectorLenOp},
                       Flags);
  }

  SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
                  SDValue N2, SDValue N3, SDNodeFlags Flags) {
    unsigned VPOpcode = *ISD::getVPForBaseOpcode(Opcode);
    assert(ISD::getVPMaskIdx(VPOpcode) == 3 &&
           ISD::getVPExplicitVectorLengthIdx(VPOpcode) == 4);
    return DAG.getNode(VPOpcode, DL, VT,
                       {N1, N2, N3, RootMaskOp, RootVectorLenOp}, Flags);
  }

  bool isOperationLegal(unsigned Op, EVT VT) const {
    unsigned VPOp = *ISD::getVPForBaseOpcode(Op);
    return TLI.isOperationLegal(VPOp, VT);
  }

  bool isOperationLegalOrCustom(unsigned Op, EVT VT,
                                bool LegalOnly = false) const {
    unsigned VPOp = *ISD::getVPForBaseOpcode(Op);
    return TLI.isOperationLegalOrCustom(VPOp, VT, LegalOnly);
  }

  unsigned getNumOperands(SDValue N) const {
    return N->isVPOpcode() ? N->getNumOperands() - 2 : N->getNumOperands();
  }
};

} // namespace llvm

#endif // LLVM_LIB_CODEGEN_SELECTIONDAG_MATCHCONTEXT_H
