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