//===-- GCNPreRAAntiHints.cpp - MFMA register anti-hints ------------------===//
//
// 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
/// Insert register allocation anti-hints.
///
//===----------------------------------------------------------------------===//

#include "GCNPreRAAntiHints.h"
#include "GCNSubtarget.h"
#include "SIInstrInfo.h"
#include "SIRegisterInfo.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/LiveIntervals.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SlotIndexes.h"
#include "llvm/CodeGen/TargetSchedule.h"

using namespace llvm;
using namespace llvm::AMDGPU;

#define DEBUG_TYPE "amdgpu-anti-hints"

namespace HC = llvm::AMDGPU::HazardClass;

enum class AntiHintRule {
  None,
  MFMAWAW,
  MFMAWAR,
  WMMAWARAB,
  SWMMACWARIndex,
  WMMAWAW,
  TransWAR,
  MemAddrWAR,
  VAVdstWAR,
  All,
};

static cl::list<AntiHintRule> AntiHintRuleSelection(
    "amdgpu-anti-hints-rules", cl::Hidden, cl::CommaSeparated,
    cl::desc("Anti-hints rules to select."),
    cl::values(clEnumValN(AntiHintRule::None, "none", "Select no rules"),
               clEnumValN(AntiHintRule::MFMAWAW, "mfma-waw",
                          "MFMA destination write-after-write"),
               clEnumValN(AntiHintRule::MFMAWAR, "mfma-war",
                          "XDL MFMA src2 write-after-read"),
               clEnumValN(AntiHintRule::WMMAWARAB, "wmma-war-ab",
                          "XDL WMMA A/B source write-after-read"),
               clEnumValN(AntiHintRule::SWMMACWARIndex, "swmmac-war-index",
                          "XDL SWMMAC sparse index write-after-read"),
               clEnumValN(AntiHintRule::WMMAWAW, "wmma-waw",
                          "XDL WMMA destination write-after-write"),
               clEnumValN(AntiHintRule::TransWAR, "trans-war",
                          "TRANS source write-after-read"),
               clEnumValN(AntiHintRule::MemAddrWAR, "mem-addr-war",
                          "Memory address/data write-after-read (s_wait_xcnt)"),
               clEnumValN(AntiHintRule::VAVdstWAR, "va-vdst-war",
                          "VALU source write-after-read by a load "
                          "(s_wait_alu va_vdst)"),
               clEnumValN(AntiHintRule::All, "all",
                          "Select all rules (default); per-rule "
                          "-amdgpu-anti-hints-for-* still apply")));

static cl::opt<bool>
    EnableAntiHintsForAddr("amdgpu-anti-hints-for-addr", cl::Hidden,
                           cl::desc("Enable Anti-Hints for memory address "
                                    "operands and subsequent VGPR writes to "
                                    "avoid wait xcnt."),
                           cl::init(true));

static cl::opt<bool>
    EnableAntiHintsForVAVdst("amdgpu-anti-hints-for-va-vdst", cl::Hidden,
                             cl::desc("Enable Anti-Hints for VA-VDST."),
                             cl::init(false));

static cl::opt<unsigned>
    VAVDSTLookbackWindow("amdgpu-va-vdst-lookback-window", cl::Hidden,
                         cl::desc("Lookback window for VA_VDST anti-hints."),
                         cl::init(32));

static cl::opt<unsigned>
    AddrAntiHintWindow("amdgpu-addr-anti-hint-window", cl::Hidden,
                       cl::desc("Number of later memory instructions an "
                                "address anti-hint stays open."),
                       cl::init(16));

