LLVM 24.0.0git
AMDGPUSubtarget.h
Go to the documentation of this file.
1//=====-- AMDGPUSubtarget.h - Define Subtarget for AMDGPU -------*- 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/// \file
10/// Base class for AMDGPU specific classes of TargetSubtarget.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUSUBTARGET_H
15#define LLVM_LIB_TARGET_AMDGPU_AMDGPUSUBTARGET_H
16
18#include "llvm/IR/CallingConv.h"
21
22namespace llvm {
23
24enum AMDGPUDwarfFlavour : unsigned;
25class Function;
26class Instruction;
27class MachineFunction;
28class TargetMachine;
29
31public:
47
48private:
49 const Triple &TargetTriple;
50
51protected:
52 bool HasMulI24 = true;
53 bool HasMulU24 = true;
54 bool HasSMulHi = false;
55 bool HasFminFmaxLegacy = true;
56
57 unsigned NumWorkGroupSIMDs = 4;
58 // Set from TableGen subtarget features; R600Subtarget sets it directly.
59 unsigned MaxWavesPerEU = 0;
60 unsigned LocalMemorySize = 0;
64 unsigned FlatOffsetBitWidth = 0;
65
66public:
67 AMDGPUSubtarget(const Triple &TT) : TargetTriple(TT) {}
68
69 static const AMDGPUSubtarget &get(const MachineFunction &MF);
70 static const AMDGPUSubtarget &get(const TargetMachine &TM,
71 const Function &F);
72
73 /// \returns Default range flat work group size for a calling convention.
74 std::pair<unsigned, unsigned> getDefaultFlatWorkGroupSize(CallingConv::ID CC) const;
75
76 /// \returns Subtarget's default pair of minimum/maximum flat work group sizes
77 /// for function \p F, or minimum/maximum flat work group sizes explicitly
78 /// requested using "amdgpu-flat-work-group-size" attribute attached to
79 /// function \p F.
80 ///
81 /// \returns Subtarget's default values if explicitly requested values cannot
82 /// be converted to integer, or violate subtarget's specifications.
83 std::pair<unsigned, unsigned> getFlatWorkGroupSizes(const Function &F) const;
84
85 /// \returns The required size of workgroups that will be used to execute \p F
86 /// in the \p Dim dimension, if it is known (from `!reqd_work_group_size`
87 /// metadata. Otherwise, returns std::nullopt.
88 std::optional<unsigned> getReqdWorkGroupSize(const Function &F,
89 unsigned Dim) const;
90
91 /// \returns true if \p F will execute in a manner that leaves the X
92 /// dimensions of the workitem ID evenly tiling wavefronts - that is, if X /
93 /// wavefrontsize is uniform. This is true if either the Y and Z block
94 /// dimensions are known to always be 1 or if the X dimension will always be a
95 /// power of 2. If \p RequireUniformYZ is true, it also ensures that the Y and
96 /// Z workitem IDs will be uniform (so, while a (32, 2, 1) launch with
97 /// wavesize64 would ordinarily pass this test, it won't with
98 /// \pRequiresUniformYZ).
99 ///
100 /// This information is currently only gathered from the !reqd_work_group_size
101 /// metadata on \p F, but this may be improved in the future.
103 bool REquiresUniformYZ = false) const;
104
105 /// \returns Subtarget's default pair of minimum/maximum number of waves per
106 /// execution unit for function \p F, or minimum/maximum number of waves per
107 /// execution unit explicitly requested using "amdgpu-waves-per-eu" attribute
108 /// attached to function \p F.
109 ///
110 /// \returns Subtarget's default values if explicitly requested values cannot
111 /// be converted to integer, violate subtarget's specifications, or are not
112 /// compatible with minimum/maximum number of waves limited by flat work group
113 /// size, register usage, and/or lds usage.
114 std::pair<unsigned, unsigned> getWavesPerEU(const Function &F) const;
115
116 /// Overload which uses the specified values for the flat workgroup sizes and
117 /// LDS space rather than querying the function itself. \p FlatWorkGroupSizes
118 /// should correspond to the function's value for getFlatWorkGroupSizes and \p
119 /// LDSBytes to the per-workgroup LDS allocation.
120 std::pair<unsigned, unsigned>
121 getWavesPerEU(std::pair<unsigned, unsigned> FlatWorkGroupSizes,
122 unsigned LDSBytes, const Function &F) const;
123
124 /// Returns the target minimum/maximum number of waves per EU. This is based
125 /// on the minimum/maximum number of \p RequestedWavesPerEU and further
126 /// limited by the maximum achievable occupancy derived from the range of \p
127 /// FlatWorkGroupSizes and number of \p LDSBytes per workgroup.
128 std::pair<unsigned, unsigned>
129 getEffectiveWavesPerEU(std::pair<unsigned, unsigned> RequestedWavesPerEU,
130 std::pair<unsigned, unsigned> FlatWorkGroupSizes,
131 unsigned LDSBytes) const;
132
133 /// Return the amount of LDS that can be used that will not restrict the
134 /// occupancy lower than WaveCount.
135 unsigned getMaxLocalMemSizeWithWaveCount(unsigned WaveCount,
136 const Function &) const;
137
138 /// Subtarget's minimum/maximum occupancy, in number of waves per EU, that can
139 /// be achieved when the only function running on a CU is \p F and each
140 /// workgroup running the function requires \p LDSBytes bytes of LDS space.
141 /// This notably depends on the range of allowed flat group sizes for the
142 /// function and hardware characteristics.
143 std::pair<unsigned, unsigned>
147
148 /// Overload which uses the specified values for the flat work group sizes,
149 /// rather than querying the function itself. \p FlatWorkGroupSizes should
150 /// correspond to the function's value for getFlatWorkGroupSizes.
151 std::pair<unsigned, unsigned> getOccupancyWithWorkGroupSizes(
152 uint32_t LDSBytes,
153 std::pair<unsigned, unsigned> FlatWorkGroupSizes) const;
154
155 /// Subtarget's minimum/maximum occupancy, in number of waves per EU, that can
156 /// be achieved when the only function running on a CU is \p MF. This notably
157 /// depends on the range of allowed flat group sizes for the function, the
158 /// amount of per-workgroup LDS space required by the function, and hardware
159 /// characteristics.
160 std::pair<unsigned, unsigned>
162
163 bool isAmdHsaOS() const {
164 return TargetTriple.getOS() == Triple::AMDHSA;
165 }
166
167 bool isAmdPalOS() const {
168 return TargetTriple.getOS() == Triple::AMDPAL;
169 }
170
171 bool isMesa3DOS() const {
172 return TargetTriple.getOS() == Triple::Mesa3D;
173 }
174
175 bool isMesaKernel(const Function &F) const;
176
177 bool isAmdHsaOrMesa(const Function &F) const {
178 return isAmdHsaOS() || isMesaKernel(F);
179 }
180
181 bool isGCN() const { return TargetTriple.isAMDGCN(); }
182
183 //==---------------------------------------------------------------------===//
184 // TableGen-generated feature getters.
185 //==---------------------------------------------------------------------===//
186#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
187 virtual bool GETTER() const { return false; }
188#include "AMDGPUGenSubtargetInfo.inc"
189 //==---------------------------------------------------------------------===//
190
191 /// Return true if real (non-fake) variants of True16 instructions using
192 /// 16-bit registers should be code-generated. Fake True16 instructions are
193 /// identical to non-fake ones except that they take 32-bit registers as
194 /// operands and always use their low halves.
195 // TODO: Remove and use hasTrue16BitInsts() instead once True16 is fully
196 // supported and the support for fake True16 instructions is removed.
197 bool useRealTrue16Insts() const {
198 return hasTrue16BitInsts() && enableRealTrue16Insts();
199 }
200
201 bool hasMulI24() const {
202 return HasMulI24;
203 }
204
205 bool hasMulU24() const {
206 return HasMulU24;
207 }
208
209 bool hasSMulHi() const {
210 return HasSMulHi;
211 }
212
213 bool hasFminFmaxLegacy() const {
214 return HasFminFmaxLegacy;
215 }
216
217 unsigned getWavefrontSize() const {
218 return 1 << WavefrontSizeLog2;
219 }
220
221 unsigned getWavefrontSizeLog2() const {
222 return WavefrontSizeLog2;
223 }
224
225 /// Return the maximum number of bytes of LDS available for all workgroups
226 /// running on the same WGP or CU.
227 /// For GFX10-GFX12 in WGP mode this is 128k even though each workgroup is
228 /// limited to 64k.
229 unsigned getLocalMemorySize() const {
230 return LocalMemorySize;
231 }
232
233 /// Return the maximum number of bytes of LDS that can be allocated to a
234 /// single workgroup.
235 /// For GFX10-GFX12 in WGP mode this is limited to 64k even though the WGP has
236 /// 128k in total.
239 }
240
241 /// \returns Number of SIMDs a work-group's waves run on: all of the block's
242 /// SIMDs in full-SIMD mode, half of them otherwise.
243 unsigned getNumWorkGroupSIMDs() const { return NumWorkGroupSIMDs; }
244
246 return isAmdHsaOS() ? Align(8) : Align(4);
247 }
248
249 /// Returns the offset in bytes from the start of the input buffer
250 /// of the first explicit kernel argument.
251 unsigned getExplicitKernelArgOffset() const {
252 switch (TargetTriple.getOS()) {
253 case Triple::AMDHSA:
254 case Triple::AMDPAL:
255 case Triple::Mesa3D:
256 return 0;
258 default:
259 // For legacy reasons unknown/other is treated as a different version of
260 // mesa.
261 return 36;
262 }
263
264 llvm_unreachable("invalid triple OS");
265 }
266
267 /// \returns Maximum number of work groups per compute unit supported by the
268 /// subtarget and limited by given \p FlatWorkGroupSize.
269 virtual unsigned getMaxWorkGroupsPerCU(unsigned FlatWorkGroupSize) const = 0;
270
271 /// \returns Minimum flat work group size supported by the subtarget.
272 virtual unsigned getMinFlatWorkGroupSize() const = 0;
273
274 /// \returns Maximum flat work group size supported by the subtarget.
275 virtual unsigned getMaxFlatWorkGroupSize() const = 0;
276
277 /// \returns Number of waves per execution unit required to support the given
278 /// \p FlatWorkGroupSize.
279 virtual unsigned
280 getWavesPerEUForWorkGroup(unsigned FlatWorkGroupSize) const = 0;
281
282 /// \returns Minimum number of waves per execution unit supported by the
283 /// subtarget.
284 virtual unsigned getMinWavesPerEU() const = 0;
285
286 /// \returns Maximum number of waves per execution unit supported by the
287 /// subtarget without any kind of limitation.
288 unsigned getMaxWavesPerEU() const { return MaxWavesPerEU; }
289
290 /// Return the maximum workitem ID value in the function, for the given (0, 1,
291 /// 2) dimension.
292 unsigned getMaxWorkitemID(const Function &Kernel, unsigned Dimension) const;
293
294 /// Return true if only a single workitem can be active in a wave.
295 bool isSingleLaneExecution(const Function &Kernel) const;
296
297 /// Creates value range metadata on an workitemid.* intrinsic call or load.
299
300 /// \returns Number of bytes of arguments that are passed to a shader or
301 /// kernel in addition to the explicit ones declared for the function.
302 unsigned getImplicitArgNumBytes(const Function &F) const;
303 uint64_t getExplicitKernArgSize(const Function &F, Align &MaxAlign) const;
304 unsigned getKernArgSegmentSize(const Function &F, Align &MaxAlign) const;
305
306 /// \returns Corresponding DWARF register number mapping flavour for the
307 /// \p WavefrontSize.
309
310 virtual ~AMDGPUSubtarget() = default;
311};
312
313} // end namespace llvm
314
315#endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUSUBTARGET_H
unsigned uint64_t
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
This file defines the SmallVector class.
bool hasFminFmaxLegacy() const
std::pair< unsigned, unsigned > getDefaultFlatWorkGroupSize(CallingConv::ID CC) const
std::optional< unsigned > getReqdWorkGroupSize(const Function &F, unsigned Dim) const
Align getAlignmentForImplicitArgPtr() const
bool isMesaKernel(const Function &F) const
std::pair< unsigned, unsigned > getWavesPerEU(const Function &F) const
std::pair< unsigned, unsigned > getOccupancyWithWorkGroupSizes(uint32_t LDSBytes, const Function &F) const
Subtarget's minimum/maximum occupancy, in number of waves per EU, that can be achieved when the only ...
virtual unsigned getMinWavesPerEU() const =0
std::pair< unsigned, unsigned > getFlatWorkGroupSizes(const Function &F) const
bool makeLIDRangeMetadata(Instruction *I) const
Creates value range metadata on an workitemid.* intrinsic call or load.
unsigned getMaxWorkitemID(const Function &Kernel, unsigned Dimension) const
Return the maximum workitem ID value in the function, for the given (0, 1, 2) dimension.
unsigned getImplicitArgNumBytes(const Function &F) const
unsigned getLocalMemorySize() const
Return the maximum number of bytes of LDS available for all workgroups running on the same WGP or CU.
unsigned getAddressableLocalMemorySize() const
Return the maximum number of bytes of LDS that can be allocated to a single workgroup.
virtual unsigned getWavesPerEUForWorkGroup(unsigned FlatWorkGroupSize) const =0
virtual unsigned getMaxWorkGroupsPerCU(unsigned FlatWorkGroupSize) const =0
unsigned getWavefrontSizeLog2() const
unsigned getKernArgSegmentSize(const Function &F, Align &MaxAlign) const
unsigned getNumWorkGroupSIMDs() const
virtual ~AMDGPUSubtarget()=default
bool isAmdHsaOrMesa(const Function &F) const
AMDGPUSubtarget(const Triple &TT)
AMDGPUDwarfFlavour getAMDGPUDwarfFlavour() const
unsigned getMaxLocalMemSizeWithWaveCount(unsigned WaveCount, const Function &) const
Return the amount of LDS that can be used that will not restrict the occupancy lower than WaveCount.
virtual unsigned getMaxFlatWorkGroupSize() const =0
unsigned getExplicitKernelArgOffset() const
Returns the offset in bytes from the start of the input buffer of the first explicit kernel argument.
unsigned getMaxWavesPerEU() const
bool hasWavefrontsEvenlySplittingXDim(const Function &F, bool REquiresUniformYZ=false) const
uint64_t getExplicitKernArgSize(const Function &F, Align &MaxAlign) const
unsigned AddressableLocalMemorySize
bool isSingleLaneExecution(const Function &Kernel) const
Return true if only a single workitem can be active in a wave.
static const AMDGPUSubtarget & get(const MachineFunction &MF)
unsigned getWavefrontSize() const
virtual unsigned getMinFlatWorkGroupSize() const =0
std::pair< unsigned, unsigned > getEffectiveWavesPerEU(std::pair< unsigned, unsigned > RequestedWavesPerEU, std::pair< unsigned, unsigned > FlatWorkGroupSizes, unsigned LDSBytes) const
Returns the target minimum/maximum number of waves per EU.
bool useRealTrue16Insts() const
Return true if real (non-fake) variants of True16 instructions using 16-bit registers should be code-...
Primary interface to the complete machine description for the target machine.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
This is an optimization pass for GlobalISel generic memory operations.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39