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
24namespace AMDGPU {
25// DPP/Iterative option enables the atomic optimizer with given strategy
26// whereas None disables the atomic optimizer.
27enum class ScanOptions { DPP, Iterative, None };
28
41
42enum class CarriedLatency { Off, Fence, All };
43
45} // namespace AMDGPU
46} // namespace llvm
47
48#define OPTIONS_STRUCT_DECL
49#include "AMDGPUOptions.inc"
50
51namespace llvm {
52
54class Function;
55class Instruction;
56class MachineFunction;
57class TargetMachine;
58
60public:
76
77private:
78 const AMDGPUOptions &CLOpts;
79 const Triple &TargetTriple;
80
81protected:
82 bool HasMulI24 = true;
83 bool HasMulU24 = true;
84 bool HasSMulHi = false;
85 bool HasFminFmaxLegacy = true;
86
87 unsigned NumWorkGroupSIMDs = 4;
88 // Set from TableGen subtarget features; R600Subtarget sets it directly.
89 unsigned MaxWavesPerEU = 0;
90 unsigned LocalMemorySize = 0;
95 unsigned FlatOffsetBitWidth = 0;
96
97public:
98 AMDGPUSubtarget(const Triple &TT, const AMDGPUOptions &CLOpts)
99 : CLOpts(CLOpts), TargetTriple(TT) {}
100
101 const AMDGPUOptions &getCLOpts() const { return CLOpts; }
102
103 static const AMDGPUSubtarget &get(const MachineFunction &MF);
104 static const AMDGPUSubtarget &get(const TargetMachine &TM,
105 const Function &F);
106
107 /// \returns Default range flat work group size for a calling convention.
108 std::pair<unsigned, unsigned> getDefaultFlatWorkGroupSize(CallingConv::ID CC) const;
109
110 /// \returns Subtarget's default pair of minimum/maximum flat work group sizes
111 /// for function \p F, or minimum/maximum flat work group sizes explicitly
112 /// requested using "amdgpu-flat-work-group-size" attribute attached to
113 /// function \p F.
114 ///
115 /// \returns Subtarget's default values if explicitly requested values cannot
116 /// be converted to integer, or violate subtarget's specifications.
117 std::pair<unsigned, unsigned> getFlatWorkGroupSizes(const Function &F) const;
118
119 /// \returns true if the maximum flat work-group size for \p F is at most the
120 /// wavefront size, so a work-group may fit in a single wavefront.
121 bool isSingleWavefrontWorkgroup(const Function &F) const;
122
123 /// \returns The required size of workgroups that will be used to execute \p F
124 /// in the \p Dim dimension, if it is known (from `!reqd_work_group_size`
125 /// metadata. Otherwise, returns std::nullopt.
126 std::optional<unsigned> getReqdWorkGroupSize(const Function &F,
127 unsigned Dim) const;
128
129 /// \returns true if \p F will execute in a manner that leaves the X
130 /// dimensions of the workitem ID evenly tiling wavefronts - that is, if X /
131 /// wavefrontsize is uniform. This is true if either the Y and Z block
132 /// dimensions are known to always be 1 or if the X dimension will always be a
133 /// power of 2. If \p RequireUniformYZ is true, it also ensures that the Y and
134 /// Z workitem IDs will be uniform (so, while a (32, 2, 1) launch with
135 /// wavesize64 would ordinarily pass this test, it won't with
136 /// \pRequiresUniformYZ).
137 ///
138 /// This information is currently only gathered from the !reqd_work_group_size
139 /// metadata on \p F, but this may be improved in the future.
141 bool RequiresUniformYZ = false) const;
142
143 /// \returns Subtarget's default pair of minimum/maximum number of waves per
144 /// execution unit for function \p F, or minimum/maximum number of waves per
145 /// execution unit explicitly requested using "amdgpu-waves-per-eu" attribute
146 /// attached to function \p F.
147 ///
148 /// \returns Subtarget's default values if explicitly requested values cannot
149 /// be converted to integer, violate subtarget's specifications, or are not
150 /// compatible with minimum/maximum number of waves limited by flat work group
151 /// size, register usage, and/or lds usage.
152 std::pair<unsigned, unsigned> getWavesPerEU(const Function &F) const;
153
154 /// Overload which uses the specified values for the flat workgroup sizes and
155 /// LDS space rather than querying the function itself. \p FlatWorkGroupSizes
156 /// should correspond to the function's value for getFlatWorkGroupSizes and \p
157 /// LDSBytes to the per-workgroup LDS allocation.
158 std::pair<unsigned, unsigned>
159 getWavesPerEU(std::pair<unsigned, unsigned> FlatWorkGroupSizes,
160 unsigned LDSBytes, const Function &F) const;
161
162 /// Returns the target minimum/maximum number of waves per EU. This is based
163 /// on the minimum/maximum number of \p RequestedWavesPerEU and further
164 /// limited by the maximum achievable occupancy derived from the range of \p
165 /// FlatWorkGroupSizes and number of \p LDSBytes per workgroup.
166 std::pair<unsigned, unsigned>
167 getEffectiveWavesPerEU(std::pair<unsigned, unsigned> RequestedWavesPerEU,
168 std::pair<unsigned, unsigned> FlatWorkGroupSizes,
169 unsigned LDSBytes) const;
170
171 /// Return the amount of LDS that can be used that will not restrict the
172 /// occupancy lower than WaveCount.
173 unsigned getMaxLocalMemSizeWithWaveCount(unsigned WaveCount,
174 const Function &) const;
175
176 /// Subtarget's minimum/maximum occupancy, in number of waves per EU, that can
177 /// be achieved when the only function running on a CU is \p F and each
178 /// workgroup running the function requires \p LDSBytes bytes of LDS space.
179 /// This notably depends on the range of allowed flat group sizes for the
180 /// function and hardware characteristics.
181 std::pair<unsigned, unsigned>
185
186 /// Overload which uses the specified values for the flat work group sizes,
187 /// rather than querying the function itself. \p FlatWorkGroupSizes should
188 /// correspond to the function's value for getFlatWorkGroupSizes.
189 std::pair<unsigned, unsigned> getOccupancyWithWorkGroupSizes(
190 uint32_t LDSBytes,
191 std::pair<unsigned, unsigned> FlatWorkGroupSizes) const;
192
193 /// Subtarget's minimum/maximum occupancy, in number of waves per EU, that can
194 /// be achieved when the only function running on a CU is \p MF. This notably
195 /// depends on the range of allowed flat group sizes for the function, the
196 /// amount of per-workgroup LDS space required by the function, and hardware
197 /// characteristics.
198 std::pair<unsigned, unsigned>
200
201 bool isAmdHsaOS() const {
202 return TargetTriple.getOS() == Triple::AMDHSA;
203 }
204
205 bool isAmdPalOS() const {
206 return TargetTriple.getOS() == Triple::AMDPAL;
207 }
208
209 bool isMesa3DOS() const {
210 return TargetTriple.getOS() == Triple::Mesa3D;
211 }
212
213 bool isMesaKernel(const Function &F) const;
214
215 bool isAmdHsaOrMesa(const Function &F) const {
216 return isAmdHsaOS() || isMesaKernel(F);
217 }
218
219 bool isGCN() const { return TargetTriple.isAMDGCN(); }
220
221 //==---------------------------------------------------------------------===//
222 // TableGen-generated feature getters.
223 //==---------------------------------------------------------------------===//
224#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
225 virtual bool GETTER() const { return false; }
226#include "AMDGPUGenSubtargetInfo.inc"
227 //==---------------------------------------------------------------------===//
228
229 /// Return true if real (non-fake) variants of True16 instructions using
230 /// 16-bit registers should be code-generated. Fake True16 instructions are
231 /// identical to non-fake ones except that they take 32-bit registers as
232 /// operands and always use their low halves.
233 // TODO: Remove and use hasTrue16BitInsts() instead once True16 is fully
234 // supported and the support for fake True16 instructions is removed.
235 bool useRealTrue16Insts() const {
236 return hasTrue16BitInsts() && enableRealTrue16Insts();
237 }
238
239 bool hasMulI24() const {
240 return HasMulI24;
241 }
242
243 bool hasMulU24() const {
244 return HasMulU24;
245 }
246
247 bool hasSMulHi() const {
248 return HasSMulHi;
249 }
250
251 bool hasFminFmaxLegacy() const {
252 return HasFminFmaxLegacy;
253 }
254
255 unsigned getWavefrontSize() const {
256 return 1 << WavefrontSizeLog2;
257 }
258
259 unsigned getWavefrontSizeLog2() const {
260 return WavefrontSizeLog2;
261 }
262
263 /// Return the maximum number of bytes of LDS available for all workgroups
264 /// running on the same WGP or CU.
265 /// For GFX10-GFX12 in WGP mode this is 128k even though each workgroup is
266 /// limited to 64k.
267 unsigned getLocalMemorySize() const {
268 return LocalMemorySize;
269 }
270
271 /// Return the maximum number of bytes of LDS that can be allocated to a
272 /// single workgroup.
273 /// For GFX10-GFX12 in WGP mode this is limited to 64k even though the WGP has
274 /// 128k in total.
277 }
278
279 /// \returns Number of SIMDs a work-group's waves run on: all of the block's
280 /// SIMDs in full-SIMD mode, half of them otherwise.
281 unsigned getNumWorkGroupSIMDs() const { return NumWorkGroupSIMDs; }
282
284 return isAmdHsaOS() ? Align(8) : Align(4);
285 }
286
287 /// Returns the offset in bytes from the start of the input buffer
288 /// of the first explicit kernel argument.
289 unsigned getExplicitKernelArgOffset() const {
290 switch (TargetTriple.getOS()) {
291 case Triple::AMDHSA:
292 case Triple::AMDPAL:
293 case Triple::Mesa3D:
294 return 0;
296 default:
297 // For legacy reasons unknown/other is treated as a different version of
298 // mesa.
299 return 36;
300 }
301
302 llvm_unreachable("invalid triple OS");
303 }
304
305 /// \returns Maximum number of work groups per compute unit supported by the
306 /// subtarget and limited by given \p FlatWorkGroupSize.
307 virtual unsigned getMaxWorkGroupsPerCU(unsigned FlatWorkGroupSize) const = 0;
308
309 /// \returns Minimum flat work group size supported by the subtarget.
310 virtual unsigned getMinFlatWorkGroupSize() const = 0;
311
312 /// \returns Maximum flat work group size supported by the subtarget.
313 virtual unsigned getMaxFlatWorkGroupSize() const = 0;
314
315 /// \returns Number of waves per execution unit required to support the given
316 /// \p FlatWorkGroupSize.
317 virtual unsigned
318 getWavesPerEUForWorkGroup(unsigned FlatWorkGroupSize) const = 0;
319
320 /// \returns Minimum number of waves per execution unit supported by the
321 /// subtarget.
322 virtual unsigned getMinWavesPerEU() const = 0;
323
324 /// \returns Maximum number of waves per execution unit supported by the
325 /// subtarget without any kind of limitation.
326 unsigned getMaxWavesPerEU() const { return MaxWavesPerEU; }
327
328 /// Return the maximum workitem ID value in the function, for the given (0, 1,
329 /// 2) dimension.
330 unsigned getMaxWorkitemID(const Function &Kernel, unsigned Dimension) const;
331
332 /// Return true if only a single workitem can be active in a wave.
333 bool isSingleLaneExecution(const Function &Kernel) const;
334
335 /// Creates value range metadata on an workitemid.* intrinsic call or load.
337
338 /// \returns Number of bytes of arguments that are passed to a shader or
339 /// kernel in addition to the explicit ones declared for the function.
340 unsigned getImplicitArgNumBytes(const Function &F) const;
341 uint64_t getExplicitKernArgSize(const Function &F, Align &MaxAlign) const;
342 unsigned getKernArgSegmentSize(const Function &F, Align &MaxAlign) const;
343
344 /// \returns Corresponding DWARF register number mapping flavour for the
345 /// \p WavefrontSize.
347
348 virtual ~AMDGPUSubtarget() = default;
349};
350
351} // end namespace llvm
352
353#endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUSUBTARGET_H
uint64_t uint64_t
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
RISCVCC::CondCode CC
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
const AMDGPUOptions & getCLOpts() const
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
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)
AMDGPUSubtarget(const Triple &TT, const AMDGPUOptions &CLOpts)
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 isSingleWavefrontWorkgroup(const Function &F) const
bool hasWavefrontsEvenlySplittingXDim(const Function &F, bool RequiresUniformYZ=false) const
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