namespace {

// Classify the MI into a HazardClassMask.
HazardClassMask getInstHazardClass(const MachineInstr &MI,
                                   const HazardContext &Ctx) {
  const SIInstrInfo &TII = *Ctx.TII;
  HazardClassMask Mask = HC::None;

  if (TII.isLDSDMA(MI))
    Mask = HC::VALU | HC::VMEM | HC::DS | HC::LDSDMA;
  else if (TII.isWMMA(MI) || SIInstrInfo::isSWMMAC(MI))
    Mask = HC::WMMA;
  else if (TII.isMFMA(MI))
    Mask = HC::MFMA;
  else if (SIInstrInfo::isTRANS(MI))
    Mask = HC::TRANS;
  else if (SIInstrInfo::isVALU(MI, /*AllowLDSDMA=*/true))
    Mask = HC::VALU;
  else if (TII.isDS(MI))
    Mask = HC::DS;
  else if (TII.isVMEM(MI))
    Mask = HC::VMEM;
  else if (TII.isSMRD(MI))
    Mask = HC::SMEM;
  else if (TII.isEXP(MI))
    Mask = HC::EXP;
  else if (SIInstrInfo::isSALU(MI))
    Mask = HC::SALU;
  else if (MI.isCopy() && MI.getOperand(0).getReg().isVirtual() &&
           Ctx.TRI->hasVGPRs(Ctx.MRI->getRegClass(MI.getOperand(0).getReg())))
    Mask = HC::VALU;
  if (SIInstrInfo::isVALU(MI, /*AllowLDSDMA=*/true))
    Mask |= HC::RawVALU;
  if (MI.mayLoad())
    Mask |= HC::Load;
  for (const MachineOperand &MO : MI.defs()) {
    if (MO.isReg() && MO.getReg().isVirtual() &&
        Ctx.TRI->hasVGPRs(Ctx.MRI->getRegClass(MO.getReg()))) {
      Mask |= HC::WritesVGPR;
      break;
    }
  }

  return Mask;
}

bool isVirtualVGPR(const HazardContext &Ctx, const MachineOperand &MO) {
  if (!MO.isReg() || !MO.getReg().isVirtual())
    return false;
  return Ctx.TRI->hasVGPRs(Ctx.MRI->getRegClass(MO.getReg()));
}

void collectOperandRegs(const MachineInstr &MI, HazardOperand Op,
                        const HazardContext &Ctx,
                        SmallVectorImpl<Register> &Out) {
  const SIInstrInfo &TII = *Ctx.TII;
  switch (Op) {
  case HazardOperand::None:
    break;
  case HazardOperand::Def:
    for (const MachineOperand &MO : MI.all_defs()) {
      if (isVirtualVGPR(Ctx, MO))
        Out.push_back(MO.getReg());
    }
    break;
  case HazardOperand::Src0:
    if (const MachineOperand *MO =
            TII.getNamedOperand(MI, AMDGPU::OpName::src0)) {
      if (isVirtualVGPR(Ctx, *MO))
        Out.push_back(MO->getReg());
    }
    break;
  case HazardOperand::Src1:
    if (const MachineOperand *MO =
            TII.getNamedOperand(MI, AMDGPU::OpName::src1)) {
      if (isVirtualVGPR(Ctx, *MO))
        Out.push_back(MO->getReg());
    }
    break;
  case HazardOperand::Src2:
    if (const MachineOperand *MO =
            TII.getNamedOperand(MI, AMDGPU::OpName::src2)) {
      if (isVirtualVGPR(Ctx, *MO))
        Out.push_back(MO->getReg());
    }
    break;
  case HazardOperand::Src0Src1:
    for (AMDGPU::OpName Name : {AMDGPU::OpName::src0, AMDGPU::OpName::src1}) {
      if (const MachineOperand *MO = TII.getNamedOperand(MI, Name)) {
        if (isVirtualVGPR(Ctx, *MO))
          Out.push_back(MO->getReg());
      }
    }
    break;
  case HazardOperand::Idx:
    if (const MachineOperand *MO =
            TII.getNamedOperand(MI, AMDGPU::OpName::idx)) {
      if (isVirtualVGPR(Ctx, *MO))
        Out.push_back(MO->getReg());
    }
    break;
  case HazardOperand::Vaddr:
    if (const MachineOperand *MO =
            TII.getNamedOperand(MI, AMDGPU::OpName::vaddr)) {
      if (isVirtualVGPR(Ctx, *MO))
        Out.push_back(MO->getReg());
    }
    break;
  case HazardOperand::AnySrc:
    for (AMDGPU::OpName Name :
         {AMDGPU::OpName::src0, AMDGPU::OpName::src1, AMDGPU::OpName::src2}) {
      if (const MachineOperand *MO = TII.getNamedOperand(MI, Name)) {
        if (isVirtualVGPR(Ctx, *MO))
          Out.push_back(MO->getReg());
      }
    }
    break;
  case HazardOperand::AnyUse:
    for (const MachineOperand &MO : MI.all_uses()) {
      if (isVirtualVGPR(Ctx, MO))
        Out.push_back(MO.getReg());
    }
    break;
  }
}

enum class MFMAHazardKind { RAW, WAW, WAR };

// MFMA anti-hint wait-state window, mirroring GCNHazardRecognizer.cpp wait
// states.
unsigned mfmaWaitStates(const MachineInstr &MFMA, MFMAHazardKind Kind,
                        HazardClassMask ReaderClass, const HazardContext &Ctx) {
  const SIInstrInfo &TII = *Ctx.TII;
  const GCNSubtarget &ST = *Ctx.ST;
  const int NumPasses = Ctx.SchedModel->computeInstrLatency(&MFMA);
  const bool IsDGEMM = SIInstrInfo::isDGEMM(MFMA.getOpcode());
  const bool Mem = ReaderClass & (HC::VMEM | HC::DS | HC::EXP);

  auto GFX940NPass = [&]() -> unsigned {
    return TII.isXDL(MFMA)
               ? NumPasses + 3 + (NumPasses != 2 && ST.hasGFX950Insts())
               : NumPasses + 2;
  };
  auto SMFMANPass = [&]() -> unsigned {
    switch (NumPasses) {
    case 2:
      return 5;
    case 8:
      return 11;
    case 16:
      return 19;
    default:
      return 0;
    }
  };

  switch (Kind) {
  case MFMAHazardKind::RAW:
    if (IsDGEMM) {
      switch (NumPasses) {
      case 4:
        return Mem ? 9 : 6;
      case 8:
      case 16:
        return Mem ? 18 : (ST.hasGFX950Insts() ? 19 : 11);
      default:
        return 0;
      }
    }
    return ST.hasGFX940Insts() ? GFX940NPass() : SMFMANPass();

  case MFMAHazardKind::WAW:
    if (IsDGEMM) {
      switch (NumPasses) {
      case 4:
        return 6;
      case 8:
      case 16:
        return 11;
      default:
        return 0;
      }
    }
    return ST.hasGFX940Insts() ? GFX940NPass() : SMFMANPass();

  case MFMAHazardKind::WAR:
    switch (NumPasses) {
    case 2:
      return 1;
    case 4:
      return 3;
    case 8:
      return 7;
    case 16:
      return 15;
    default:
      return 15;
    }
  }
  return 0;
}

unsigned mfmaWawWindow(const MachineInstr &P, HazardClassMask,
                       const HazardContext &Ctx) {
  return mfmaWaitStates(P, MFMAHazardKind::WAW, HC::None, Ctx);
}
unsigned mfmaWarWindow(const MachineInstr &P, HazardClassMask,
                       const HazardContext &Ctx) {
  return mfmaWaitStates(P, MFMAHazardKind::WAR, HC::None, Ctx);
}

constexpr unsigned NumWMMAHazardCategories = 7;
unsigned wmmaHazardCategory(const MachineInstr &Producer,
                            const HazardContext &Ctx) {
  const bool IsSWMMAC = SIInstrInfo::isSWMMAC(Producer);
  const bool LowestRate = Ctx.ST->hasGFX125xLowestRateWMMA();
  switch (Ctx.SchedModel->computeInstrLatency(&Producer)) {
  case 4:
    return 6;
  case 8:
    return IsSWMMAC ? 2 : 0;
  case 16:
    return LowestRate ? 4 : (IsSWMMAC ? 3 : 1);
  case 32:
    return 5;
  default:
    return NumWMMAHazardCategories;
  }
}

// WMMA/SWMMAC co-exec window.
unsigned wmmaCoexecWindow(const MachineInstr &Producer,
                          HazardClassMask ConsumerClass,
                          const HazardContext &Ctx) {
  const unsigned Category = wmmaHazardCategory(Producer, Ctx);
  if (Category >= NumWMMAHazardCategories)
    return 0;

  static constexpr unsigned WMMAWaitStates[] = {5, 9, 3, 5, 9, 17, 2};
  static constexpr unsigned VALUWaitStates[] = {4, 8, 2, 4, 8, 16, 1};
  return (ConsumerClass & HC::WMMA) ? WMMAWaitStates[Category]
                                    : VALUWaitStates[Category];
}

unsigned mfmaReaderRawWindow(const MachineInstr &Producer,
                             HazardClassMask ReaderClass,
                             const HazardContext &Ctx) {
  return mfmaWaitStates(Producer, MFMAHazardKind::RAW, ReaderClass, Ctx);
}

bool hasMFMAHazard(const HazardContext &Ctx) {
  return Ctx.ST->hasGFX90AInsts();
}

bool hasWMMACoexecHazard(const HazardContext &Ctx) {
  return Ctx.ST->hasWMMACoexecutionHazards();
}

bool hasTransCoexecHazard(const HazardContext &Ctx) {
  return Ctx.ST->hasTransCoexecutionHazard();
}

bool hasGFX1250Insts(const HazardContext &Ctx) {
  return Ctx.ST->hasGFX1250Insts();
}

bool ruleSelected(AntiHintRule Rule) {
  // No -amdgpu-anti-hints-rules on the command line selects every rule.
  if (AntiHintRuleSelection.empty() ||
      is_contained(AntiHintRuleSelection, AntiHintRule::All))
    return true;
  return is_contained(AntiHintRuleSelection, Rule);
}

bool isMFMAWAWRuleEnabled(const HazardContext &Ctx) {
  return hasMFMAHazard(Ctx) && ruleSelected(AntiHintRule::MFMAWAW);
}

bool isMFMAWARRuleEnabled(const HazardContext &Ctx) {
  return hasMFMAHazard(Ctx) && ruleSelected(AntiHintRule::MFMAWAR);
}

bool isWMMAWARABRuleEnabled(const HazardContext &Ctx) {
  return hasWMMACoexecHazard(Ctx) && ruleSelected(AntiHintRule::WMMAWARAB);
}

bool isSWMMACWARIndexRuleEnabled(const HazardContext &Ctx) {
  return hasWMMACoexecHazard(Ctx) && ruleSelected(AntiHintRule::SWMMACWARIndex);
}

bool isWMMAWAWRuleEnabled(const HazardContext &Ctx) {
  return hasWMMACoexecHazard(Ctx) && ruleSelected(AntiHintRule::WMMAWAW);
}

bool isTransWARRuleEnabled(const HazardContext &Ctx) {
  return hasTransCoexecHazard(Ctx) && ruleSelected(AntiHintRule::TransWAR);
}

bool isAddrWARRuleEnabled(const HazardContext &Ctx) {
  return EnableAntiHintsForAddr && hasGFX1250Insts(Ctx) &&
         ruleSelected(AntiHintRule::MemAddrWAR);
}

bool isVAVdstWARRuleEnabled(const HazardContext &Ctx) {
  return EnableAntiHintsForVAVdst && hasGFX1250Insts(Ctx) &&
         ruleSelected(AntiHintRule::VAVdstWAR);
}

bool isXDLMFMA(const MachineInstr &MI, const HazardContext &Ctx) {
  return Ctx.TII->isXDL(MI);
}

bool isXDLWMMA(const MachineInstr &MI, const HazardContext &Ctx) {
  return Ctx.TII->isXDLWMMA(MI);
}

bool isXDLSWMMAC(const MachineInstr &MI, const HazardContext &Ctx) {
  return Ctx.TII->isXDLWMMA(MI) && SIInstrInfo::isSWMMAC(MI);
}

bool isDSorVMEMLoad(const MachineInstr &MI, const HazardContext &Ctx) {
  return MI.mayLoad() && (Ctx.TII->isDS(MI) || Ctx.TII->isVMEM(MI));
}

unsigned resolveWindow(const ConsumerTarget &CT, const MachineInstr &MI,
                       const HazardContext &Ctx) {
  // Explicity given window length overrides the computed one.
  if (CT.Window.OptWindowLength)
    return *CT.Window.OptWindowLength;
  if (CT.Window.Fn)
    return CT.Window.Fn(MI, CT.Side.Match.AnyOf, Ctx);
  return CT.Window.WindowLength;
}

// Build the anti-hints rules.
class HazardRuleSet {
  SmallVector<HazardAntiHintRule, 0> Rules;

public:
  class RuleBuilder {

