LLVM 23.0.0git
AMDGPUHazardLatency.cpp
Go to the documentation of this file.
1//===--- AMDGPUHazardLatency.cpp - AMDGPU Hazard Latency Adjustment -------===//
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/// \file This file contains a DAG scheduling mutation to adjust the
10/// latency of data edges between instructions which use registers
11/// potentially subject to additional hazard waits not accounted
12/// for in the normal scheduling model.
13/// While the scheduling model is typically still accurate in these
14/// scenarios, adjusting latency of relevant edges can improve wait
15/// merging and reduce pipeline impact of any required waits.
16//
17//===----------------------------------------------------------------------===//
18
19#include "AMDGPUHazardLatency.h"
20#include "GCNSubtarget.h"
22#include "SIInstrInfo.h"
24
25using namespace llvm;
26
27namespace {
28
29class HazardLatency : public ScheduleDAGMutation {
30private:
31 const GCNSubtarget &ST;
32 const SIRegisterInfo &TRI;
33 const MachineRegisterInfo &MRI;
34
35public:
36 HazardLatency(MachineFunction *MF)
37 : ST(MF->getSubtarget<GCNSubtarget>()), TRI(*ST.getRegisterInfo()),
38 MRI(MF->getRegInfo()) {}
39 void apply(ScheduleDAGInstrs *DAG) override;
40};
41
42void HazardLatency::apply(ScheduleDAGInstrs *DAG) {
43 constexpr unsigned MaskLatencyBoost = 3;
44
45 // Hazard only manifests in Wave64
46 if (!ST.hasVALUMaskWriteHazard() || !ST.isWave64())
47 return;
48
49 for (SUnit &SU : DAG->SUnits) {
50 const MachineInstr *MI = SU.getInstr();
52 continue;
53 if (MI->getOpcode() == AMDGPU::V_READLANE_B32 ||
54 MI->getOpcode() == AMDGPU::V_READFIRSTLANE_B32)
55 continue;
56 for (SDep &SuccDep : SU.Succs) {
57 if (SuccDep.isCtrl())
58 continue;
59 // Boost latency on VALU writes to SGPRs used by VALUs.
60 // Reduce risk of premature VALU pipeline stall on associated reads.
61 MachineInstr *DestMI = SuccDep.getSUnit()->getInstr();
62 if (!SIInstrInfo::isVALU(*DestMI))
63 continue;
64 Register Reg = SuccDep.getReg();
65 if (!TRI.isSGPRReg(MRI, Reg))
66 continue;
67 SuccDep.setLatency(SuccDep.getLatency() * MaskLatencyBoost);
68 }
69 }
70}
71
72} // end namespace
73
74std::unique_ptr<ScheduleDAGMutation>
76 return std::make_unique<HazardLatency>(MF);
77}
unsigned const MachineRegisterInfo * MRI
Provides AMDGPU specific target descriptions.
AMD GCN specific subclass of TargetSubtarget.
IRTranslator LLVM IR MI
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
Interface definition for SIInstrInfo.
bool hasVALUMaskWriteHazard() const
bool isWave64() const
SUnit * getSUnit() const
void setLatency(unsigned Lat)
Sets the latency for this edge.
unsigned getLatency() const
Returns the latency value for this edge, which roughly means the minimum number of cycles that must e...
bool isCtrl() const
Shorthand for getKind() != SDep::Data.
Register getReg() const
Returns the register associated with this edge.
static bool isVALU(const MachineInstr &MI)
SmallVector< SDep, 4 > Succs
All sunit successors.
MachineInstr * getInstr() const
Returns the representative MachineInstr for this SUnit.
A ScheduleDAG for scheduling lists of MachineInstr.
Mutate the DAG as a postpass after normal DAG building.
std::vector< SUnit > SUnits
The scheduling units.
void apply(Opt *O, const Mod &M, const Mods &... Ms)
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
std::unique_ptr< ScheduleDAGMutation > createAMDGPUHazardLatencyDAGMutation(MachineFunction *MF)