//===-- R600ClauseMergePass - Merge consecutive CF_ALU -------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
/// \file
/// R600EmitClauseMarker pass emits CFAlu instruction in a conservative maneer.
/// This pass is merging consecutive CFAlus where applicable.
/// It needs to be called after IfCvt for best results.
//===----------------------------------------------------------------------===//

#include "AMDGPU.h"
#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
#include "R600Subtarget.h"

using namespace llvm;

#define DEBUG_TYPE "r600mergeclause"

namespace {

static bool isCFAlu(const MachineInstr &MI) {
  switch (MI.getOpcode()) {
  case R600::CF_ALU:
  case R600::CF_ALU_PUSH_BEFORE:
    return true;
  default:
    return false;
  }
}

class R600ClauseMergePass : public MachineFunctionPass {

private:
  const R600InstrInfo *TII;

  unsigned getCFAluSize(const MachineInstr &MI) const;
  bool isCFAluEnabled(const MachineInstr &MI) const;

  /// IfCvt pass can generate "disabled" ALU clause marker that need to be
  /// removed and their content affected to the previous alu clause.
  /// This function parse instructions after CFAlu until it find a disabled
  /// CFAlu and merge the content, or an enabled CFAlu.
  void cleanPotentialDisabledCFAlu(MachineInstr &CFAlu) const;

  /// Check whether LatrCFAlu can be merged into RootCFAlu and do it if
  /// it is the case.
  bool mergeIfPossible(MachineInstr &RootCFAlu,
                       const MachineInstr &LatrCFAlu) const;

public:
  static char ID;

  R600ClauseMergePass() : MachineFunctionPass(ID) { }

  bool runOnMachineFunction(MachineFunction &MF) override;

  StringRef getPassName() const override;
};

} // end anonymous namespace

INITIALIZE_PASS_BEGIN(R600ClauseMergePass, DEBUG_TYPE,
                      "R600 Clause Merge", false, false)
INITIALIZE_PASS_END(R600ClauseMergePass, DEBUG_TYPE,
                    "R600 Clause Merge", false, false)

char R600ClauseMergePass::ID = 0;

char &llvm::R600ClauseMergePassID = R600ClauseMergePass::ID;

unsigned R600ClauseMergePass::getCFAluSize(const MachineInstr &MI) const {
  assert(isCFAlu(MI));
  return MI
      .getOperand(TII->getOperandIdx(MI.getOpcode(), R600::OpName::COUNT))
      .getImm();
}

bool R600ClauseMergePass::isCFAluEnabled(const MachineInstr &MI) const {
  assert(isCFAlu(MI));
  return MI
      .getOperand(TII->getOperandIdx(MI.getOpcode(), R600::OpName::Enabled))
      .getImm();
}

void R600ClauseMergePass::cleanPotentialDisabledCFAlu(
    MachineInstr &CFAlu) const {
  int CntIdx = TII->getOperandIdx(R600::CF_ALU, R600::OpName::COUNT);
  MachineBasicBlock::iterator I = CFAlu, E = CFAlu.getParent()->end();
  I++;
  do {
    while (I != E && !isCFAlu(*I))
      I++;
    if (I == E)
      return;
    MachineInstr &MI = *I++;
    if (isCFAluEnabled(MI))
      break;
    CFAlu.getOperand(CntIdx).setImm(getCFAluSize(CFAlu) + getCFAluSize(MI));
    MI.eraseFromParent();
  } while (I != E);
}