    HazardRuleSet &S;
    unsigned Idx;
    HazardAntiHintRule &rule() const { return S.Rules[Idx]; }

  public:
    RuleBuilder(HazardRuleSet &S, unsigned Idx) : S(S), Idx(Idx) {}

    RuleBuilder &producer(ClassMatch M, HazardOperand Op,
                          InstPredicate Predicate = nullptr) {
      rule().Producer = {M, Op, Predicate};
      return *this;
    }

    RuleBuilder &rawCredit(AdvanceForRawWindowFn AdvanceForRawWindow) {
      rule().AdvanceForRawWindow = AdvanceForRawWindow;
      return *this;
    }

    RuleBuilder &
    consumer(ClassMatch M, HazardOperand Op, WindowSpec Window,
             HazardClassMask CountMask = 0,
             AntiHintDirection Direction = AntiHintDirection::OneDirectional,
             InstPredicate Predicate = nullptr) {
      rule().Consumers.push_back(
          {{M, Op, Predicate}, Window, CountMask, Direction});
      return *this;
    }

    RuleBuilder &enabledIf(RulePredicate Predicate) {
      rule().Predicate = Predicate;
      return *this;
    }

    RuleBuilder &lifetime(Lifetime Life) {
      rule().Life = Life;
      return *this;
    }
  };

