LLVM 23.0.0git
GCNHazardRecognizer.h
Go to the documentation of this file.
1//===-- GCNHazardRecognizers.h - GCN Hazard Recognizers ---------*- 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// This file defines hazard recognizers for scheduling on GCN processors.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_LIB_TARGET_AMDGPUHAZARDRECOGNIZERS_H
14#define LLVM_LIB_TARGET_AMDGPUHAZARDRECOGNIZERS_H
15
16#include "llvm/ADT/BitVector.h"
17#include "llvm/ADT/STLExtras.h"
21#include <list>
22
23namespace llvm {
24
25class MachineFunction;
26class MachineInstr;
27class MachineOperand;
29class SIInstrInfo;
30class SIRegisterInfo;
31class GCNSubtarget;
32
34public:
36 typedef function_ref<bool(const MachineInstr &, int WaitStates)> IsExpiredFn;
37 typedef function_ref<unsigned int(const MachineInstr &)> GetNumWaitStatesFn;
38
39private:
40 // Distinguish if we are called from scheduler or hazard recognizer
41 bool IsHazardRecognizerMode;
42
43 // This variable stores the instruction that has been emitted this cycle. It
44 // will be added to EmittedInstrs, when AdvanceCycle() or RecedeCycle() is
45 // called.
46 MachineInstr *CurrCycleInstr;
47 std::list<MachineInstr*> EmittedInstrs;
48 const MachineFunction &MF;
49 const GCNSubtarget &ST;
50 const SIInstrInfo &TII;
51 const SIRegisterInfo &TRI;
52 const TargetSchedModel &TSchedModel;
53
54 // Loop info for V_NOP hoisting, passed from the pass manager.
55 MachineLoopInfo *MLI = nullptr;
56
57 bool RunLdsBranchVmemWARHazardFixup;
58
59 /// RegUnits of uses in the current soft memory clause.
60 BitVector ClauseUses;
61
62 /// RegUnits of defs in the current soft memory clause.
63 BitVector ClauseDefs;
64
65 void resetClause() {
66 ClauseUses.reset();
67 ClauseDefs.reset();
68 }
69
70 void addClauseInst(const MachineInstr &MI);
71
72 /// \returns the number of wait states before another MFMA instruction can be
73 /// issued after \p MI.
74 unsigned getMFMAPipelineWaitStates(const MachineInstr &MI) const;
75
76 // Advance over a MachineInstr bundle. Look for hazards in the bundled
77 // instructions.
78 void processBundle();
79
80 // Run on an individual instruction in hazard recognizer mode. This can be
81 // used on a newly inserted instruction before returning from PreEmitNoops.
82 void runOnInstruction(MachineInstr *MI);
83
84 int getWaitStatesSince(IsHazardFn IsHazard, int Limit,
85 GetNumWaitStatesFn GetNumWaitStates);
86 int getWaitStatesSince(IsHazardFn IsHazard, int Limit);
87 int getWaitStatesSinceDef(unsigned Reg, IsHazardFn IsHazardDef, int Limit);
88 int getWaitStatesSinceSetReg(IsHazardFn IsHazard, int Limit);
89
90 int checkSoftClauseHazards(MachineInstr *SMEM);
91 int checkSMRDHazards(MachineInstr *SMRD);
92 int checkVMEMHazards(MachineInstr* VMEM);
93 int checkDPPHazards(MachineInstr *DPP);
94 int checkDivFMasHazards(MachineInstr *DivFMas);
95 int checkGetRegHazards(MachineInstr *GetRegInstr);
96 int checkSetRegHazards(MachineInstr *SetRegInstr);
97 int createsVALUHazard(const MachineInstr &MI);
98 int checkVALUHazards(MachineInstr *VALU);
99 int checkVALUHazardsHelper(const MachineOperand &Def, const MachineRegisterInfo &MRI);
100 int checkRWLaneHazards(MachineInstr *RWLane);
101 int checkRFEHazards(MachineInstr *RFE);
102 int checkInlineAsmHazards(MachineInstr *IA);
103 int checkReadM0Hazards(MachineInstr *SMovRel);
104 int checkNSAtoVMEMHazard(MachineInstr *MI);
105 int checkFPAtomicToDenormModeHazard(MachineInstr *MI);
106 // Emit \p WaitStatesNeeded V_NOP instructions before \p InsertPt.
107 // If IsHoisting is true, uses empty DebugLoc for compiler-inserted NOPs.
108 void emitVNops(MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertPt,
109 int WaitStatesNeeded, bool IsHoisting = false);
110 void fixHazards(MachineInstr *MI);
111 bool fixVcmpxPermlaneHazards(MachineInstr *MI);
112 bool fixVMEMtoScalarWriteHazards(MachineInstr *MI);
113 bool fixSMEMtoVectorWriteHazards(MachineInstr *MI);
114 bool fixVcmpxExecWARHazard(MachineInstr *MI);
115 bool fixLdsBranchVmemWARHazard(MachineInstr *MI);
116 bool fixLdsDirectVALUHazard(MachineInstr *MI);
117 bool fixLdsDirectVMEMHazard(MachineInstr *MI);
118 bool fixVALUPartialForwardingHazard(MachineInstr *MI);
119 bool fixVALUTransUseHazard(MachineInstr *MI);
120 bool fixVALUTransCoexecutionHazards(MachineInstr *MI);
121 bool fixWMMAHazards(MachineInstr *MI);
122 int checkWMMACoexecutionHazards(MachineInstr *MI);
123 bool fixWMMACoexecutionHazards(MachineInstr *MI);
124 bool tryHoistWMMAVnopsFromLoop(MachineInstr *MI, int WaitStatesNeeded);
125 bool hasWMMAHazardInLoop(MachineLoop *L, MachineInstr *MI,
126 bool IncludeSubloops = true);
127 bool hasWMMAToWMMARegOverlap(const MachineInstr &WMMA,
128 const MachineInstr &MI) const;
129 bool hasWMMAToVALURegOverlap(const MachineInstr &WMMA,
130 const MachineInstr &MI) const;
131 bool isCoexecutionHazardFor(const MachineInstr &I,
132 const MachineInstr &MI) const;
133 bool fixShift64HighRegBug(MachineInstr *MI);
134 bool fixVALUMaskWriteHazard(MachineInstr *MI);
135 bool fixRequiredExportPriority(MachineInstr *MI);
136 bool fixGetRegWaitIdle(MachineInstr *MI);
137 bool fixDsAtomicAsyncBarrierArriveB64(MachineInstr *MI);
138 bool fixScratchBaseForwardingHazard(MachineInstr *MI);
139 bool fixSetRegMode(MachineInstr *MI);
140
141 int checkMAIHazards(MachineInstr *MI);
142 int checkMAIHazards908(MachineInstr *MI);
143 int checkMAIHazards90A(MachineInstr *MI);
144 /// Pad the latency between neighboring MFMA instructions with s_nops. The
145 /// percentage of wait states to fill with s_nops is specified by the command
146 /// line option '-amdgpu-mfma-padding-ratio'.
147 ///
148 /// For example, with '-amdgpu-mfma-padding-ratio=100':
149 ///
150 /// 2 pass MFMA instructions have a latency of 2 wait states. Therefore, a
151 /// 'S_NOP 1' will be added between sequential MFMA instructions.
152 ///
153 /// V_MFMA_F32_4X4X1F32
154 /// V_MFMA_F32_4X4X1F32
155 ///-->
156 /// V_MFMA_F32_4X4X1F32
157 /// S_NOP 1
158 /// V_MFMA_F32_4X4X1F32
159 int checkMFMAPadding(MachineInstr *MI);
160 int checkMAIVALUHazards(MachineInstr *MI);
161 int checkMAILdStHazards(MachineInstr *MI);
162 int checkPermlaneHazards(MachineInstr *MI);
163
164public:
166 MachineLoopInfo *MLI = nullptr);
167 // We can only issue one instruction per cycle.
168 bool atIssueLimit() const override { return true; }
169 void EmitInstruction(SUnit *SU) override;
170 void EmitInstruction(MachineInstr *MI) override;
171 HazardType getHazardType(SUnit *SU, int Stalls) override;
172 void EmitNoop() override;
173 unsigned PreEmitNoops(MachineInstr *) override;
175 void AdvanceCycle() override;
176 void RecedeCycle() override;
177 bool ShouldPreferAnother(SUnit *SU) override;
178 void Reset() override;
179};
180
181} // end namespace llvm
182
183#endif //LLVM_LIB_TARGET_AMDGPUHAZARDRECOGNIZERS_H
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock & MBB
This file implements the BitVector class.
static int getWaitStatesSince(GCNHazardRecognizer::IsHazardFn IsHazard, const MachineBasicBlock *MBB, MachineBasicBlock::const_reverse_instr_iterator I, int WaitStates, GCNHazardRecognizer::IsExpiredFn IsExpired, DenseSet< const MachineBasicBlock * > &Visited, GCNHazardRecognizer::GetNumWaitStatesFn GetNumWaitStates=SIInstrInfo::getNumWaitStates)
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
This file contains some templates that are useful if you are working with the STL at all.
BitVector & reset()
Definition BitVector.h:411
void EmitNoop() override
EmitNoop - This callback is invoked when a noop was added to the instruction stream.
void Reset() override
Reset - This callback is invoked when a new block of instructions is about to be schedule.
unsigned PreEmitNoops(MachineInstr *) override
This overload will be used when the hazard recognizer is being used by a non-scheduling pass,...
void EmitInstruction(SUnit *SU) override
EmitInstruction - This callback is invoked when an instruction is emitted, to advance the hazard stat...
function_ref< bool(const MachineInstr &)> IsHazardFn
void AdvanceCycle() override
AdvanceCycle - This callback is invoked whenever the next top-down instruction to be scheduled cannot...
function_ref< unsigned int(const MachineInstr &)> GetNumWaitStatesFn
unsigned PreEmitNoopsCommon(MachineInstr *)
function_ref< bool(const MachineInstr &, int WaitStates)> IsExpiredFn
GCNHazardRecognizer(const MachineFunction &MF, MachineLoopInfo *MLI=nullptr)
bool ShouldPreferAnother(SUnit *SU) override
ShouldPreferAnother - This callback may be invoked if getHazardType returns NoHazard.
HazardType getHazardType(SUnit *SU, int Stalls) override
getHazardType - Return the hazard type of emitting this node.
void RecedeCycle() override
RecedeCycle - This callback is invoked whenever the next bottom-up instruction to be scheduled cannot...
bool atIssueLimit() const override
atIssueLimit - Return true if no more instructions may be issued in this cycle.
MachineInstrBundleIterator< MachineInstr > iterator
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Scheduling unit. This is a node in the scheduling DAG.
Provide an instruction scheduling machine model to CodeGen passes.
An efficient, type-erasing, non-owning reference to a callable.
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26