bool R600ClauseMergePass::mergeIfPossible(MachineInstr &RootCFAlu,
                                          const MachineInstr &LatrCFAlu) const {
  assert(isCFAlu(RootCFAlu) && isCFAlu(LatrCFAlu));
  int CntIdx = TII->getOperandIdx(R600::CF_ALU, R600::OpName::COUNT);
  unsigned RootInstCount = getCFAluSize(RootCFAlu),
      LaterInstCount = getCFAluSize(LatrCFAlu);
  unsigned CumuledInsts = RootInstCount + LaterInstCount;
  if (CumuledInsts >= TII->getMaxAlusPerClause()) {
    LLVM_DEBUG(dbgs() << "Excess inst counts\n");
    return false;
  }
  if (RootCFAlu.getOpcode() == R600::CF_ALU_PUSH_BEFORE)
    return false;
  // Is KCache Bank 0 compatible ?
  int Mode0Idx =
      TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_MODE0);
  int KBank0Idx =
      TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_BANK0);
  int KBank0LineIdx =
      TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_ADDR0);
  if (LatrCFAlu.getOperand(Mode0Idx).getImm() &&
      RootCFAlu.getOperand(Mode0Idx).getImm() &&
      (LatrCFAlu.getOperand(KBank0Idx).getImm() !=
           RootCFAlu.getOperand(KBank0Idx).getImm() ||
       LatrCFAlu.getOperand(KBank0LineIdx).getImm() !=
           RootCFAlu.getOperand(KBank0LineIdx).getImm())) {
    LLVM_DEBUG(dbgs() << "Wrong KC0\n");
    return false;
  }
  // Is KCache Bank 1 compatible ?
  int Mode1Idx =
      TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_MODE1);
  int KBank1Idx =
      TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_BANK1);
  int KBank1LineIdx =
      TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_ADDR1);
  if (LatrCFAlu.getOperand(Mode1Idx).getImm() &&
      RootCFAlu.getOperand(Mode1Idx).getImm() &&
      (LatrCFAlu.getOperand(KBank1Idx).getImm() !=
           RootCFAlu.getOperand(KBank1Idx).getImm() ||
       LatrCFAlu.getOperand(KBank1LineIdx).getImm() !=
           RootCFAlu.getOperand(KBank1LineIdx).getImm())) {
    LLVM_DEBUG(dbgs() << "Wrong KC0\n");
    return false;
  }
  if (LatrCFAlu.getOperand(Mode0Idx).getImm()) {
    RootCFAlu.getOperand(Mode0Idx).setImm(
        LatrCFAlu.getOperand(Mode0Idx).getImm());
    RootCFAlu.getOperand(KBank0Idx).setImm(
        LatrCFAlu.getOperand(KBank0Idx).getImm());
    RootCFAlu.getOperand(KBank0LineIdx)
        .setImm(LatrCFAlu.getOperand(KBank0LineIdx).getImm());
  }
  if (LatrCFAlu.getOperand(Mode1Idx).getImm()) {
    RootCFAlu.getOperand(Mode1Idx).setImm(
        LatrCFAlu.getOperand(Mode1Idx).getImm());
    RootCFAlu.getOperand(KBank1Idx).setImm(
        LatrCFAlu.getOperand(KBank1Idx).getImm());
    RootCFAlu.getOperand(KBank1LineIdx)
        .setImm(LatrCFAlu.getOperand(KBank1LineIdx).getImm());
  }
  RootCFAlu.getOperand(CntIdx).setImm(CumuledInsts);
  RootCFAlu.setDesc(TII->get(LatrCFAlu.getOpcode()));
  return true;
}

bool R600ClauseMergePass::runOnMachineFunction(MachineFunction &MF) {
  if (skipFunction(MF.getFunction()))
    return false;

  const R600Subtarget &ST = MF.getSubtarget<R600Subtarget>();
  TII = ST.getInstrInfo();

  for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
                                                  BB != BB_E; ++BB) {
    MachineBasicBlock &MBB = *BB;
    MachineBasicBlock::iterator I = MBB.begin(),  E = MBB.end();
    MachineBasicBlock::iterator LatestCFAlu = E;
    while (I != E) {
      MachineInstr &MI = *I++;
      if ((!TII->canBeConsideredALU(MI) && !isCFAlu(MI)) ||
          TII->mustBeLastInClause(MI.getOpcode()))
        LatestCFAlu = E;
      if (!isCFAlu(MI))
        continue;
      cleanPotentialDisabledCFAlu(MI);

      if (LatestCFAlu != E && mergeIfPossible(*LatestCFAlu, MI)) {
        MI.eraseFromParent();
      } else {
        assert(MI.getOperand(8).getImm() && "CF ALU instruction disabled");
        LatestCFAlu = MI;
      }
    }
  }
  return false;
}

StringRef R600ClauseMergePass::getPassName() const {
  return "R600 Merge Clause Markers Pass";
}

llvm::FunctionPass *llvm::createR600ClauseMergePass() {
  return new R600ClauseMergePass();
}
