LLVM 24.0.0git
AMDGPUTargetParser.h
Go to the documentation of this file.
1//===-- AMDGPUTargetParser - Parser for AMDGPU features ---------*- 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// This file implements a target parser to recognise AMDGPU hardware features.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_TARGETPARSER_AMDGPUTARGETPARSER_H
14#define LLVM_TARGETPARSER_AMDGPUTARGETPARSER_H
15
16#include "llvm/ADT/Bitset.h"
17#include "llvm/ADT/StringMap.h"
18#include "llvm/ADT/StringRef.h"
21#include <cstdint>
22#include <optional>
23#include <string>
24#include <utility>
25
26namespace llvm {
27
28class raw_ostream;
29template <typename T> class SmallVectorImpl;
30class Triple;
31
32namespace AMDGPU {
33
34/// GPU kinds supported by the AMDGPU target.
36 // Not specified processor.
38
39#define GET_R600_GPU_ENUM
40#include "llvm/TargetParser/R600TargetParserDef.inc"
41
42#define GET_AMDGPU_GPU_ENUM
43#include "llvm/TargetParser/AMDGPUTargetParserDef.inc"
44};
45
46/// One enumerator per frontend-visible feature bit; NUM_FEATURES is the count.
47enum AMDGPUFeature : unsigned {
48#define GET_AMDGPU_FEATURE_ENUM
49#include "llvm/TargetParser/AMDGPUTargetParserDef.inc"
50};
51
53
54/// One enumerator per frontend-visible R600 feature bit; R600_NUM_FEATURES is
55/// the count.
56enum R600Feature : unsigned {
57#define GET_R600_FEATURE_ENUM
58#include "llvm/TargetParser/R600TargetParserDef.inc"
59};
60
62
63/// Instruction set architecture version.
64struct IsaVersion {
68
69 bool operator==(const IsaVersion &Other) const {
70 return Major == Other.Major && Minor == Other.Minor &&
71 Stepping == Other.Stepping;
72 }
73 bool operator!=(const IsaVersion &Other) const { return !(*this == Other); }
74};
75
81
83
85
86/// Returns the preferred subarch for a GPU name \p CPU, or NoSubArch if
87/// unrecognized.
89
91
92/// Return true if subarch \p A is compatible with subarch \p B, i.e. they are
93/// equal or one is the major-family subarch of the other (e.g. AMDGPUSubArch9
94/// is compatible with AMDGPUSubArch900). NoSubArch is compatible with anything.
95LLVM_ABI bool isSubArchCompatible(const Triple &A, const Triple &B);
97
98/// Return true if the GPU \p AK is usable with the triple subarch \p SubArch.
99/// A NoSubArch triple (legacy "amdgcn") accepts any GPU. Otherwise the GPU's
100/// subarch must equal \p SubArch, or \p SubArch must be the major-family
101/// subarch of the GPU (e.g. the amdgpu9 triple accepts gfx900).
102LLVM_ABI bool isCPUValidForSubArch(Triple::SubArchType SubArch, GPUKind AK);
103
104/// Convenience overload of isCPUValidForSubArch taking a GPU name \p CPU, which
105/// is parsed via parseArchAMDGCN. An unrecognized name is never valid.
107
108/// Return true if \p AK is a pseudo target (e.g. "generic"/"generic-hsa"): a
109/// recognized AMDGCN GPU that represents no concrete hardware and has no
110/// subarch of its own. Such targets are resolved by the backend as a default
111/// device but are not valid as an explicit -mcpu.
112LLVM_ABI bool isPseudoTarget(GPUKind AK);
113
114/// Convenience overload of isPseudoTarget taking a GPU name \p CPU, which is
115/// parsed via parseArchAMDGCN.
117
118/// Returns the effective triple appropriate to use when linking \p B into \p A
119/// by merging the subarches in case of inexact match.
120///
121/// In cases where isSubArchCompatible would return / false, returns \p B. This
122/// assumes that the non-arch triple components are the same
123LLVM_ABI std::string mergeSubArch(const Triple &A, const Triple &B);
124
127
128/// Returns the canonical GPU name for an AMDGPU subarch, e.g.
129/// AMDGPUSubArch1030 -> "gfx1030", AMDGPUSubArch9 -> "gfx9-generic",
130/// AMDGPUSubArch6 -> "gfx600". Returns "" for NoSubArch or a non-AMDGPU
131/// subarch. The major-only subarches map to their generic/lowest
132/// representative, matching the default subtarget for an unspecified -mcpu.
134
135/// Returns the triple subarch name for an AMDGPU subarch, e.g.
136/// AMDGPUSubArch900 -> "amdgpu9.00". Returns "amdgpu" for NoSubArch.
140LLVM_ABI GPUKind parseArchR600(StringRef CPU);
142
143/// Returns \p AK's feature bitset, or an empty bitset if unknown.
145
146/// Returns R600 GPU \p AK's feature bitset, or an empty bitset if unknown.
148
149/// Appends the feature name of each bit set in \p Features to \p Names.
150LLVM_ABI void getFeatureNames(const AMDGPUFeatureBitset &Features,
152
153/// Append the valid AMDGCN GPU names to \p Values. If \p SubArch is not
154/// NoSubArch, only GPUs compatible with that subarch (see isCPUValidForSubArch)
155/// are appended.
156LLVM_ABI void
160
161LLVM_ABI IsaVersion getIsaVersion(StringRef GPU);
162LLVM_ABI IsaVersion getIsaVersion(Triple::SubArchType SubArch);
163
165
166LLVM_ABI unsigned getTotalNumSGPRs(GPUKind AK);
168
169LLVM_ABI unsigned getAddressableNumSGPRs(GPUKind AK);
171
172LLVM_ABI unsigned getSGPRAllocGranule(GPUKind AK);
174
175/// \returns VGPR allocation granularity for \p AK, in registers. \p IsWave32
176/// selects the wavefront size, which is a per-kernel mode rather than a
177/// property of the GPU. This does not account for dynamic VGPR mode, where the
178/// block size chosen by the caller is the granule.
179LLVM_ABI unsigned getVGPRAllocGranule(GPUKind AK, bool IsWave32);
181 bool IsWave32);
182
183/// \returns Number of physical VGPRs, i.e. the size of the register file a
184/// work-group's waves share. \p IsWave32 selects the wavefront size.
185LLVM_ABI unsigned getTotalNumVGPRs(GPUKind AK, bool IsWave32);
186LLVM_ABI unsigned getTotalNumVGPRs(Triple::SubArchType SubArch, bool IsWave32);
187
188/// \returns Number of VGPRs a single wave can address. On a target with a
189/// unified register file this covers the AGPRs as well. This does not account
190/// for dynamic VGPR mode, which caps allocation at a fixed number of blocks.
191LLVM_ABI unsigned getAddressableNumVGPRs(GPUKind AK, bool IsWave32);
193 bool IsWave32);
194
195/// LDS size queries.
196///
197/// \c getMaxHWAddressableLocalMemorySize returns the architectural limit that
198/// one work-group can address. It is independent of execution mode.
199///
200/// \c getLocalMemorySize returns the LDS available to all work-groups sharing a
201/// physical block, which is the LDS capacity used to compute occupancy. In
202/// full-SIMD mode, a work-group runs on four SIMDs and the query returns the
203/// full physical block. In half-SIMD mode, it runs on two SIMDs and the query
204/// returns half the block.
205///
206/// \c getAddressableLocalMemorySize returns the amount one work-group can
207/// allocate:
208///
209/// min(getMaxHWAddressableLocalMemorySize(), getLocalMemorySize())
210///
211/// The physical LDS block belongs to a WGP on gfx10/11/12 and to a CU
212/// otherwise. On gfx6 and gfx10/11/12, the block is twice the address limit, so
213/// a work-group cannot address the entire block in full-SIMD mode.
214///
215/// The mode columns below show local/addressable LDS, in KiB:
216///
217/// GPU address limit full-SIMD half-SIMD
218/// gfx600 32 64/32 n/a (always full-SIMD)
219/// gfx900 64 64/64 n/a (always full-SIMD)
220/// gfx1030 64 128/64 64/64
221/// gfx1250 320 320/320 n/a (always full-SIMD)
222
223/// \returns Maximum LDS in bytes a single work-group can address.
225LLVM_ABI unsigned
227
228/// \returns Total LDS in bytes available to work-groups sharing a physical
229/// block. \p FullSIMDMode selects full-SIMD mode (four SIMDs) when true and
230/// half-SIMD mode (two SIMDs) otherwise.
231LLVM_ABI unsigned getLocalMemorySize(GPUKind AK, bool FullSIMDMode);
233 bool FullSIMDMode);
234
235/// \returns LDS in bytes a single work-group can allocate.
236LLVM_ABI unsigned getAddressableLocalMemorySize(GPUKind AK, bool FullSIMDMode);
238 bool FullSIMDMode);
239
240/// \returns Number of LDS banks per compute unit.
241LLVM_ABI unsigned getLDSBankCount(GPUKind AK);
243
244/// \returns Number of SIMDs a work-group's waves run on. All four SIMDs of the
245/// functional block in full-SIMD mode, half of them otherwise.
246constexpr unsigned getNumWorkGroupSIMDs(bool FullSIMDMode) {
247 return FullSIMDMode ? 4 : 2;
248}
249
250/// \returns Minimum number of waves per execution unit.
251constexpr unsigned getMinWavesPerEU() { return 1; }
252
253/// \returns Number of bits in the num_records field in a buffer resource,
254/// or nullopt if it is not known concretely.
255LLVM_ABI std::optional<unsigned> getBufferResourceNumRecordsWidth(GPUKind AK);
256LLVM_ABI std::optional<unsigned>
258
259/// \returns Maximum number of waves per execution unit without any kind of
260/// limitation.
261LLVM_ABI unsigned getMaxWavesPerEU(GPUKind AK);
263
264/// \returns Minimum flat work group size.
265constexpr unsigned getMinFlatWorkGroupSize() { return 1; }
266
267/// \returns Maximum flat work group size.
268constexpr unsigned getMaxFlatWorkGroupSize() {
269 // Some subtargets allow encoding 2048, but this isn't tested or supported.
270 return 1024;
271}
272
273/// Fills Features map with default values for given target GPU.
274/// \p Features contains overriding target features and this function returns
275/// default target features with entries overridden by \p Features.
276LLVM_ABI std::pair<FeatureError, StringRef>
278
280
282private:
283 GPUKind Arch;
284 std::string TargetTripleString;
285 TargetIDSetting XnackSetting;
286 TargetIDSetting SramEccSetting;
287 bool IsAMDHSA;
288
289public:
290 TargetID(GPUKind Arch, const Triple &TT, TargetIDSetting XnackSetting,
291 TargetIDSetting SramEccSetting);
292
293 /// Construct a TargetID from a triple \p TT and the processor+features string
294 /// e.g. "gfx90a", "gfx90a:xnack+:sramecc-", "".
295 TargetID(const Triple &TT, StringRef TargetIDStr);
296
297 ~TargetID() = default;
298
299 /// \return True if the current xnack setting is not "Unsupported".
300 bool isXnackSupported() const {
301 return XnackSetting != TargetIDSetting::Unsupported;
302 }
303
304 /// \returns True if the current xnack setting is "On" or "Any".
305 bool isXnackOnOrAny() const {
306 return XnackSetting == TargetIDSetting::On ||
307 XnackSetting == TargetIDSetting::Any;
308 }
309
310 /// \returns True if current xnack setting is "On" or "Off",
311 /// false otherwise.
312 bool isXnackOnOrOff() const {
313 return getXnackSetting() == TargetIDSetting::On ||
314 getXnackSetting() == TargetIDSetting::Off;
315 }
316
317 /// \returns The current xnack TargetIDSetting, possible options are
318 /// "Unsupported", "Any", "Off", and "On".
319 TargetIDSetting getXnackSetting() const { return XnackSetting; }
320
321 /// Sets xnack setting to \p NewXnackSetting.
322 void setXnackSetting(TargetIDSetting NewXnackSetting) {
323 XnackSetting = NewXnackSetting;
324 }
325
326 /// \return True if the current sramecc setting is not "Unsupported".
327 bool isSramEccSupported() const {
328 return SramEccSetting != TargetIDSetting::Unsupported;
329 }
330
331 /// \returns True if the current sramecc setting is "On" or "Any".
332 bool isSramEccOnOrAny() const {
333 return SramEccSetting == TargetIDSetting::On ||
334 SramEccSetting == TargetIDSetting::Any;
335 }
336
337 /// \returns True if current sramecc setting is "On" or "Off",
338 /// false otherwise.
339 bool isSramEccOnOrOff() const {
340 return getSramEccSetting() == TargetIDSetting::On ||
341 getSramEccSetting() == TargetIDSetting::Off;
342 }
343
344 /// \returns The current sramecc TargetIDSetting, possible options are
345 /// "Unsupported", "Any", "Off", and "On".
346 TargetIDSetting getSramEccSetting() const { return SramEccSetting; }
347
348 /// Sets sramecc setting to \p NewSramEccSetting.
349 void setSramEccSetting(TargetIDSetting NewSramEccSetting) {
350 SramEccSetting = NewSramEccSetting;
351 }
352
353 GPUKind getGPUKind() const { return Arch; }
354
355 StringRef getTargetTripleString() const { return TargetTripleString; }
356
357 /// \returns True if this is an AMDHSA target.
358 bool isAMDHSA() const { return IsAMDHSA; }
359
360 /// Parse and validate a TargetID for triple \p TT from the processor+features
361 /// string \p ProcAndFeatures (e.g. "gfx90a", "gfx90a:xnack+:sramecc-", "").
362 /// Returns std::nullopt if the triple is not AMDGCN, the processor is
363 /// unrecognized, or a feature modifier is invalid for the processor.
364 static std::optional<TargetID> parse(const Triple &TT,
365 StringRef ProcAndFeatures);
366
367 /// Parse and validate a TargetID from a full
368 /// "<triple>-<processor>:<features>" directive string.
369 static std::optional<TargetID>
370 parseTargetIDString(StringRef TargetIDDirective);
371
372 /// Construct a TargetID for triple \p TT and processor \p CPU, taking the
373 /// xnack/sramecc modes from the subtarget \p FeatureString (a comma-separated
374 /// "+xnack,-sramecc" list). Unspecified modes keep the processor's default.
375 /// The assembler uses this because it has no target directive to carry the
376 /// mode.
377 static TargetID createFromSubtargetFeatures(const Triple &TT, StringRef CPU,
378 StringRef FeatureString);
379
380 /// Returns true if \p Other denotes the same target as *this, i.e. the same
381 /// processor and xnack/sramecc settings on a compatible triple. This is a
382 /// semantic equality that looks through spelling differences.
383 bool isEquivalent(const TargetID &Other) const;
384
385 /// Returns true if a device image for *this can provide the device code for a
386 /// request for \p Other. This is directional and models logical-linking
387 /// compatibility.
388 bool providesFor(const TargetID &Other) const;
389
390 void print(raw_ostream &OS) const;
391
392 std::string toString() const;
393
394 /// Print the canonical processor name followed by any explicit xnack and
395 /// sramecc feature modifiers (e.g. "gfx908:sramecc-:xnack+"), without the
396 /// triple prefix.
397 void printCanonicalTargetIDString(raw_ostream &OS) const;
398
399 /// \returns the canonical processor name followed by any explicit xnack and
400 /// sramecc feature modifiers order (e.g. "gfx908:sramecc-:xnack+"), without
401 /// the triple prefix.
402 std::string getCanonicalFeatureString() const;
403
404 bool operator==(const TargetID &Other) const;
405 bool operator!=(const TargetID &Other) const { return !(*this == Other); }
406};
407
409 TargetID.print(OS);
410 return OS;
411}
412
413} // namespace AMDGPU
414
415} // namespace llvm
416
417#endif
This file defines the StringMap class.
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_ABI
Definition Compiler.h:215
static llvm::Error parse(GsymDataExtractor &Data, uint64_t BaseAddr, LineEntryCallback const &Callback)
Definition LineTable.cpp:54
static const char * toString(MIToken::TokenKind TokenKind)
Definition MIParser.cpp:607
bool operator==(const MergedFunctionsInfo &LHS, const MergedFunctionsInfo &RHS)
#define T
void setSramEccSetting(TargetIDSetting NewSramEccSetting)
Sets sramecc setting to NewSramEccSetting.
void print(raw_ostream &OS) const
TargetIDSetting getXnackSetting() const
bool operator!=(const TargetID &Other) const
StringRef getTargetTripleString() const
TargetID(GPUKind Arch, const Triple &TT, TargetIDSetting XnackSetting, TargetIDSetting SramEccSetting)
void setXnackSetting(TargetIDSetting NewXnackSetting)
Sets xnack setting to NewXnackSetting.
TargetIDSetting getSramEccSetting() const
This is a constexpr reimplementation of a subset of std::bitset.
Definition Bitset.h:30
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition StringMap.h:129
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
LLVM_ABI StringRef getArchNameR600(GPUKind AK)
LLVM_ABI void fillValidArchListAMDGCN(SmallVectorImpl< StringRef > &Values, Triple::SubArchType SubArch=Triple::NoSubArch)
Append the valid AMDGCN GPU names to Values.
LLVM_ABI unsigned getMaxWavesPerEU(GPUKind AK)
LLVM_ABI StringRef getCanonicalArchName(const Triple &T, StringRef Arch)
LLVM_ABI unsigned getAddressableLocalMemorySize(GPUKind AK, bool FullSIMDMode)
constexpr unsigned getMaxFlatWorkGroupSize()
LLVM_ABI void fillValidArchListR600(SmallVectorImpl< StringRef > &Values)
constexpr unsigned getNumWorkGroupSIMDs(bool FullSIMDMode)
constexpr unsigned getMinFlatWorkGroupSize()
LLVM_ABI std::string mergeSubArch(const Triple &A, const Triple &B)
Returns the effective triple appropriate to use when linking B into A by merging the subarches in cas...
LLVM_ABI bool isCPUValidForSubArch(Triple::SubArchType SubArch, GPUKind AK)
Return true if the GPU AK is usable with the triple subarch SubArch.
LLVM_ABI bool isSubArchCompatible(const Triple &A, const Triple &B)
Return true if subarch A is compatible with subarch B, i.e.
LLVM_ABI unsigned getLDSBankCount(GPUKind AK)
LLVM_ABI unsigned getMaxHWAddressableLocalMemorySize(GPUKind AK)
LDS size queries.
LLVM_ABI StringRef getArchFamilyNameAMDGCN(GPUKind AK)
LLVM_ABI StringRef getSubArchName(Triple::SubArchType SubArch)
Returns the triple subarch name for an AMDGPU subarch, e.g.
LLVM_ABI unsigned getAddressableNumSGPRs(GPUKind AK)
LLVM_ABI IsaVersion getIsaVersion(StringRef GPU)
LLVM_ABI unsigned getTotalNumVGPRs(GPUKind AK, bool IsWave32)
LLVM_ABI unsigned getTotalNumSGPRs(GPUKind AK)
LLVM_ABI std::optional< unsigned > getBufferResourceNumRecordsWidth(GPUKind AK)
GPUKind
GPU kinds supported by the AMDGPU target.
Bitset< NUM_FEATURES > AMDGPUFeatureBitset
LLVM_ABI Triple::SubArchType getSubArchFromGPUName(StringRef CPU)
Returns the preferred subarch for a GPU name CPU, or NoSubArch if unrecognized.
LLVM_ABI unsigned getLocalMemorySize(GPUKind AK, bool FullSIMDMode)
LLVM_ABI unsigned getSGPRAllocGranule(GPUKind AK)
LLVM_ABI Triple::SubArchType getSubArch(GPUKind AK)
LLVM_ABI StringRef getArchNameFromSubArch(Triple::SubArchType SubArch)
Returns the canonical GPU name for an AMDGPU subarch, e.g.
LLVM_ABI unsigned getVGPRAllocGranule(GPUKind AK, bool IsWave32)
constexpr unsigned getMinWavesPerEU()
LLVM_ABI GPUKind parseArchAMDGCN(StringRef CPU)
AMDGPUFeature
One enumerator per frontend-visible feature bit; NUM_FEATURES is the count.
raw_ostream & operator<<(raw_ostream &OS, const TargetID &TargetID)
LLVM_ABI bool isPseudoTarget(GPUKind AK)
Return true if AK is a pseudo target (e.g.
LLVM_ABI GPUKind getGPUKindFromSubArch(Triple::SubArchType SubArch)
LLVM_ABI std::pair< FeatureError, StringRef > fillAMDGPUFeatureMap(StringRef GPU, const Triple &T, StringMap< bool > &Features)
Fills Features map with default values for given target GPU.
LLVM_ABI unsigned getAddressableNumVGPRs(GPUKind AK, bool IsWave32)
LLVM_ABI void getFeatureNames(const AMDGPUFeatureBitset &Features, SmallVectorImpl< StringRef > &Names)
Appends the feature name of each bit set in Features to Names.
LLVM_ABI StringRef getArchNameAMDGCN(GPUKind AK)
LLVM_ABI Triple::SubArchType getMajorSubArch(Triple::SubArchType SubArch)
LLVM_ABI const AMDGPUFeatureBitset & getFeatureBitset(GPUKind AK)
Returns AK's feature bitset, or an empty bitset if unknown.
LLVM_ABI const R600FeatureBitset & getFeatureBitsetR600(GPUKind AK)
Returns R600 GPU AK's feature bitset, or an empty bitset if unknown.
Bitset< R600_NUM_FEATURES > R600FeatureBitset
R600Feature
One enumerator per frontend-visible R600 feature bit; R600_NUM_FEATURES is the count.
LLVM_ABI GPUKind parseArchR600(StringRef CPU)
This is an optimization pass for GlobalISel generic memory operations.
RelativeUniformCounterPtr Values
Definition InstrProf.h:91
Instruction set architecture version.
bool operator==(const IsaVersion &Other) const
bool operator!=(const IsaVersion &Other) const