  RuleBuilder addRule() {
    Rules.emplace_back();
    return RuleBuilder(*this, Rules.size() - 1);
  }

  SmallVector<HazardAntiHintRule, 0> buildRules() { return std::move(Rules); }
};

// Here the anti-hints rules are inserted.
SmallVector<HazardAntiHintRule, 0> buildAntiHintsRules() {
  using HO = HazardOperand;
  HazardRuleSet S;

  // MFMA relevent windows and consumers
  const WindowSpec MfmaWawWindow{0, nullptr, mfmaWawWindow};
  const WindowSpec MfmaWarWindow{0, nullptr, mfmaWarWindow};
  const ClassMatch MfmaConsumers = {HC::DS | HC::VALU | HC::VMEM | HC::TRANS |
                                    HC::EXP};

  // WMMA relevent windows and consumers
  const WindowSpec WmmaCoexecWindow{0, nullptr, wmmaCoexecWindow};
  const ClassMatch WmmaCoexecConsumers = {/*AnyOf=*/HC::VALU | HC::TRANS,
                                          /*AllOf=*/HC::None,
                                          /*NoneOf=*/HC::LDSDMA};
  const HazardClassMask CoexecCounters = HC::VALU | HC::TRANS | HC::WMMA;

  // MFMA WAW rules
  S.addRule()
      .enabledIf(isMFMAWAWRuleEnabled)
      .producer({HC::MFMA}, HO::Def)
      .rawCredit(mfmaReaderRawWindow)
      .consumer(MfmaConsumers, HO::Def, MfmaWawWindow, HC::None,
                AntiHintDirection::OneDirectional);

  // MFMA WAR rules
  S.addRule()
      .enabledIf(isMFMAWARRuleEnabled)
      .producer({HC::MFMA}, HO::Src2, isXDLMFMA)
      .rawCredit(mfmaReaderRawWindow)
      .consumer(MfmaConsumers, HO::Def, MfmaWarWindow, HC::None,
                AntiHintDirection::OneDirectional);

  // WMMA WAR.
  S.addRule()
      .enabledIf(isWMMAWARABRuleEnabled)
      .producer({HC::WMMA}, HO::Src0Src1, isXDLWMMA)
      .consumer(WmmaCoexecConsumers, HO::Def, WmmaCoexecWindow, CoexecCounters,
                AntiHintDirection::OneDirectional)
      .consumer({HC::VMEM | HC::DS}, HO::Def, WmmaCoexecWindow, CoexecCounters,
                AntiHintDirection::OneDirectional);

  // SWMMAC WAR.
  S.addRule()
      .enabledIf(isSWMMACWARIndexRuleEnabled)
      .producer({HC::WMMA}, HO::Src2, isXDLSWMMAC)
      .consumer(WmmaCoexecConsumers, HO::Def, WmmaCoexecWindow, CoexecCounters,
                AntiHintDirection::OneDirectional);

  // WMMA WAW.
  S.addRule()
      .enabledIf(isWMMAWAWRuleEnabled)
      .producer({HC::WMMA}, HO::Def, isXDLWMMA)
      .consumer(WmmaCoexecConsumers, HO::Def, WmmaCoexecWindow, CoexecCounters,
                AntiHintDirection::OneDirectional);

  // TRANS WAR.
  S.addRule()
      .enabledIf(isTransWARRuleEnabled)
      .producer({HC::TRANS}, HO::AnyUse)
      .consumer({HC::VALU | HC::WMMA}, HO::Def, {/*WindowLength=*/1},
                CoexecCounters, AntiHintDirection::OneDirectional);

  // Address WAR.
  S.addRule()
      .enabledIf(isAddrWARRuleEnabled)
      .producer({HC::VMEM}, HO::AnyUse)
      .consumer({HC::WritesVGPR}, HO::Def, {0, &AddrAntiHintWindow}, HC::VMEM,
                AntiHintDirection::Symmetric);

  // VA_VDST WAR.
  S.addRule()
      .enabledIf(isVAVdstWARRuleEnabled)
      .lifetime(Lifetime::RegisterCount)
      .producer({HC::RawVALU}, HO::AnyUse)
      .consumer({HC::Load}, HO::Def, {0, &VAVDSTLookbackWindow}, HC::None,
                AntiHintDirection::Symmetric, isDSorVMEMLoad);

  return S.buildRules();
}

ArrayRef<HazardAntiHintRule> getAntiHintsRules() {
  static const SmallVector<HazardAntiHintRule, 0> Rules = buildAntiHintsRules();
  return Rules;
}

struct AntiHintWindow {
  SmallVector<Register, 4> Regs;
  const MachineInstr *Producer = nullptr;
  unsigned Len = 0;
  unsigned Elapsed = 0;
};

using ConsumerTracking = SmallVector<AntiHintWindow, 3>;
// One per consumer target of a rule.
using RuleTracking = SmallVector<ConsumerTracking, 3>;

class AntiHintEngine {
  const HazardContext &Ctx;
  ArrayRef<HazardAntiHintRule> Rules;

