llvm.org GIT mirror llvm / 44bc30d
AMDGPU/NFC: Rename code object metadata as HSA metadata - Rename AMDGPUCodeObjectMetadata to AMDGPUMetadata (PAL metadata will be included in this file in the follow up change) - Rename AMDGPUCodeObjectMetadataStreamer to AMDGPUHSAMetadataStreamer - Introduce HSAMD namespace - Other minor name changes in function and test names git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@315522 91177308-0d34-0410-b5e6-96231b3b80d8 Konstantin Zhuravlyov 3 years ago
41 changed file(s) with 2955 addition(s) and 2960 deletion(s). Raw diff Collapse all Expand all
+0
-426
include/llvm/Support/AMDGPUCodeObjectMetadata.h less more
None //===--- AMDGPUCodeObjectMetadata.h -----------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// \file
10 /// \brief AMDGPU Code Object Metadata definitions and in-memory
11 /// representations.
12 ///
13 //
14 //===----------------------------------------------------------------------===//
15
16 #ifndef LLVM_SUPPORT_AMDGPUCODEOBJECTMETADATA_H
17 #define LLVM_SUPPORT_AMDGPUCODEOBJECTMETADATA_H
18
19 #include
20 #include
21 #include
22 #include
23
24 namespace llvm {
25 namespace AMDGPU {
26
27 //===----------------------------------------------------------------------===//
28 // Code Object Metadata.
29 //===----------------------------------------------------------------------===//
30 namespace CodeObject {
31
32 /// \brief Code object metadata major version.
33 constexpr uint32_t MetadataVersionMajor = 1;
34 /// \brief Code object metadata minor version.
35 constexpr uint32_t MetadataVersionMinor = 0;
36
37 /// \brief Code object metadata beginning assembler directive.
38 constexpr char MetadataAssemblerDirectiveBegin[] =
39 ".amdgpu_code_object_metadata";
40 /// \brief Code object metadata ending assembler directive.
41 constexpr char MetadataAssemblerDirectiveEnd[] =
42 ".end_amdgpu_code_object_metadata";
43
44 /// \brief Access qualifiers.
45 enum class AccessQualifier : uint8_t {
46 Default = 0,
47 ReadOnly = 1,
48 WriteOnly = 2,
49 ReadWrite = 3,
50 Unknown = 0xff
51 };
52
53 /// \brief Address space qualifiers.
54 enum class AddressSpaceQualifier : uint8_t {
55 Private = 0,
56 Global = 1,
57 Constant = 2,
58 Local = 3,
59 Generic = 4,
60 Region = 5,
61 Unknown = 0xff
62 };
63
64 /// \brief Value kinds.
65 enum class ValueKind : uint8_t {
66 ByValue = 0,
67 GlobalBuffer = 1,
68 DynamicSharedPointer = 2,
69 Sampler = 3,
70 Image = 4,
71 Pipe = 5,
72 Queue = 6,
73 HiddenGlobalOffsetX = 7,
74 HiddenGlobalOffsetY = 8,
75 HiddenGlobalOffsetZ = 9,
76 HiddenNone = 10,
77 HiddenPrintfBuffer = 11,
78 HiddenDefaultQueue = 12,
79 HiddenCompletionAction = 13,
80 Unknown = 0xff
81 };
82
83 /// \brief Value types.
84 enum class ValueType : uint8_t {
85 Struct = 0,
86 I8 = 1,
87 U8 = 2,
88 I16 = 3,
89 U16 = 4,
90 F16 = 5,
91 I32 = 6,
92 U32 = 7,
93 F32 = 8,
94 I64 = 9,
95 U64 = 10,
96 F64 = 11,
97 Unknown = 0xff
98 };
99
100 //===----------------------------------------------------------------------===//
101 // Kernel Metadata.
102 //===----------------------------------------------------------------------===//
103 namespace Kernel {
104
105 //===----------------------------------------------------------------------===//
106 // Kernel Attributes Metadata.
107 //===----------------------------------------------------------------------===//
108 namespace Attrs {
109
110 namespace Key {
111 /// \brief Key for Kernel::Attr::Metadata::mReqdWorkGroupSize.
112 constexpr char ReqdWorkGroupSize[] = "ReqdWorkGroupSize";
113 /// \brief Key for Kernel::Attr::Metadata::mWorkGroupSizeHint.
114 constexpr char WorkGroupSizeHint[] = "WorkGroupSizeHint";
115 /// \brief Key for Kernel::Attr::Metadata::mVecTypeHint.
116 constexpr char VecTypeHint[] = "VecTypeHint";
117 /// \brief Key for Kernel::Attr::Metadata::mRuntimeHandle.
118 constexpr char RuntimeHandle[] = "RuntimeHandle";
119 } // end namespace Key
120
121 /// \brief In-memory representation of kernel attributes metadata.
122 struct Metadata final {
123 /// \brief 'reqd_work_group_size' attribute. Optional.
124 std::vector mReqdWorkGroupSize = std::vector();
125 /// \brief 'work_group_size_hint' attribute. Optional.
126 std::vector mWorkGroupSizeHint = std::vector();
127 /// \brief 'vec_type_hint' attribute. Optional.
128 std::string mVecTypeHint = std::string();
129 /// \brief External symbol created by runtime to store the kernel address
130 /// for enqueued blocks.
131 std::string mRuntimeHandle = std::string();
132
133 /// \brief Default constructor.
134 Metadata() = default;
135
136 /// \returns True if kernel attributes metadata is empty, false otherwise.
137 bool empty() const {
138 return mReqdWorkGroupSize.empty() && mWorkGroupSizeHint.empty() &&
139 mVecTypeHint.empty() && mRuntimeHandle.empty();
140 }
141
142 /// \returns True if kernel attributes metadata is not empty, false otherwise.
143 bool notEmpty() const {
144 return !empty();
145 }
146 };
147
148 } // end namespace Attrs
149
150 //===----------------------------------------------------------------------===//
151 // Kernel Argument Metadata.
152 //===----------------------------------------------------------------------===//
153 namespace Arg {
154
155 namespace Key {
156 /// \brief Key for Kernel::Arg::Metadata::mSize.
157 constexpr char Size[] = "Size";
158 /// \brief Key for Kernel::Arg::Metadata::mAlign.
159 constexpr char Align[] = "Align";
160 /// \brief Key for Kernel::Arg::Metadata::mValueKind.
161 constexpr char ValueKind[] = "ValueKind";
162 /// \brief Key for Kernel::Arg::Metadata::mValueType.
163 constexpr char ValueType[] = "ValueType";
164 /// \brief Key for Kernel::Arg::Metadata::mPointeeAlign.
165 constexpr char PointeeAlign[] = "PointeeAlign";
166 /// \brief Key for Kernel::Arg::Metadata::mAccQual.
167 constexpr char AccQual[] = "AccQual";
168 /// \brief Key for Kernel::Arg::Metadata::mAddrSpaceQual.
169 constexpr char AddrSpaceQual[] = "AddrSpaceQual";
170 /// \brief Key for Kernel::Arg::Metadata::mIsConst.
171 constexpr char IsConst[] = "IsConst";
172 /// \brief Key for Kernel::Arg::Metadata::mIsPipe.
173 constexpr char IsPipe[] = "IsPipe";
174 /// \brief Key for Kernel::Arg::Metadata::mIsRestrict.
175 constexpr char IsRestrict[] = "IsRestrict";
176 /// \brief Key for Kernel::Arg::Metadata::mIsVolatile.
177 constexpr char IsVolatile[] = "IsVolatile";
178 /// \brief Key for Kernel::Arg::Metadata::mName.
179 constexpr char Name[] = "Name";
180 /// \brief Key for Kernel::Arg::Metadata::mTypeName.
181 constexpr char TypeName[] = "TypeName";
182 } // end namespace Key
183
184 /// \brief In-memory representation of kernel argument metadata.
185 struct Metadata final {
186 /// \brief Size in bytes. Required.
187 uint32_t mSize = 0;
188 /// \brief Alignment in bytes. Required.
189 uint32_t mAlign = 0;
190 /// \brief Value kind. Required.
191 ValueKind mValueKind = ValueKind::Unknown;
192 /// \brief Value type. Required.
193 ValueType mValueType = ValueType::Unknown;
194 /// \brief Pointee alignment in bytes. Optional.
195 uint32_t mPointeeAlign = 0;
196 /// \brief Access qualifier. Optional.
197 AccessQualifier mAccQual = AccessQualifier::Unknown;
198 /// \brief Address space qualifier. Optional.
199 AddressSpaceQualifier mAddrSpaceQual = AddressSpaceQualifier::Unknown;
200 /// \brief True if 'const' qualifier is specified. Optional.
201 bool mIsConst = false;
202 /// \brief True if 'pipe' qualifier is specified. Optional.
203 bool mIsPipe = false;
204 /// \brief True if 'restrict' qualifier is specified. Optional.
205 bool mIsRestrict = false;
206 /// \brief True if 'volatile' qualifier is specified. Optional.
207 bool mIsVolatile = false;
208 /// \brief Name. Optional.
209 std::string mName = std::string();
210 /// \brief Type name. Optional.
211 std::string mTypeName = std::string();
212
213 /// \brief Default constructor.
214 Metadata() = default;
215 };
216
217 } // end namespace Arg
218
219 //===----------------------------------------------------------------------===//
220 // Kernel Code Properties Metadata.
221 //===----------------------------------------------------------------------===//
222 namespace CodeProps {
223
224 namespace Key {
225 /// \brief Key for Kernel::CodeProps::Metadata::mKernargSegmentSize.
226 constexpr char KernargSegmentSize[] = "KernargSegmentSize";
227 /// \brief Key for Kernel::CodeProps::Metadata::mWorkgroupGroupSegmentSize.
228 constexpr char WorkgroupGroupSegmentSize[] = "WorkgroupGroupSegmentSize";
229 /// \brief Key for Kernel::CodeProps::Metadata::mWorkitemPrivateSegmentSize.
230 constexpr char WorkitemPrivateSegmentSize[] = "WorkitemPrivateSegmentSize";
231 /// \brief Key for Kernel::CodeProps::Metadata::mWavefrontNumSGPRs.
232 constexpr char WavefrontNumSGPRs[] = "WavefrontNumSGPRs";
233 /// \brief Key for Kernel::CodeProps::Metadata::mWorkitemNumVGPRs.
234 constexpr char WorkitemNumVGPRs[] = "WorkitemNumVGPRs";
235 /// \brief Key for Kernel::CodeProps::Metadata::mKernargSegmentAlign.
236 constexpr char KernargSegmentAlign[] = "KernargSegmentAlign";
237 /// \brief Key for Kernel::CodeProps::Metadata::mGroupSegmentAlign.
238 constexpr char GroupSegmentAlign[] = "GroupSegmentAlign";
239 /// \brief Key for Kernel::CodeProps::Metadata::mPrivateSegmentAlign.
240 constexpr char PrivateSegmentAlign[] = "PrivateSegmentAlign";
241 /// \brief Key for Kernel::CodeProps::Metadata::mWavefrontSize.
242 constexpr char WavefrontSize[] = "WavefrontSize";
243 } // end namespace Key
244
245 /// \brief In-memory representation of kernel code properties metadata.
246 struct Metadata final {
247 /// \brief Size in bytes of the kernarg segment memory. Kernarg segment memory
248 /// holds the values of the arguments to the kernel. Optional.
249 uint64_t mKernargSegmentSize = 0;
250 /// \brief Size in bytes of the group segment memory required by a workgroup.
251 /// This value does not include any dynamically allocated group segment memory
252 /// that may be added when the kernel is dispatched. Optional.
253 uint32_t mWorkgroupGroupSegmentSize = 0;
254 /// \brief Size in bytes of the private segment memory required by a workitem.
255 /// Private segment memory includes arg, spill and private segments. Optional.
256 uint32_t mWorkitemPrivateSegmentSize = 0;
257 /// \brief Total number of SGPRs used by a wavefront. Optional.
258 uint16_t mWavefrontNumSGPRs = 0;
259 /// \brief Total number of VGPRs used by a workitem. Optional.
260 uint16_t mWorkitemNumVGPRs = 0;
261 /// \brief Maximum byte alignment of variables used by the kernel in the
262 /// kernarg memory segment. Expressed as a power of two. Optional.
263 uint8_t mKernargSegmentAlign = 0;
264 /// \brief Maximum byte alignment of variables used by the kernel in the
265 /// group memory segment. Expressed as a power of two. Optional.
266 uint8_t mGroupSegmentAlign = 0;
267 /// \brief Maximum byte alignment of variables used by the kernel in the
268 /// private memory segment. Expressed as a power of two. Optional.
269 uint8_t mPrivateSegmentAlign = 0;
270 /// \brief Wavefront size. Expressed as a power of two. Optional.
271 uint8_t mWavefrontSize = 0;
272
273 /// \brief Default constructor.
274 Metadata() = default;
275
276 /// \returns True if kernel code properties metadata is empty, false
277 /// otherwise.
278 bool empty() const {
279 return !notEmpty();
280 }
281
282 /// \returns True if kernel code properties metadata is not empty, false
283 /// otherwise.
284 bool notEmpty() const {
285 return mKernargSegmentSize || mWorkgroupGroupSegmentSize ||
286 mWorkitemPrivateSegmentSize || mWavefrontNumSGPRs ||
287 mWorkitemNumVGPRs || mKernargSegmentAlign || mGroupSegmentAlign ||
288 mPrivateSegmentAlign || mWavefrontSize;
289 }
290 };
291
292 } // end namespace CodeProps
293
294 //===----------------------------------------------------------------------===//
295 // Kernel Debug Properties Metadata.
296 //===----------------------------------------------------------------------===//
297 namespace DebugProps {
298
299 namespace Key {
300 /// \brief Key for Kernel::DebugProps::Metadata::mDebuggerABIVersion.
301 constexpr char DebuggerABIVersion[] = "DebuggerABIVersion";
302 /// \brief Key for Kernel::DebugProps::Metadata::mReservedNumVGPRs.
303 constexpr char ReservedNumVGPRs[] = "ReservedNumVGPRs";
304 /// \brief Key for Kernel::DebugProps::Metadata::mReservedFirstVGPR.
305 constexpr char ReservedFirstVGPR[] = "ReservedFirstVGPR";
306 /// \brief Key for Kernel::DebugProps::Metadata::mPrivateSegmentBufferSGPR.
307 constexpr char PrivateSegmentBufferSGPR[] = "PrivateSegmentBufferSGPR";
308 /// \brief Key for
309 /// Kernel::DebugProps::Metadata::mWavefrontPrivateSegmentOffsetSGPR.
310 constexpr char WavefrontPrivateSegmentOffsetSGPR[] =
311 "WavefrontPrivateSegmentOffsetSGPR";
312 } // end namespace Key
313
314 /// \brief In-memory representation of kernel debug properties metadata.
315 struct Metadata final {
316 /// \brief Debugger ABI version. Optional.
317 std::vector mDebuggerABIVersion = std::vector();
318 /// \brief Consecutive number of VGPRs reserved for debugger use. Must be 0 if
319 /// mDebuggerABIVersion is not set. Optional.
320 uint16_t mReservedNumVGPRs = 0;
321 /// \brief First fixed VGPR reserved. Must be uint16_t(-1) if
322 /// mDebuggerABIVersion is not set or mReservedFirstVGPR is 0. Optional.
323 uint16_t mReservedFirstVGPR = uint16_t(-1);
324 /// \brief Fixed SGPR of the first of 4 SGPRs used to hold the scratch V# used
325 /// for the entire kernel execution. Must be uint16_t(-1) if
326 /// mDebuggerABIVersion is not set or SGPR not used or not known. Optional.
327 uint16_t mPrivateSegmentBufferSGPR = uint16_t(-1);
328 /// \brief Fixed SGPR used to hold the wave scratch offset for the entire
329 /// kernel execution. Must be uint16_t(-1) if mDebuggerABIVersion is not set
330 /// or SGPR is not used or not known. Optional.
331 uint16_t mWavefrontPrivateSegmentOffsetSGPR = uint16_t(-1);
332
333 /// \brief Default constructor.
334 Metadata() = default;
335
336 /// \returns True if kernel debug properties metadata is empty, false
337 /// otherwise.
338 bool empty() const {
339 return !notEmpty();
340 }
341
342 /// \returns True if kernel debug properties metadata is not empty, false
343 /// otherwise.
344 bool notEmpty() const {
345 return !mDebuggerABIVersion.empty();
346 }
347 };
348
349 } // end namespace DebugProps
350
351 namespace Key {
352 /// \brief Key for Kernel::Metadata::mName.
353 constexpr char Name[] = "Name";
354 /// \brief Key for Kernel::Metadata::mLanguage.
355 constexpr char Language[] = "Language";
356 /// \brief Key for Kernel::Metadata::mLanguageVersion.
357 constexpr char LanguageVersion[] = "LanguageVersion";
358 /// \brief Key for Kernel::Metadata::mAttrs.
359 constexpr char Attrs[] = "Attrs";
360 /// \brief Key for Kernel::Metadata::mArgs.
361 constexpr char Args[] = "Args";
362 /// \brief Key for Kernel::Metadata::mCodeProps.
363 constexpr char CodeProps[] = "CodeProps";
364 /// \brief Key for Kernel::Metadata::mDebugProps.
365 constexpr char DebugProps[] = "DebugProps";
366 } // end namespace Key
367
368 /// \brief In-memory representation of kernel metadata.
369 struct Metadata final {
370 /// \brief Name. Required.
371 std::string mName = std::string();
372 /// \brief Language. Optional.
373 std::string mLanguage = std::string();
374 /// \brief Language version. Optional.
375 std::vector mLanguageVersion = std::vector();
376 /// \brief Attributes metadata. Optional.
377 Attrs::Metadata mAttrs = Attrs::Metadata();
378 /// \brief Arguments metadata. Optional.
379 std::vector mArgs = std::vector();
380 /// \brief Code properties metadata. Optional.
381 CodeProps::Metadata mCodeProps = CodeProps::Metadata();
382 /// \brief Debug properties metadata. Optional.
383 DebugProps::Metadata mDebugProps = DebugProps::Metadata();
384
385 /// \brief Default constructor.
386 Metadata() = default;
387 };
388
389 } // end namespace Kernel
390
391 namespace Key {
392 /// \brief Key for CodeObject::Metadata::mVersion.
393 constexpr char Version[] = "Version";
394 /// \brief Key for CodeObject::Metadata::mPrintf.
395 constexpr char Printf[] = "Printf";
396 /// \brief Key for CodeObject::Metadata::mKernels.
397 constexpr char Kernels[] = "Kernels";
398 } // end namespace Key
399
400 /// \brief In-memory representation of code object metadata.
401 struct Metadata final {
402 /// \brief Code object metadata version. Required.
403 std::vector mVersion = std::vector();
404 /// \brief Printf metadata. Optional.
405 std::vector mPrintf = std::vector();
406 /// \brief Kernels metadata. Optional.
407 std::vector mKernels = std::vector();
408
409 /// \brief Default constructor.
410 Metadata() = default;
411
412 /// \brief Converts \p YamlString to \p CodeObjectMetadata.
413 static std::error_code fromYamlString(std::string YamlString,
414 Metadata &CodeObjectMetadata);
415
416 /// \brief Converts \p CodeObjectMetadata to \p YamlString.
417 static std::error_code toYamlString(Metadata CodeObjectMetadata,
418 std::string &YamlString);
419 };
420
421 } // end namespace CodeObject
422 } // end namespace AMDGPU
423 } // end namespace llvm
424
425 #endif // LLVM_SUPPORT_AMDGPUCODEOBJECTMETADATA_H
0 //===--- AMDGPUMetadata.h ---------------------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// \file
10 /// \brief 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
19 #include
20 #include
21 #include
22
23 namespace llvm {
24 namespace AMDGPU {
25
26 //===----------------------------------------------------------------------===//
27 // HSA metadata.
28 //===----------------------------------------------------------------------===//
29 namespace HSAMD {
30
31 /// \brief HSA metadata major version.
32 constexpr uint32_t VersionMajor = 1;
33 /// \brief HSA metadata minor version.
34 constexpr uint32_t VersionMinor = 0;
35
36 /// \brief HSA metadata beginning assembler directive.
37 constexpr char AssemblerDirectiveBegin[] = ".amd_amdgpu_hsa_metadata";
38 /// \brief HSA metadata ending assembler directive.
39 constexpr char AssemblerDirectiveEnd[] = ".end_amd_amdgpu_hsa_metadata";
40
41 /// \brief Access qualifiers.
42 enum class AccessQualifier : uint8_t {
43 Default = 0,
44 ReadOnly = 1,
45 WriteOnly = 2,
46 ReadWrite = 3,
47 Unknown = 0xff
48 };
49
50 /// \brief Address space qualifiers.
51 enum class AddressSpaceQualifier : uint8_t {
52 Private = 0,
53 Global = 1,
54 Constant = 2,
55 Local = 3,
56 Generic = 4,
57 Region = 5,
58 Unknown = 0xff
59 };
60
61 /// \brief Value kinds.
62 enum class ValueKind : uint8_t {
63 ByValue = 0,
64 GlobalBuffer = 1,
65 DynamicSharedPointer = 2,
66 Sampler = 3,
67 Image = 4,
68 Pipe = 5,
69 Queue = 6,
70 HiddenGlobalOffsetX = 7,
71 HiddenGlobalOffsetY = 8,
72 HiddenGlobalOffsetZ = 9,
73 HiddenNone = 10,
74 HiddenPrintfBuffer = 11,
75 HiddenDefaultQueue = 12,
76 HiddenCompletionAction = 13,
77 Unknown = 0xff
78 };
79
80 /// \brief Value types.
81 enum class ValueType : uint8_t {
82 Struct = 0,
83 I8 = 1,
84 U8 = 2,
85 I16 = 3,
86 U16 = 4,
87 F16 = 5,
88 I32 = 6,
89 U32 = 7,
90 F32 = 8,
91 I64 = 9,
92 U64 = 10,
93 F64 = 11,
94 Unknown = 0xff
95 };
96
97 //===----------------------------------------------------------------------===//
98 // Kernel Metadata.
99 //===----------------------------------------------------------------------===//
100 namespace Kernel {
101
102 //===----------------------------------------------------------------------===//
103 // Kernel Attributes Metadata.
104 //===----------------------------------------------------------------------===//
105 namespace Attrs {
106
107 namespace Key {
108 /// \brief Key for Kernel::Attr::Metadata::mReqdWorkGroupSize.
109 constexpr char ReqdWorkGroupSize[] = "ReqdWorkGroupSize";
110 /// \brief Key for Kernel::Attr::Metadata::mWorkGroupSizeHint.
111 constexpr char WorkGroupSizeHint[] = "WorkGroupSizeHint";
112 /// \brief Key for Kernel::Attr::Metadata::mVecTypeHint.
113 constexpr char VecTypeHint[] = "VecTypeHint";
114 /// \brief Key for Kernel::Attr::Metadata::mRuntimeHandle.
115 constexpr char RuntimeHandle[] = "RuntimeHandle";
116 } // end namespace Key
117
118 /// \brief In-memory representation of kernel attributes metadata.
119 struct Metadata final {
120 /// \brief 'reqd_work_group_size' attribute. Optional.
121 std::vector mReqdWorkGroupSize = std::vector();
122 /// \brief 'work_group_size_hint' attribute. Optional.
123 std::vector mWorkGroupSizeHint = std::vector();
124 /// \brief 'vec_type_hint' attribute. Optional.
125 std::string mVecTypeHint = std::string();
126 /// \brief External symbol created by runtime to store the kernel address
127 /// for enqueued blocks.
128 std::string mRuntimeHandle = std::string();
129
130 /// \brief Default constructor.
131 Metadata() = default;
132
133 /// \returns True if kernel attributes metadata is empty, false otherwise.
134 bool empty() const {
135 return mReqdWorkGroupSize.empty() && mWorkGroupSizeHint.empty() &&
136 mVecTypeHint.empty() && mRuntimeHandle.empty();
137 }
138
139 /// \returns True if kernel attributes metadata is not empty, false otherwise.
140 bool notEmpty() const {
141 return !empty();
142 }
143 };
144
145 } // end namespace Attrs
146
147 //===----------------------------------------------------------------------===//
148 // Kernel Argument Metadata.
149 //===----------------------------------------------------------------------===//
150 namespace Arg {
151
152 namespace Key {
153 /// \brief Key for Kernel::Arg::Metadata::mSize.
154 constexpr char Size[] = "Size";
155 /// \brief Key for Kernel::Arg::Metadata::mAlign.
156 constexpr char Align[] = "Align";
157 /// \brief Key for Kernel::Arg::Metadata::mValueKind.
158 constexpr char ValueKind[] = "ValueKind";
159 /// \brief Key for Kernel::Arg::Metadata::mValueType.
160 constexpr char ValueType[] = "ValueType";
161 /// \brief Key for Kernel::Arg::Metadata::mPointeeAlign.
162 constexpr char PointeeAlign[] = "PointeeAlign";
163 /// \brief Key for Kernel::Arg::Metadata::mAccQual.
164 constexpr char AccQual[] = "AccQual";
165 /// \brief Key for Kernel::Arg::Metadata::mAddrSpaceQual.
166 constexpr char AddrSpaceQual[] = "AddrSpaceQual";
167 /// \brief Key for Kernel::Arg::Metadata::mIsConst.
168 constexpr char IsConst[] = "IsConst";
169 /// \brief Key for Kernel::Arg::Metadata::mIsPipe.
170 constexpr char IsPipe[] = "IsPipe";
171 /// \brief Key for Kernel::Arg::Metadata::mIsRestrict.
172 constexpr char IsRestrict[] = "IsRestrict";
173 /// \brief Key for Kernel::Arg::Metadata::mIsVolatile.
174 constexpr char IsVolatile[] = "IsVolatile";
175 /// \brief Key for Kernel::Arg::Metadata::mName.
176 constexpr char Name[] = "Name";
177 /// \brief Key for Kernel::Arg::Metadata::mTypeName.
178 constexpr char TypeName[] = "TypeName";
179 } // end namespace Key
180
181 /// \brief In-memory representation of kernel argument metadata.
182 struct Metadata final {
183 /// \brief Size in bytes. Required.
184 uint32_t mSize = 0;
185 /// \brief Alignment in bytes. Required.
186 uint32_t mAlign = 0;
187 /// \brief Value kind. Required.
188 ValueKind mValueKind = ValueKind::Unknown;
189 /// \brief Value type. Required.
190 ValueType mValueType = ValueType::Unknown;
191 /// \brief Pointee alignment in bytes. Optional.
192 uint32_t mPointeeAlign = 0;
193 /// \brief Access qualifier. Optional.
194 AccessQualifier mAccQual = AccessQualifier::Unknown;
195 /// \brief Address space qualifier. Optional.
196 AddressSpaceQualifier mAddrSpaceQual = AddressSpaceQualifier::Unknown;
197 /// \brief True if 'const' qualifier is specified. Optional.
198 bool mIsConst = false;
199 /// \brief True if 'pipe' qualifier is specified. Optional.
200 bool mIsPipe = false;
201 /// \brief True if 'restrict' qualifier is specified. Optional.
202 bool mIsRestrict = false;
203 /// \brief True if 'volatile' qualifier is specified. Optional.
204 bool mIsVolatile = false;
205 /// \brief Name. Optional.
206 std::string mName = std::string();
207 /// \brief Type name. Optional.
208 std::string mTypeName = std::string();
209
210 /// \brief Default constructor.
211 Metadata() = default;
212 };
213
214 } // end namespace Arg
215
216 //===----------------------------------------------------------------------===//
217 // Kernel Code Properties Metadata.
218 //===----------------------------------------------------------------------===//
219 namespace CodeProps {
220
221 namespace Key {
222 /// \brief Key for Kernel::CodeProps::Metadata::mKernargSegmentSize.
223 constexpr char KernargSegmentSize[] = "KernargSegmentSize";
224 /// \brief Key for Kernel::CodeProps::Metadata::mWorkgroupGroupSegmentSize.
225 constexpr char WorkgroupGroupSegmentSize[] = "WorkgroupGroupSegmentSize";
226 /// \brief Key for Kernel::CodeProps::Metadata::mWorkitemPrivateSegmentSize.
227 constexpr char WorkitemPrivateSegmentSize[] = "WorkitemPrivateSegmentSize";
228 /// \brief Key for Kernel::CodeProps::Metadata::mWavefrontNumSGPRs.
229 constexpr char WavefrontNumSGPRs[] = "WavefrontNumSGPRs";
230 /// \brief Key for Kernel::CodeProps::Metadata::mWorkitemNumVGPRs.
231 constexpr char WorkitemNumVGPRs[] = "WorkitemNumVGPRs";
232 /// \brief Key for Kernel::CodeProps::Metadata::mKernargSegmentAlign.
233 constexpr char KernargSegmentAlign[] = "KernargSegmentAlign";
234 /// \brief Key for Kernel::CodeProps::Metadata::mGroupSegmentAlign.
235 constexpr char GroupSegmentAlign[] = "GroupSegmentAlign";
236 /// \brief Key for Kernel::CodeProps::Metadata::mPrivateSegmentAlign.
237 constexpr char PrivateSegmentAlign[] = "PrivateSegmentAlign";
238 /// \brief Key for Kernel::CodeProps::Metadata::mWavefrontSize.
239 constexpr char WavefrontSize[] = "WavefrontSize";
240 } // end namespace Key
241
242 /// \brief In-memory representation of kernel code properties metadata.
243 struct Metadata final {
244 /// \brief Size in bytes of the kernarg segment memory. Kernarg segment memory
245 /// holds the values of the arguments to the kernel. Optional.
246 uint64_t mKernargSegmentSize = 0;
247 /// \brief Size in bytes of the group segment memory required by a workgroup.
248 /// This value does not include any dynamically allocated group segment memory
249 /// that may be added when the kernel is dispatched. Optional.
250 uint32_t mWorkgroupGroupSegmentSize = 0;
251 /// \brief Size in bytes of the private segment memory required by a workitem.
252 /// Private segment memory includes arg, spill and private segments. Optional.
253 uint32_t mWorkitemPrivateSegmentSize = 0;
254 /// \brief Total number of SGPRs used by a wavefront. Optional.
255 uint16_t mWavefrontNumSGPRs = 0;
256 /// \brief Total number of VGPRs used by a workitem. Optional.
257 uint16_t mWorkitemNumVGPRs = 0;
258 /// \brief Maximum byte alignment of variables used by the kernel in the
259 /// kernarg memory segment. Expressed as a power of two. Optional.
260 uint8_t mKernargSegmentAlign = 0;
261 /// \brief Maximum byte alignment of variables used by the kernel in the
262 /// group memory segment. Expressed as a power of two. Optional.
263 uint8_t mGroupSegmentAlign = 0;
264 /// \brief Maximum byte alignment of variables used by the kernel in the
265 /// private memory segment. Expressed as a power of two. Optional.
266 uint8_t mPrivateSegmentAlign = 0;
267 /// \brief Wavefront size. Expressed as a power of two. Optional.
268 uint8_t mWavefrontSize = 0;
269
270 /// \brief Default constructor.
271 Metadata() = default;
272
273 /// \returns True if kernel code properties metadata is empty, false
274 /// otherwise.
275 bool empty() const {
276 return !notEmpty();
277 }
278
279 /// \returns True if kernel code properties metadata is not empty, false
280 /// otherwise.
281 bool notEmpty() const {
282 return mKernargSegmentSize || mWorkgroupGroupSegmentSize ||
283 mWorkitemPrivateSegmentSize || mWavefrontNumSGPRs ||
284 mWorkitemNumVGPRs || mKernargSegmentAlign || mGroupSegmentAlign ||
285 mPrivateSegmentAlign || mWavefrontSize;
286 }
287 };
288
289 } // end namespace CodeProps
290
291 //===----------------------------------------------------------------------===//
292 // Kernel Debug Properties Metadata.
293 //===----------------------------------------------------------------------===//
294 namespace DebugProps {
295
296 namespace Key {
297 /// \brief Key for Kernel::DebugProps::Metadata::mDebuggerABIVersion.
298 constexpr char DebuggerABIVersion[] = "DebuggerABIVersion";
299 /// \brief Key for Kernel::DebugProps::Metadata::mReservedNumVGPRs.
300 constexpr char ReservedNumVGPRs[] = "ReservedNumVGPRs";
301 /// \brief Key for Kernel::DebugProps::Metadata::mReservedFirstVGPR.
302 constexpr char ReservedFirstVGPR[] = "ReservedFirstVGPR";
303 /// \brief Key for Kernel::DebugProps::Metadata::mPrivateSegmentBufferSGPR.
304 constexpr char PrivateSegmentBufferSGPR[] = "PrivateSegmentBufferSGPR";
305 /// \brief Key for
306 /// Kernel::DebugProps::Metadata::mWavefrontPrivateSegmentOffsetSGPR.
307 constexpr char WavefrontPrivateSegmentOffsetSGPR[] =
308 "WavefrontPrivateSegmentOffsetSGPR";
309 } // end namespace Key
310
311 /// \brief In-memory representation of kernel debug properties metadata.
312 struct Metadata final {
313 /// \brief Debugger ABI version. Optional.
314 std::vector mDebuggerABIVersion = std::vector();
315 /// \brief Consecutive number of VGPRs reserved for debugger use. Must be 0 if
316 /// mDebuggerABIVersion is not set. Optional.
317 uint16_t mReservedNumVGPRs = 0;
318 /// \brief First fixed VGPR reserved. Must be uint16_t(-1) if
319 /// mDebuggerABIVersion is not set or mReservedFirstVGPR is 0. Optional.
320 uint16_t mReservedFirstVGPR = uint16_t(-1);
321 /// \brief Fixed SGPR of the first of 4 SGPRs used to hold the scratch V# used
322 /// for the entire kernel execution. Must be uint16_t(-1) if
323 /// mDebuggerABIVersion is not set or SGPR not used or not known. Optional.
324 uint16_t mPrivateSegmentBufferSGPR = uint16_t(-1);
325 /// \brief Fixed SGPR used to hold the wave scratch offset for the entire
326 /// kernel execution. Must be uint16_t(-1) if mDebuggerABIVersion is not set
327 /// or SGPR is not used or not known. Optional.
328 uint16_t mWavefrontPrivateSegmentOffsetSGPR = uint16_t(-1);
329
330 /// \brief Default constructor.
331 Metadata() = default;
332
333 /// \returns True if kernel debug properties metadata is empty, false
334 /// otherwise.
335 bool empty() const {
336 return !notEmpty();
337 }
338
339 /// \returns True if kernel debug properties metadata is not empty, false
340 /// otherwise.
341 bool notEmpty() const {
342 return !mDebuggerABIVersion.empty();
343 }
344 };
345
346 } // end namespace DebugProps
347
348 namespace Key {
349 /// \brief Key for Kernel::Metadata::mName.
350 constexpr char Name[] = "Name";
351 /// \brief Key for Kernel::Metadata::mLanguage.
352 constexpr char Language[] = "Language";
353 /// \brief Key for Kernel::Metadata::mLanguageVersion.
354 constexpr char LanguageVersion[] = "LanguageVersion";
355 /// \brief Key for Kernel::Metadata::mAttrs.
356 constexpr char Attrs[] = "Attrs";
357 /// \brief Key for Kernel::Metadata::mArgs.
358 constexpr char Args[] = "Args";
359 /// \brief Key for Kernel::Metadata::mCodeProps.
360 constexpr char CodeProps[] = "CodeProps";
361 /// \brief Key for Kernel::Metadata::mDebugProps.
362 constexpr char DebugProps[] = "DebugProps";
363 } // end namespace Key
364
365 /// \brief In-memory representation of kernel metadata.
366 struct Metadata final {
367 /// \brief Name. Required.
368 std::string mName = std::string();
369 /// \brief Language. Optional.
370 std::string mLanguage = std::string();
371 /// \brief Language version. Optional.
372 std::vector mLanguageVersion = std::vector();
373 /// \brief Attributes metadata. Optional.
374 Attrs::Metadata mAttrs = Attrs::Metadata();
375 /// \brief Arguments metadata. Optional.
376 std::vector mArgs = std::vector();
377 /// \brief Code properties metadata. Optional.
378 CodeProps::Metadata mCodeProps = CodeProps::Metadata();
379 /// \brief Debug properties metadata. Optional.
380 DebugProps::Metadata mDebugProps = DebugProps::Metadata();
381
382 /// \brief Default constructor.
383 Metadata() = default;
384 };
385
386 } // end namespace Kernel
387
388 namespace Key {
389 /// \brief Key for HSA::Metadata::mVersion.
390 constexpr char Version[] = "Version";
391 /// \brief Key for HSA::Metadata::mPrintf.
392 constexpr char Printf[] = "Printf";
393 /// \brief Key for HSA::Metadata::mKernels.
394 constexpr char Kernels[] = "Kernels";
395 } // end namespace Key
396
397 /// \brief In-memory representation of HSA metadata.
398 struct Metadata final {
399 /// \brief HSA metadata version. Required.
400 std::vector mVersion = std::vector();
401 /// \brief Printf metadata. Optional.
402 std::vector mPrintf = std::vector();
403 /// \brief Kernels metadata. Optional.
404 std::vector mKernels = std::vector();
405
406 /// \brief Default constructor.
407 Metadata() = default;
408
409 /// \brief Converts \p YamlString to \p HSAMetadata.
410 static std::error_code fromYamlString(std::string YamlString,
411 Metadata &HSAMetadata);
412
413 /// \brief Converts \p HSAMetadata to \p YamlString.
414 static std::error_code toYamlString(Metadata HSAMetadata,
415 std::string &YamlString);
416 };
417
418 } // end namespace HSAMD
419 } // end namespace AMDGPU
420 } // end namespace llvm
421
422 #endif // LLVM_SUPPORT_AMDGPUMETADATA_H
+0
-218
lib/Support/AMDGPUCodeObjectMetadata.cpp less more
None //===--- AMDGPUCodeObjectMetadata.cpp ---------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// \file
10 /// \brief AMDGPU Code Object Metadata definitions and in-memory
11 /// representations.
12 ///
13 //
14 //===----------------------------------------------------------------------===//
15
16 #include "llvm/Support/AMDGPUCodeObjectMetadata.h"
17 #include "llvm/Support/YAMLTraits.h"
18
19 using namespace llvm::AMDGPU;
20 using namespace llvm::AMDGPU::CodeObject;
21
22 LLVM_YAML_IS_SEQUENCE_VECTOR(Kernel::Arg::Metadata)
23 LLVM_YAML_IS_SEQUENCE_VECTOR(Kernel::Metadata)
24
25 namespace llvm {
26 namespace yaml {
27
28 template <>
29 struct ScalarEnumerationTraits {
30 static void enumeration(IO &YIO, AccessQualifier &EN) {
31 YIO.enumCase(EN, "Default", AccessQualifier::Default);
32 YIO.enumCase(EN, "ReadOnly", AccessQualifier::ReadOnly);
33 YIO.enumCase(EN, "WriteOnly", AccessQualifier::WriteOnly);
34 YIO.enumCase(EN, "ReadWrite", AccessQualifier::ReadWrite);
35 }
36 };
37
38 template <>
39 struct ScalarEnumerationTraits {
40 static void enumeration(IO &YIO, AddressSpaceQualifier &EN) {
41 YIO.enumCase(EN, "Private", AddressSpaceQualifier::Private);
42 YIO.enumCase(EN, "Global", AddressSpaceQualifier::Global);
43 YIO.enumCase(EN, "Constant", AddressSpaceQualifier::Constant);
44 YIO.enumCase(EN, "Local", AddressSpaceQualifier::Local);
45 YIO.enumCase(EN, "Generic", AddressSpaceQualifier::Generic);
46 YIO.enumCase(EN, "Region", AddressSpaceQualifier::Region);
47 }
48 };
49
50 template <>
51 struct ScalarEnumerationTraits {
52 static void enumeration(IO &YIO, ValueKind &EN) {
53 YIO.enumCase(EN, "ByValue", ValueKind::ByValue);
54 YIO.enumCase(EN, "GlobalBuffer", ValueKind::GlobalBuffer);
55 YIO.enumCase(EN, "DynamicSharedPointer", ValueKind::DynamicSharedPointer);
56 YIO.enumCase(EN, "Sampler", ValueKind::Sampler);
57 YIO.enumCase(EN, "Image", ValueKind::Image);
58 YIO.enumCase(EN, "Pipe", ValueKind::Pipe);
59 YIO.enumCase(EN, "Queue", ValueKind::Queue);
60 YIO.enumCase(EN, "HiddenGlobalOffsetX", ValueKind::HiddenGlobalOffsetX);
61 YIO.enumCase(EN, "HiddenGlobalOffsetY", ValueKind::HiddenGlobalOffsetY);
62 YIO.enumCase(EN, "HiddenGlobalOffsetZ", ValueKind::HiddenGlobalOffsetZ);
63 YIO.enumCase(EN, "HiddenNone", ValueKind::HiddenNone);
64 YIO.enumCase(EN, "HiddenPrintfBuffer", ValueKind::HiddenPrintfBuffer);
65 YIO.enumCase(EN, "HiddenDefaultQueue", ValueKind::HiddenDefaultQueue);
66 YIO.enumCase(EN, "HiddenCompletionAction",
67 ValueKind::HiddenCompletionAction);
68 }
69 };
70
71 template <>
72 struct ScalarEnumerationTraits {
73 static void enumeration(IO &YIO, ValueType &EN) {
74 YIO.enumCase(EN, "Struct", ValueType::Struct);
75 YIO.enumCase(EN, "I8", ValueType::I8);
76 YIO.enumCase(EN, "U8", ValueType::U8);
77 YIO.enumCase(EN, "I16", ValueType::I16);
78 YIO.enumCase(EN, "U16", ValueType::U16);
79 YIO.enumCase(EN, "F16", ValueType::F16);
80 YIO.enumCase(EN, "I32", ValueType::I32);
81 YIO.enumCase(EN, "U32", ValueType::U32);
82 YIO.enumCase(EN, "F32", ValueType::F32);
83 YIO.enumCase(EN, "I64", ValueType::I64);
84 YIO.enumCase(EN, "U64", ValueType::U64);
85 YIO.enumCase(EN, "F64", ValueType::F64);
86 }
87 };
88
89 template <>
90 struct MappingTraits {
91 static void mapping(IO &YIO, Kernel::Attrs::Metadata &MD) {
92 YIO.mapOptional(Kernel::Attrs::Key::ReqdWorkGroupSize,
93 MD.mReqdWorkGroupSize, std::vector());
94 YIO.mapOptional(Kernel::Attrs::Key::WorkGroupSizeHint,
95 MD.mWorkGroupSizeHint, std::vector());
96 YIO.mapOptional(Kernel::Attrs::Key::VecTypeHint,
97 MD.mVecTypeHint, std::string());
98 YIO.mapOptional(Kernel::Attrs::Key::RuntimeHandle, MD.mRuntimeHandle,
99 std::string());
100 }
101 };
102
103 template <>
104 struct MappingTraits {
105 static void mapping(IO &YIO, Kernel::Arg::Metadata &MD) {
106 YIO.mapRequired(Kernel::Arg::Key::Size, MD.mSize);
107 YIO.mapRequired(Kernel::Arg::Key::Align, MD.mAlign);
108 YIO.mapRequired(Kernel::Arg::Key::ValueKind, MD.mValueKind);
109 YIO.mapRequired(Kernel::Arg::Key::ValueType, MD.mValueType);
110 YIO.mapOptional(Kernel::Arg::Key::PointeeAlign, MD.mPointeeAlign,
111 uint32_t(0));
112 YIO.mapOptional(Kernel::Arg::Key::AccQual, MD.mAccQual,
113 AccessQualifier::Unknown);
114 YIO.mapOptional(Kernel::Arg::Key::AddrSpaceQual, MD.mAddrSpaceQual,
115 AddressSpaceQualifier::Unknown);
116 YIO.mapOptional(Kernel::Arg::Key::IsConst, MD.mIsConst, false);
117 YIO.mapOptional(Kernel::Arg::Key::IsPipe, MD.mIsPipe, false);
118 YIO.mapOptional(Kernel::Arg::Key::IsRestrict, MD.mIsRestrict, false);
119 YIO.mapOptional(Kernel::Arg::Key::IsVolatile, MD.mIsVolatile, false);
120 YIO.mapOptional(Kernel::Arg::Key::Name, MD.mName, std::string());
121 YIO.mapOptional(Kernel::Arg::Key::TypeName, MD.mTypeName, std::string());
122 }
123 };
124
125 template <>
126 struct MappingTraits {
127 static void mapping(IO &YIO, Kernel::CodeProps::Metadata &MD) {
128 YIO.mapOptional(Kernel::CodeProps::Key::KernargSegmentSize,
129 MD.mKernargSegmentSize, uint64_t(0));
130 YIO.mapOptional(Kernel::CodeProps::Key::WorkgroupGroupSegmentSize,
131 MD.mWorkgroupGroupSegmentSize, uint32_t(0));
132 YIO.mapOptional(Kernel::CodeProps::Key::WorkitemPrivateSegmentSize,
133 MD.mWorkitemPrivateSegmentSize, uint32_t(0));
134 YIO.mapOptional(Kernel::CodeProps::Key::WavefrontNumSGPRs,
135 MD.mWavefrontNumSGPRs, uint16_t(0));
136 YIO.mapOptional(Kernel::CodeProps::Key::WorkitemNumVGPRs,
137 MD.mWorkitemNumVGPRs, uint16_t(0));
138 YIO.mapOptional(Kernel::CodeProps::Key::KernargSegmentAlign,
139 MD.mKernargSegmentAlign, uint8_t(0));
140 YIO.mapOptional(Kernel::CodeProps::Key::GroupSegmentAlign,
141 MD.mGroupSegmentAlign, uint8_t(0));
142 YIO.mapOptional(Kernel::CodeProps::Key::PrivateSegmentAlign,
143 MD.mPrivateSegmentAlign, uint8_t(0));
144 YIO.mapOptional(Kernel::CodeProps::Key::WavefrontSize,
145 MD.mWavefrontSize, uint8_t(0));
146 }
147 };
148
149 template <>
150 struct MappingTraits {
151 static void mapping(IO &YIO, Kernel::DebugProps::Metadata &MD) {
152 YIO.mapOptional(Kernel::DebugProps::Key::DebuggerABIVersion,
153 MD.mDebuggerABIVersion, std::vector());
154 YIO.mapOptional(Kernel::DebugProps::Key::ReservedNumVGPRs,
155 MD.mReservedNumVGPRs, uint16_t(0));
156 YIO.mapOptional(Kernel::DebugProps::Key::ReservedFirstVGPR,
157 MD.mReservedFirstVGPR, uint16_t(-1));
158 YIO.mapOptional(Kernel::DebugProps::Key::PrivateSegmentBufferSGPR,
159 MD.mPrivateSegmentBufferSGPR, uint16_t(-1));
160 YIO.mapOptional(Kernel::DebugProps::Key::WavefrontPrivateSegmentOffsetSGPR,
161 MD.mWavefrontPrivateSegmentOffsetSGPR, uint16_t(-1));
162 }
163 };
164
165 template <>
166 struct MappingTraits {
167 static void mapping(IO &YIO, Kernel::Metadata &MD) {
168 YIO.mapRequired(Kernel::Key::Name, MD.mName);
169 YIO.mapOptional(Kernel::Key::Language, MD.mLanguage, std::string());
170 YIO.mapOptional(Kernel::Key::LanguageVersion, MD.mLanguageVersion,
171 std::vector());
172 if (!MD.mAttrs.empty() || !YIO.outputting())
173 YIO.mapOptional(Kernel::Key::Attrs, MD.mAttrs);
174 if (!MD.mArgs.empty() || !YIO.outputting())
175 YIO.mapOptional(Kernel::Key::Args, MD.mArgs);
176 if (!MD.mCodeProps.empty() || !YIO.outputting())
177 YIO.mapOptional(Kernel::Key::CodeProps, MD.mCodeProps);
178 if (!MD.mDebugProps.empty() || !YIO.outputting())
179 YIO.mapOptional(Kernel::Key::DebugProps, MD.mDebugProps);
180 }
181 };
182
183 template <>
184 struct MappingTraits {
185 static void mapping(IO &YIO, CodeObject::Metadata &MD) {
186 YIO.mapRequired(Key::Version, MD.mVersion);
187 YIO.mapOptional(Key::Printf, MD.mPrintf, std::vector());
188 if (!MD.mKernels.empty() || !YIO.outputting())
189 YIO.mapOptional(Key::Kernels, MD.mKernels);
190 }
191 };
192
193 } // end namespace yaml
194
195 namespace AMDGPU {
196 namespace CodeObject {
197
198 /* static */
199 std::error_code Metadata::fromYamlString(
200 std::string YamlString, Metadata &CodeObjectMetadata) {
201 yaml::Input YamlInput(YamlString);
202 YamlInput >> CodeObjectMetadata;
203 return YamlInput.error();
204 }
205
206 /* static */
207 std::error_code Metadata::toYamlString(
208 Metadata CodeObjectMetadata, std::string &YamlString) {
209 raw_string_ostream YamlStream(YamlString);
210 yaml::Output YamlOutput(YamlStream, nullptr, std::numeric_limits::max());
211 YamlOutput << CodeObjectMetadata;
212 return std::error_code();
213 }
214
215 } // end namespace CodeObject
216 } // end namespace AMDGPU
217 } // end namespace llvm
0 //===--- AMDGPUMetadata.cpp -------------------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// \file
10 /// \brief AMDGPU metadata definitions and in-memory representations.
11 ///
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "llvm/Support/AMDGPUMetadata.h"
16 #include "llvm/Support/YAMLTraits.h"
17
18 using namespace llvm::AMDGPU;
19 using namespace llvm::AMDGPU::HSAMD;
20
21 LLVM_YAML_IS_SEQUENCE_VECTOR(Kernel::Arg::Metadata)
22 LLVM_YAML_IS_SEQUENCE_VECTOR(Kernel::Metadata)
23
24 namespace llvm {
25 namespace yaml {
26
27 template <>
28 struct ScalarEnumerationTraits {
29 static void enumeration(IO &YIO, AccessQualifier &EN) {
30 YIO.enumCase(EN, "Default", AccessQualifier::Default);
31 YIO.enumCase(EN, "ReadOnly", AccessQualifier::ReadOnly);
32 YIO.enumCase(EN, "WriteOnly", AccessQualifier::WriteOnly);
33 YIO.enumCase(EN, "ReadWrite", AccessQualifier::ReadWrite);
34 }
35 };
36
37 template <>
38 struct ScalarEnumerationTraits {
39 static void enumeration(IO &YIO, AddressSpaceQualifier &EN) {
40 YIO.enumCase(EN, "Private", AddressSpaceQualifier::Private);
41 YIO.enumCase(EN, "Global", AddressSpaceQualifier::Global);
42 YIO.enumCase(EN, "Constant", AddressSpaceQualifier::Constant);
43 YIO.enumCase(EN, "Local", AddressSpaceQualifier::Local);
44 YIO.enumCase(EN, "Generic", AddressSpaceQualifier::Generic);
45 YIO.enumCase(EN, "Region", AddressSpaceQualifier::Region);
46 }
47 };
48
49 template <>
50 struct ScalarEnumerationTraits {
51 static void enumeration(IO &YIO, ValueKind &EN) {
52 YIO.enumCase(EN, "ByValue", ValueKind::ByValue);
53 YIO.enumCase(EN, "GlobalBuffer", ValueKind::GlobalBuffer);
54 YIO.enumCase(EN, "DynamicSharedPointer", ValueKind::DynamicSharedPointer);
55 YIO.enumCase(EN, "Sampler", ValueKind::Sampler);
56 YIO.enumCase(EN, "Image", ValueKind::Image);
57 YIO.enumCase(EN, "Pipe", ValueKind::Pipe);
58 YIO.enumCase(EN, "Queue", ValueKind::Queue);
59 YIO.enumCase(EN, "HiddenGlobalOffsetX", ValueKind::HiddenGlobalOffsetX);
60 YIO.enumCase(EN, "HiddenGlobalOffsetY", ValueKind::HiddenGlobalOffsetY);
61 YIO.enumCase(EN, "HiddenGlobalOffsetZ", ValueKind::HiddenGlobalOffsetZ);
62 YIO.enumCase(EN, "HiddenNone", ValueKind::HiddenNone);
63 YIO.enumCase(EN, "HiddenPrintfBuffer", ValueKind::HiddenPrintfBuffer);
64 YIO.enumCase(EN, "HiddenDefaultQueue", ValueKind::HiddenDefaultQueue);
65 YIO.enumCase(EN, "HiddenCompletionAction",
66 ValueKind::HiddenCompletionAction);
67 }
68 };
69
70 template <>
71 struct ScalarEnumerationTraits {
72 static void enumeration(IO &YIO, ValueType &EN) {
73 YIO.enumCase(EN, "Struct", ValueType::Struct);
74 YIO.enumCase(EN, "I8", ValueType::I8);
75 YIO.enumCase(EN, "U8", ValueType::U8);
76 YIO.enumCase(EN, "I16", ValueType::I16);
77 YIO.enumCase(EN, "U16", ValueType::U16);
78 YIO.enumCase(EN, "F16", ValueType::F16);
79 YIO.enumCase(EN, "I32", ValueType::I32);
80 YIO.enumCase(EN, "U32", ValueType::U32);
81 YIO.enumCase(EN, "F32", ValueType::F32);
82 YIO.enumCase(EN, "I64", ValueType::I64);
83 YIO.enumCase(EN, "U64", ValueType::U64);
84 YIO.enumCase(EN, "F64", ValueType::F64);
85 }
86 };
87
88 template <>
89 struct MappingTraits {
90 static void mapping(IO &YIO, Kernel::Attrs::Metadata &MD) {
91 YIO.mapOptional(Kernel::Attrs::Key::ReqdWorkGroupSize,
92 MD.mReqdWorkGroupSize, std::vector());
93 YIO.mapOptional(Kernel::Attrs::Key::WorkGroupSizeHint,
94 MD.mWorkGroupSizeHint, std::vector());
95 YIO.mapOptional(Kernel::Attrs::Key::VecTypeHint,
96 MD.mVecTypeHint, std::string());
97 YIO.mapOptional(Kernel::Attrs::Key::RuntimeHandle, MD.mRuntimeHandle,
98 std::string());
99 }
100 };
101
102 template <>
103 struct MappingTraits {
104 static void mapping(IO &YIO, Kernel::Arg::Metadata &MD) {
105 YIO.mapRequired(Kernel::Arg::Key::Size, MD.mSize);
106 YIO.mapRequired(Kernel::Arg::Key::Align, MD.mAlign);
107 YIO.mapRequired(Kernel::Arg::Key::ValueKind, MD.mValueKind);
108 YIO.mapRequired(Kernel::Arg::Key::ValueType, MD.mValueType);
109 YIO.mapOptional(Kernel::Arg::Key::PointeeAlign, MD.mPointeeAlign,
110 uint32_t(0));
111 YIO.mapOptional(Kernel::Arg::Key::AccQual, MD.mAccQual,
112 AccessQualifier::Unknown);
113 YIO.mapOptional(Kernel::Arg::Key::AddrSpaceQual, MD.mAddrSpaceQual,
114 AddressSpaceQualifier::Unknown);
115 YIO.mapOptional(Kernel::Arg::Key::IsConst, MD.mIsConst, false);
116 YIO.mapOptional(Kernel::Arg::Key::IsPipe, MD.mIsPipe, false);
117 YIO.mapOptional(Kernel::Arg::Key::IsRestrict, MD.mIsRestrict, false);
118 YIO.mapOptional(Kernel::Arg::Key::IsVolatile, MD.mIsVolatile, false);
119 YIO.mapOptional(Kernel::Arg::Key::Name, MD.mName, std::string());
120 YIO.mapOptional(Kernel::Arg::Key::TypeName, MD.mTypeName, std::string());
121 }
122 };
123
124 template <>
125 struct MappingTraits {
126 static void mapping(IO &YIO, Kernel::CodeProps::Metadata &MD) {
127 YIO.mapOptional(Kernel::CodeProps::Key::KernargSegmentSize,
128 MD.mKernargSegmentSize, uint64_t(0));
129 YIO.mapOptional(Kernel::CodeProps::Key::WorkgroupGroupSegmentSize,
130 MD.mWorkgroupGroupSegmentSize, uint32_t(0));
131 YIO.mapOptional(Kernel::CodeProps::Key::WorkitemPrivateSegmentSize,
132 MD.mWorkitemPrivateSegmentSize, uint32_t(0));
133 YIO.mapOptional(Kernel::CodeProps::Key::WavefrontNumSGPRs,
134 MD.mWavefrontNumSGPRs, uint16_t(0));
135 YIO.mapOptional(Kernel::CodeProps::Key::WorkitemNumVGPRs,
136 MD.mWorkitemNumVGPRs, uint16_t(0));
137 YIO.mapOptional(Kernel::CodeProps::Key::KernargSegmentAlign,
138 MD.mKernargSegmentAlign, uint8_t(0));
139 YIO.mapOptional(Kernel::CodeProps::Key::GroupSegmentAlign,
140 MD.mGroupSegmentAlign, uint8_t(0));
141 YIO.mapOptional(Kernel::CodeProps::Key::PrivateSegmentAlign,
142 MD.mPrivateSegmentAlign, uint8_t(0));
143 YIO.mapOptional(Kernel::CodeProps::Key::WavefrontSize,
144 MD.mWavefrontSize, uint8_t(0));
145 }
146 };
147
148 template <>
149 struct MappingTraits {
150 static void mapping(IO &YIO, Kernel::DebugProps::Metadata &MD) {
151 YIO.mapOptional(Kernel::DebugProps::Key::DebuggerABIVersion,
152 MD.mDebuggerABIVersion, std::vector());
153 YIO.mapOptional(Kernel::DebugProps::Key::ReservedNumVGPRs,
154 MD.mReservedNumVGPRs, uint16_t(0));
155 YIO.mapOptional(Kernel::DebugProps::Key::ReservedFirstVGPR,
156 MD.mReservedFirstVGPR, uint16_t(-1));
157 YIO.mapOptional(Kernel::DebugProps::Key::PrivateSegmentBufferSGPR,
158 MD.mPrivateSegmentBufferSGPR, uint16_t(-1));
159 YIO.mapOptional(Kernel::DebugProps::Key::WavefrontPrivateSegmentOffsetSGPR,
160 MD.mWavefrontPrivateSegmentOffsetSGPR, uint16_t(-1));
161 }
162 };
163
164 template <>
165 struct MappingTraits {
166 static void mapping(IO &YIO, Kernel::Metadata &MD) {
167 YIO.mapRequired(Kernel::Key::Name, MD.mName);
168 YIO.mapOptional(Kernel::Key::Language, MD.mLanguage, std::string());
169 YIO.mapOptional(Kernel::Key::LanguageVersion, MD.mLanguageVersion,
170 std::vector());
171 if (!MD.mAttrs.empty() || !YIO.outputting())
172 YIO.mapOptional(Kernel::Key::Attrs, MD.mAttrs);
173 if (!MD.mArgs.empty() || !YIO.outputting())
174 YIO.mapOptional(Kernel::Key::Args, MD.mArgs);
175 if (!MD.mCodeProps.empty() || !YIO.outputting())
176 YIO.mapOptional(Kernel::Key::CodeProps, MD.mCodeProps);
177 if (!MD.mDebugProps.empty() || !YIO.outputting())
178 YIO.mapOptional(Kernel::Key::DebugProps, MD.mDebugProps);
179 }
180 };
181
182 template <>
183 struct MappingTraits {
184 static void mapping(IO &YIO, HSAMD::Metadata &MD) {
185 YIO.mapRequired(Key::Version, MD.mVersion);
186 YIO.mapOptional(Key::Printf, MD.mPrintf, std::vector());
187 if (!MD.mKernels.empty() || !YIO.outputting())
188 YIO.mapOptional(Key::Kernels, MD.mKernels);
189 }
190 };
191
192 } // end namespace yaml
193
194 namespace AMDGPU {
195 namespace HSAMD {
196
197 /* static */
198 std::error_code Metadata::fromYamlString(
199 std::string YamlString, Metadata &HSAMetadata) {
200 yaml::Input YamlInput(YamlString);
201 YamlInput >> HSAMetadata;
202 return YamlInput.error();
203 }
204
205 /* static */
206 std::error_code Metadata::toYamlString(
207 Metadata HSAMetadata, std::string &YamlString) {
208 raw_string_ostream YamlStream(YamlString);
209 yaml::Output YamlOutput(YamlStream, nullptr, std::numeric_limits::max());
210 YamlOutput << HSAMetadata;
211 return std::error_code();
212 }
213
214 } // end namespace HSAMD
215 } // end namespace AMDGPU
216 } // end namespace llvm
2929 endif( MSVC OR MINGW )
3030
3131 add_llvm_library(LLVMSupport
32 AMDGPUCodeObjectMetadata.cpp
32 AMDGPUMetadata.cpp
3333 APFloat.cpp
3434 APInt.cpp
3535 APSInt.cpp
124124 getTargetStreamer().EmitDirectiveHSACodeObjectVersion(2, 1);
125125 getTargetStreamer().EmitDirectiveHSACodeObjectISA(
126126 ISA.Major, ISA.Minor, ISA.Stepping, "AMD", "AMDGPU");
127 getTargetStreamer().EmitStartOfCodeObjectMetadata(M);
127 getTargetStreamer().EmitStartOfHSAMetadata(M);
128128 }
129129
130130 void AMDGPUAsmPrinter::EmitEndOfAsmFile(Module &M) {
142142 if (TM.getTargetTriple().getOS() != Triple::AMDHSA)
143143 return;
144144
145 getTargetStreamer().EmitEndOfCodeObjectMetadata();
145 getTargetStreamer().EmitEndOfHSAMetadata();
146146 }
147147
148148 bool AMDGPUAsmPrinter::isBlockOnlyReachableByFallthrough(
175175
176176 if (TM.getTargetTriple().getOS() != Triple::AMDHSA)
177177 return;
178 getTargetStreamer().EmitKernelCodeObjectMetadata(*MF->getFunction(),
179 KernelCode);
178 getTargetStreamer().EmitKernelHSAMetadata(*MF->getFunction(), KernelCode);
180179 }
181180
182181 void AMDGPUAsmPrinter::EmitFunctionEntryLabel() {
4040 #include "llvm/MC/MCStreamer.h"
4141 #include "llvm/MC/MCSubtargetInfo.h"
4242 #include "llvm/MC/MCSymbol.h"
43 #include "llvm/Support/AMDGPUCodeObjectMetadata.h"
43 #include "llvm/Support/AMDGPUMetadata.h"
4444 #include "llvm/Support/Casting.h"
4545 #include "llvm/Support/Compiler.h"
4646 #include "llvm/Support/ErrorHandling.h"
826826 bool ParseDirectiveMajorMinor(uint32_t &Major, uint32_t &Minor);
827827 bool ParseDirectiveHSACodeObjectVersion();
828828 bool ParseDirectiveHSACodeObjectISA();
829 bool ParseDirectiveCodeObjectMetadata();
829 bool ParseDirectiveHSAMetadata();
830830 bool ParseAMDKernelCodeTValue(StringRef ID, amd_kernel_code_t &Header);
831831 bool ParseDirectiveAMDKernelCodeT();
832832 bool subtargetHasRegister(const MCRegisterInfo &MRI, unsigned RegNo) const;
23972397 return false;
23982398 }
23992399
2400 bool AMDGPUAsmParser::ParseDirectiveCodeObjectMetadata() {
2400 bool AMDGPUAsmParser::ParseDirectiveHSAMetadata() {
24012401 std::string YamlString;
24022402 raw_string_ostream YamlStream(YamlString);
24032403
24122412
24132413 if (getLexer().is(AsmToken::Identifier)) {
24142414 StringRef ID = getLexer().getTok().getIdentifier();
2415 if (ID == AMDGPU::CodeObject::MetadataAssemblerDirectiveEnd) {
2415 if (ID == AMDGPU::HSAMD::AssemblerDirectiveEnd) {
24162416 Lex();
24172417 FoundEnd = true;
24182418 break;
24292429
24302430 if (getLexer().is(AsmToken::Eof) && !FoundEnd) {
24312431 return TokError(
2432 "expected directive .end_amdgpu_code_object_metadata not found");
2432 "expected directive .end_amd_amdgpu_hsa_metadata not found");
24332433 }
24342434
24352435 YamlStream.flush();
24362436
2437 if (!getTargetStreamer().EmitCodeObjectMetadata(YamlString))
2437 if (!getTargetStreamer().EmitHSAMetadata(YamlString))
24382438 return Error(getParser().getTok().getLoc(), "invalid code object metadata");
24392439
24402440 return false;
25162516 if (IDVal == ".hsa_code_object_isa")
25172517 return ParseDirectiveHSACodeObjectISA();
25182518
2519 if (IDVal == AMDGPU::CodeObject::MetadataAssemblerDirectiveBegin)
2520 return ParseDirectiveCodeObjectMetadata();
2519 if (IDVal == AMDGPU::HSAMD::AssemblerDirectiveBegin)
2520 return ParseDirectiveHSAMetadata();
25212521
25222522 if (IDVal == ".amd_kernel_code_t")
25232523 return ParseDirectiveAMDKernelCodeT();
+0
-436
lib/Target/AMDGPU/MCTargetDesc/AMDGPUCodeObjectMetadataStreamer.cpp less more
None //===--- AMDGPUCodeObjectMetadataStreamer.cpp -------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// \file
10 /// \brief AMDGPU Code Object Metadata Streamer.
11 ///
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "AMDGPUCodeObjectMetadataStreamer.h"
16 #include "AMDGPU.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/IR/Constants.h"
19 #include "llvm/IR/Module.h"
20 #include "llvm/Support/raw_ostream.h"
21
22 namespace llvm {
23
24 static cl::opt DumpCodeObjectMetadata(
25 "amdgpu-dump-comd",
26 cl::desc("Dump AMDGPU Code Object Metadata"));
27 static cl::opt VerifyCodeObjectMetadata(
28 "amdgpu-verify-comd",
29 cl::desc("Verify AMDGPU Code Object Metadata"));
30
31 namespace AMDGPU {
32 namespace CodeObject {
33
34 void MetadataStreamer::dump(StringRef YamlString) const {
35 errs() << "AMDGPU Code Object Metadata:\n" << YamlString << '\n';
36 }
37
38 void MetadataStreamer::verify(StringRef YamlString) const {
39 errs() << "AMDGPU Code Object Metadata Parser Test: ";
40
41 CodeObject::Metadata FromYamlString;
42 if (Metadata::fromYamlString(YamlString, FromYamlString)) {
43 errs() << "FAIL\n";
44 return;
45 }
46
47 std::string ToYamlString;
48 if (Metadata::toYamlString(FromYamlString, ToYamlString)) {
49 errs() << "FAIL\n";
50 return;
51 }
52
53 errs() << (YamlString == ToYamlString ? "PASS" : "FAIL") << '\n';
54 if (YamlString != ToYamlString) {
55 errs() << "Original input: " << YamlString << '\n'
56 << "Produced output: " << ToYamlString << '\n';
57 }
58 }
59
60 AccessQualifier MetadataStreamer::getAccessQualifier(StringRef AccQual) const {
61 if (AccQual.empty())
62 return AccessQualifier::Unknown;
63
64 return StringSwitch(AccQual)
65 .Case("read_only", AccessQualifier::ReadOnly)
66 .Case("write_only", AccessQualifier::WriteOnly)
67 .Case("read_write", AccessQualifier::ReadWrite)
68 .Default(AccessQualifier::Default);
69 }
70
71 AddressSpaceQualifier MetadataStreamer::getAddressSpaceQualifer(
72 unsigned AddressSpace) const {
73 if (AddressSpace == AMDGPUASI.PRIVATE_ADDRESS)
74 return AddressSpaceQualifier::Private;
75 if (AddressSpace == AMDGPUASI.GLOBAL_ADDRESS)
76 return AddressSpaceQualifier::Global;
77 if (AddressSpace == AMDGPUASI.CONSTANT_ADDRESS)
78 return AddressSpaceQualifier::Constant;
79 if (AddressSpace == AMDGPUASI.LOCAL_ADDRESS)
80 return AddressSpaceQualifier::Local;
81 if (AddressSpace == AMDGPUASI.FLAT_ADDRESS)
82 return AddressSpaceQualifier::Generic;
83 if (AddressSpace == AMDGPUASI.REGION_ADDRESS)
84 return AddressSpaceQualifier::Region;
85
86 llvm_unreachable("Unknown address space qualifier");
87 }
88
89 ValueKind MetadataStreamer::getValueKind(Type *Ty, StringRef TypeQual,
90 StringRef BaseTypeName) const {
91 if (TypeQual.find("pipe") != StringRef::npos)
92 return ValueKind::Pipe;
93
94 return StringSwitch(BaseTypeName)
95 .Case("image1d_t", ValueKind::Image)
96 .Case("image1d_array_t", ValueKind::Image)
97 .Case("image1d_buffer_t", ValueKind::Image)
98 .Case("image2d_t", ValueKind::Image)
99 .Case("image2d_array_t", ValueKind::Image)
100 .Case("image2d_array_depth_t", ValueKind::Image)
101 .Case("image2d_array_msaa_t", ValueKind::Image)
102 .Case("image2d_array_msaa_depth_t", ValueKind::Image)
103 .Case("image2d_depth_t", ValueKind::Image)
104 .Case("image2d_msaa_t", ValueKind::Image)
105 .Case("image2d_msaa_depth_t", ValueKind::Image)
106 .Case("image3d_t", ValueKind::Image)
107 .Case("sampler_t", ValueKind::Sampler)
108 .Case("queue_t", ValueKind::Queue)
109 .Default(isa(Ty) ?
110 (Ty->getPointerAddressSpace() ==
111 AMDGPUASI.LOCAL_ADDRESS ?
112 ValueKind::DynamicSharedPointer :
113 ValueKind::GlobalBuffer) :
114 ValueKind::ByValue);
115 }
116
117 ValueType MetadataStreamer::getValueType(Type *Ty, StringRef TypeName) const {
118 switch (Ty->getTypeID()) {
119 case Type::IntegerTyID: {
120 auto Signed = !TypeName.startswith("u");
121 switch (Ty->getIntegerBitWidth()) {
122 case 8:
123 return Signed ? ValueType::I8 : ValueType::U8;
124 case 16:
125 return Signed ? ValueType::I16 : ValueType::U16;
126 case 32:
127 return Signed ? ValueType::I32 : ValueType::U32;
128 case 64:
129 return Signed ? ValueType::I64 : ValueType::U64;
130 default:
131 return ValueType::Struct;
132 }
133 }
134 case Type::HalfTyID:
135 return ValueType::F16;
136 case Type::FloatTyID:
137 return ValueType::F32;
138 case Type::DoubleTyID:
139 return ValueType::F64;
140 case Type::PointerTyID:
141 return getValueType(Ty->getPointerElementType(), TypeName);
142 case Type::VectorTyID:
143 return getValueType(Ty->getVectorElementType(), TypeName);
144 default:
145 return ValueType::Struct;
146 }
147 }
148
149 std::string MetadataStreamer::getTypeName(Type *Ty, bool Signed) const {
150 switch (Ty->getTypeID()) {
151 case Type::IntegerTyID: {
152 if (!Signed)
153 return (Twine('u') + getTypeName(Ty, true)).str();
154
155 auto BitWidth = Ty->getIntegerBitWidth();
156 switch (BitWidth) {
157 case 8:
158 return "char";
159 case 16:
160 return "short";
161 case 32:
162 return "int";
163 case 64:
164 return "long";
165 default:
166 return (Twine('i') + Twine(BitWidth)).str();
167 }
168 }
169 case Type::HalfTyID:
170 return "half";
171 case Type::FloatTyID:
172 return "float";
173 case Type::DoubleTyID:
174 return "double";
175 case Type::VectorTyID: {
176 auto VecTy = cast(Ty);
177 auto ElTy = VecTy->getElementType();
178 auto NumElements = VecTy->getVectorNumElements();
179 return (Twine(getTypeName(ElTy, Signed)) + Twine(NumElements)).str();
180 }
181 default:
182 return "unknown";
183 }
184 }
185
186 std::vector MetadataStreamer::getWorkGroupDimensions(
187 MDNode *Node) const {
188 std::vector Dims;
189 if (Node->getNumOperands() != 3)
190 return Dims;
191
192 for (auto &Op : Node->operands())
193 Dims.push_back(mdconst::extract(Op)->getZExtValue());
194 return Dims;
195 }
196
197 void MetadataStreamer::emitVersion() {
198 auto &Version = CodeObjectMetadata.mVersion;
199
200 Version.push_back(MetadataVersionMajor);
201 Version.push_back(MetadataVersionMinor);
202 }
203
204 void MetadataStreamer::emitPrintf(const Module &Mod) {
205 auto &Printf = CodeObjectMetadata.mPrintf;
206
207 auto Node = Mod.getNamedMetadata("llvm.printf.fmts");
208 if (!Node)
209 return;
210
211 for (auto Op : Node->operands())
212 if (Op->getNumOperands())
213 Printf.push_back(cast(Op->getOperand(0))->getString());
214 }
215
216 void MetadataStreamer::emitKernelLanguage(const Function &Func) {
217 auto &Kernel = CodeObjectMetadata.mKernels.back();
218
219 // TODO: What about other languages?
220 auto Node = Func.getParent()->getNamedMetadata("opencl.ocl.version");
221 if (!Node || !Node->getNumOperands())
222 return;
223 auto Op0 = Node->getOperand(0);
224 if (Op0->getNumOperands() <= 1)
225 return;
226
227 Kernel.mLanguage = "OpenCL C";
228 Kernel.mLanguageVersion.push_back(
229 mdconst::extract(Op0->getOperand(0))->getZExtValue());
230 Kernel.mLanguageVersion.push_back(
231 mdconst::extract(Op0->getOperand(1))->getZExtValue());
232 }
233
234 void MetadataStreamer::emitKernelAttrs(const Function &Func) {
235 auto &Attrs = CodeObjectMetadata.mKernels.back().mAttrs;
236
237 if (auto Node = Func.getMetadata("reqd_work_group_size"))
238 Attrs.mReqdWorkGroupSize = getWorkGroupDimensions(Node);
239 if (auto Node = Func.getMetadata("work_group_size_hint"))
240 Attrs.mWorkGroupSizeHint = getWorkGroupDimensions(Node);
241 if (auto Node = Func.getMetadata("vec_type_hint")) {
242 Attrs.mVecTypeHint = getTypeName(
243 cast(Node->getOperand(0))->getType(),
244 mdconst::extract(Node->getOperand(1))->getZExtValue());
245 }
246 if (Func.hasFnAttribute("runtime-handle")) {
247 Attrs.mRuntimeHandle =
248 Func.getFnAttribute("runtime-handle").getValueAsString().str();
249 }
250 }
251
252 void MetadataStreamer::emitKernelArgs(const Function &Func) {
253 for (auto &Arg : Func.args())
254 emitKernelArg(Arg);
255
256 // TODO: What about other languages?
257 if (!Func.getParent()->getNamedMetadata("opencl.ocl.version"))
258 return;
259
260 auto &DL = Func.getParent()->getDataLayout();
261 auto Int64Ty = Type::getInt64Ty(Func.getContext());
262
263 emitKernelArg(DL, Int64Ty, ValueKind::HiddenGlobalOffsetX);
264 emitKernelArg(DL, Int64Ty, ValueKind::HiddenGlobalOffsetY);
265 emitKernelArg(DL, Int64Ty, ValueKind::HiddenGlobalOffsetZ);
266
267 if (!Func.getParent()->getNamedMetadata("llvm.printf.fmts"))
268 return;
269
270 auto Int8PtrTy = Type::getInt8PtrTy(Func.getContext(),
271 AMDGPUASI.GLOBAL_ADDRESS);
272 emitKernelArg(DL, Int8PtrTy, ValueKind::HiddenPrintfBuffer);
273 }
274
275 void MetadataStreamer::emitKernelArg(const Argument &Arg) {
276 auto Func = Arg.getParent();
277 auto ArgNo = Arg.getArgNo();
278 const MDNode *Node;
279
280 StringRef TypeQual;
281 Node = Func->getMetadata("kernel_arg_type_qual");
282 if (Node && ArgNo < Node->getNumOperands())
283 TypeQual = cast(Node->getOperand(ArgNo))->getString();
284
285 StringRef BaseTypeName;
286 Node = Func->getMetadata("kernel_arg_base_type");
287 if (Node && ArgNo < Node->getNumOperands())
288 BaseTypeName = cast(Node->getOperand(ArgNo))->getString();
289
290 StringRef AccQual;
291 if (Arg.getType()->isPointerTy() && Arg.onlyReadsMemory() &&
292 Arg.hasNoAliasAttr()) {
293 AccQual = "read_only";
294 } else {
295 Node = Func->getMetadata("kernel_arg_access_qual");
296 if (Node && ArgNo < Node->getNumOperands())
297 AccQual = cast(Node->getOperand(ArgNo))->getString();
298 }
299
300 StringRef Name;
301 Node = Func->getMetadata("kernel_arg_name");
302 if (Node && ArgNo < Node->getNumOperands())
303 Name = cast(Node->getOperand(ArgNo))->getString();
304
305 StringRef TypeName;
306 Node = Func->getMetadata("kernel_arg_type");
307 if (Node && ArgNo < Node->getNumOperands())
308 TypeName = cast(Node->getOperand(ArgNo))->getString();
309
310 emitKernelArg(Func->getParent()->getDataLayout(), Arg.getType(),
311 getValueKind(Arg.getType(), TypeQual, BaseTypeName), TypeQual,
312 BaseTypeName, AccQual, Name, TypeName);
313 }
314
315 void MetadataStreamer::emitKernelArg(const DataLayout &DL, Type *Ty,
316 ValueKind ValueKind, StringRef TypeQual,
317 StringRef BaseTypeName, StringRef AccQual,
318 StringRef Name, StringRef TypeName) {
319 CodeObjectMetadata.mKernels.back().mArgs.push_back(Kernel::Arg::Metadata());
320 auto &Arg = CodeObjectMetadata.mKernels.back().mArgs.back();
321
322 Arg.mSize = DL.getTypeAllocSize(Ty);
323 Arg.mAlign = DL.getABITypeAlignment(Ty);
324 Arg.mValueKind = ValueKind;
325 Arg.mValueType = getValueType(Ty, BaseTypeName);
326
327 if (auto PtrTy = dyn_cast(Ty)) {
328 auto ElTy = PtrTy->getElementType();
329 if (PtrTy->getAddressSpace() == AMDGPUASI.LOCAL_ADDRESS && ElTy->isSized())
330 Arg.mPointeeAlign = DL.getABITypeAlignment(ElTy);
331 }
332
333 Arg.mAccQual = getAccessQualifier(AccQual);
334
335 if (auto PtrTy = dyn_cast(Ty))
336 Arg.mAddrSpaceQual = getAddressSpaceQualifer(PtrTy->getAddressSpace());
337
338 SmallVector SplitTypeQuals;
339 TypeQual.split(SplitTypeQuals, " ", -1, false);
340 for (StringRef Key : SplitTypeQuals) {
341 auto P = StringSwitch(Key)
342 .Case("const", &Arg.mIsConst)
343 .Case("pipe", &Arg.mIsPipe)
344 .Case("restrict", &Arg.mIsRestrict)
345 .Case("volatile", &Arg.mIsVolatile)
346 .Default(nullptr);
347 if (P)
348 *P = true;
349 }
350
351 Arg.mName = Name;
352 Arg.mTypeName = TypeName;
353 }
354
355 void MetadataStreamer::emitKernelCodeProps(
356 const amd_kernel_code_t &KernelCode) {
357 auto &CodeProps = CodeObjectMetadata.mKernels.back().mCodeProps;
358
359 CodeProps.mKernargSegmentSize = KernelCode.kernarg_segment_byte_size;
360 CodeProps.mWorkgroupGroupSegmentSize =
361 KernelCode.workgroup_group_segment_byte_size;
362 CodeProps.mWorkitemPrivateSegmentSize =
363 KernelCode.workitem_private_segment_byte_size;
364 CodeProps.mWavefrontNumSGPRs = KernelCode.wavefront_sgpr_count;
365 CodeProps.mWorkitemNumVGPRs = KernelCode.workitem_vgpr_count;
366 CodeProps.mKernargSegmentAlign = KernelCode.kernarg_segment_alignment;
367 CodeProps.mGroupSegmentAlign = KernelCode.group_segment_alignment;
368 CodeProps.mPrivateSegmentAlign = KernelCode.private_segment_alignment;
369 CodeProps.mWavefrontSize = KernelCode.wavefront_size;
370 }
371
372 void MetadataStreamer::emitKernelDebugProps(
373 const amd_kernel_code_t &KernelCode) {
374 if (!(KernelCode.code_properties & AMD_CODE_PROPERTY_IS_DEBUG_SUPPORTED))
375 return;
376
377 auto &DebugProps = CodeObjectMetadata.mKernels.back().mDebugProps;
378
379 // FIXME: Need to pass down debugger ABI version through features. This is ok
380 // for now because we only have one version.
381 DebugProps.mDebuggerABIVersion.push_back(1);
382 DebugProps.mDebuggerABIVersion.push_back(0);
383 DebugProps.mReservedNumVGPRs = KernelCode.reserved_vgpr_count;
384 DebugProps.mReservedFirstVGPR = KernelCode.reserved_vgpr_first;
385 DebugProps.mPrivateSegmentBufferSGPR =
386 KernelCode.debug_private_segment_buffer_sgpr;
387 DebugProps.mWavefrontPrivateSegmentOffsetSGPR =
388 KernelCode.debug_wavefront_private_segment_offset_sgpr;
389 }
390
391 void MetadataStreamer::begin(const Module &Mod) {
392 AMDGPUASI = getAMDGPUAS(Mod);
393 emitVersion();
394 emitPrintf(Mod);
395 }
396
397 void MetadataStreamer::emitKernel(const Function &Func,
398 const amd_kernel_code_t &KernelCode) {
399 if (Func.getCallingConv() != CallingConv::AMDGPU_KERNEL)
400 return;
401
402 CodeObjectMetadata.mKernels.push_back(Kernel::Metadata());
403 auto &Kernel = CodeObjectMetadata.mKernels.back();
404
405 Kernel.mName = Func.getName();
406 emitKernelLanguage(Func);
407 emitKernelAttrs(Func);
408 emitKernelArgs(Func);
409 emitKernelCodeProps(KernelCode);
410 emitKernelDebugProps(KernelCode);
411 }
412
413 ErrorOr MetadataStreamer::toYamlString() {
414 std::string YamlString;
415 if (auto Error = Metadata::toYamlString(CodeObjectMetadata, YamlString))
416 return Error;
417
418 if (DumpCodeObjectMetadata)
419 dump(YamlString);
420 if (VerifyCodeObjectMetadata)
421 verify(YamlString);
422
423 return YamlString;
424 }
425
426 ErrorOr MetadataStreamer::toYamlString(StringRef YamlString) {
427 if (auto Error = Metadata::fromYamlString(YamlString, CodeObjectMetadata))
428 return Error;
429
430 return toYamlString();
431 }
432
433 } // end namespace CodeObject
434 } // end namespace AMDGPU
435 } // end namespace llvm
+0
-99
lib/Target/AMDGPU/MCTargetDesc/AMDGPUCodeObjectMetadataStreamer.h less more
None //===--- AMDGPUCodeObjectMetadataStreamer.h ---------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// \file
10 /// \brief AMDGPU Code Object Metadata Streamer.
11 ///
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUCODEOBJECTMETADATASTREAMER_H
16 #define LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUCODEOBJECTMETADATASTREAMER_H
17
18 #include "AMDGPU.h"
19 #include "AMDKernelCodeT.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/Support/AMDGPUCodeObjectMetadata.h"
22 #include "llvm/Support/ErrorOr.h"
23
24 namespace llvm {
25
26 class Argument;
27 class DataLayout;
28 class Function;
29 class MDNode;
30 class Module;
31 class Type;
32
33 namespace AMDGPU {
34 namespace CodeObject {
35
36 class MetadataStreamer final {
37 private:
38 Metadata CodeObjectMetadata;
39 AMDGPUAS AMDGPUASI;
40
41 void dump(StringRef YamlString) const;
42
43 void verify(StringRef YamlString) const;
44
45 AccessQualifier getAccessQualifier(StringRef AccQual) const;
46
47 AddressSpaceQualifier getAddressSpaceQualifer(unsigned AddressSpace) const;
48
49 ValueKind getValueKind(Type *Ty, StringRef TypeQual,
50 StringRef BaseTypeName) const;
51
52 ValueType getValueType(Type *Ty, StringRef TypeName) const;
53
54 std::string getTypeName(Type *Ty, bool Signed) const;
55
56 std::vector getWorkGroupDimensions(MDNode *Node) const;
57
58 void emitVersion();
59
60 void emitPrintf(const Module &Mod);
61
62 void emitKernelLanguage(const Function &Func);
63
64 void emitKernelAttrs(const Function &Func);
65
66 void emitKernelArgs(const Function &Func);
67
68 void emitKernelArg(const Argument &Arg);
69
70 void emitKernelArg(const DataLayout &DL, Type *Ty, ValueKind ValueKind,
71 StringRef TypeQual = "", StringRef BaseTypeName = "",
72 StringRef AccQual = "", StringRef Name = "",
73 StringRef TypeName = "");
74
75 void emitKernelCodeProps(const amd_kernel_code_t &KernelCode);
76
77 void emitKernelDebugProps(const amd_kernel_code_t &KernelCode);
78
79 public:
80 MetadataStreamer() = default;
81 ~MetadataStreamer() = default;
82
83 void begin(const Module &Mod);
84
85 void end() {}
86
87 void emitKernel(const Function &Func, const amd_kernel_code_t &KernelCode);
88
89 ErrorOr toYamlString();
90
91 ErrorOr toYamlString(StringRef YamlString);
92 };
93
94 } // end namespace CodeObject
95 } // end namespace AMDGPU
96 } // end namespace llvm
97
98 #endif // LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUCODEOBJECTMETADATASTREAMER_H
0 //===--- AMDGPUHSAMetadataStreamer.cpp --------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// \file
10 /// \brief AMDGPU HSA Metadata Streamer.
11 ///
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "AMDGPUHSAMetadataStreamer.h"
16 #include "AMDGPU.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/IR/Constants.h"
19 #include "llvm/IR/Module.h"
20 #include "llvm/Support/raw_ostream.h"
21
22 namespace llvm {
23
24 static cl::opt DumpHSAMetadata(
25 "amdgpu-dump-hsa-metadata",
26 cl::desc("Dump AMDGPU HSA Metadata"));
27 static cl::opt VerifyHSAMetadata(
28 "amdgpu-verify-hsa-metadata",
29 cl::desc("Verify AMDGPU HSA Metadata"));
30
31 namespace AMDGPU {
32 namespace HSAMD {
33
34 void MetadataStreamer::dump(StringRef YamlString) const {
35 errs() << "AMDGPU HSA Metadata:\n" << YamlString << '\n';
36 }
37
38 void MetadataStreamer::verify(StringRef YamlString) const {
39 errs() << "AMDGPU HSA Metadata Parser Test: ";
40
41 HSAMD::Metadata FromYamlString;
42 if (Metadata::fromYamlString(YamlString, FromYamlString)) {
43 errs() << "FAIL\n";
44 return;
45 }
46
47 std::string ToYamlString;
48 if (Metadata::toYamlString(FromYamlString, ToYamlString)) {
49 errs() << "FAIL\n";
50 return;
51 }
52
53 errs() << (YamlString == ToYamlString ? "PASS" : "FAIL") << '\n';
54 if (YamlString != ToYamlString) {
55 errs() << "Original input: " << YamlString << '\n'
56 << "Produced output: " << ToYamlString << '\n';
57 }
58 }
59
60 AccessQualifier MetadataStreamer::getAccessQualifier(StringRef AccQual) const {
61 if (AccQual.empty())
62 return AccessQualifier::Unknown;
63
64 return StringSwitch(AccQual)
65 .Case("read_only", AccessQualifier::ReadOnly)
66 .Case("write_only", AccessQualifier::WriteOnly)
67 .Case("read_write", AccessQualifier::ReadWrite)
68 .Default(AccessQualifier::Default);
69 }
70
71 AddressSpaceQualifier MetadataStreamer::getAddressSpaceQualifer(
72 unsigned AddressSpace) const {
73 if (AddressSpace == AMDGPUASI.PRIVATE_ADDRESS)
74 return AddressSpaceQualifier::Private;
75 if (AddressSpace == AMDGPUASI.GLOBAL_ADDRESS)
76 return AddressSpaceQualifier::Global;
77 if (AddressSpace == AMDGPUASI.CONSTANT_ADDRESS)
78 return AddressSpaceQualifier::Constant;
79 if (AddressSpace == AMDGPUASI.LOCAL_ADDRESS)
80 return AddressSpaceQualifier::Local;
81 if (AddressSpace == AMDGPUASI.FLAT_ADDRESS)
82 return AddressSpaceQualifier::Generic;
83 if (AddressSpace == AMDGPUASI.REGION_ADDRESS)
84 return AddressSpaceQualifier::Region;
85
86 llvm_unreachable("Unknown address space qualifier");
87 }
88
89 ValueKind MetadataStreamer::getValueKind(Type *Ty, StringRef TypeQual,
90 StringRef BaseTypeName) const {
91 if (TypeQual.find("pipe") != StringRef::npos)
92 return ValueKind::Pipe;
93
94 return StringSwitch(BaseTypeName)
95 .Case("image1d_t", ValueKind::Image)
96 .Case("image1d_array_t", ValueKind::Image)
97 .Case("image1d_buffer_t", ValueKind::Image)
98 .Case("image2d_t", ValueKind::Image)
99 .Case("image2d_array_t", ValueKind::Image)
100 .Case("image2d_array_depth_t", ValueKind::Image)
101 .Case("image2d_array_msaa_t", ValueKind::Image)
102 .Case("image2d_array_msaa_depth_t", ValueKind::Image)
103 .Case("image2d_depth_t", ValueKind::Image)
104 .Case("image2d_msaa_t", ValueKind::Image)
105 .Case("image2d_msaa_depth_t", ValueKind::Image)
106 .Case("image3d_t", ValueKind::Image)
107 .Case("sampler_t", ValueKind::Sampler)
108 .Case("queue_t", ValueKind::Queue)
109 .Default(isa(Ty) ?
110 (Ty->getPointerAddressSpace() ==
111 AMDGPUASI.LOCAL_ADDRESS ?
112 ValueKind::DynamicSharedPointer :
113 ValueKind::GlobalBuffer) :
114 ValueKind::ByValue);
115 }
116
117 ValueType MetadataStreamer::getValueType(Type *Ty, StringRef TypeName) const {
118 switch (Ty->getTypeID()) {
119 case Type::IntegerTyID: {
120 auto Signed = !TypeName.startswith("u");
121 switch (Ty->getIntegerBitWidth()) {
122 case 8:
123 return Signed ? ValueType::I8 : ValueType::U8;
124 case 16:
125 return Signed ? ValueType::I16 : ValueType::U16;
126 case 32:
127 return Signed ? ValueType::I32 : ValueType::U32;
128 case 64:
129 return Signed ? ValueType::I64 : ValueType::U64;
130 default:
131 return ValueType::Struct;
132 }
133 }
134 case Type::HalfTyID:
135 return ValueType::F16;
136 case Type::FloatTyID:
137 return ValueType::F32;
138 case Type::DoubleTyID:
139 return ValueType::F64;
140 case Type::PointerTyID:
141 return getValueType(Ty->getPointerElementType(), TypeName);
142 case Type::VectorTyID:
143 return getValueType(Ty->getVectorElementType(), TypeName);
144 default:
145 return ValueType::Struct;
146 }
147 }
148
149 std::string MetadataStreamer::getTypeName(Type *Ty, bool Signed) const {
150 switch (Ty->getTypeID()) {
151 case Type::IntegerTyID: {
152 if (!Signed)
153 return (Twine('u') + getTypeName(Ty, true)).str();
154
155 auto BitWidth = Ty->getIntegerBitWidth();
156 switch (BitWidth) {
157 case 8:
158 return "char";
159 case 16:
160 return "short";
161 case 32:
162 return "int";
163 case 64:
164 return "long";
165 default:
166 return (Twine('i') + Twine(BitWidth)).str();
167 }
168 }
169 case Type::HalfTyID:
170 return "half";
171 case Type::FloatTyID:
172 return "float";
173 case Type::DoubleTyID:
174 return "double";
175 case Type::VectorTyID: {
176 auto VecTy = cast(Ty);
177 auto ElTy = VecTy->getElementType();
178 auto NumElements = VecTy->getVectorNumElements();
179 return (Twine(getTypeName(ElTy, Signed)) + Twine(NumElements)).str();
180 }
181 default:
182 return "unknown";
183 }
184 }
185
186 std::vector MetadataStreamer::getWorkGroupDimensions(
187 MDNode *Node) const {
188 std::vector Dims;
189 if (Node->getNumOperands() != 3)
190 return Dims;
191
192 for (auto &Op : Node->operands())
193 Dims.push_back(mdconst::extract(Op)->getZExtValue());
194 return Dims;
195 }
196
197 void MetadataStreamer::emitVersion() {
198 auto &Version = HSAMetadata.mVersion;
199
200 Version.push_back(VersionMajor);
201 Version.push_back(VersionMinor);
202 }
203
204 void MetadataStreamer::emitPrintf(const Module &Mod) {
205 auto &Printf = HSAMetadata.mPrintf;
206
207 auto Node = Mod.getNamedMetadata("llvm.printf.fmts");
208 if (!Node)
209 return;
210
211 for (auto Op : Node->operands())
212 if (Op->getNumOperands())
213 Printf.push_back(cast(Op->getOperand(0))->getString());
214 }
215
216 void MetadataStreamer::emitKernelLanguage(const Function &Func) {
217 auto &Kernel = HSAMetadata.mKernels.back();
218
219 // TODO: What about other languages?
220 auto Node = Func.getParent()->getNamedMetadata("opencl.ocl.version");
221 if (!Node || !Node->getNumOperands())
222 return;
223 auto Op0 = Node->getOperand(0);
224 if (Op0->getNumOperands() <= 1)
225 return;
226
227 Kernel.mLanguage = "OpenCL C";
228 Kernel.mLanguageVersion.push_back(
229 mdconst::extract(Op0->getOperand(0))->getZExtValue());
230 Kernel.mLanguageVersion.push_back(
231 mdconst::extract(Op0->getOperand(1))->getZExtValue());
232 }
233
234 void MetadataStreamer::emitKernelAttrs(const Function &Func) {
235 auto &Attrs = HSAMetadata.mKernels.back().mAttrs;
236
237 if (auto Node = Func.getMetadata("reqd_work_group_size"))
238 Attrs.mReqdWorkGroupSize = getWorkGroupDimensions(Node);
239 if (auto Node = Func.getMetadata("work_group_size_hint"))
240 Attrs.mWorkGroupSizeHint = getWorkGroupDimensions(Node);
241 if (auto Node = Func.getMetadata("vec_type_hint")) {
242 Attrs.mVecTypeHint = getTypeName(
243 cast(Node->getOperand(0))->getType(),
244 mdconst::extract(Node->getOperand(1))->getZExtValue());
245 }
246 if (Func.hasFnAttribute("runtime-handle")) {
247 Attrs.mRuntimeHandle =
248 Func.getFnAttribute("runtime-handle").getValueAsString().str();
249 }
250 }
251
252 void MetadataStreamer::emitKernelArgs(const Function &Func) {
253 for (auto &Arg : Func.args())
254 emitKernelArg(Arg);
255
256 // TODO: What about other languages?
257 if (!Func.getParent()->getNamedMetadata("opencl.ocl.version"))
258 return;
259
260 auto &DL = Func.getParent()->getDataLayout();
261 auto Int64Ty = Type::getInt64Ty(Func.getContext());
262
263 emitKernelArg(DL, Int64Ty, ValueKind::HiddenGlobalOffsetX);
264 emitKernelArg(DL, Int64Ty, ValueKind::HiddenGlobalOffsetY);
265 emitKernelArg(DL, Int64Ty, ValueKind::HiddenGlobalOffsetZ);
266
267 if (!Func.getParent()->getNamedMetadata("llvm.printf.fmts"))
268 return;
269
270 auto Int8PtrTy = Type::getInt8PtrTy(Func.getContext(),
271 AMDGPUASI.GLOBAL_ADDRESS);
272 emitKernelArg(DL, Int8PtrTy, ValueKind::HiddenPrintfBuffer);
273 }
274
275 void MetadataStreamer::emitKernelArg(const Argument &Arg) {
276 auto Func = Arg.getParent();
277 auto ArgNo = Arg.getArgNo();
278 const MDNode *Node;
279
280 StringRef TypeQual;
281 Node = Func->getMetadata("kernel_arg_type_qual");
282 if (Node && ArgNo < Node->getNumOperands())
283 TypeQual = cast(Node->getOperand(ArgNo))->getString();
284
285 StringRef BaseTypeName;
286 Node = Func->getMetadata("kernel_arg_base_type");
287 if (Node && ArgNo < Node->getNumOperands())
288 BaseTypeName = cast(Node->getOperand(ArgNo))->getString();
289
290 StringRef AccQual;
291 if (Arg.getType()->isPointerTy() && Arg.onlyReadsMemory() &&
292 Arg.hasNoAliasAttr()) {
293 AccQual = "read_only";
294 } else {
295 Node = Func->getMetadata("kernel_arg_access_qual");
296 if (Node && ArgNo < Node->getNumOperands())
297 AccQual = cast(Node->getOperand(ArgNo))->getString();
298 }
299
300 StringRef Name;
301 Node = Func->getMetadata("kernel_arg_name");
302 if (Node && ArgNo < Node->getNumOperands())
303 Name = cast(Node->getOperand(ArgNo))->getString();
304
305 StringRef TypeName;
306 Node = Func->getMetadata("kernel_arg_type");
307 if (Node && ArgNo < Node->getNumOperands())
308 TypeName = cast(Node->getOperand(ArgNo))->getString();
309
310 emitKernelArg(Func->getParent()->getDataLayout(), Arg.getType(),
311 getValueKind(Arg.getType(), TypeQual, BaseTypeName), TypeQual,
312 BaseTypeName, AccQual, Name, TypeName);
313 }
314
315 void MetadataStreamer::emitKernelArg(const DataLayout &DL, Type *Ty,
316 ValueKind ValueKind, StringRef TypeQual,
317 StringRef BaseTypeName, StringRef AccQual,
318 StringRef Name, StringRef TypeName) {
319 HSAMetadata.mKernels.back().mArgs.push_back(Kernel::Arg::Metadata());
320 auto &Arg = HSAMetadata.mKernels.back().mArgs.back();
321
322 Arg.mSize = DL.getTypeAllocSize(Ty);
323 Arg.mAlign = DL.getABITypeAlignment(Ty);
324 Arg.mValueKind = ValueKind;
325 Arg.mValueType = getValueType(Ty, BaseTypeName);
326
327 if (auto PtrTy = dyn_cast(Ty)) {
328 auto ElTy = PtrTy->getElementType();
329 if (PtrTy->getAddressSpace() == AMDGPUASI.LOCAL_ADDRESS && ElTy->isSized())
330 Arg.mPointeeAlign = DL.getABITypeAlignment(ElTy);
331 }
332
333 Arg.mAccQual = getAccessQualifier(AccQual);
334
335 if (auto PtrTy = dyn_cast(Ty))
336 Arg.mAddrSpaceQual = getAddressSpaceQualifer(PtrTy->getAddressSpace());
337
338 SmallVector SplitTypeQuals;
339 TypeQual.split(SplitTypeQuals, " ", -1, false);
340 for (StringRef Key : SplitTypeQuals) {
341 auto P = StringSwitch(Key)
342 .Case("const", &Arg.mIsConst)
343 .Case("pipe", &Arg.mIsPipe)
344 .Case("restrict", &Arg.mIsRestrict)
345 .Case("volatile", &Arg.mIsVolatile)
346 .Default(nullptr);
347 if (P)
348 *P = true;
349 }
350
351 Arg.mName = Name;
352 Arg.mTypeName = TypeName;
353 }
354
355 void MetadataStreamer::emitKernelCodeProps(
356 const amd_kernel_code_t &KernelCode) {
357 auto &CodeProps = HSAMetadata.mKernels.back().mCodeProps;
358
359 CodeProps.mKernargSegmentSize = KernelCode.kernarg_segment_byte_size;
360 CodeProps.mWorkgroupGroupSegmentSize =
361 KernelCode.workgroup_group_segment_byte_size;
362 CodeProps.mWorkitemPrivateSegmentSize =
363 KernelCode.workitem_private_segment_byte_size;
364 CodeProps.mWavefrontNumSGPRs = KernelCode.wavefront_sgpr_count;
365 CodeProps.mWorkitemNumVGPRs = KernelCode.workitem_vgpr_count;
366 CodeProps.mKernargSegmentAlign = KernelCode.kernarg_segment_alignment;
367 CodeProps.mGroupSegmentAlign = KernelCode.group_segment_alignment;
368 CodeProps.mPrivateSegmentAlign = KernelCode.private_segment_alignment;
369 CodeProps.mWavefrontSize = KernelCode.wavefront_size;
370 }
371
372 void MetadataStreamer::emitKernelDebugProps(
373 const amd_kernel_code_t &KernelCode) {
374 if (!(KernelCode.code_properties & AMD_CODE_PROPERTY_IS_DEBUG_SUPPORTED))
375 return;
376
377 auto &DebugProps = HSAMetadata.mKernels.back().mDebugProps;
378
379 // FIXME: Need to pass down debugger ABI version through features. This is ok
380 // for now because we only have one version.
381 DebugProps.mDebuggerABIVersion.push_back(1);
382 DebugProps.mDebuggerABIVersion.push_back(0);
383 DebugProps.mReservedNumVGPRs = KernelCode.reserved_vgpr_count;
384 DebugProps.mReservedFirstVGPR = KernelCode.reserved_vgpr_first;
385 DebugProps.mPrivateSegmentBufferSGPR =
386 KernelCode.debug_private_segment_buffer_sgpr;
387 DebugProps.mWavefrontPrivateSegmentOffsetSGPR =
388 KernelCode.debug_wavefront_private_segment_offset_sgpr;
389 }
390
391 void MetadataStreamer::begin(const Module &Mod) {
392 AMDGPUASI = getAMDGPUAS(Mod);
393 emitVersion();
394 emitPrintf(Mod);
395 }
396
397 void MetadataStreamer::emitKernel(const Function &Func,
398 const amd_kernel_code_t &KernelCode) {
399 if (Func.getCallingConv() != CallingConv::AMDGPU_KERNEL)
400 return;
401
402 HSAMetadata.mKernels.push_back(Kernel::Metadata());
403 auto &Kernel = HSAMetadata.mKernels.back();
404
405 Kernel.mName = Func.getName();
406 emitKernelLanguage(Func);
407 emitKernelAttrs(Func);
408 emitKernelArgs(Func);
409 emitKernelCodeProps(KernelCode);
410 emitKernelDebugProps(KernelCode);
411 }
412
413 ErrorOr MetadataStreamer::toYamlString() {
414 std::string ToYamlString;
415 if (auto Error = Metadata::toYamlString(HSAMetadata, ToYamlString))
416 return Error;
417
418 if (DumpHSAMetadata)
419 dump(ToYamlString);
420 if (VerifyHSAMetadata)
421 verify(ToYamlString);
422
423 return ToYamlString;
424 }
425
426 ErrorOr MetadataStreamer::toYamlString(StringRef YamlString) {
427 if (auto Error = Metadata::fromYamlString(YamlString, HSAMetadata))
428 return Error;
429
430 return toYamlString();
431 }
432
433 } // end namespace HSAMD
434 } // end namespace AMDGPU
435 } // end namespace llvm
0 //===--- AMDGPUHSAMetadataStreamer.h ----------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// \file
10 /// \brief AMDGPU HSA Metadata Streamer.
11 ///
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUHSAMETADATASTREAMER_H
16 #define LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUHSAMETADATASTREAMER_H
17
18 #include "AMDGPU.h"
19 #include "AMDKernelCodeT.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/Support/AMDGPUMetadata.h"
22 #include "llvm/Support/ErrorOr.h"
23
24 namespace llvm {
25
26 class Argument;
27 class DataLayout;
28 class Function;
29 class MDNode;
30 class Module;
31 class Type;
32
33 namespace AMDGPU {
34 namespace HSAMD {
35
36 class MetadataStreamer final {
37 private:
38 Metadata HSAMetadata;
39 AMDGPUAS AMDGPUASI;
40
41 void dump(StringRef YamlString) const;
42
43 void verify(StringRef YamlString) const;
44
45 AccessQualifier getAccessQualifier(StringRef AccQual) const;
46
47 AddressSpaceQualifier getAddressSpaceQualifer(unsigned AddressSpace) const;
48
49 ValueKind getValueKind(Type *Ty, StringRef TypeQual,
50 StringRef BaseTypeName) const;
51
52 ValueType getValueType(Type *Ty, StringRef TypeName) const;
53
54 std::string getTypeName(Type *Ty, bool Signed) const;
55
56 std::vector getWorkGroupDimensions(MDNode *Node) const;
57
58 void emitVersion();
59
60 void emitPrintf(const Module &Mod);
61
62 void emitKernelLanguage(const Function &Func);
63
64 void emitKernelAttrs(const Function &Func);
65
66 void emitKernelArgs(const Function &Func);
67
68 void emitKernelArg(const Argument &Arg);
69
70 void emitKernelArg(const DataLayout &DL, Type *Ty, ValueKind ValueKind,
71 StringRef TypeQual = "", StringRef BaseTypeName = "",
72 StringRef AccQual = "", StringRef Name = "",
73 StringRef TypeName = "");
74
75 void emitKernelCodeProps(const amd_kernel_code_t &KernelCode);
76
77 void emitKernelDebugProps(const amd_kernel_code_t &KernelCode);
78
79 public:
80 MetadataStreamer() = default;
81 ~MetadataStreamer() = default;
82
83 void begin(const Module &Mod);
84
85 void end() {}
86
87 void emitKernel(const Function &Func, const amd_kernel_code_t &KernelCode);
88
89 ErrorOr toYamlString();
90
91 ErrorOr toYamlString(StringRef YamlString);
92 };
93
94 } // end namespace HSAMD
95 } // end namespace AMDGPU
96 } // end namespace llvm
97
98 #endif // LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUHSAMETADATASTREAMER_H
4141 AMDGPUTargetStreamer::AMDGPUTargetStreamer(MCStreamer &S)
4242 : MCTargetStreamer(S) {}
4343
44 void AMDGPUTargetStreamer::EmitStartOfCodeObjectMetadata(const Module &Mod) {
45 CodeObjectMetadataStreamer.begin(Mod);
46 }
47
48 void AMDGPUTargetStreamer::EmitKernelCodeObjectMetadata(
44 void AMDGPUTargetStreamer::EmitStartOfHSAMetadata(const Module &Mod) {
45 HSAMetadataStreamer.begin(Mod);
46 }
47
48 void AMDGPUTargetStreamer::EmitKernelHSAMetadata(
4949 const Function &Func, const amd_kernel_code_t &KernelCode) {
50 CodeObjectMetadataStreamer.emitKernel(Func, KernelCode);
51 }
52
53 void AMDGPUTargetStreamer::EmitEndOfCodeObjectMetadata() {
54 CodeObjectMetadataStreamer.end();
55 EmitCodeObjectMetadata(CodeObjectMetadataStreamer.toYamlString().get());
50 HSAMetadataStreamer.emitKernel(Func, KernelCode);
51 }
52
53 void AMDGPUTargetStreamer::EmitEndOfHSAMetadata() {
54 HSAMetadataStreamer.end();
55 EmitHSAMetadata(HSAMetadataStreamer.toYamlString().get());
5656 }
5757
5858 //===----------------------------------------------------------------------===//
9999 }
100100 }
101101
102 bool AMDGPUTargetAsmStreamer::EmitCodeObjectMetadata(StringRef YamlString) {
103 auto VerifiedYamlString = CodeObjectMetadataStreamer.toYamlString(YamlString);
102 bool AMDGPUTargetAsmStreamer::EmitHSAMetadata(StringRef YamlString) {
103 auto VerifiedYamlString = HSAMetadataStreamer.toYamlString(YamlString);
104104 if (!VerifiedYamlString)
105105 return false;
106106
107 OS << '\t' << AMDGPU::CodeObject::MetadataAssemblerDirectiveBegin << '\n';
107 OS << '\t' << AMDGPU::HSAMD::AssemblerDirectiveBegin << '\n';
108108 OS << VerifiedYamlString.get();
109 OS << '\t' << AMDGPU::CodeObject::MetadataAssemblerDirectiveEnd << '\n';
109 OS << '\t' << AMDGPU::HSAMD::AssemblerDirectiveEnd << '\n';
110110
111111 return true;
112112 }
211211 Symbol->setType(ELF::STT_AMDGPU_HSA_KERNEL);
212212 }
213213
214 bool AMDGPUTargetELFStreamer::EmitCodeObjectMetadata(StringRef YamlString) {
215 auto VerifiedYamlString = CodeObjectMetadataStreamer.toYamlString(YamlString);
214 bool AMDGPUTargetELFStreamer::EmitHSAMetadata(StringRef YamlString) {
215 auto VerifiedYamlString = HSAMetadataStreamer.toYamlString(YamlString);
216216 if (!VerifiedYamlString)
217217 return false;
218218
99 #ifndef LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUTARGETSTREAMER_H
1010 #define LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUTARGETSTREAMER_H
1111
12 #include "AMDGPUCodeObjectMetadataStreamer.h"
12 #include "AMDGPUHSAMetadataStreamer.h"
1313 #include "AMDKernelCodeT.h"
1414 #include "llvm/MC/MCStreamer.h"
1515
2626
2727 class AMDGPUTargetStreamer : public MCTargetStreamer {
2828 protected:
29 AMDGPU::CodeObject::MetadataStreamer CodeObjectMetadataStreamer;
29 AMDGPU::HSAMD::MetadataStreamer HSAMetadataStreamer;
3030 MCContext &getContext() const { return Streamer.getContext(); }
3131
3232 public:
4343
4444 virtual void EmitAMDGPUSymbolType(StringRef SymbolName, unsigned Type) = 0;
4545
46 virtual void EmitStartOfCodeObjectMetadata(const Module &Mod);
46 virtual void EmitStartOfHSAMetadata(const Module &Mod);
4747
48 virtual void EmitKernelCodeObjectMetadata(
48 virtual void EmitKernelHSAMetadata(
4949 const Function &Func, const amd_kernel_code_t &KernelCode);
5050
51 virtual void EmitEndOfCodeObjectMetadata();
51 virtual void EmitEndOfHSAMetadata();
5252
5353 /// \returns True on success, false on failure.
54 virtual bool EmitCodeObjectMetadata(StringRef YamlString) = 0;
54 virtual bool EmitHSAMetadata(StringRef YamlString) = 0;
5555
5656 virtual bool EmitPalMetadata(ArrayRef Data) = 0;
5757 };
7272 void EmitAMDGPUSymbolType(StringRef SymbolName, unsigned Type) override;
7373
7474 /// \returns True on success, false on failure.
75 bool EmitCodeObjectMetadata(StringRef YamlString) override;
75 bool EmitHSAMetadata(StringRef YamlString) override;
7676
7777 bool EmitPalMetadata(ArrayRef data) override;
7878 };
101101 void EmitAMDGPUSymbolType(StringRef SymbolName, unsigned Type) override;
102102
103103 /// \returns True on success, false on failure.
104 bool EmitCodeObjectMetadata(StringRef YamlString) override;
104 bool EmitHSAMetadata(StringRef YamlString) override;
105105
106106 bool EmitPalMetadata(ArrayRef data) override;
107107 };
0 add_llvm_library(LLVMAMDGPUDesc
11 AMDGPUAsmBackend.cpp
2 AMDGPUCodeObjectMetadataStreamer.cpp
32 AMDGPUELFObjectWriter.cpp
43 AMDGPUELFStreamer.cpp
4 AMDGPUHSAMetadataStreamer.cpp
55 AMDGPUMCAsmInfo.cpp
66 AMDGPUMCCodeEmitter.cpp
77 AMDGPUMCTargetDesc.cpp
+0
-33
test/CodeGen/AMDGPU/code-object-metadata-deduce-ro-arg.ll less more
None ; RUN: llc -mtriple=amdgcn-amd-amdhsa -filetype=obj -o - < %s | llvm-readobj -amdgpu-code-object-metadata -elf-output-style=GNU -notes | FileCheck %s
1
2 ; CHECK: - Name: test_ro_arg
3 ; CHECK: Args:
4 ; CHECK-NEXT: - Size: 8
5 ; CHECK-NEXT: Align: 8
6 ; CHECK-NEXT: ValueKind: GlobalBuffer
7 ; CHECK-NEXT: ValueType: F32
8 ; CHECK-NEXT: AccQual: ReadOnly
9 ; CHECK-NEXT: AddrSpaceQual: Global
10 ; CHECK-NEXT: IsConst: true
11 ; CHECK-NEXT: IsRestrict: true
12 ; CHECK-NEXT: TypeName: 'float*'
13
14 ; CHECK-NEXT: - Size: 8
15 ; CHECK-NEXT: Align: 8
16 ; CHECK-NEXT: ValueKind: GlobalBuffer
17 ; CHECK-NEXT: ValueType: F32
18 ; CHECK-NEXT: AccQual: Default
19 ; CHECK-NEXT: AddrSpaceQual: Global
20 ; CHECK-NEXT: TypeName: 'float*'
21
22 define amdgpu_kernel void @test_ro_arg(float addrspace(1)* noalias readonly %in, float addrspace(1)* %out)
23 !kernel_arg_addr_space !0 !kernel_arg_access_qual !1 !kernel_arg_type !2
24 !kernel_arg_base_type !2 !kernel_arg_type_qual !3 {
25 ret void
26 }
27
28 !0 = !{i32 1, i32 1}
29 !1 = !{!"none", !"none"}
30 !2 = !{!"float*", !"float*"}
31 !3 = !{!"const restrict", !""}
32
+0
-1303
test/CodeGen/AMDGPU/code-object-metadata-from-llvm-ir-full.ll less more
None ; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx700 -filetype=obj -o - < %s | llvm-readobj -amdgpu-code-object-metadata -elf-output-style=GNU -notes | FileCheck --check-prefix=CHECK --check-prefix=GFX700 --check-prefix=NOTES %s
1 ; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx800 -filetype=obj -o - < %s | llvm-readobj -amdgpu-code-object-metadata -elf-output-style=GNU -notes | FileCheck --check-prefix=CHECK --check-prefix=GFX800 --check-prefix=NOTES %s
2 ; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -filetype=obj -o - < %s | llvm-readobj -amdgpu-code-object-metadata -elf-output-style=GNU -notes | FileCheck --check-prefix=CHECK --check-prefix=GFX900 --check-prefix=NOTES %s
3 ; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx700 -amdgpu-dump-comd -amdgpu-verify-comd -filetype=obj -o - < %s 2>&1 | FileCheck --check-prefix=PARSER %s
4 ; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx800 -amdgpu-dump-comd -amdgpu-verify-comd -filetype=obj -o - < %s 2>&1 | FileCheck --check-prefix=PARSER %s
5 ; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -amdgpu-dump-comd -amdgpu-verify-comd -filetype=obj -o - < %s 2>&1 | FileCheck --check-prefix=PARSER %s
6
7 %struct.A = type { i8, float }
8 %opencl.image1d_t = type opaque
9 %opencl.image2d_t = type opaque
10 %opencl.image3d_t = type opaque
11 %opencl.queue_t = type opaque
12 %opencl.pipe_t = type opaque
13 %struct.B = type { i32 addrspace(1)*}
14 %opencl.clk_event_t = type opaque
15
16 @__test_block_invoke_kernel_runtime_handle = external addrspace(1) externally_initialized constant i8 addrspace(1)*
17
18 ; CHECK: ---
19 ; CHECK: Version: [ 1, 0 ]
20 ; CHECK: Printf:
21 ; CHECK: - '1:1:4:%d\n'
22 ; CHECK: - '2:1:8:%g\n'
23 ; CHECK: Kernels:
24
25 ; CHECK: - Name: test_char
26 ; CHECK-NEXT: Language: OpenCL C
27 ; CHECK-NEXT: LanguageVersion: [ 2, 0 ]
28 ; CHECK-NEXT: Args:
29 ; CHECK-NEXT: - Size: 1
30 ; CHECK-NEXT: Align: 1
31 ; CHECK-NEXT: ValueKind: ByValue
32 ; CHECK-NEXT: ValueType: I8
33 ; CHECK-NEXT: AccQual: Default
34 ; CHECK-NEXT: TypeName: char
35 ; CHECK-NEXT: - Size: 8
36 ; CHECK-NEXT: Align: 8
37 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetX
38 ; CHECK-NEXT: ValueType: I64
39 ; CHECK-NEXT: - Size: 8
40 ; CHECK-NEXT: Align: 8
41 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetY
42 ; CHECK-NEXT: ValueType: I64
43 ; CHECK-NEXT: - Size: 8
44 ; CHECK-NEXT: Align: 8
45 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetZ
46 ; CHECK-NEXT: ValueType: I64
47 ; CHECK-NEXT: - Size: 8
48 ; CHECK-NEXT: Align: 8
49 ; CHECK-NEXT: ValueKind: HiddenPrintfBuffer
50 ; CHECK-NEXT: ValueType: I8
51 ; CHECK-NEXT: AddrSpaceQual: Global
52 define amdgpu_kernel void @test_char(i8 %a)
53 !kernel_arg_addr_space !1 !kernel_arg_access_qual !2 !kernel_arg_type !9
54 !kernel_arg_base_type !9 !kernel_arg_type_qual !4 {
55 ret void
56 }
57
58 ; CHECK: - Name: test_ushort2
59 ; CHECK-NEXT: Language: OpenCL C
60 ; CHECK-NEXT: LanguageVersion: [ 2, 0 ]
61 ; CHECK-NEXT: Args:
62 ; CHECK-NEXT: - Size: 4
63 ; CHECK-NEXT: Align: 4
64 ; CHECK-NEXT: ValueKind: ByValue
65 ; CHECK-NEXT: ValueType: U16
66 ; CHECK-NEXT: AccQual: Default
67 ; CHECK-NEXT: TypeName: ushort2
68 ; CHECK-NEXT: - Size: 8
69 ; CHECK-NEXT: Align: 8
70 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetX
71 ; CHECK-NEXT: ValueType: I64
72 ; CHECK-NEXT: - Size: 8
73 ; CHECK-NEXT: Align: 8
74 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetY
75 ; CHECK-NEXT: ValueType: I64
76 ; CHECK-NEXT: - Size: 8
77 ; CHECK-NEXT: Align: 8
78 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetZ
79 ; CHECK-NEXT: ValueType: I64
80 ; CHECK-NEXT: - Size: 8
81 ; CHECK-NEXT: Align: 8
82 ; CHECK-NEXT: ValueKind: HiddenPrintfBuffer
83 ; CHECK-NEXT: ValueType: I8
84 ; CHECK-NEXT: AddrSpaceQual: Global
85 define amdgpu_kernel void @test_ushort2(<2 x i16> %a)
86 !kernel_arg_addr_space !1 !kernel_arg_access_qual !2 !kernel_arg_type !10
87 !kernel_arg_base_type !10 !kernel_arg_type_qual !4 {
88 ret void
89 }
90
91 ; CHECK: - Name: test_int3
92 ; CHECK-NEXT: Language: OpenCL C
93 ; CHECK-NEXT: LanguageVersion: [ 2, 0 ]
94 ; CHECK-NEXT: Args:
95 ; CHECK-NEXT: - Size: 16
96 ; CHECK-NEXT: Align: 16
97 ; CHECK-NEXT: ValueKind: ByValue
98 ; CHECK-NEXT: ValueType: I32
99 ; CHECK-NEXT: AccQual: Default
100 ; CHECK-NEXT: TypeName: int3
101 ; CHECK-NEXT: - Size: 8
102 ; CHECK-NEXT: Align: 8
103 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetX
104 ; CHECK-NEXT: ValueType: I64
105 ; CHECK-NEXT: - Size: 8
106 ; CHECK-NEXT: Align: 8
107 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetY
108 ; CHECK-NEXT: ValueType: I64
109 ; CHECK-NEXT: - Size: 8
110 ; CHECK-NEXT: Align: 8
111 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetZ
112 ; CHECK-NEXT: ValueType: I64
113 ; CHECK-NEXT: - Size: 8
114 ; CHECK-NEXT: Align: 8
115 ; CHECK-NEXT: ValueKind: HiddenPrintfBuffer
116 ; CHECK-NEXT: ValueType: I8
117 ; CHECK-NEXT: AddrSpaceQual: Global
118 define amdgpu_kernel void @test_int3(<3 x i32> %a)
119 !kernel_arg_addr_space !1 !kernel_arg_access_qual !2 !kernel_arg_type !11
120 !kernel_arg_base_type !11 !kernel_arg_type_qual !4 {
121 ret void
122 }
123
124 ; CHECK: - Name: test_ulong4
125 ; CHECK-NEXT: Language: OpenCL C
126 ; CHECK-NEXT: LanguageVersion: [ 2, 0 ]
127 ; CHECK-NEXT: Args:
128 ; CHECK-NEXT: - Size: 32
129 ; CHECK-NEXT: Align: 32
130 ; CHECK-NEXT: ValueKind: ByValue
131 ; CHECK-NEXT: ValueType: U64
132 ; CHECK-NEXT: AccQual: Default
133 ; CHECK-NEXT: TypeName: ulong4
134 ; CHECK-NEXT: - Size: 8
135 ; CHECK-NEXT: Align: 8
136 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetX
137 ; CHECK-NEXT: ValueType: I64
138 ; CHECK-NEXT: - Size: 8
139 ; CHECK-NEXT: Align: 8
140 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetY
141 ; CHECK-NEXT: ValueType: I64
142 ; CHECK-NEXT: - Size: 8
143 ; CHECK-NEXT: Align: 8
144 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetZ
145 ; CHECK-NEXT: ValueType: I64
146 ; CHECK-NEXT: - Size: 8
147 ; CHECK-NEXT: Align: 8
148 ; CHECK-NEXT: ValueKind: HiddenPrintfBuffer
149 ; CHECK-NEXT: ValueType: I8
150 ; CHECK-NEXT: AddrSpaceQual: Global
151 define amdgpu_kernel void @test_ulong4(<4 x i64> %a)
152 !kernel_arg_addr_space !1 !kernel_arg_access_qual !2 !kernel_arg_type !12
153 !kernel_arg_base_type !12 !kernel_arg_type_qual !4 {
154 ret void
155 }
156
157 ; CHECK: - Name: test_half8
158 ; CHECK-NEXT: Language: OpenCL C
159 ; CHECK-NEXT: LanguageVersion: [ 2, 0 ]
160 ; CHECK-NEXT: Args:
161 ; CHECK-NEXT: - Size: 16
162 ; CHECK-NEXT: Align: 16
163 ; CHECK-NEXT: ValueKind: ByValue
164 ; CHECK-NEXT: ValueType: F16
165 ; CHECK-NEXT: AccQual: Default
166 ; CHECK-NEXT: TypeName: half8
167 ; CHECK-NEXT: - Size: 8
168 ; CHECK-NEXT: Align: 8
169 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetX
170 ; CHECK-NEXT: ValueType: I64
171 ; CHECK-NEXT: - Size: 8
172 ; CHECK-NEXT: Align: 8
173 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetY
174 ; CHECK-NEXT: ValueType: I64
175 ; CHECK-NEXT: - Size: 8
176 ; CHECK-NEXT: Align: 8
177 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetZ
178 ; CHECK-NEXT: ValueType: I64
179 ; CHECK-NEXT: - Size: 8
180 ; CHECK-NEXT: Align: 8
181 ; CHECK-NEXT: ValueKind: HiddenPrintfBuffer
182 ; CHECK-NEXT: ValueType: I8
183 ; CHECK-NEXT: AddrSpaceQual: Global
184 define amdgpu_kernel void @test_half8(<8 x half> %a)
185 !kernel_arg_addr_space !1 !kernel_arg_access_qual !2 !kernel_arg_type !13
186 !kernel_arg_base_type !13 !kernel_arg_type_qual !4 {
187 ret void
188 }
189
190 ; CHECK: - Name: test_float16
191 ; CHECK-NEXT: Language: OpenCL C
192 ; CHECK-NEXT: LanguageVersion: [ 2, 0 ]
193 ; CHECK-NEXT: Args:
194 ; CHECK-NEXT: - Size: 64
195 ; CHECK-NEXT: Align: 64
196 ; CHECK-NEXT: ValueKind: ByValue
197 ; CHECK-NEXT: ValueType: F32
198 ; CHECK-NEXT: AccQual: Default
199 ; CHECK-NEXT: TypeName: float16
200 ; CHECK-NEXT: - Size: 8
201 ; CHECK-NEXT: Align: 8
202 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetX
203 ; CHECK-NEXT: ValueType: I64
204 ; CHECK-NEXT: - Size: 8
205 ; CHECK-NEXT: Align: 8
206 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetY
207 ; CHECK-NEXT: ValueType: I64
208 ; CHECK-NEXT: - Size: 8
209 ; CHECK-NEXT: Align: 8
210 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetZ
211 ; CHECK-NEXT: ValueType: I64
212 ; CHECK-NEXT: - Size: 8
213 ; CHECK-NEXT: Align: 8
214 ; CHECK-NEXT: ValueKind: HiddenPrintfBuffer
215 ; CHECK-NEXT: ValueType: I8
216 ; CHECK-NEXT: AddrSpaceQual: Global
217 define amdgpu_kernel void @test_float16(<16 x float> %a)
218 !kernel_arg_addr_space !1 !kernel_arg_access_qual !2 !kernel_arg_type !14
219 !kernel_arg_base_type !14 !kernel_arg_type_qual !4 {
220 ret void
221 }
222
223 ; CHECK: - Name: test_double16
224 ; CHECK-NEXT: Language: OpenCL C
225 ; CHECK-NEXT: LanguageVersion: [ 2, 0 ]
226 ; CHECK-NEXT: Args:
227 ; CHECK-NEXT: - Size: 128
228 ; CHECK-NEXT: Align: 128
229 ; CHECK-NEXT: ValueKind: ByValue
230 ; CHECK-NEXT: ValueType: F64
231 ; CHECK-NEXT: AccQual: Default
232 ; CHECK-NEXT: TypeName: double16
233 ; CHECK-NEXT: - Size: 8
234 ; CHECK-NEXT: Align: 8
235 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetX
236 ; CHECK-NEXT: ValueType: I64
237 ; CHECK-NEXT: - Size: 8
238 ; CHECK-NEXT: Align: 8
239 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetY
240 ; CHECK-NEXT: ValueType: I64
241 ; CHECK-NEXT: - Size: 8
242 ; CHECK-NEXT: Align: 8
243 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetZ
244 ; CHECK-NEXT: ValueType: I64
245 ; CHECK-NEXT: - Size: 8
246 ; CHECK-NEXT: Align: 8
247 ; CHECK-NEXT: ValueKind: HiddenPrintfBuffer
248 ; CHECK-NEXT: ValueType: I8
249 ; CHECK-NEXT: AddrSpaceQual: Global
250 define amdgpu_kernel void @test_double16(<16 x double> %a)
251 !kernel_arg_addr_space !1 !kernel_arg_access_qual !2 !kernel_arg_type !15
252 !kernel_arg_base_type !15 !kernel_arg_type_qual !4 {
253 ret void
254 }
255
256 ; CHECK: - Name: test_pointer
257 ; CHECK-NEXT: Language: OpenCL C
258 ; CHECK-NEXT: LanguageVersion: [ 2, 0 ]
259 ; CHECK-NEXT: Args:
260 ; CHECK-NEXT: - Size: 8
261 ; CHECK-NEXT: Align: 8
262 ; CHECK-NEXT: ValueKind: GlobalBuffer
263 ; CHECK-NEXT: ValueType: I32
264 ; CHECK-NEXT: AccQual: Default
265 ; CHECK-NEXT: AddrSpaceQual: Global
266 ; CHECK-NEXT: TypeName: 'int *'
267 ; CHECK-NEXT: - Size: 8
268 ; CHECK-NEXT: Align: 8
269 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetX
270 ; CHECK-NEXT: ValueType: I64
271 ; CHECK-NEXT: - Size: 8
272 ; CHECK-NEXT: Align: 8
273 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetY
274 ; CHECK-NEXT: ValueType: I64
275 ; CHECK-NEXT: - Size: 8
276 ; CHECK-NEXT: Align: 8
277 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetZ
278 ; CHECK-NEXT: ValueType: I64
279 ; CHECK-NEXT: - Size: 8
280 ; CHECK-NEXT: Align: 8
281 ; CHECK-NEXT: ValueKind: HiddenPrintfBuffer
282 ; CHECK-NEXT: ValueType: I8
283 ; CHECK-NEXT: AddrSpaceQual: Global
284 define amdgpu_kernel void @test_pointer(i32 addrspace(1)* %a)
285 !kernel_arg_addr_space !1 !kernel_arg_access_qual !2 !kernel_arg_type !16
286 !kernel_arg_base_type !16 !kernel_arg_type_qual !4 {
287 ret void
288 }
289
290 ; CHECK: - Name: test_image
291 ; CHECK-NEXT: Language: OpenCL C
292 ; CHECK-NEXT: LanguageVersion: [ 2, 0 ]
293 ; CHECK-NEXT: Args:
294 ; CHECK-NEXT: - Size: 8
295 ; CHECK-NEXT: Align: 8
296 ; CHECK-NEXT: ValueKind: Image
297 ; CHECK-NEXT: ValueType: Struct
298 ; CHECK-NEXT: AccQual: Default
299 ; CHECK-NEXT: AddrSpaceQual: Global
300 ; CHECK-NEXT: TypeName: image2d_t
301 ; CHECK-NEXT: - Size: 8
302 ; CHECK-NEXT: Align: 8
303 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetX
304 ; CHECK-NEXT: ValueType: I64
305 ; CHECK-NEXT: - Size: 8
306 ; CHECK-NEXT: Align: 8
307 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetY
308 ; CHECK-NEXT: ValueType: I64
309 ; CHECK-NEXT: - Size: 8
310 ; CHECK-NEXT: Align: 8
311 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetZ
312 ; CHECK-NEXT: ValueType: I64
313 ; CHECK-NEXT: - Size: 8
314 ; CHECK-NEXT: Align: 8
315 ; CHECK-NEXT: ValueKind: HiddenPrintfBuffer
316 ; CHECK-NEXT: ValueType: I8
317 ; CHECK-NEXT: AddrSpaceQual: Global
318 define amdgpu_kernel void @test_image(%opencl.image2d_t addrspace(1)* %a)
319 !kernel_arg_addr_space !1 !kernel_arg_access_qual !2 !kernel_arg_type !17
320 !kernel_arg_base_type !17 !kernel_arg_type_qual !4 {
321 ret void
322 }
323
324 ; CHECK: - Name: test_sampler
325 ; CHECK-NEXT: Language: OpenCL C
326 ; CHECK-NEXT: LanguageVersion: [ 2, 0 ]
327 ; CHECK-NEXT: Args:
328 ; CHECK-NEXT: - Size: 4
329 ; CHECK-NEXT: Align: 4
330 ; CHECK-NEXT: ValueKind: Sampler
331 ; CHECK-NEXT: ValueType: I32
332 ; CHECK-NEXT: AccQual: Default
333 ; CHECK-NEXT: TypeName: sampler_t
334 ; CHECK-NEXT: - Size: 8
335 ; CHECK-NEXT: Align: 8
336 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetX
337 ; CHECK-NEXT: ValueType: I64
338 ; CHECK-NEXT: - Size: 8
339 ; CHECK-NEXT: Align: 8
340 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetY
341 ; CHECK-NEXT: ValueType: I64
342 ; CHECK-NEXT: - Size: 8
343 ; CHECK-NEXT: Align: 8
344 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetZ
345 ; CHECK-NEXT: ValueType: I64
346 ; CHECK-NEXT: - Size: 8
347 ; CHECK-NEXT: Align: 8
348 ; CHECK-NEXT: ValueKind: HiddenPrintfBuffer
349 ; CHECK-NEXT: ValueType: I8
350 ; CHECK-NEXT: AddrSpaceQual: Global
351 define amdgpu_kernel void @test_sampler(i32 %a)
352 !kernel_arg_addr_space !1 !kernel_arg_access_qual !2 !kernel_arg_type !18
353 !kernel_arg_base_type !18 !kernel_arg_type_qual !4 {
354 ret void
355 }
356
357 ; CHECK: - Name: test_queue
358 ; CHECK-NEXT: Language: OpenCL C
359 ; CHECK-NEXT: LanguageVersion: [ 2, 0 ]
360 ; CHECK-NEXT: Args:
361 ; CHECK-NEXT: - Size: 8
362 ; CHECK-NEXT: Align: 8
363 ; CHECK-NEXT: ValueKind: Queue
364 ; CHECK-NEXT: ValueType: Struct
365 ; CHECK-NEXT: AccQual: Default
366 ; CHECK-NEXT: AddrSpaceQual: Global
367 ; CHECK-NEXT: TypeName: queue_t
368 ; CHECK-NEXT: - Size: 8
369 ; CHECK-NEXT: Align: 8
370 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetX
371 ; CHECK-NEXT: ValueType: I64
372 ; CHECK-NEXT: - Size: 8
373 ; CHECK-NEXT: Align: 8
374 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetY
375 ; CHECK-NEXT: ValueType: I64
376 ; CHECK-NEXT: - Size: 8
377 ; CHECK-NEXT: Align: 8
378 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetZ
379 ; CHECK-NEXT: ValueType: I64
380 ; CHECK-NEXT: - Size: 8
381 ; CHECK-NEXT: Align: 8
382 ; CHECK-NEXT: ValueKind: HiddenPrintfBuffer
383 ; CHECK-NEXT: ValueType: I8
384 ; CHECK-NEXT: AddrSpaceQual: Global
385 define amdgpu_kernel void @test_queue(%opencl.queue_t addrspace(1)* %a)
386 !kernel_arg_addr_space !1 !kernel_arg_access_qual !2 !kernel_arg_type !19
387 !kernel_arg_base_type !19 !kernel_arg_type_qual !4 {
388 ret void
389 }
390
391 ; CHECK: - Name: test_struct
392 ; CHECK-NEXT: Language: OpenCL C
393 ; CHECK-NEXT: LanguageVersion: [ 2, 0 ]
394 ; CHECK-NEXT: Args:
395 ; CHECK-NEXT: - Size: 4
396 ; CHECK-NEXT: Align: 4
397 ; CHECK-NEXT: ValueKind: GlobalBuffer
398 ; CHECK-NEXT: ValueType: Struct
399 ; CHECK-NEXT: AccQual: Default
400 ; CHECK-NEXT: AddrSpaceQual: Private
401 ; CHECK-NEXT: TypeName: struct A
402 ; CHECK-NEXT: - Size: 8
403 ; CHECK-NEXT: Align: 8
404 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetX
405 ; CHECK-NEXT: ValueType: I64
406 ; CHECK-NEXT: - Size: 8
407 ; CHECK-NEXT: Align: 8
408 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetY
409 ; CHECK-NEXT: ValueType: I64
410 ; CHECK-NEXT: - Size: 8
411 ; CHECK-NEXT: Align: 8
412 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetZ
413 ; CHECK-NEXT: ValueType: I64
414 ; CHECK-NEXT: - Size: 8
415 ; CHECK-NEXT: Align: 8
416 ; CHECK-NEXT: ValueKind: HiddenPrintfBuffer
417 ; CHECK-NEXT: ValueType: I8
418 ; CHECK-NEXT: AddrSpaceQual: Global
419 define amdgpu_kernel void @test_struct(%struct.A* byval %a)
420 !kernel_arg_addr_space !1 !kernel_arg_access_qual !2 !kernel_arg_type !20
421 !kernel_arg_base_type !20 !kernel_arg_type_qual !4 {
422 ret void
423 }
424
425 ; CHECK: - Name: test_i128
426 ; CHECK-NEXT: Language: OpenCL C
427 ; CHECK-NEXT: LanguageVersion: [ 2, 0 ]
428 ; CHECK-NEXT: Args:
429 ; CHECK-NEXT: - Size: 16
430 ; CHECK-NEXT: Align: 8
431 ; CHECK-NEXT: ValueKind: ByValue
432 ; CHECK-NEXT: ValueType: Struct
433 ; CHECK-NEXT: AccQual: Default
434 ; CHECK-NEXT: TypeName: i128
435 ; CHECK-NEXT: - Size: 8
436 ; CHECK-NEXT: Align: 8
437 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetX
438 ; CHECK-NEXT: ValueType: I64
439 ; CHECK-NEXT: - Size: 8
440 ; CHECK-NEXT: Align: 8
441 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetY
442 ; CHECK-NEXT: ValueType: I64
443 ; CHECK-NEXT: - Size: 8
444 ; CHECK-NEXT: Align: 8
445 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetZ
446 ; CHECK-NEXT: ValueType: I64
447 ; CHECK-NEXT: - Size: 8
448 ; CHECK-NEXT: Align: 8
449 ; CHECK-NEXT: ValueKind: HiddenPrintfBuffer
450 ; CHECK-NEXT: ValueType: I8
451 ; CHECK-NEXT: AddrSpaceQual: Global
452 define amdgpu_kernel void @test_i128(i128 %a)
453 !kernel_arg_addr_space !1 !kernel_arg_access_qual !2 !kernel_arg_type !21
454 !kernel_arg_base_type !21 !kernel_arg_type_qual !4 {
455 ret void
456 }
457
458 ; CHECK: - Name: test_multi_arg
459 ; CHECK-NEXT: Language: OpenCL C
460 ; CHECK-NEXT: LanguageVersion: [ 2, 0 ]
461 ; CHECK-NEXT: Args:
462 ; CHECK-NEXT: - Size: 4
463 ; CHECK-NEXT: Align: 4
464 ; CHECK-NEXT: ValueKind: ByValue
465 ; CHECK-NEXT: ValueType: I32
466 ; CHECK-NEXT: AccQual: Default
467 ; CHECK-NEXT: TypeName: int
468 ; CHECK-NEXT: - Size: 4
469 ; CHECK-NEXT: Align: 4
470 ; CHECK-NEXT: ValueKind: ByValue
471 ; CHECK-NEXT: ValueType: I16
472 ; CHECK-NEXT: AccQual: Default
473 ; CHECK-NEXT: TypeName: short2
474 ; CHECK-NEXT: - Size: 4
475 ; CHECK-NEXT: Align: 4
476 ; CHECK-NEXT: ValueKind: ByValue
477 ; CHECK-NEXT: ValueType: I8
478 ; CHECK-NEXT: AccQual: Default
479 ; CHECK-NEXT: TypeName: char3
480 ; CHECK-NEXT: - Size: 8
481 ; CHECK-NEXT: Align: 8
482 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetX
483 ; CHECK-NEXT: ValueType: I64
484 ; CHECK-NEXT: - Size: 8
485 ; CHECK-NEXT: Align: 8
486 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetY
487 ; CHECK-NEXT: ValueType: I64
488 ; CHECK-NEXT: - Size: 8
489 ; CHECK-NEXT: Align: 8
490 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetZ
491 ; CHECK-NEXT: ValueType: I64
492 ; CHECK-NEXT: - Size: 8
493 ; CHECK-NEXT: Align: 8
494 ; CHECK-NEXT: ValueKind: HiddenPrintfBuffer
495 ; CHECK-NEXT: ValueType: I8
496 ; CHECK-NEXT: AddrSpaceQual: Global
497 define amdgpu_kernel void @test_multi_arg(i32 %a, <2 x i16> %b, <3 x i8> %c)
498 !kernel_arg_addr_space !22 !kernel_arg_access_qual !23 !kernel_arg_type !24
499 !kernel_arg_base_type !24 !kernel_arg_type_qual !25 {
500 ret void
501 }
502
503 ; CHECK: - Name: test_addr_space
504 ; CHECK-NEXT: Language: OpenCL C
505 ; CHECK-NEXT: LanguageVersion: [ 2, 0 ]
506 ; CHECK-NEXT: Args:
507 ; CHECK-NEXT: - Size: 8
508 ; CHECK-NEXT: Align: 8
509 ; CHECK-NEXT: ValueKind: GlobalBuffer
510 ; CHECK-NEXT: ValueType: I32
511 ; CHECK-NEXT: AccQual: Default
512 ; CHECK-NEXT: AddrSpaceQual: Global
513 ; CHECK-NEXT: TypeName: 'int *'
514 ; CHECK-NEXT: - Size: 8
515 ; CHECK-NEXT: Align: 8
516 ; CHECK-NEXT: ValueKind: GlobalBuffer
517 ; CHECK-NEXT: ValueType: I32
518 ; CHECK-NEXT: AccQual: Default
519 ; CHECK-NEXT: AddrSpaceQual: Constant
520 ; CHECK-NEXT: TypeName: 'int *'
521 ; CHECK-NEXT: - Size: 4
522 ; CHECK-NEXT: Align: 4
523 ; CHECK-NEXT: ValueKind: DynamicSharedPointer
524 ; CHECK-NEXT: ValueType: I32
525 ; CHECK-NEXT: PointeeAlign: 4
526 ; CHECK-NEXT: AccQual: Default
527 ; CHECK-NEXT: AddrSpaceQual: Local
528 ; CHECK-NEXT: TypeName: 'int *'
529 ; CHECK-NEXT: - Size: 8
530 ; CHECK-NEXT: Align: 8
531 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetX
532 ; CHECK-NEXT: ValueType: I64
533 ; CHECK-NEXT: - Size: 8
534 ; CHECK-NEXT: Align: 8
535 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetY
536 ; CHECK-NEXT: ValueType: I64
537 ; CHECK-NEXT: - Size: 8
538 ; CHECK-NEXT: Align: 8
539 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetZ
540 ; CHECK-NEXT: ValueType: I64
541 ; CHECK-NEXT: - Size: 8
542 ; CHECK-NEXT: Align: 8
543 ; CHECK-NEXT: ValueKind: HiddenPrintfBuffer
544 ; CHECK-NEXT: ValueType: I8
545 ; CHECK-NEXT: AddrSpaceQual: Global
546 define amdgpu_kernel void @test_addr_space(i32 addrspace(1)* %g,
547 i32 addrspace(2)* %c,
548 i32 addrspace(3)* %l)
549 !kernel_arg_addr_space !50 !kernel_arg_access_qual !23 !kernel_arg_type !51
550 !kernel_arg_base_type !51 !kernel_arg_type_qual !25 {
551 ret void
552 }
553
554 ; CHECK: - Name: test_type_qual
555 ; CHECK-NEXT: Language: OpenCL C
556 ; CHECK-NEXT: LanguageVersion: [ 2, 0 ]
557 ; CHECK-NEXT: Args:
558 ; CHECK-NEXT: - Size: 8
559 ; CHECK-NEXT: Align: 8
560 ; CHECK-NEXT: ValueKind: GlobalBuffer
561 ; CHECK-NEXT: ValueType: I32
562 ; CHECK-NEXT: AccQual: Default
563 ; CHECK-NEXT: AddrSpaceQual: Global
564 ; CHECK-NEXT: IsVolatile: true
565 ; CHECK-NEXT: TypeName: 'int *'
566 ; CHECK-NEXT: - Size: 8
567 ; CHECK-NEXT: Align: 8
568 ; CHECK-NEXT: ValueKind: GlobalBuffer
569 ; CHECK-NEXT: ValueType: I32
570 ; CHECK-NEXT: AccQual: Default
571 ; CHECK-NEXT: AddrSpaceQual: Global
572 ; CHECK-NEXT: IsConst: true
573 ; CHECK-NEXT: IsRestrict: true
574 ; CHECK-NEXT: TypeName: 'int *'
575 ; CHECK-NEXT: - Size: 8
576 ; CHECK-NEXT: Align: 8
577 ; CHECK-NEXT: ValueKind: Pipe
578 ; CHECK-NEXT: ValueType: Struct
579 ; CHECK-NEXT: AccQual: Default
580 ; CHECK-NEXT: AddrSpaceQual: Global
581 ; CHECK-NEXT: IsPipe: true
582 ; CHECK-NEXT: TypeName: 'int *'
583 ; CHECK-NEXT: - Size: 8
584 ; CHECK-NEXT: Align: 8
585 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetX
586 ; CHECK-NEXT: ValueType: I64
587 ; CHECK-NEXT: - Size: 8
588 ; CHECK-NEXT: Align: 8
589 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetY
590 ; CHECK-NEXT: ValueType: I64
591 ; CHECK-NEXT: - Size: 8
592 ; CHECK-NEXT: Align: 8
593 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetZ
594 ; CHECK-NEXT: ValueType: I64
595 ; CHECK-NEXT: - Size: 8
596 ; CHECK-NEXT: Align: 8
597 ; CHECK-NEXT: ValueKind: HiddenPrintfBuffer
598 ; CHECK-NEXT: ValueType: I8
599 ; CHECK-NEXT: AddrSpaceQual: Global
600 define amdgpu_kernel void @test_type_qual(i32 addrspace(1)* %a,
601 i32 addrspace(1)* %b,
602 %opencl.pipe_t addrspace(1)* %c)
603 !kernel_arg_addr_space !22 !kernel_arg_access_qual !23 !kernel_arg_type !51
604 !kernel_arg_base_type !51 !kernel_arg_type_qual !70 {
605 ret void
606 }
607
608 ; CHECK: - Name: test_access_qual
609 ; CHECK-NEXT: Language: OpenCL C
610 ; CHECK-NEXT: LanguageVersion: [ 2, 0 ]
611 ; CHECK-NEXT: Args:
612 ; CHECK-NEXT: - Size: 8
613 ; CHECK-NEXT: Align: 8
614 ; CHECK-NEXT: ValueKind: Image
615 ; CHECK-NEXT: ValueType: Struct
616 ; CHECK-NEXT: AccQual: ReadOnly
617 ; CHECK-NEXT: AddrSpaceQual: Global
618 ; CHECK-NEXT: TypeName: image1d_t
619 ; CHECK-NEXT: - Size: 8
620 ; CHECK-NEXT: Align: 8
621 ; CHECK-NEXT: ValueKind: Image
622 ; CHECK-NEXT: ValueType: Struct
623 ; CHECK-NEXT: AccQual: WriteOnly
624 ; CHECK-NEXT: AddrSpaceQual: Global
625 ; CHECK-NEXT: TypeName: image2d_t
626 ; CHECK-NEXT: - Size: 8
627 ; CHECK-NEXT: Align: 8
628 ; CHECK-NEXT: ValueKind: Image
629 ; CHECK-NEXT: ValueType: Struct
630 ; CHECK-NEXT: AccQual: ReadWrite
631 ; CHECK-NEXT: AddrSpaceQual: Global
632 ; CHECK-NEXT: TypeName: image3d_t
633 ; CHECK-NEXT: - Size: 8
634 ; CHECK-NEXT: Align: 8
635 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetX
636 ; CHECK-NEXT: ValueType: I64
637 ; CHECK-NEXT: - Size: 8
638 ; CHECK-NEXT: Align: 8
639 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetY
640 ; CHECK-NEXT: ValueType: I64
641 ; CHECK-NEXT: - Size: 8
642 ; CHECK-NEXT: Align: 8
643 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetZ
644 ; CHECK-NEXT: ValueType: I64
645 ; CHECK-NEXT: - Size: 8
646 ; CHECK-NEXT: Align: 8
647 ; CHECK-NEXT: ValueKind: HiddenPrintfBuffer
648 ; CHECK-NEXT: ValueType: I8
649 ; CHECK-NEXT: AddrSpaceQual: Global
650 define amdgpu_kernel void @test_access_qual(%opencl.image1d_t addrspace(1)* %ro,
651 %opencl.image2d_t addrspace(1)* %wo,
652 %opencl.image3d_t addrspace(1)* %rw)
653 !kernel_arg_addr_space !60 !kernel_arg_access_qual !61 !kernel_arg_type !62
654 !kernel_arg_base_type !62 !kernel_arg_type_qual !25 {
655 ret void
656 }
657
658 ; CHECK: - Name: test_vec_type_hint_half
659 ; CHECK-NEXT: Language: OpenCL C
660 ; CHECK-NEXT: LanguageVersion: [ 2, 0 ]
661 ; CHECK-NEXT: Attrs:
662 ; CHECK-NEXT: VecTypeHint: half
663 ; CHECK-NEXT: Args:
664 ; CHECK-NEXT: - Size: 4
665 ; CHECK-NEXT: Align: 4
666 ; CHECK-NEXT: ValueKind: ByValue
667 ; CHECK-NEXT: ValueType: I32
668 ; CHECK-NEXT: AccQual: Default
669 ; CHECK-NEXT: TypeName: int
670 ; CHECK-NEXT: - Size: 8
671 ; CHECK-NEXT: Align: 8
672 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetX
673 ; CHECK-NEXT: ValueType: I64
674 ; CHECK-NEXT: - Size: 8
675 ; CHECK-NEXT: Align: 8
676 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetY
677 ; CHECK-NEXT: ValueType: I64
678 ; CHECK-NEXT: - Size: 8
679 ; CHECK-NEXT: Align: 8
680 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetZ
681 ; CHECK-NEXT: ValueType: I64
682 ; CHECK-NEXT: - Size: 8
683 ; CHECK-NEXT: Align: 8
684 ; CHECK-NEXT: ValueKind: HiddenPrintfBuffer
685 ; CHECK-NEXT: ValueType: I8
686 ; CHECK-NEXT: AddrSpaceQual: Global
687 define amdgpu_kernel void @test_vec_type_hint_half(i32 %a)
688 !kernel_arg_addr_space !1 !kernel_arg_access_qual !2 !kernel_arg_type !3
689 !kernel_arg_base_type !3 !kernel_arg_type_qual !4 !vec_type_hint !26 {
690 ret void
691 }
692
693 ; CHECK: - Name: test_vec_type_hint_float
694 ; CHECK-NEXT: Language: OpenCL C
695 ; CHECK-NEXT: LanguageVersion: [ 2, 0 ]
696 ; CHECK-NEXT: Attrs:
697 ; CHECK-NEXT: VecTypeHint: float
698 ; CHECK-NEXT: Args:
699 ; CHECK-NEXT: - Size: 4
700 ; CHECK-NEXT: Align: 4
701 ; CHECK-NEXT: ValueKind: ByValue
702 ; CHECK-NEXT: ValueType: I32
703 ; CHECK-NEXT: AccQual: Default
704 ; CHECK-NEXT: TypeName: int
705 ; CHECK-NEXT: - Size: 8
706 ; CHECK-NEXT: Align: 8
707 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetX
708 ; CHECK-NEXT: ValueType: I64
709 ; CHECK-NEXT: - Size: 8
710 ; CHECK-NEXT: Align: 8
711 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetY
712 ; CHECK-NEXT: ValueType: I64
713 ; CHECK-NEXT: - Size: 8
714 ; CHECK-NEXT: Align: 8
715 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetZ
716 ; CHECK-NEXT: ValueType: I64
717 ; CHECK-NEXT: - Size: 8
718 ; CHECK-NEXT: Align: 8
719 ; CHECK-NEXT: ValueKind: HiddenPrintfBuffer
720 ; CHECK-NEXT: ValueType: I8
721 ; CHECK-NEXT: AddrSpaceQual: Global
722 define amdgpu_kernel void @test_vec_type_hint_float(i32 %a)
723 !kernel_arg_addr_space !1 !kernel_arg_access_qual !2 !kernel_arg_type !3
724 !kernel_arg_base_type !3 !kernel_arg_type_qual !4 !vec_type_hint !27 {
725 ret void
726 }
727
728 ; CHECK: - Name: test_vec_type_hint_double
729 ; CHECK-NEXT: Language: OpenCL C
730 ; CHECK-NEXT: LanguageVersion: [ 2, 0 ]
731 ; CHECK-NEXT: Attrs:
732 ; CHECK-NEXT: VecTypeHint: double
733 ; CHECK-NEXT: Args:
734 ; CHECK-NEXT: - Size: 4
735 ; CHECK-NEXT: Align: 4
736 ; CHECK-NEXT: ValueKind: ByValue
737 ; CHECK-NEXT: ValueType: I32
738 ; CHECK-NEXT: AccQual: Default
739 ; CHECK-NEXT: TypeName: int
740 ; CHECK-NEXT: - Size: 8
741 ; CHECK-NEXT: Align: 8
742 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetX
743 ; CHECK-NEXT: ValueType: I64
744 ; CHECK-NEXT: - Size: 8
745 ; CHECK-NEXT: Align: 8
746 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetY
747 ; CHECK-NEXT: ValueType: I64
748 ; CHECK-NEXT: - Size: 8
749 ; CHECK-NEXT: Align: 8
750 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetZ
751 ; CHECK-NEXT: ValueType: I64
752 ; CHECK-NEXT: - Size: 8
753 ; CHECK-NEXT: Align: 8
754 ; CHECK-NEXT: ValueKind: HiddenPrintfBuffer
755 ; CHECK-NEXT: ValueType: I8
756 ; CHECK-NEXT: AddrSpaceQual: Global
757 define amdgpu_kernel void @test_vec_type_hint_double(i32 %a)
758 !kernel_arg_addr_space !1 !kernel_arg_access_qual !2 !kernel_arg_type !3
759 !kernel_arg_base_type !3 !kernel_arg_type_qual !4 !vec_type_hint !28 {
760 ret void
761 }
762
763 ; CHECK: - Name: test_vec_type_hint_char
764 ; CHECK-NEXT: Language: OpenCL C
765 ; CHECK-NEXT: LanguageVersion: [ 2, 0 ]
766 ; CHECK-NEXT: Attrs:
767 ; CHECK-NEXT: VecTypeHint: char
768 ; CHECK-NEXT: Args:
769 ; CHECK-NEXT: - Size: 4
770 ; CHECK-NEXT: Align: 4
771 ; CHECK-NEXT: ValueKind: ByValue
772 ; CHECK-NEXT: ValueType: I32
773 ; CHECK-NEXT: AccQual: Default
774 ; CHECK-NEXT: TypeName: int
775 ; CHECK-NEXT: - Size: 8
776 ; CHECK-NEXT: Align: 8
777 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetX
778 ; CHECK-NEXT: ValueType: I64
779 ; CHECK-NEXT: - Size: 8
780 ; CHECK-NEXT: Align: 8
781 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetY
782 ; CHECK-NEXT: ValueType: I64
783 ; CHECK-NEXT: - Size: 8
784 ; CHECK-NEXT: Align: 8
785 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetZ
786 ; CHECK-NEXT: ValueType: I64
787 ; CHECK-NEXT: - Size: 8
788 ; CHECK-NEXT: Align: 8
789 ; CHECK-NEXT: ValueKind: HiddenPrintfBuffer
790 ; CHECK-NEXT: ValueType: I8
791 ; CHECK-NEXT: AddrSpaceQual: Global
792 define amdgpu_kernel void @test_vec_type_hint_char(i32 %a)
793 !kernel_arg_addr_space !1 !kernel_arg_access_qual !2 !kernel_arg_type !3
794 !kernel_arg_base_type !3 !kernel_arg_type_qual !4 !vec_type_hint !29 {
795 ret void
796 }
797
798 ; CHECK: - Name: test_vec_type_hint_short
799 ; CHECK-NEXT: Language: OpenCL C
800 ; CHECK-NEXT: LanguageVersion: [ 2, 0 ]
801 ; CHECK-NEXT: Attrs:
802 ; CHECK-NEXT: VecTypeHint: short
803 ; CHECK-NEXT: Args:
804 ; CHECK-NEXT: - Size: 4
805 ; CHECK-NEXT: Align: 4
806 ; CHECK-NEXT: ValueKind: ByValue
807 ; CHECK-NEXT: ValueType: I32
808 ; CHECK-NEXT: AccQual: Default
809 ; CHECK-NEXT: TypeName: int
810 ; CHECK-NEXT: - Size: 8
811 ; CHECK-NEXT: Align: 8
812 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetX
813 ; CHECK-NEXT: ValueType: I64
814 ; CHECK-NEXT: - Size: 8
815 ; CHECK-NEXT: Align: 8
816 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetY
817 ; CHECK-NEXT: ValueType: I64
818 ; CHECK-NEXT: - Size: 8
819 ; CHECK-NEXT: Align: 8
820 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetZ
821 ; CHECK-NEXT: ValueType: I64
822 ; CHECK-NEXT: - Size: 8
823 ; CHECK-NEXT: Align: 8
824 ; CHECK-NEXT: ValueKind: HiddenPrintfBuffer
825 ; CHECK-NEXT: ValueType: I8
826 ; CHECK-NEXT: AddrSpaceQual: Global
827 define amdgpu_kernel void @test_vec_type_hint_short(i32 %a)
828 !kernel_arg_addr_space !1 !kernel_arg_access_qual !2 !kernel_arg_type !3
829 !kernel_arg_base_type !3 !kernel_arg_type_qual !4 !vec_type_hint !30 {
830 ret void
831 }
832
833 ; CHECK: - Name: test_vec_type_hint_long
834 ; CHECK-NEXT: Language: OpenCL C
835 ; CHECK-NEXT: LanguageVersion: [ 2, 0 ]
836 ; CHECK-NEXT: Attrs:
837 ; CHECK-NEXT: VecTypeHint: long
838 ; CHECK-NEXT: Args:
839 ; CHECK-NEXT: - Size: 4
840 ; CHECK-NEXT: Align: 4
841 ; CHECK-NEXT: ValueKind: ByValue
842 ; CHECK-NEXT: ValueType: I32
843 ; CHECK-NEXT: AccQual: Default
844 ; CHECK-NEXT: TypeName: int
845 ; CHECK-NEXT: - Size: 8
846 ; CHECK-NEXT: Align: 8
847 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetX
848 ; CHECK-NEXT: ValueType: I64
849 ; CHECK-NEXT: - Size: 8
850 ; CHECK-NEXT: Align: 8
851 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetY
852 ; CHECK-NEXT: ValueType: I64
853 ; CHECK-NEXT: - Size: 8
854 ; CHECK-NEXT: Align: 8
855 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetZ
856 ; CHECK-NEXT: ValueType: I64
857 ; CHECK-NEXT: - Size: 8
858 ; CHECK-NEXT: Align: 8
859 ; CHECK-NEXT: ValueKind: HiddenPrintfBuffer
860 ; CHECK-NEXT: ValueType: I8
861 ; CHECK-NEXT: AddrSpaceQual: Global
862 define amdgpu_kernel void @test_vec_type_hint_long(i32 %a)
863 !kernel_arg_addr_space !1 !kernel_arg_access_qual !2 !kernel_arg_type !3
864 !kernel_arg_base_type !3 !kernel_arg_type_qual !4 !vec_type_hint !31 {
865 ret void
866 }
867
868 ; CHECK: - Name: test_vec_type_hint_unknown
869 ; CHECK-NEXT: Language: OpenCL C
870 ; CHECK-NEXT: LanguageVersion: [ 2, 0 ]
871 ; CHECK-NEXT: Attrs:
872 ; CHECK-NEXT: VecTypeHint: unknown
873 ; CHECK-NEXT: Args:
874 ; CHECK-NEXT: - Size: 4
875 ; CHECK-NEXT: Align: 4
876 ; CHECK-NEXT: ValueKind: ByValue
877 ; CHECK-NEXT: ValueType: I32
878 ; CHECK-NEXT: AccQual: Default
879 ; CHECK-NEXT: TypeName: int
880 ; CHECK-NEXT: - Size: 8
881 ; CHECK-NEXT: Align: 8
882 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetX
883 ; CHECK-NEXT: ValueType: I64
884 ; CHECK-NEXT: - Size: 8
885 ; CHECK-NEXT: Align: 8
886 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetY
887 ; CHECK-NEXT: ValueType: I64
888 ; CHECK-NEXT: - Size: 8
889 ; CHECK-NEXT: Align: 8
890 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetZ
891 ; CHECK-NEXT: ValueType: I64
892 ; CHECK-NEXT: - Size: 8
893 ; CHECK-NEXT: Align: 8
894 ; CHECK-NEXT: ValueKind: HiddenPrintfBuffer
895 ; CHECK-NEXT: ValueType: I8
896 ; CHECK-NEXT: AddrSpaceQual: Global
897 define amdgpu_kernel void @test_vec_type_hint_unknown(i32 %a)
898 !kernel_arg_addr_space !1 !kernel_arg_access_qual !2 !kernel_arg_type !3
899 !kernel_arg_base_type !3 !kernel_arg_type_qual !4 !vec_type_hint !32 {
900 ret void
901 }
902
903 ; CHECK: - Name: test_reqd_wgs_vec_type_hint
904 ; CHECK-NEXT: Language: OpenCL C
905 ; CHECK-NEXT: LanguageVersion: [ 2, 0 ]
906 ; CHECK-NEXT: Attrs:
907 ; CHECK-NEXT: ReqdWorkGroupSize: [ 1, 2, 4 ]
908 ; CHECK-NEXT: VecTypeHint: int
909 ; CHECK-NEXT: Args:
910 ; CHECK-NEXT: - Size: 4
911 ; CHECK-NEXT: Align: 4
912 ; CHECK-NEXT: ValueKind: ByValue
913 ; CHECK-NEXT: ValueType: I32
914 ; CHECK-NEXT: AccQual: Default
915 ; CHECK-NEXT: TypeName: int
916 ; CHECK-NEXT: - Size: 8
917 ; CHECK-NEXT: Align: 8
918 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetX
919 ; CHECK-NEXT: ValueType: I64
920 ; CHECK-NEXT: - Size: 8
921 ; CHECK-NEXT: Align: 8
922 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetY
923 ; CHECK-NEXT: ValueType: I64
924 ; CHECK-NEXT: - Size: 8
925 ; CHECK-NEXT: Align: 8
926 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetZ
927 ; CHECK-NEXT: ValueType: I64
928 ; CHECK-NEXT: - Size: 8
929 ; CHECK-NEXT: Align: 8
930 ; CHECK-NEXT: ValueKind: HiddenPrintfBuffer
931 ; CHECK-NEXT: ValueType: I8
932 ; CHECK-NEXT: AddrSpaceQual: Global
933 define amdgpu_kernel void @test_reqd_wgs_vec_type_hint(i32 %a)
934 !kernel_arg_addr_space !1 !kernel_arg_access_qual !2 !kernel_arg_type !3
935 !kernel_arg_base_type !3 !kernel_arg_type_qual !4 !vec_type_hint !5
936 !reqd_work_group_size !6 {
937 ret void
938 }
939
940 ; CHECK: - Name: test_wgs_hint_vec_type_hint
941 ; CHECK-NEXT: Language: OpenCL C
942 ; CHECK-NEXT: LanguageVersion: [ 2, 0 ]
943 ; CHECK-NEXT: Attrs:
944 ; CHECK-NEXT: WorkGroupSizeHint: [ 8, 16, 32 ]
945 ; CHECK-NEXT: VecTypeHint: uint4
946 ; CHECK-NEXT: Args:
947 ; CHECK-NEXT: - Size: 4
948 ; CHECK-NEXT: Align: 4
949 ; CHECK-NEXT: ValueKind: ByValue
950 ; CHECK-NEXT: ValueType: I32
951 ; CHECK-NEXT: AccQual: Default
952 ; CHECK-NEXT: TypeName: int
953 ; CHECK-NEXT: - Size: 8
954 ; CHECK-NEXT: Align: 8
955 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetX