//===- MachineConvergenceVerifier.cpp - Verify convergencectrl ------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/MachineConvergenceVerifier.h"
#include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/MachineSSAContext.h"
#include "llvm/IR/GenericConvergenceVerifierImpl.h"

using namespace llvm;

template <>
auto GenericConvergenceVerifier<MachineSSAContext>::getConvOp(
    const MachineInstr &MI) -> ConvOpKind {
  switch (MI.getOpcode()) {
  default:
    return CONV_NONE;
  case TargetOpcode::CONVERGENCECTRL_ENTRY:
    return CONV_ENTRY;
  case TargetOpcode::CONVERGENCECTRL_ANCHOR:
    return CONV_ANCHOR;
  case TargetOpcode::CONVERGENCECTRL_LOOP:
    return CONV_LOOP;
  }
}

template <>
void GenericConvergenceVerifier<
    MachineSSAContext>::checkConvergenceTokenProduced(const MachineInstr &MI) {
  Check(!MI.hasImplicitDef(),
        "Convergence control tokens are defined explicitly.",
        {Context.print(&MI)});
  const MachineOperand &Def = MI.getOperand(0);
  const MachineRegisterInfo &MRI = Context.getFunction()->getRegInfo();
  Check(MRI.getUniqueVRegDef(Def.getReg()),
        "Convergence control tokens must have unique definitions.",
        {Context.print(&MI)});
}

template <>
const MachineInstr *
GenericConvergenceVerifier<MachineSSAContext>::findAndCheckConvergenceTokenUsed(
    const MachineInstr &MI) {
  const MachineRegisterInfo &MRI = Context.getFunction()->getRegInfo();
  const MachineInstr *TokenDef = nullptr;

  for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) {
    const MachineOperand &MO = MI.getOperand(I);
    if (!MO.isReg() || !MO.isUse())
      continue;
    Register OpReg = MO.getReg();
    if (!OpReg.isVirtual())
      continue;

    const MachineInstr *Def = MRI.getUniqueVRegDef(OpReg);
    if (!Def)
      continue;
    if (getConvOp(*Def) == CONV_NONE)
      continue;

    CheckOrNull(
        MI.isConvergent(),
        "Convergence control tokens can only be used by convergent operations.",
        {Context.print(OpReg), Context.print(&MI)});

    CheckOrNull(!TokenDef,
                "An operation can use at most one convergence control token.",
                {Context.print(OpReg), Context.print(&MI)});

    TokenDef = Def;
  }

  if (TokenDef)
    Tokens[&MI] = TokenDef;

  return TokenDef;
}

template <>
bool GenericConvergenceVerifier<MachineSSAContext>::isInsideConvergentFunction(
    const MachineInstr &MI) {
  // The class MachineFunction does not have any property to indicate whether it
  // is convergent. Trivially return true so that the check always passes.
  return true;
}

template <>
bool GenericConvergenceVerifier<MachineSSAContext>::isConvergent(
    const MachineInstr &MI) {
  return MI.isConvergent();
}

template class llvm::GenericConvergenceVerifier<MachineSSAContext>;