  SmallVector<bool, 8> RuleApplies;
  bool AnyEnabled = false;

public:
  AntiHintEngine(const HazardContext &Ctx)
      : Ctx(Ctx), Rules(getAntiHintsRules()), RuleApplies(Rules.size()) {
    for (unsigned R = 0; R < Rules.size(); ++R) {
      const HazardAntiHintRule &Rule = Rules[R];
      RuleApplies[R] = !Rule.Predicate || Rule.Predicate(Ctx);
      AnyEnabled |= RuleApplies[R];
    }
  }

  void run(MachineFunction &MF) {
    if (!AnyEnabled)
      return;

    SmallVector<RuleTracking, 8> Tracking(Rules.size());
    for (unsigned R = 0; R < Rules.size(); ++R)
      Tracking[R].resize(Rules[R].Consumers.size());

    for (const MachineBasicBlock &MBB : MF) {
      for (RuleTracking &RT : Tracking) {
        for (ConsumerTracking &Track : RT)
          Track.clear();
      }
      for (const MachineInstr &MI : MBB) {
        if (MI.isMetaInstruction())
          continue;
        const HazardClassMask C = getInstHazardClass(MI, Ctx);
        // Wait states this instruction contributes to an open window.
        unsigned WaitStates = SIInstrInfo::getNumWaitStates(MI);
        addAntiHintsAndExpire(MI, C, WaitStates, Tracking);
        addWindows(MI, C, Tracking);
      }
    }
  }

private:
  // Check if the right class and predicate matches.
  bool sideMatches(const HazardSide &Side, const MachineInstr &MI,
                   HazardClassMask C) {
    return Side.Match.matches(C) &&
           (!Side.Predicate || Side.Predicate(MI, Ctx));
  }

