1//===- GCNPreRAAntiHints.h --------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_LIB_TARGET_AMDGPU_GCNPRERAANTIHINTS_H
10#define LLVM_LIB_TARGET_AMDGPU_GCNPRERAANTIHINTS_H
11
12#include "llvm/ADT/SmallVector.h"
13#include "llvm/Support/CommandLine.h"
14
15namespace llvm {
16
17class MachineFunction;
18class MachineInstr;
19class MachineRegisterInfo;
20class LiveIntervals;
21class SIRegisterInfo;
22class SIInstrInfo;
23class GCNSubtarget;
24class TargetSchedModel;
25
26namespace AMDGPU {
27
28using HazardClassMask = uint32_t;
29namespace HazardClass {
30
31// Coherent with CoExec instruction types
32enum : HazardClassMask {
33 None = 0,
34 CTRL = 1u << 0,
35 VALU = 1u << 1,
36 TRANS = 1u << 2,
37 SALU = 1u << 3,
38 DS = 1u << 4,
39 VMEM = 1u << 5,
40 SMEM = 1u << 6,
41 WMMA = 1u << 7,
42 MFMA = 1u << 8,
43 EXP = 1u << 9,
44
45 Load = 1u << 10,
46 WritesVGPR = 1u << 11,
47 RawVALU = 1u << 12,
48 LDSDMA = 1u << 13,
49};
50} // namespace HazardClass
51
52enum class HazardOperand : uint8_t {
53 None,
54 Def,
55 Src0,
56 Src1,
57 Src2,
58 Src0Src1,
59 Idx,
60 Vaddr,
61 AnySrc,
62 AnyUse,
63};
64
65enum class AntiHintDirection : uint8_t {
66 OneDirectional,
67 Symmetric,
68};
69
70enum class Lifetime : uint8_t {
71 // Wait-state budget.
72 WindowBudget,
73 // Most recent producer regs count cap.
74 RegisterCount,
75};
76struct HazardContext {
77 const SIInstrInfo *TII;
78 const SIRegisterInfo *TRI;
79 MachineRegisterInfo *MRI;
80 LiveIntervals *LIS;
81 const GCNSubtarget *ST;
82 const TargetSchedModel *SchedModel;
83};
84
85struct ClassMatch {
86 HazardClassMask AnyOf = 0;
87 HazardClassMask AllOf = 0;
88 HazardClassMask NoneOf = 0;
89 bool matches(HazardClassMask Mask) const {
90 return (!AnyOf || (Mask & AnyOf)) && ((Mask & AllOf) == AllOf) &&
91 !(Mask & NoneOf);
92 }
93};
94
95// To enable or disable the whole rule.
96using RulePredicate = bool (*)(const HazardContext &);
97
98// To gate the rule for producer or consumer.
99using InstPredicate = bool (*)(const MachineInstr &, const HazardContext &);
100
101// This helps advancing a window for the WAW/WAR case where a RAW sits between
102// the producer and the consumer.
103using AdvanceForRawWindowFn = unsigned (*)(const MachineInstr &Producer,
104 HazardClassMask ReaderClass,
105 const HazardContext &Ctx);
106
107struct HazardSide {
108 ClassMatch Match;
109 HazardOperand Op = HazardOperand::None;
110 InstPredicate Predicate = nullptr;
111};
112
113// Length of a hazard window in wait states.
114// Precedence: OptWindowLength --> Fn --> WindowLength.
115struct WindowSpec {
116 unsigned WindowLength = 0;
117 const cl::opt<unsigned> *OptWindowLength = nullptr;
118 unsigned (*Fn)(const MachineInstr &Producer, HazardClassMask ConsumerClass,
119 const HazardContext &Ctx) = nullptr;
120};
121
122struct ConsumerTarget {
123 HazardSide Side;
124 WindowSpec Window;
125 HazardClassMask CounterMask = HazardClass::None;
126 AntiHintDirection Direction = AntiHintDirection::OneDirectional;
127};
128
129struct HazardAntiHintRule {
130 RulePredicate Predicate = nullptr;
131 Lifetime Life = Lifetime::WindowBudget;
132 HazardSide Producer;
133 SmallVector<ConsumerTarget, 3> Consumers;
134 AdvanceForRawWindowFn AdvanceForRawWindow = nullptr;
135};
136
137void applyAntiHintRules(MachineFunction &MF, const HazardContext &Ctx);
138
139} // namespace AMDGPU
140} // namespace llvm
141
142#endif // LLVM_LIB_TARGET_AMDGPU_GCNPRERAANTIHINTS_H
143