//===-- R600ClauseMergePass - Merge consecutive CF_ALU -------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
/// \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 "AMDGPUSubtarget.h"
#include "R600Defines.h"
#include "R600InstrInfo.h"
#include "R600MachineFunctionInfo.h"
#include "R600RegisterInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

#define DEBUG_TYPE "r600mergeclause"

namespace {

static bool isCFAlu(const MachineInstr *MI) {
  switch (MI->getOpcode()) {
  case AMDGPU::CF_ALU:
  case AMDGPU::CF_ALU_PUSH_BEFORE:
    return true;
  default:
    return false;
  }
}

class R600ClauseMergePass : public MachineFunctionPass {

private:
  static char ID;
  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:
  R600ClauseMergePass(TargetMachine &tm) : MachineFunctionPass(ID) { }

  bool runOnMachineFunction(MachineFunction &MF) override;

  const char *getPassName() const override;
};

char R600ClauseMergePass::ID = 0;

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

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

void R600ClauseMergePass::cleanPotentialDisabledCFAlu(MachineInstr *CFAlu)
    const {
  int CntIdx = TII->getOperandIdx(AMDGPU::CF_ALU, AMDGPU::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(AMDGPU::CF_ALU, AMDGPU::OpName::COUNT);
  unsigned RootInstCount = getCFAluSize(RootCFAlu),
      LaterInstCount = getCFAluSize(LatrCFAlu);
  unsigned CumuledInsts = RootInstCount + LaterInstCount;
  if (CumuledInsts >= TII->getMaxAlusPerClause()) {
    DEBUG(dbgs() << "Excess inst counts\n");
    return false;
  }
  if (RootCFAlu->getOpcode() == AMDGPU::CF_ALU_PUSH_BEFORE)
    return false;
  // Is KCache Bank 0 compatible ?
  int Mode0Idx =
      TII->getOperandIdx(AMDGPU::CF_ALU, AMDGPU::OpName::KCACHE_MODE0);
  int KBank0Idx =
      TII->getOperandIdx(AMDGPU::CF_ALU, AMDGPU::OpName::KCACHE_BANK0);
  int KBank0LineIdx =
      TII->getOperandIdx(AMDGPU::CF_ALU, AMDGPU::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())) {
    DEBUG(dbgs() << "Wrong KC0\n");
    return false;
  }
  // Is KCache Bank 1 compatible ?
  int Mode1Idx =
      TII->getOperandIdx(AMDGPU::CF_ALU, AMDGPU::OpName::KCACHE_MODE1);
  int KBank1Idx =
      TII->getOperandIdx(AMDGPU::CF_ALU, AMDGPU::OpName::KCACHE_BANK1);
  int KBank1LineIdx =
      TII->getOperandIdx(AMDGPU::CF_ALU, AMDGPU::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())) {
    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;
}

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

} // end anonymous namespace


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