  // Producer phase: open a window for each consumer target.
  void addWindows(const MachineInstr &MI, HazardClassMask C,
                  MutableArrayRef<RuleTracking> Tracking) {
    for (unsigned R = 0; R < Rules.size(); ++R) {
      const HazardAntiHintRule &Rule = Rules[R];
      if (!RuleApplies[R] || !sideMatches(Rule.Producer, MI, C))
        continue;

      SmallVector<Register, 4> Regs;
      // Collect the producer regs.
      collectOperandRegs(MI, Rule.Producer.Op, Ctx, Regs);
      if (Regs.empty())
        continue;
      for (unsigned ConsumerIdx = 0, E = Rule.Consumers.size();
           ConsumerIdx != E; ++ConsumerIdx)
        seedWindow(Rule, Rule.Consumers[ConsumerIdx], MI, Regs,
                   Tracking[R][ConsumerIdx]);
    }
  }

  void seedWindow(const HazardAntiHintRule &Rule, const ConsumerTarget &CT,
                  const MachineInstr &MI, ArrayRef<Register> Regs,
                  ConsumerTracking &Track) {
    unsigned Window = resolveWindow(CT, MI, Ctx);
    if (!Window)
      return;

    if (Rule.Life == Lifetime::RegisterCount) {
      // Window length caps the register count.
      if (Track.empty())
        Track.push_back({{}, &MI, Window, 0});
      SmallVectorImpl<Register> &Recent = Track.front().Regs;
      for (Register Reg : Regs) {
        if (llvm::is_contained(Recent, Reg))
          continue;
        Recent.push_back(Reg);
        if (Recent.size() > Window)
          Recent.erase(Recent.begin());
      }
      return;
    }

    Track.push_back({SmallVector<Register, 4>(Regs), &MI, Window, 0});
  }

