blob: 6aa2e70dfbfb91602f15f562ea92fbf9228c215b [file] [log] [blame]
Tom Stellardcb6ba622016-04-30 00:23:06 +00001//===-- GCNHazardRecognizers.h - GCN Hazard Recognizers ---------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Tom Stellardcb6ba622016-04-30 00:23:06 +00006//
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
Matt Arsenault03c67d12017-11-17 04:18:24 +000016#include "llvm/ADT/BitVector.h"
Benjamin Kramerd3f4c052016-06-12 16:13:55 +000017#include "llvm/ADT/STLExtras.h"
Tom Stellardcb6ba622016-04-30 00:23:06 +000018#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
Stanislav Mekhanoshin7d2019b2019-07-11 21:30:34 +000019#include "llvm/CodeGen/TargetSchedule.h"
Tom Stellardcb6ba622016-04-30 00:23:06 +000020#include <list>
21
22namespace llvm {
23
24class MachineFunction;
25class MachineInstr;
Mark Searlesd29f24a2017-12-07 20:34:25 +000026class MachineOperand;
27class MachineRegisterInfo;
Tom Stellardcb6ba622016-04-30 00:23:06 +000028class ScheduleDAG;
29class SIInstrInfo;
Matt Arsenault03c67d12017-11-17 04:18:24 +000030class SIRegisterInfo;
Tom Stellard5bfbae52018-07-11 20:59:01 +000031class GCNSubtarget;
Tom Stellardcb6ba622016-04-30 00:23:06 +000032
33class GCNHazardRecognizer final : public ScheduleHazardRecognizer {
Stanislav Mekhanoshinf92ed692019-01-21 19:11:26 +000034public:
35 typedef function_ref<bool(MachineInstr *)> IsHazardFn;
36
37private:
38 // Distinguish if we are called from scheduler or hazard recognizer
39 bool IsHazardRecognizerMode;
40
Matt Arsenault43e92fe2016-06-24 06:30:11 +000041 // This variable stores the instruction that has been emitted this cycle. It
42 // will be added to EmittedInstrs, when AdvanceCycle() or RecedeCycle() is
Tom Stellardcb6ba622016-04-30 00:23:06 +000043 // called.
44 MachineInstr *CurrCycleInstr;
45 std::list<MachineInstr*> EmittedInstrs;
46 const MachineFunction &MF;
Tom Stellard5bfbae52018-07-11 20:59:01 +000047 const GCNSubtarget &ST;
Matt Arsenault59ece952017-03-17 21:36:28 +000048 const SIInstrInfo &TII;
Matt Arsenault03c67d12017-11-17 04:18:24 +000049 const SIRegisterInfo &TRI;
Stanislav Mekhanoshin7d2019b2019-07-11 21:30:34 +000050 TargetSchedModel TSchedModel;
Matt Arsenault03c67d12017-11-17 04:18:24 +000051
52 /// RegUnits of uses in the current soft memory clause.
53 BitVector ClauseUses;
54
55 /// RegUnits of defs in the current soft memory clause.
56 BitVector ClauseDefs;
57
58 void resetClause() {
59 ClauseUses.reset();
60 ClauseDefs.reset();
61 }
62
63 void addClauseInst(const MachineInstr &MI);
Tom Stellardcb6ba622016-04-30 00:23:06 +000064
Austin Kerbow8a3d3a92019-05-07 22:12:15 +000065 // Advance over a MachineInstr bundle. Look for hazards in the bundled
66 // instructions.
67 void processBundle();
68
Stanislav Mekhanoshinf92ed692019-01-21 19:11:26 +000069 int getWaitStatesSince(IsHazardFn IsHazard, int Limit);
70 int getWaitStatesSinceDef(unsigned Reg, IsHazardFn IsHazardDef, int Limit);
71 int getWaitStatesSinceSetReg(IsHazardFn IsHazard, int Limit);
Tom Stellardcb6ba622016-04-30 00:23:06 +000072
Matt Arsenaulta41351e2017-11-17 21:35:32 +000073 int checkSoftClauseHazards(MachineInstr *SMEM);
Tom Stellardcb6ba622016-04-30 00:23:06 +000074 int checkSMRDHazards(MachineInstr *SMRD);
75 int checkVMEMHazards(MachineInstr* VMEM);
Tom Stellarda27007e2016-05-02 16:23:09 +000076 int checkDPPHazards(MachineInstr *DPP);
Tom Stellard5ab61542016-10-07 23:42:48 +000077 int checkDivFMasHazards(MachineInstr *DivFMas);
Tom Stellard961811c2016-10-15 00:58:14 +000078 int checkGetRegHazards(MachineInstr *GetRegInstr);
Tom Stellard30d30822016-10-27 20:39:09 +000079 int checkSetRegHazards(MachineInstr *SetRegInstr);
Tom Stellardb133fbb2016-10-27 23:05:31 +000080 int createsVALUHazard(const MachineInstr &MI);
81 int checkVALUHazards(MachineInstr *VALU);
Mark Searlesd29f24a2017-12-07 20:34:25 +000082 int checkVALUHazardsHelper(const MachineOperand &Def, const MachineRegisterInfo &MRI);
Tom Stellard04051b52016-10-27 23:42:29 +000083 int checkRWLaneHazards(MachineInstr *RWLane);
Tom Stellardaea899e2016-10-27 23:50:21 +000084 int checkRFEHazards(MachineInstr *RFE);
Mark Searlesd29f24a2017-12-07 20:34:25 +000085 int checkInlineAsmHazards(MachineInstr *IA);
Matt Arsenaulte823d922017-02-18 18:29:53 +000086 int checkAnyInstHazards(MachineInstr *MI);
87 int checkReadM0Hazards(MachineInstr *SMovRel);
Stanislav Mekhanoshin51d14152019-05-04 04:30:57 +000088 int checkNSAtoVMEMHazard(MachineInstr *MI);
Stanislav Mekhanoshinbdf7f812019-06-21 16:30:14 +000089 int checkFPAtomicToDenormModeHazard(MachineInstr *MI);
Austin Kerbow8a3d3a92019-05-07 22:12:15 +000090 void fixHazards(MachineInstr *MI);
Stanislav Mekhanoshin5f581c92019-06-12 17:52:51 +000091 bool fixVcmpxPermlaneHazards(MachineInstr *MI);
Stanislav Mekhanoshin51d14152019-05-04 04:30:57 +000092 bool fixVMEMtoScalarWriteHazards(MachineInstr *MI);
93 bool fixSMEMtoVectorWriteHazards(MachineInstr *MI);
94 bool fixVcmpxExecWARHazard(MachineInstr *MI);
95 bool fixLdsBranchVmemWARHazard(MachineInstr *MI);
96
Stanislav Mekhanoshin7d2019b2019-07-11 21:30:34 +000097 int checkMAIHazards(MachineInstr *MI);
98 int checkMAILdStHazards(MachineInstr *MI);
99
Tom Stellardcb6ba622016-04-30 00:23:06 +0000100public:
101 GCNHazardRecognizer(const MachineFunction &MF);
102 // We can only issue one instruction per cycle.
103 bool atIssueLimit() const override { return true; }
104 void EmitInstruction(SUnit *SU) override;
105 void EmitInstruction(MachineInstr *MI) override;
106 HazardType getHazardType(SUnit *SU, int Stalls) override;
107 void EmitNoop() override;
108 unsigned PreEmitNoops(SUnit *SU) override;
109 unsigned PreEmitNoops(MachineInstr *) override;
Stanislav Mekhanoshinf92ed692019-01-21 19:11:26 +0000110 unsigned PreEmitNoopsCommon(MachineInstr *);
Tom Stellardcb6ba622016-04-30 00:23:06 +0000111 void AdvanceCycle() override;
112 void RecedeCycle() override;
113};
114
115} // end namespace llvm
116
117#endif //LLVM_LIB_TARGET_AMDGPUHAZARDRECOGNIZERS_H