1//===--- AMDGPUMetadata.h ---------------------------------------*- 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/// AMDGPU metadata definitions and in-memory representations.
11///
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_SUPPORT_AMDGPUMETADATA_H
16#define LLVM_SUPPORT_AMDGPUMETADATA_H
17
18#include "llvm/ADT/StringRef.h"
19#include <cstdint>
20#include <string>
21#include <system_error>
22#include <vector>
23
24namespace llvm {
25namespace AMDGPU {
26
27//===----------------------------------------------------------------------===//
28// HSA metadata.
29//===----------------------------------------------------------------------===//
30namespace HSAMD {
31
32/// HSA metadata major version for code object V3.
33constexpr uint32_t VersionMajorV3 = 1;
34/// HSA metadata minor version for code object V3.
35constexpr uint32_t VersionMinorV3 = 0;
36
37/// HSA metadata major version for code object V4.
38constexpr uint32_t VersionMajorV4 = 1;
39/// HSA metadata minor version for code object V4.
40constexpr uint32_t VersionMinorV4 = 1;
41
42/// HSA metadata major version for code object V5.
43constexpr uint32_t VersionMajorV5 = 1;
44/// HSA metadata minor version for code object V5.
45constexpr uint32_t VersionMinorV5 = 2;
46
47/// Old HSA metadata beginning assembler directive for V2. This is only used for
48/// diagnostics now.
49constexpr char AssemblerDirectiveBegin[] = ".amd_amdgpu_hsa_metadata";
50
51/// Access qualifiers.
52enum class AccessQualifier : uint8_t {
53  Default   = 0,
54  ReadOnly  = 1,
55  WriteOnly = 2,
56  ReadWrite = 3,
57  Unknown   = 0xff
58};
59
60/// Address space qualifiers.
61enum class AddressSpaceQualifier : uint8_t {
62  Private  = 0,
63  Global   = 1,
64  Constant = 2,
65  Local    = 3,
66  Generic  = 4,
67  Region   = 5,
68  Unknown  = 0xff
69};
70
71/// Value kinds.
72enum class ValueKind : uint8_t {
73  ByValue                = 0,
74  GlobalBuffer           = 1,
75  DynamicSharedPointer   = 2,
76  Sampler                = 3,
77  Image                  = 4,
78  Pipe                   = 5,
79  Queue                  = 6,
80  HiddenGlobalOffsetX    = 7,
81  HiddenGlobalOffsetY    = 8,
82  HiddenGlobalOffsetZ    = 9,
83  HiddenNone             = 10,
84  HiddenPrintfBuffer     = 11,
85  HiddenDefaultQueue     = 12,
86  HiddenCompletionAction = 13,
87  HiddenMultiGridSyncArg = 14,
88  HiddenHostcallBuffer   = 15,
89  Unknown                = 0xff
90};
91
92/// Value types. This is deprecated and only remains for compatibility parsing
93/// of old metadata.
94enum class ValueType : uint8_t {
95  Struct  = 0,
96  I8      = 1,
97  U8      = 2,
98  I16     = 3,
99  U16     = 4,
100  F16     = 5,
101  I32     = 6,
102  U32     = 7,
103  F32     = 8,
104  I64     = 9,
105  U64     = 10,
106  F64     = 11,
107  Unknown = 0xff
108};
109
110//===----------------------------------------------------------------------===//
111// Kernel Metadata.
112//===----------------------------------------------------------------------===//
113namespace Kernel {
114
115//===----------------------------------------------------------------------===//
116// Kernel Attributes Metadata.
117//===----------------------------------------------------------------------===//
118namespace Attrs {
119
120namespace Key {
121/// Key for Kernel::Attr::Metadata::mReqdWorkGroupSize.
122constexpr char ReqdWorkGroupSize[] = "ReqdWorkGroupSize";
123/// Key for Kernel::Attr::Metadata::mWorkGroupSizeHint.
124constexpr char WorkGroupSizeHint[] = "WorkGroupSizeHint";
125/// Key for Kernel::Attr::Metadata::mVecTypeHint.
126constexpr char VecTypeHint[] = "VecTypeHint";
127/// Key for Kernel::Attr::Metadata::mRuntimeHandle.
128constexpr char RuntimeHandle[] = "RuntimeHandle";
129} // end namespace Key
130
131/// In-memory representation of kernel attributes metadata.
132struct Metadata final {
133  /// 'reqd_work_group_size' attribute. Optional.
134  std::vector<uint32_t> mReqdWorkGroupSize = std::vector<uint32_t>();
135  /// 'work_group_size_hint' attribute. Optional.
136  std::vector<uint32_t> mWorkGroupSizeHint = std::vector<uint32_t>();
137  /// 'vec_type_hint' attribute. Optional.
138  std::string mVecTypeHint = std::string();
139  /// External symbol created by runtime to store the kernel address
140  /// for enqueued blocks.
141  std::string mRuntimeHandle = std::string();
142
143  /// Default constructor.
144  Metadata() = default;
145
146  /// \returns True if kernel attributes metadata is empty, false otherwise.
147  bool empty() const {
148    return !notEmpty();
149  }
150
151  /// \returns True if kernel attributes metadata is not empty, false otherwise.
152  bool notEmpty() const {
153    return !mReqdWorkGroupSize.empty() || !mWorkGroupSizeHint.empty() ||
154           !mVecTypeHint.empty() || !mRuntimeHandle.empty();
155  }
156};
157
158} // end namespace Attrs
159
160//===----------------------------------------------------------------------===//
161// Kernel Argument Metadata.
162//===----------------------------------------------------------------------===//
163namespace Arg {
164
165namespace Key {
166/// Key for Kernel::Arg::Metadata::mName.
167constexpr char Name[] = "Name";
168/// Key for Kernel::Arg::Metadata::mTypeName.
169constexpr char TypeName[] = "TypeName";
170/// Key for Kernel::Arg::Metadata::mSize.
171constexpr char Size[] = "Size";
172/// Key for Kernel::Arg::Metadata::mOffset.
173constexpr char Offset[] = "Offset";
174/// Key for Kernel::Arg::Metadata::mAlign.
175constexpr char Align[] = "Align";
176/// Key for Kernel::Arg::Metadata::mValueKind.
177constexpr char ValueKind[] = "ValueKind";
178/// Key for Kernel::Arg::Metadata::mValueType. (deprecated)
179constexpr char ValueType[] = "ValueType";
180/// Key for Kernel::Arg::Metadata::mPointeeAlign.
181constexpr char PointeeAlign[] = "PointeeAlign";
182/// Key for Kernel::Arg::Metadata::mAddrSpaceQual.
183constexpr char AddrSpaceQual[] = "AddrSpaceQual";
184/// Key for Kernel::Arg::Metadata::mAccQual.
185constexpr char AccQual[] = "AccQual";
186/// Key for Kernel::Arg::Metadata::mActualAccQual.
187constexpr char ActualAccQual[] = "ActualAccQual";
188/// Key for Kernel::Arg::Metadata::mIsConst.
189constexpr char IsConst[] = "IsConst";
190/// Key for Kernel::Arg::Metadata::mIsRestrict.
191constexpr char IsRestrict[] = "IsRestrict";
192/// Key for Kernel::Arg::Metadata::mIsVolatile.
193constexpr char IsVolatile[] = "IsVolatile";
194/// Key for Kernel::Arg::Metadata::mIsPipe.
195constexpr char IsPipe[] = "IsPipe";
196} // end namespace Key
197
198/// In-memory representation of kernel argument metadata.
199struct Metadata final {
200  /// Name. Optional.
201  std::string mName = std::string();
202  /// Type name. Optional.
203  std::string mTypeName = std::string();
204  /// Size in bytes. Required.
205  uint32_t mSize = 0;
206  /// Offset in bytes. Required for code object v3, unused for code object v2.
207  uint32_t mOffset = 0;
208  /// Alignment in bytes. Required.
209  uint32_t mAlign = 0;
210  /// Value kind. Required.
211  ValueKind mValueKind = ValueKind::Unknown;
212  /// Pointee alignment in bytes. Optional.
213  uint32_t mPointeeAlign = 0;
214  /// Address space qualifier. Optional.
215  AddressSpaceQualifier mAddrSpaceQual = AddressSpaceQualifier::Unknown;
216  /// Access qualifier. Optional.
217  AccessQualifier mAccQual = AccessQualifier::Unknown;
218  /// Actual access qualifier. Optional.
219  AccessQualifier mActualAccQual = AccessQualifier::Unknown;
220  /// True if 'const' qualifier is specified. Optional.
221  bool mIsConst = false;
222  /// True if 'restrict' qualifier is specified. Optional.
223  bool mIsRestrict = false;
224  /// True if 'volatile' qualifier is specified. Optional.
225  bool mIsVolatile = false;
226  /// True if 'pipe' qualifier is specified. Optional.
227  bool mIsPipe = false;
228
229  /// Default constructor.
230  Metadata() = default;
231};
232
233} // end namespace Arg
234
235//===----------------------------------------------------------------------===//
236// Kernel Code Properties Metadata.
237//===----------------------------------------------------------------------===//
238namespace CodeProps {
239
240namespace Key {
241/// Key for Kernel::CodeProps::Metadata::mKernargSegmentSize.
242constexpr char KernargSegmentSize[] = "KernargSegmentSize";
243/// Key for Kernel::CodeProps::Metadata::mGroupSegmentFixedSize.
244constexpr char GroupSegmentFixedSize[] = "GroupSegmentFixedSize";
245/// Key for Kernel::CodeProps::Metadata::mPrivateSegmentFixedSize.
246constexpr char PrivateSegmentFixedSize[] = "PrivateSegmentFixedSize";
247/// Key for Kernel::CodeProps::Metadata::mKernargSegmentAlign.
248constexpr char KernargSegmentAlign[] = "KernargSegmentAlign";
249/// Key for Kernel::CodeProps::Metadata::mWavefrontSize.
250constexpr char WavefrontSize[] = "WavefrontSize";
251/// Key for Kernel::CodeProps::Metadata::mNumSGPRs.
252constexpr char NumSGPRs[] = "NumSGPRs";
253/// Key for Kernel::CodeProps::Metadata::mNumVGPRs.
254constexpr char NumVGPRs[] = "NumVGPRs";
255/// Key for Kernel::CodeProps::Metadata::mMaxFlatWorkGroupSize.
256constexpr char MaxFlatWorkGroupSize[] = "MaxFlatWorkGroupSize";
257/// Key for Kernel::CodeProps::Metadata::mIsDynamicCallStack.
258constexpr char IsDynamicCallStack[] = "IsDynamicCallStack";
259/// Key for Kernel::CodeProps::Metadata::mIsXNACKEnabled.
260constexpr char IsXNACKEnabled[] = "IsXNACKEnabled";
261/// Key for Kernel::CodeProps::Metadata::mNumSpilledSGPRs.
262constexpr char NumSpilledSGPRs[] = "NumSpilledSGPRs";
263/// Key for Kernel::CodeProps::Metadata::mNumSpilledVGPRs.
264constexpr char NumSpilledVGPRs[] = "NumSpilledVGPRs";
265} // end namespace Key
266
267/// In-memory representation of kernel code properties metadata.
268struct Metadata final {
269  /// Size in bytes of the kernarg segment memory. Kernarg segment memory
270  /// holds the values of the arguments to the kernel. Required.
271  uint64_t mKernargSegmentSize = 0;
272  /// Size in bytes of the group segment memory required by a workgroup.
273  /// This value does not include any dynamically allocated group segment memory
274  /// that may be added when the kernel is dispatched. Required.
275  uint32_t mGroupSegmentFixedSize = 0;
276  /// Size in bytes of the private segment memory required by a workitem.
277  /// Private segment memory includes arg, spill and private segments. Required.
278  uint32_t mPrivateSegmentFixedSize = 0;
279  /// Maximum byte alignment of variables used by the kernel in the
280  /// kernarg memory segment. Required.
281  uint32_t mKernargSegmentAlign = 0;
282  /// Wavefront size. Required.
283  uint32_t mWavefrontSize = 0;
284  /// Total number of SGPRs used by a wavefront. Optional.
285  uint16_t mNumSGPRs = 0;
286  /// Total number of VGPRs used by a workitem. Optional.
287  uint16_t mNumVGPRs = 0;
288  /// Maximum flat work-group size supported by the kernel. Optional.
289  uint32_t mMaxFlatWorkGroupSize = 0;
290  /// True if the generated machine code is using a dynamically sized
291  /// call stack. Optional.
292  bool mIsDynamicCallStack = false;
293  /// True if the generated machine code is capable of supporting XNACK.
294  /// Optional.
295  bool mIsXNACKEnabled = false;
296  /// Number of SGPRs spilled by a wavefront. Optional.
297  uint16_t mNumSpilledSGPRs = 0;
298  /// Number of VGPRs spilled by a workitem. Optional.
299  uint16_t mNumSpilledVGPRs = 0;
300
301  /// Default constructor.
302  Metadata() = default;
303
304  /// \returns True if kernel code properties metadata is empty, false
305  /// otherwise.
306  bool empty() const {
307    return !notEmpty();
308  }
309
310  /// \returns True if kernel code properties metadata is not empty, false
311  /// otherwise.
312  bool notEmpty() const {
313    return true;
314  }
315};
316
317} // end namespace CodeProps
318
319//===----------------------------------------------------------------------===//
320// Kernel Debug Properties Metadata.
321//===----------------------------------------------------------------------===//
322namespace DebugProps {
323
324namespace Key {
325/// Key for Kernel::DebugProps::Metadata::mDebuggerABIVersion.
326constexpr char DebuggerABIVersion[] = "DebuggerABIVersion";
327/// Key for Kernel::DebugProps::Metadata::mReservedNumVGPRs.
328constexpr char ReservedNumVGPRs[] = "ReservedNumVGPRs";
329/// Key for Kernel::DebugProps::Metadata::mReservedFirstVGPR.
330constexpr char ReservedFirstVGPR[] = "ReservedFirstVGPR";
331/// Key for Kernel::DebugProps::Metadata::mPrivateSegmentBufferSGPR.
332constexpr char PrivateSegmentBufferSGPR[] = "PrivateSegmentBufferSGPR";
333/// Key for
334///     Kernel::DebugProps::Metadata::mWavefrontPrivateSegmentOffsetSGPR.
335constexpr char WavefrontPrivateSegmentOffsetSGPR[] =
336    "WavefrontPrivateSegmentOffsetSGPR";
337} // end namespace Key
338
339/// In-memory representation of kernel debug properties metadata.
340struct Metadata final {
341  /// Debugger ABI version. Optional.
342  std::vector<uint32_t> mDebuggerABIVersion = std::vector<uint32_t>();
343  /// Consecutive number of VGPRs reserved for debugger use. Must be 0 if
344  /// mDebuggerABIVersion is not set. Optional.
345  uint16_t mReservedNumVGPRs = 0;
346  /// First fixed VGPR reserved. Must be uint16_t(-1) if
347  /// mDebuggerABIVersion is not set or mReservedFirstVGPR is 0. Optional.
348  uint16_t mReservedFirstVGPR = uint16_t(-1);
349  /// Fixed SGPR of the first of 4 SGPRs used to hold the scratch V# used
350  /// for the entire kernel execution. Must be uint16_t(-1) if
351  /// mDebuggerABIVersion is not set or SGPR not used or not known. Optional.
352  uint16_t mPrivateSegmentBufferSGPR = uint16_t(-1);
353  /// Fixed SGPR used to hold the wave scratch offset for the entire
354  /// kernel execution. Must be uint16_t(-1) if mDebuggerABIVersion is not set
355  /// or SGPR is not used or not known. Optional.
356  uint16_t mWavefrontPrivateSegmentOffsetSGPR = uint16_t(-1);
357
358  /// Default constructor.
359  Metadata() = default;
360
361  /// \returns True if kernel debug properties metadata is empty, false
362  /// otherwise.
363  bool empty() const {
364    return !notEmpty();
365  }
366
367  /// \returns True if kernel debug properties metadata is not empty, false
368  /// otherwise.
369  bool notEmpty() const {
370    return !mDebuggerABIVersion.empty();
371  }
372};
373
374} // end namespace DebugProps
375
376namespace Key {
377/// Key for Kernel::Metadata::mName.
378constexpr char Name[] = "Name";
379/// Key for Kernel::Metadata::mSymbolName.
380constexpr char SymbolName[] = "SymbolName";
381/// Key for Kernel::Metadata::mLanguage.
382constexpr char Language[] = "Language";
383/// Key for Kernel::Metadata::mLanguageVersion.
384constexpr char LanguageVersion[] = "LanguageVersion";
385/// Key for Kernel::Metadata::mAttrs.
386constexpr char Attrs[] = "Attrs";
387/// Key for Kernel::Metadata::mArgs.
388constexpr char Args[] = "Args";
389/// Key for Kernel::Metadata::mCodeProps.
390constexpr char CodeProps[] = "CodeProps";
391/// Key for Kernel::Metadata::mDebugProps.
392constexpr char DebugProps[] = "DebugProps";
393} // end namespace Key
394
395/// In-memory representation of kernel metadata.
396struct Metadata final {
397  /// Kernel source name. Required.
398  std::string mName = std::string();
399  /// Kernel descriptor name. Required.
400  std::string mSymbolName = std::string();
401  /// Language. Optional.
402  std::string mLanguage = std::string();
403  /// Language version. Optional.
404  std::vector<uint32_t> mLanguageVersion = std::vector<uint32_t>();
405  /// Attributes metadata. Optional.
406  Attrs::Metadata mAttrs = Attrs::Metadata();
407  /// Arguments metadata. Optional.
408  std::vector<Arg::Metadata> mArgs = std::vector<Arg::Metadata>();
409  /// Code properties metadata. Optional.
410  CodeProps::Metadata mCodeProps = CodeProps::Metadata();
411  /// Debug properties metadata. Optional.
412  DebugProps::Metadata mDebugProps = DebugProps::Metadata();
413
414  /// Default constructor.
415  Metadata() = default;
416};
417
418} // end namespace Kernel
419
420namespace Key {
421/// Key for HSA::Metadata::mVersion.
422constexpr char Version[] = "Version";
423/// Key for HSA::Metadata::mPrintf.
424constexpr char Printf[] = "Printf";
425/// Key for HSA::Metadata::mKernels.
426constexpr char Kernels[] = "Kernels";
427} // end namespace Key
428
429/// In-memory representation of HSA metadata.
430struct Metadata final {
431  /// HSA metadata version. Required.
432  std::vector<uint32_t> mVersion = std::vector<uint32_t>();
433  /// Printf metadata. Optional.
434  std::vector<std::string> mPrintf = std::vector<std::string>();
435  /// Kernels metadata. Required.
436  std::vector<Kernel::Metadata> mKernels = std::vector<Kernel::Metadata>();
437
438  /// Default constructor.
439  Metadata() = default;
440};
441
442/// Converts \p String to \p HSAMetadata.
443std::error_code fromString(StringRef String, Metadata &HSAMetadata);
444
445/// Converts \p HSAMetadata to \p String.
446std::error_code toString(Metadata HSAMetadata, std::string &String);
447
448//===----------------------------------------------------------------------===//
449// HSA metadata for v3 code object.
450//===----------------------------------------------------------------------===//
451namespace V3 {
452/// HSA metadata major version.
453constexpr uint32_t VersionMajor = 1;
454/// HSA metadata minor version.
455constexpr uint32_t VersionMinor = 0;
456
457/// HSA metadata beginning assembler directive.
458constexpr char AssemblerDirectiveBegin[] = ".amdgpu_metadata";
459/// HSA metadata ending assembler directive.
460constexpr char AssemblerDirectiveEnd[] = ".end_amdgpu_metadata";
461} // end namespace V3
462
463} // end namespace HSAMD
464
465//===----------------------------------------------------------------------===//
466// PAL metadata.
467//===----------------------------------------------------------------------===//
468namespace PALMD {
469
470/// PAL metadata (old linear format) assembler directive.
471constexpr char AssemblerDirective[] = ".amd_amdgpu_pal_metadata";
472
473/// PAL metadata (new MsgPack format) beginning assembler directive.
474constexpr char AssemblerDirectiveBegin[] = ".amdgpu_pal_metadata";
475
476/// PAL metadata (new MsgPack format) ending assembler directive.
477constexpr char AssemblerDirectiveEnd[] = ".end_amdgpu_pal_metadata";
478
479/// PAL metadata keys.
480enum Key : uint32_t {
481  R_2E12_COMPUTE_PGM_RSRC1 = 0x2e12,
482  R_2D4A_SPI_SHADER_PGM_RSRC1_LS = 0x2d4a,
483  R_2D0A_SPI_SHADER_PGM_RSRC1_HS = 0x2d0a,
484  R_2CCA_SPI_SHADER_PGM_RSRC1_ES = 0x2cca,
485  R_2C8A_SPI_SHADER_PGM_RSRC1_GS = 0x2c8a,
486  R_2C4A_SPI_SHADER_PGM_RSRC1_VS = 0x2c4a,
487  R_2C0A_SPI_SHADER_PGM_RSRC1_PS = 0x2c0a,
488  R_2E00_COMPUTE_DISPATCH_INITIATOR = 0x2e00,
489  R_A1B3_SPI_PS_INPUT_ENA = 0xa1b3,
490  R_A1B4_SPI_PS_INPUT_ADDR = 0xa1b4,
491  R_A1B6_SPI_PS_IN_CONTROL = 0xa1b6,
492  R_A2D5_VGT_SHADER_STAGES_EN = 0xa2d5,
493
494  LS_NUM_USED_VGPRS = 0x10000021,
495  HS_NUM_USED_VGPRS = 0x10000022,
496  ES_NUM_USED_VGPRS = 0x10000023,
497  GS_NUM_USED_VGPRS = 0x10000024,
498  VS_NUM_USED_VGPRS = 0x10000025,
499  PS_NUM_USED_VGPRS = 0x10000026,
500  CS_NUM_USED_VGPRS = 0x10000027,
501
502  LS_NUM_USED_SGPRS = 0x10000028,
503  HS_NUM_USED_SGPRS = 0x10000029,
504  ES_NUM_USED_SGPRS = 0x1000002a,
505  GS_NUM_USED_SGPRS = 0x1000002b,
506  VS_NUM_USED_SGPRS = 0x1000002c,
507  PS_NUM_USED_SGPRS = 0x1000002d,
508  CS_NUM_USED_SGPRS = 0x1000002e,
509
510  LS_SCRATCH_SIZE = 0x10000044,
511  HS_SCRATCH_SIZE = 0x10000045,
512  ES_SCRATCH_SIZE = 0x10000046,
513  GS_SCRATCH_SIZE = 0x10000047,
514  VS_SCRATCH_SIZE = 0x10000048,
515  PS_SCRATCH_SIZE = 0x10000049,
516  CS_SCRATCH_SIZE = 0x1000004a
517};
518
519} // end namespace PALMD
520} // end namespace AMDGPU
521} // end namespace llvm
522
523#endif // LLVM_SUPPORT_AMDGPUMETADATA_H
524