  void advanceByRawWindow(const MachineInstr &MI, HazardClassMask C,
                          const HazardAntiHintRule &Rule,
                          const ConsumerTarget &CT, ConsumerTracking &Track) {

    if (!Rule.AdvanceForRawWindow || !CT.Side.Match.matches(C))
      return;
    for (AntiHintWindow &Window : Track) {
      // Determine if def generated by producer is read by the MI consumer.
      bool ReadsProducerDef = llvm::any_of(
          Window.Producer->all_defs(), [&](const MachineOperand &MO) {
            return MO.getReg().isVirtual() &&
                   MI.readsVirtualRegister(MO.getReg());
          });
      // Advance by RAW window from the producer if that is larger than current
      // Window.Elapsed.
      if (ReadsProducerDef) {
        Window.Elapsed = std::max(
            Window.Elapsed, Rule.AdvanceForRawWindow(*Window.Producer, C, Ctx));
      }
    }
  }

  // Consumer phase: add anti-hints, then charge and expire open windows.
  void addAntiHintsAndExpire(const MachineInstr &MI, HazardClassMask C,
                             unsigned WaitStates,
                             MutableArrayRef<RuleTracking> Tracking) {
    for (unsigned R = 0; R < Rules.size(); ++R) {
      const HazardAntiHintRule &Rule = Rules[R];
      if (!RuleApplies[R])
        continue;
      for (unsigned ConsumerIdx = 0, E = Rule.Consumers.size();
           ConsumerIdx != E; ++ConsumerIdx) {
        const ConsumerTarget &CT = Rule.Consumers[ConsumerIdx];
        ConsumerTracking &Track = Tracking[R][ConsumerIdx];
        if (Track.empty())
          continue;

        // Before adding the anti-hints, see if advancing by RAW window will
        // help remove the window.
        const bool Counts = Rule.Life == Lifetime::WindowBudget;
        if (Counts) {
          advanceByRawWindow(MI, C, Rule, CT, Track);
          llvm::erase_if(Track, [](const AntiHintWindow &Window) {
            return Window.Elapsed >= Window.Len;
          });
        }

        // Add anti-hints if the consumer matches the instruction.
        if (sideMatches(CT.Side, MI, C))
          addAntiHints(CT, MI, Track);

        // This instruction's own wait states count toward the next one.
        if (Counts && (!CT.CounterMask || (C & CT.CounterMask))) {
          for (AntiHintWindow &Window : Track)
            Window.Elapsed += WaitStates;
        }
      }
    }
  }

