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} // namespace HazardClass
46
47enum class HazardOperand : uint8_t {
48 None,
49 Def,
50 Src0,
51 Src1,
52 Src2,
53 Idx,
54 Vaddr,
55 AnySrc,
56 AnyUse,
57};
58
59enum class ConsumerHint : uint8_t {
60 OneDirectional,
61 Symmetric,
62};
63
64struct HazardContext {
65 const SIInstrInfo *TII;
66 const SIRegisterInfo *TRI;
67 MachineRegisterInfo *MRI;
68 LiveIntervals *LIS;
69 const GCNSubtarget *ST;
70 const TargetSchedModel *SchedModel;
71};
72
73struct ClassMatch {
74 HazardClassMask AnyOf = 0;
75 bool matches(HazardClassMask Mask) const { return !AnyOf || (Mask & AnyOf); }
76};
77
78// To enable or disable the whole rule.
79using RulePredicate = bool (*)(const HazardContext &);
80
81// To gate the rule for producer or consumer.
82using InstPredicate = bool (*)(const MachineInstr &, const HazardContext &);
83
84// This helps advancing a window for the WAW/WAR case where a RAW sits between
85// the producer and the consumer.
86using AdvanceForRawWindowFn = unsigned (*)(const MachineInstr &Producer,
87 HazardClassMask ReaderClass,
88 const HazardContext &Ctx);
89
90struct HazardSide {
91 ClassMatch Match;
92 HazardOperand Op = HazardOperand::None;
93 InstPredicate Predicate = nullptr;
94};
95
96// Length of a hazard window in wait states.
97// Precedence: OptWindowLength --> Fn --> WindowLength.
98struct WindowSpec {
99 unsigned WindowLength = 0;
100 const cl::opt<unsigned> *OptWindowLength = nullptr;
101 unsigned (*Fn)(const MachineInstr &Producer,
102 const HazardContext &Ctx) = nullptr;
103};
104
105struct ConsumerTarget {
106 HazardSide Side;
107 WindowSpec Window;
108 HazardClassMask CounterMask = HazardClass::None;
109 ConsumerHint Hint = ConsumerHint::OneDirectional;
110};
111
112struct HazardAntiHintRule {
113 RulePredicate Predicate = nullptr;
114 HazardSide Producer;
115 SmallVector<ConsumerTarget, 3> Consumers;
116 AdvanceForRawWindowFn AdvanceForRawWindow = nullptr;
117};
118
119void applyAntiHintRules(MachineFunction &MF, const HazardContext &Ctx);
120
121} // namespace AMDGPU
122} // namespace llvm
123
124#endif // LLVM_LIB_TARGET_AMDGPU_GCNPRERAANTIHINTS_H
125