  bool isCopyOf(Register Cand, Register HazardReg) const {
    const MachineInstr *Def = Ctx.MRI->getUniqueVRegDef(Cand);
    return Def && Def->isCopy() && Def->getOperand(1).getReg() == HazardReg;
  }

  void addAntiHints(const ConsumerTarget &CT, const MachineInstr &MI,
                    const ConsumerTracking &Track) {
    if (Track.empty())
      return;
    SmallVector<Register, 4> ConsumerRegs;
    // Collect the consumer regs.
    collectOperandRegs(MI, CT.Side.Op, Ctx, ConsumerRegs);
    if (ConsumerRegs.empty())
      return;
    SlotIndex Slot = Ctx.LIS->getInstructionIndex(MI).getRegSlot();
    auto AntiHint = [&](Register ProducerReg) {
      if (!Ctx.LIS->hasInterval(ProducerReg))
        return;
      const LiveInterval &ProducerLI = Ctx.LIS->getInterval(ProducerReg);
      // Skip a live producer reg.
      if (ProducerLI.liveAt(Slot))
        return;
      for (Register ConsumerReg : ConsumerRegs) {
        if (ConsumerReg == ProducerReg || isCopyOf(ConsumerReg, ProducerReg))
          continue;

        Ctx.MRI->addRegAllocationAntiHints(ConsumerReg, ProducerReg);
        if (CT.Direction == AntiHintDirection::Symmetric)
          Ctx.MRI->addRegAllocationAntiHints(ProducerReg, ConsumerReg);
        LLVM_DEBUG(
            dbgs() << "anti-hint: keep " << printReg(ProducerReg, Ctx.TRI)
                   << (CT.Direction == AntiHintDirection::Symmetric ? " <-> "
                                                                    : " <- ")
                   << printReg(ConsumerReg, Ctx.TRI) << " (consumer "
                   << Ctx.TII->getName(MI.getOpcode()) << ")\n");
      }
    };
    for (const AntiHintWindow &Window : Track) {
      for (Register ProducerReg : Window.Regs)
        AntiHint(ProducerReg);
    }
  }
};

} // namespace

void AMDGPU::applyAntiHintRules(MachineFunction &MF, const HazardContext &Ctx) {
  AntiHintEngine(Ctx).run(MF);
}
