LLVM 17.0.0git
AMDGPUHSAMetadataStreamer.cpp
Go to the documentation of this file.
1//===--- AMDGPUHSAMetadataStreamer.cpp --------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9/// \file
10/// AMDGPU HSA Metadata Streamer.
11///
12//
13//===----------------------------------------------------------------------===//
14
16#include "AMDGPU.h"
17#include "GCNSubtarget.h"
20#include "SIProgramInfo.h"
21#include "llvm/IR/Module.h"
22using namespace llvm;
23
24static std::pair<Type *, Align> getArgumentTypeAlign(const Argument &Arg,
25 const DataLayout &DL) {
26 Type *Ty = Arg.getType();
27 MaybeAlign ArgAlign;
28 if (Arg.hasByRefAttr()) {
29 Ty = Arg.getParamByRefType();
30 ArgAlign = Arg.getParamAlign();
31 }
32
33 if (!ArgAlign)
34 ArgAlign = DL.getABITypeAlign(Ty);
35
36 return std::pair(Ty, *ArgAlign);
37}
38
39namespace llvm {
40
42 "amdgpu-dump-hsa-metadata",
43 cl::desc("Dump AMDGPU HSA Metadata"));
45 "amdgpu-verify-hsa-metadata",
46 cl::desc("Verify AMDGPU HSA Metadata"));
47
48namespace AMDGPU {
49namespace HSAMD {
50
51//===----------------------------------------------------------------------===//
52// HSAMetadataStreamerV2
53//===----------------------------------------------------------------------===//
54void MetadataStreamerYamlV2::dump(StringRef HSAMetadataString) const {
55 errs() << "AMDGPU HSA Metadata:\n" << HSAMetadataString << '\n';
56}
57
58void MetadataStreamerYamlV2::verify(StringRef HSAMetadataString) const {
59 errs() << "AMDGPU HSA Metadata Parser Test: ";
60
61 HSAMD::Metadata FromHSAMetadataString;
62 if (fromString(HSAMetadataString, FromHSAMetadataString)) {
63 errs() << "FAIL\n";
64 return;
65 }
66
67 std::string ToHSAMetadataString;
68 if (toString(FromHSAMetadataString, ToHSAMetadataString)) {
69 errs() << "FAIL\n";
70 return;
71 }
72
73 errs() << (HSAMetadataString == ToHSAMetadataString ? "PASS" : "FAIL")
74 << '\n';
75 if (HSAMetadataString != ToHSAMetadataString) {
76 errs() << "Original input: " << HSAMetadataString << '\n'
77 << "Produced output: " << ToHSAMetadataString << '\n';
78 }
79}
80
82MetadataStreamerYamlV2::getAccessQualifier(StringRef AccQual) const {
83 if (AccQual.empty())
85
86 return StringSwitch<AccessQualifier>(AccQual)
87 .Case("read_only", AccessQualifier::ReadOnly)
88 .Case("write_only", AccessQualifier::WriteOnly)
89 .Case("read_write", AccessQualifier::ReadWrite)
91}
92
94MetadataStreamerYamlV2::getAddressSpaceQualifier(unsigned AddressSpace) const {
95 switch (AddressSpace) {
108 default:
110 }
111}
112
113ValueKind MetadataStreamerYamlV2::getValueKind(Type *Ty, StringRef TypeQual,
114 StringRef BaseTypeName) const {
115 if (TypeQual.contains("pipe"))
116 return ValueKind::Pipe;
117
118 return StringSwitch<ValueKind>(BaseTypeName)
119 .Case("image1d_t", ValueKind::Image)
120 .Case("image1d_array_t", ValueKind::Image)
121 .Case("image1d_buffer_t", ValueKind::Image)
122 .Case("image2d_t", ValueKind::Image)
123 .Case("image2d_array_t", ValueKind::Image)
124 .Case("image2d_array_depth_t", ValueKind::Image)
125 .Case("image2d_array_msaa_t", ValueKind::Image)
126 .Case("image2d_array_msaa_depth_t", ValueKind::Image)
127 .Case("image2d_depth_t", ValueKind::Image)
128 .Case("image2d_msaa_t", ValueKind::Image)
129 .Case("image2d_msaa_depth_t", ValueKind::Image)
130 .Case("image3d_t", ValueKind::Image)
131 .Case("sampler_t", ValueKind::Sampler)
132 .Case("queue_t", ValueKind::Queue)
133 .Default(isa<PointerType>(Ty) ?
134 (Ty->getPointerAddressSpace() ==
139}
140
141std::string MetadataStreamerYamlV2::getTypeName(Type *Ty, bool Signed) const {
142 switch (Ty->getTypeID()) {
143 case Type::IntegerTyID: {
144 if (!Signed)
145 return (Twine('u') + getTypeName(Ty, true)).str();
146
147 auto BitWidth = Ty->getIntegerBitWidth();
148 switch (BitWidth) {
149 case 8:
150 return "char";
151 case 16:
152 return "short";
153 case 32:
154 return "int";
155 case 64:
156 return "long";
157 default:
158 return (Twine('i') + Twine(BitWidth)).str();
159 }
160 }
161 case Type::HalfTyID:
162 return "half";
163 case Type::FloatTyID:
164 return "float";
165 case Type::DoubleTyID:
166 return "double";
168 auto VecTy = cast<FixedVectorType>(Ty);
169 auto ElTy = VecTy->getElementType();
170 auto NumElements = VecTy->getNumElements();
171 return (Twine(getTypeName(ElTy, Signed)) + Twine(NumElements)).str();
172 }
173 default:
174 return "unknown";
175 }
176}
177
178std::vector<uint32_t>
179MetadataStreamerYamlV2::getWorkGroupDimensions(MDNode *Node) const {
180 std::vector<uint32_t> Dims;
181 if (Node->getNumOperands() != 3)
182 return Dims;
183
184 for (auto &Op : Node->operands())
185 Dims.push_back(mdconst::extract<ConstantInt>(Op)->getZExtValue());
186 return Dims;
187}
188
189Kernel::CodeProps::Metadata MetadataStreamerYamlV2::getHSACodeProps(
190 const MachineFunction &MF, const SIProgramInfo &ProgramInfo) const {
191 const GCNSubtarget &STM = MF.getSubtarget<GCNSubtarget>();
193 HSAMD::Kernel::CodeProps::Metadata HSACodeProps;
194 const Function &F = MF.getFunction();
195
196 assert(F.getCallingConv() == CallingConv::AMDGPU_KERNEL ||
197 F.getCallingConv() == CallingConv::SPIR_KERNEL);
198
199 Align MaxKernArgAlign;
200 HSACodeProps.mKernargSegmentSize = STM.getKernArgSegmentSize(F,
201 MaxKernArgAlign);
202 HSACodeProps.mKernargSegmentAlign =
203 std::max(MaxKernArgAlign, Align(4)).value();
204
205 HSACodeProps.mGroupSegmentFixedSize = ProgramInfo.LDSSize;
206 HSACodeProps.mPrivateSegmentFixedSize = ProgramInfo.ScratchSize;
207 HSACodeProps.mWavefrontSize = STM.getWavefrontSize();
208 HSACodeProps.mNumSGPRs = ProgramInfo.NumSGPR;
209 HSACodeProps.mNumVGPRs = ProgramInfo.NumVGPR;
210 HSACodeProps.mMaxFlatWorkGroupSize = MFI.getMaxFlatWorkGroupSize();
211 HSACodeProps.mIsDynamicCallStack = ProgramInfo.DynamicCallStack;
212 HSACodeProps.mIsXNACKEnabled = STM.isXNACKEnabled();
213 HSACodeProps.mNumSpilledSGPRs = MFI.getNumSpilledSGPRs();
214 HSACodeProps.mNumSpilledVGPRs = MFI.getNumSpilledVGPRs();
215
216 return HSACodeProps;
217}
218
219Kernel::DebugProps::Metadata MetadataStreamerYamlV2::getHSADebugProps(
220 const MachineFunction &MF, const SIProgramInfo &ProgramInfo) const {
221 return HSAMD::Kernel::DebugProps::Metadata();
222}
223
225 auto &Version = HSAMetadata.mVersion;
226
227 Version.push_back(VersionMajorV2);
228 Version.push_back(VersionMinorV2);
229}
230
231void MetadataStreamerYamlV2::emitPrintf(const Module &Mod) {
232 auto &Printf = HSAMetadata.mPrintf;
233
234 auto Node = Mod.getNamedMetadata("llvm.printf.fmts");
235 if (!Node)
236 return;
237
238 for (auto *Op : Node->operands())
239 if (Op->getNumOperands())
240 Printf.push_back(
241 std::string(cast<MDString>(Op->getOperand(0))->getString()));
242}
243
244void MetadataStreamerYamlV2::emitKernelLanguage(const Function &Func) {
245 auto &Kernel = HSAMetadata.mKernels.back();
246
247 // TODO: What about other languages?
248 auto Node = Func.getParent()->getNamedMetadata("opencl.ocl.version");
249 if (!Node || !Node->getNumOperands())
250 return;
251 auto Op0 = Node->getOperand(0);
252 if (Op0->getNumOperands() <= 1)
253 return;
254
255 Kernel.mLanguage = "OpenCL C";
256 Kernel.mLanguageVersion.push_back(
257 mdconst::extract<ConstantInt>(Op0->getOperand(0))->getZExtValue());
258 Kernel.mLanguageVersion.push_back(
259 mdconst::extract<ConstantInt>(Op0->getOperand(1))->getZExtValue());
260}
261
262void MetadataStreamerYamlV2::emitKernelAttrs(const Function &Func) {
263 auto &Attrs = HSAMetadata.mKernels.back().mAttrs;
264
265 if (auto Node = Func.getMetadata("reqd_work_group_size"))
266 Attrs.mReqdWorkGroupSize = getWorkGroupDimensions(Node);
267 if (auto Node = Func.getMetadata("work_group_size_hint"))
268 Attrs.mWorkGroupSizeHint = getWorkGroupDimensions(Node);
269 if (auto Node = Func.getMetadata("vec_type_hint")) {
270 Attrs.mVecTypeHint = getTypeName(
271 cast<ValueAsMetadata>(Node->getOperand(0))->getType(),
272 mdconst::extract<ConstantInt>(Node->getOperand(1))->getZExtValue());
273 }
274 if (Func.hasFnAttribute("runtime-handle")) {
275 Attrs.mRuntimeHandle =
276 Func.getFnAttribute("runtime-handle").getValueAsString().str();
277 }
278}
279
280void MetadataStreamerYamlV2::emitKernelArgs(const Function &Func,
281 const GCNSubtarget &ST) {
282 for (auto &Arg : Func.args())
283 emitKernelArg(Arg);
284
285 emitHiddenKernelArgs(Func, ST);
286}
287
288void MetadataStreamerYamlV2::emitKernelArg(const Argument &Arg) {
289 auto Func = Arg.getParent();
290 auto ArgNo = Arg.getArgNo();
291 const MDNode *Node;
292
294 Node = Func->getMetadata("kernel_arg_name");
295 if (Node && ArgNo < Node->getNumOperands())
296 Name = cast<MDString>(Node->getOperand(ArgNo))->getString();
297 else if (Arg.hasName())
298 Name = Arg.getName();
299
301 Node = Func->getMetadata("kernel_arg_type");
302 if (Node && ArgNo < Node->getNumOperands())
303 TypeName = cast<MDString>(Node->getOperand(ArgNo))->getString();
304
305 StringRef BaseTypeName;
306 Node = Func->getMetadata("kernel_arg_base_type");
307 if (Node && ArgNo < Node->getNumOperands())
308 BaseTypeName = cast<MDString>(Node->getOperand(ArgNo))->getString();
309
311 if (Arg.getType()->isPointerTy() && Arg.onlyReadsMemory() &&
312 Arg.hasNoAliasAttr()) {
313 AccQual = "read_only";
314 } else {
315 Node = Func->getMetadata("kernel_arg_access_qual");
316 if (Node && ArgNo < Node->getNumOperands())
317 AccQual = cast<MDString>(Node->getOperand(ArgNo))->getString();
318 }
319
320 StringRef TypeQual;
321 Node = Func->getMetadata("kernel_arg_type_qual");
322 if (Node && ArgNo < Node->getNumOperands())
323 TypeQual = cast<MDString>(Node->getOperand(ArgNo))->getString();
324
325 const DataLayout &DL = Func->getParent()->getDataLayout();
326
328 if (auto PtrTy = dyn_cast<PointerType>(Arg.getType())) {
329 if (PtrTy->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS) {
330 // FIXME: Should report this for all address spaces
331 PointeeAlign = Arg.getParamAlign().valueOrOne();
332 }
333 }
334
335 Type *ArgTy;
336 Align ArgAlign;
337 std::tie(ArgTy, ArgAlign) = getArgumentTypeAlign(Arg, DL);
338
339 emitKernelArg(DL, ArgTy, ArgAlign,
340 getValueKind(ArgTy, TypeQual, BaseTypeName), PointeeAlign, Name,
341 TypeName, BaseTypeName, AccQual, TypeQual);
342}
343
344void MetadataStreamerYamlV2::emitKernelArg(
345 const DataLayout &DL, Type *Ty, Align Alignment, ValueKind ValueKind,
346 MaybeAlign PointeeAlign, StringRef Name, StringRef TypeName,
347 StringRef BaseTypeName, StringRef AccQual, StringRef TypeQual) {
348 HSAMetadata.mKernels.back().mArgs.push_back(Kernel::Arg::Metadata());
349 auto &Arg = HSAMetadata.mKernels.back().mArgs.back();
350
351 Arg.mName = std::string(Name);
352 Arg.mTypeName = std::string(TypeName);
353 Arg.mSize = DL.getTypeAllocSize(Ty);
354 Arg.mAlign = Alignment.value();
355 Arg.mValueKind = ValueKind;
356 Arg.mPointeeAlign = PointeeAlign ? PointeeAlign->value() : 0;
357
358 if (auto PtrTy = dyn_cast<PointerType>(Ty))
359 Arg.mAddrSpaceQual = getAddressSpaceQualifier(PtrTy->getAddressSpace());
360
361 Arg.mAccQual = getAccessQualifier(AccQual);
362
363 // TODO: Emit Arg.mActualAccQual.
364
365 SmallVector<StringRef, 1> SplitTypeQuals;
366 TypeQual.split(SplitTypeQuals, " ", -1, false);
367 for (StringRef Key : SplitTypeQuals) {
368 auto P = StringSwitch<bool*>(Key)
369 .Case("const", &Arg.mIsConst)
370 .Case("restrict", &Arg.mIsRestrict)
371 .Case("volatile", &Arg.mIsVolatile)
372 .Case("pipe", &Arg.mIsPipe)
373 .Default(nullptr);
374 if (P)
375 *P = true;
376 }
377}
378
379void MetadataStreamerYamlV2::emitHiddenKernelArgs(const Function &Func,
380 const GCNSubtarget &ST) {
381 unsigned HiddenArgNumBytes = ST.getImplicitArgNumBytes(Func);
382 if (!HiddenArgNumBytes)
383 return;
384
385 auto &DL = Func.getParent()->getDataLayout();
386 auto Int64Ty = Type::getInt64Ty(Func.getContext());
387
388 if (HiddenArgNumBytes >= 8)
389 emitKernelArg(DL, Int64Ty, Align(8), ValueKind::HiddenGlobalOffsetX);
390 if (HiddenArgNumBytes >= 16)
391 emitKernelArg(DL, Int64Ty, Align(8), ValueKind::HiddenGlobalOffsetY);
392 if (HiddenArgNumBytes >= 24)
393 emitKernelArg(DL, Int64Ty, Align(8), ValueKind::HiddenGlobalOffsetZ);
394
395 auto Int8PtrTy = Type::getInt8PtrTy(Func.getContext(),
397
398 if (HiddenArgNumBytes >= 32) {
399 // We forbid the use of features requiring hostcall when compiling OpenCL
400 // before code object V5, which makes the mutual exclusion between the
401 // "printf buffer" and "hostcall buffer" here sound.
402 if (Func.getParent()->getNamedMetadata("llvm.printf.fmts"))
403 emitKernelArg(DL, Int8PtrTy, Align(8), ValueKind::HiddenPrintfBuffer);
404 else if (!Func.hasFnAttribute("amdgpu-no-hostcall-ptr"))
405 emitKernelArg(DL, Int8PtrTy, Align(8), ValueKind::HiddenHostcallBuffer);
406 else
407 emitKernelArg(DL, Int8PtrTy, Align(8), ValueKind::HiddenNone);
408 }
409
410 // Emit "default queue" and "completion action" arguments if enqueue kernel is
411 // used, otherwise emit dummy "none" arguments.
412 if (HiddenArgNumBytes >= 40) {
413 if (!Func.hasFnAttribute("amdgpu-no-default-queue")) {
414 emitKernelArg(DL, Int8PtrTy, Align(8), ValueKind::HiddenDefaultQueue);
415 } else {
416 emitKernelArg(DL, Int8PtrTy, Align(8), ValueKind::HiddenNone);
417 }
418 }
419
420 if (HiddenArgNumBytes >= 48) {
421 if (!Func.hasFnAttribute("amdgpu-no-completion-action")) {
422 emitKernelArg(DL, Int8PtrTy, Align(8), ValueKind::HiddenCompletionAction);
423 } else {
424 emitKernelArg(DL, Int8PtrTy, Align(8), ValueKind::HiddenNone);
425 }
426 }
427
428 // Emit the pointer argument for multi-grid object.
429 if (HiddenArgNumBytes >= 56) {
430 if (!Func.hasFnAttribute("amdgpu-no-multigrid-sync-arg"))
431 emitKernelArg(DL, Int8PtrTy, Align(8), ValueKind::HiddenMultiGridSyncArg);
432 else
433 emitKernelArg(DL, Int8PtrTy, Align(8), ValueKind::HiddenNone);
434 }
435}
436
438 return TargetStreamer.EmitHSAMetadata(getHSAMetadata());
439}
440
442 const IsaInfo::AMDGPUTargetID &TargetID) {
443 emitVersion();
444 emitPrintf(Mod);
445}
446
448 std::string HSAMetadataString;
449 if (toString(HSAMetadata, HSAMetadataString))
450 return;
451
452 if (DumpHSAMetadata)
453 dump(HSAMetadataString);
455 verify(HSAMetadataString);
456}
457
459 const SIProgramInfo &ProgramInfo) {
460 auto &Func = MF.getFunction();
461 if (Func.getCallingConv() != CallingConv::AMDGPU_KERNEL)
462 return;
463
464 auto CodeProps = getHSACodeProps(MF, ProgramInfo);
465 auto DebugProps = getHSADebugProps(MF, ProgramInfo);
466
467 HSAMetadata.mKernels.push_back(Kernel::Metadata());
468 auto &Kernel = HSAMetadata.mKernels.back();
469
470 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
471 Kernel.mName = std::string(Func.getName());
472 Kernel.mSymbolName = (Twine(Func.getName()) + Twine("@kd")).str();
473 emitKernelLanguage(Func);
474 emitKernelAttrs(Func);
475 emitKernelArgs(Func, ST);
476 HSAMetadata.mKernels.back().mCodeProps = CodeProps;
477 HSAMetadata.mKernels.back().mDebugProps = DebugProps;
478}
479
480//===----------------------------------------------------------------------===//
481// HSAMetadataStreamerV3
482//===----------------------------------------------------------------------===//
483
484void MetadataStreamerMsgPackV3::dump(StringRef HSAMetadataString) const {
485 errs() << "AMDGPU HSA Metadata:\n" << HSAMetadataString << '\n';
486}
487
488void MetadataStreamerMsgPackV3::verify(StringRef HSAMetadataString) const {
489 errs() << "AMDGPU HSA Metadata Parser Test: ";
490
491 msgpack::Document FromHSAMetadataString;
492
493 if (!FromHSAMetadataString.fromYAML(HSAMetadataString)) {
494 errs() << "FAIL\n";
495 return;
496 }
497
498 std::string ToHSAMetadataString;
499 raw_string_ostream StrOS(ToHSAMetadataString);
500 FromHSAMetadataString.toYAML(StrOS);
501
502 errs() << (HSAMetadataString == StrOS.str() ? "PASS" : "FAIL") << '\n';
503 if (HSAMetadataString != ToHSAMetadataString) {
504 errs() << "Original input: " << HSAMetadataString << '\n'
505 << "Produced output: " << StrOS.str() << '\n';
506 }
507}
508
509std::optional<StringRef>
512 .Case("read_only", StringRef("read_only"))
513 .Case("write_only", StringRef("write_only"))
514 .Case("read_write", StringRef("read_write"))
515 .Default(std::nullopt);
516}
517
519 unsigned AddressSpace) const {
520 switch (AddressSpace) {
522 return StringRef("private");
524 return StringRef("global");
526 return StringRef("constant");
528 return StringRef("local");
530 return StringRef("generic");
532 return StringRef("region");
533 default:
534 return std::nullopt;
535 }
536}
537
540 StringRef BaseTypeName) const {
541 if (TypeQual.contains("pipe"))
542 return "pipe";
543
544 return StringSwitch<StringRef>(BaseTypeName)
545 .Case("image1d_t", "image")
546 .Case("image1d_array_t", "image")
547 .Case("image1d_buffer_t", "image")
548 .Case("image2d_t", "image")
549 .Case("image2d_array_t", "image")
550 .Case("image2d_array_depth_t", "image")
551 .Case("image2d_array_msaa_t", "image")
552 .Case("image2d_array_msaa_depth_t", "image")
553 .Case("image2d_depth_t", "image")
554 .Case("image2d_msaa_t", "image")
555 .Case("image2d_msaa_depth_t", "image")
556 .Case("image3d_t", "image")
557 .Case("sampler_t", "sampler")
558 .Case("queue_t", "queue")
559 .Default(isa<PointerType>(Ty)
561 ? "dynamic_shared_pointer"
562 : "global_buffer")
563 : "by_value");
564}
565
567 bool Signed) const {
568 switch (Ty->getTypeID()) {
569 case Type::IntegerTyID: {
570 if (!Signed)
571 return (Twine('u') + getTypeName(Ty, true)).str();
572
573 auto BitWidth = Ty->getIntegerBitWidth();
574 switch (BitWidth) {
575 case 8:
576 return "char";
577 case 16:
578 return "short";
579 case 32:
580 return "int";
581 case 64:
582 return "long";
583 default:
584 return (Twine('i') + Twine(BitWidth)).str();
585 }
586 }
587 case Type::HalfTyID:
588 return "half";
589 case Type::FloatTyID:
590 return "float";
591 case Type::DoubleTyID:
592 return "double";
594 auto VecTy = cast<FixedVectorType>(Ty);
595 auto ElTy = VecTy->getElementType();
596 auto NumElements = VecTy->getNumElements();
597 return (Twine(getTypeName(ElTy, Signed)) + Twine(NumElements)).str();
598 }
599 default:
600 return "unknown";
601 }
602}
603
606 auto Dims = HSAMetadataDoc->getArrayNode();
607 if (Node->getNumOperands() != 3)
608 return Dims;
609
610 for (auto &Op : Node->operands())
611 Dims.push_back(Dims.getDocument()->getNode(
612 uint64_t(mdconst::extract<ConstantInt>(Op)->getZExtValue())));
613 return Dims;
614}
615
617 auto Version = HSAMetadataDoc->getArrayNode();
618 Version.push_back(Version.getDocument()->getNode(VersionMajorV3));
619 Version.push_back(Version.getDocument()->getNode(VersionMinorV3));
620 getRootMetadata("amdhsa.version") = Version;
621}
622
624 auto Node = Mod.getNamedMetadata("llvm.printf.fmts");
625 if (!Node)
626 return;
627
628 auto Printf = HSAMetadataDoc->getArrayNode();
629 for (auto *Op : Node->operands())
630 if (Op->getNumOperands())
631 Printf.push_back(Printf.getDocument()->getNode(
632 cast<MDString>(Op->getOperand(0))->getString(), /*Copy=*/true));
633 getRootMetadata("amdhsa.printf") = Printf;
634}
635
637 msgpack::MapDocNode Kern) {
638 // TODO: What about other languages?
639 auto Node = Func.getParent()->getNamedMetadata("opencl.ocl.version");
640 if (!Node || !Node->getNumOperands())
641 return;
642 auto Op0 = Node->getOperand(0);
643 if (Op0->getNumOperands() <= 1)
644 return;
645
646 Kern[".language"] = Kern.getDocument()->getNode("OpenCL C");
648 LanguageVersion.push_back(Kern.getDocument()->getNode(
649 mdconst::extract<ConstantInt>(Op0->getOperand(0))->getZExtValue()));
650 LanguageVersion.push_back(Kern.getDocument()->getNode(
651 mdconst::extract<ConstantInt>(Op0->getOperand(1))->getZExtValue()));
652 Kern[".language_version"] = LanguageVersion;
653}
654
656 msgpack::MapDocNode Kern) {
657
658 if (auto Node = Func.getMetadata("reqd_work_group_size"))
659 Kern[".reqd_workgroup_size"] = getWorkGroupDimensions(Node);
660 if (auto Node = Func.getMetadata("work_group_size_hint"))
661 Kern[".workgroup_size_hint"] = getWorkGroupDimensions(Node);
662 if (auto Node = Func.getMetadata("vec_type_hint")) {
663 Kern[".vec_type_hint"] = Kern.getDocument()->getNode(
665 cast<ValueAsMetadata>(Node->getOperand(0))->getType(),
666 mdconst::extract<ConstantInt>(Node->getOperand(1))->getZExtValue()),
667 /*Copy=*/true);
668 }
669 if (Func.hasFnAttribute("runtime-handle")) {
670 Kern[".device_enqueue_symbol"] = Kern.getDocument()->getNode(
671 Func.getFnAttribute("runtime-handle").getValueAsString().str(),
672 /*Copy=*/true);
673 }
674 if (Func.hasFnAttribute("device-init"))
675 Kern[".kind"] = Kern.getDocument()->getNode("init");
676 else if (Func.hasFnAttribute("device-fini"))
677 Kern[".kind"] = Kern.getDocument()->getNode("fini");
678}
679
681 msgpack::MapDocNode Kern) {
682 auto &Func = MF.getFunction();
683 unsigned Offset = 0;
684 auto Args = HSAMetadataDoc->getArrayNode();
685 for (auto &Arg : Func.args())
686 emitKernelArg(Arg, Offset, Args);
687
688 emitHiddenKernelArgs(MF, Offset, Args);
689
690 Kern[".args"] = Args;
691}
692
694 unsigned &Offset,
696 auto Func = Arg.getParent();
697 auto ArgNo = Arg.getArgNo();
698 const MDNode *Node;
699
701 Node = Func->getMetadata("kernel_arg_name");
702 if (Node && ArgNo < Node->getNumOperands())
703 Name = cast<MDString>(Node->getOperand(ArgNo))->getString();
704 else if (Arg.hasName())
705 Name = Arg.getName();
706
707 StringRef TypeName;
708 Node = Func->getMetadata("kernel_arg_type");
709 if (Node && ArgNo < Node->getNumOperands())
710 TypeName = cast<MDString>(Node->getOperand(ArgNo))->getString();
711
712 StringRef BaseTypeName;
713 Node = Func->getMetadata("kernel_arg_base_type");
714 if (Node && ArgNo < Node->getNumOperands())
715 BaseTypeName = cast<MDString>(Node->getOperand(ArgNo))->getString();
716
717 StringRef AccQual;
718 if (Arg.getType()->isPointerTy() && Arg.onlyReadsMemory() &&
719 Arg.hasNoAliasAttr()) {
720 AccQual = "read_only";
721 } else {
722 Node = Func->getMetadata("kernel_arg_access_qual");
723 if (Node && ArgNo < Node->getNumOperands())
724 AccQual = cast<MDString>(Node->getOperand(ArgNo))->getString();
725 }
726
727 StringRef TypeQual;
728 Node = Func->getMetadata("kernel_arg_type_qual");
729 if (Node && ArgNo < Node->getNumOperands())
730 TypeQual = cast<MDString>(Node->getOperand(ArgNo))->getString();
731
732 const DataLayout &DL = Func->getParent()->getDataLayout();
733
734 MaybeAlign PointeeAlign;
735 Type *Ty = Arg.hasByRefAttr() ? Arg.getParamByRefType() : Arg.getType();
736
737 // FIXME: Need to distinguish in memory alignment from pointer alignment.
738 if (auto PtrTy = dyn_cast<PointerType>(Ty)) {
739 if (PtrTy->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS)
740 PointeeAlign = Arg.getParamAlign().valueOrOne();
741 }
742
743 // There's no distinction between byval aggregates and raw aggregates.
744 Type *ArgTy;
745 Align ArgAlign;
746 std::tie(ArgTy, ArgAlign) = getArgumentTypeAlign(Arg, DL);
747
748 emitKernelArg(DL, ArgTy, ArgAlign,
749 getValueKind(ArgTy, TypeQual, BaseTypeName), Offset, Args,
750 PointeeAlign, Name, TypeName, BaseTypeName, AccQual, TypeQual);
751}
752
754 const DataLayout &DL, Type *Ty, Align Alignment, StringRef ValueKind,
755 unsigned &Offset, msgpack::ArrayDocNode Args, MaybeAlign PointeeAlign,
756 StringRef Name, StringRef TypeName, StringRef BaseTypeName,
757 StringRef AccQual, StringRef TypeQual) {
758 auto Arg = Args.getDocument()->getMapNode();
759
760 if (!Name.empty())
761 Arg[".name"] = Arg.getDocument()->getNode(Name, /*Copy=*/true);
762 if (!TypeName.empty())
763 Arg[".type_name"] = Arg.getDocument()->getNode(TypeName, /*Copy=*/true);
764 auto Size = DL.getTypeAllocSize(Ty);
765 Arg[".size"] = Arg.getDocument()->getNode(Size);
766 Offset = alignTo(Offset, Alignment);
767 Arg[".offset"] = Arg.getDocument()->getNode(Offset);
768 Offset += Size;
769 Arg[".value_kind"] = Arg.getDocument()->getNode(ValueKind, /*Copy=*/true);
770 if (PointeeAlign)
771 Arg[".pointee_align"] = Arg.getDocument()->getNode(PointeeAlign->value());
772
773 if (auto PtrTy = dyn_cast<PointerType>(Ty))
774 if (auto Qualifier = getAddressSpaceQualifier(PtrTy->getAddressSpace()))
775 // Limiting address space to emit only for a certain ValueKind.
776 if (ValueKind == "global_buffer" || ValueKind == "dynamic_shared_pointer")
777 Arg[".address_space"] = Arg.getDocument()->getNode(*Qualifier,
778 /*Copy=*/true);
779
780 if (auto AQ = getAccessQualifier(AccQual))
781 Arg[".access"] = Arg.getDocument()->getNode(*AQ, /*Copy=*/true);
782
783 // TODO: Emit Arg[".actual_access"].
784
785 SmallVector<StringRef, 1> SplitTypeQuals;
786 TypeQual.split(SplitTypeQuals, " ", -1, false);
787 for (StringRef Key : SplitTypeQuals) {
788 if (Key == "const")
789 Arg[".is_const"] = Arg.getDocument()->getNode(true);
790 else if (Key == "restrict")
791 Arg[".is_restrict"] = Arg.getDocument()->getNode(true);
792 else if (Key == "volatile")
793 Arg[".is_volatile"] = Arg.getDocument()->getNode(true);
794 else if (Key == "pipe")
795 Arg[".is_pipe"] = Arg.getDocument()->getNode(true);
796 }
797
798 Args.push_back(Arg);
799}
800
802 const MachineFunction &MF, unsigned &Offset, msgpack::ArrayDocNode Args) {
803 auto &Func = MF.getFunction();
804 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
805
806 unsigned HiddenArgNumBytes = ST.getImplicitArgNumBytes(Func);
807 if (!HiddenArgNumBytes)
808 return;
809
810 const Module *M = Func.getParent();
811 auto &DL = M->getDataLayout();
812 auto Int64Ty = Type::getInt64Ty(Func.getContext());
813
814 Offset = alignTo(Offset, ST.getAlignmentForImplicitArgPtr());
815
816 if (HiddenArgNumBytes >= 8)
817 emitKernelArg(DL, Int64Ty, Align(8), "hidden_global_offset_x", Offset,
818 Args);
819 if (HiddenArgNumBytes >= 16)
820 emitKernelArg(DL, Int64Ty, Align(8), "hidden_global_offset_y", Offset,
821 Args);
822 if (HiddenArgNumBytes >= 24)
823 emitKernelArg(DL, Int64Ty, Align(8), "hidden_global_offset_z", Offset,
824 Args);
825
826 auto Int8PtrTy =
828
829 if (HiddenArgNumBytes >= 32) {
830 // We forbid the use of features requiring hostcall when compiling OpenCL
831 // before code object V5, which makes the mutual exclusion between the
832 // "printf buffer" and "hostcall buffer" here sound.
833 if (M->getNamedMetadata("llvm.printf.fmts"))
834 emitKernelArg(DL, Int8PtrTy, Align(8), "hidden_printf_buffer", Offset,
835 Args);
836 else if (!Func.hasFnAttribute("amdgpu-no-hostcall-ptr"))
837 emitKernelArg(DL, Int8PtrTy, Align(8), "hidden_hostcall_buffer", Offset,
838 Args);
839 else
840 emitKernelArg(DL, Int8PtrTy, Align(8), "hidden_none", Offset, Args);
841 }
842
843 // Emit "default queue" and "completion action" arguments if enqueue kernel is
844 // used, otherwise emit dummy "none" arguments.
845 if (HiddenArgNumBytes >= 40) {
846 if (!Func.hasFnAttribute("amdgpu-no-default-queue")) {
847 emitKernelArg(DL, Int8PtrTy, Align(8), "hidden_default_queue", Offset,
848 Args);
849 } else {
850 emitKernelArg(DL, Int8PtrTy, Align(8), "hidden_none", Offset, Args);
851 }
852 }
853
854 if (HiddenArgNumBytes >= 48) {
855 if (!Func.hasFnAttribute("amdgpu-no-completion-action")) {
856 emitKernelArg(DL, Int8PtrTy, Align(8), "hidden_completion_action", Offset,
857 Args);
858 } else {
859 emitKernelArg(DL, Int8PtrTy, Align(8), "hidden_none", Offset, Args);
860 }
861 }
862
863 // Emit the pointer argument for multi-grid object.
864 if (HiddenArgNumBytes >= 56) {
865 if (!Func.hasFnAttribute("amdgpu-no-multigrid-sync-arg")) {
866 emitKernelArg(DL, Int8PtrTy, Align(8), "hidden_multigrid_sync_arg", Offset,
867 Args);
868 } else {
869 emitKernelArg(DL, Int8PtrTy, Align(8), "hidden_none", Offset, Args);
870 }
871 }
872}
873
875 const MachineFunction &MF, const SIProgramInfo &ProgramInfo,
876 unsigned CodeObjectVersion) const {
877 const GCNSubtarget &STM = MF.getSubtarget<GCNSubtarget>();
879 const Function &F = MF.getFunction();
880
881 auto Kern = HSAMetadataDoc->getMapNode();
882
883 Align MaxKernArgAlign;
884 Kern[".kernarg_segment_size"] = Kern.getDocument()->getNode(
885 STM.getKernArgSegmentSize(F, MaxKernArgAlign));
886 Kern[".group_segment_fixed_size"] =
887 Kern.getDocument()->getNode(ProgramInfo.LDSSize);
888 Kern[".private_segment_fixed_size"] =
889 Kern.getDocument()->getNode(ProgramInfo.ScratchSize);
890 if (CodeObjectVersion >= AMDGPU::AMDHSA_COV5)
891 Kern[".uses_dynamic_stack"] =
892 Kern.getDocument()->getNode(ProgramInfo.DynamicCallStack);
893
894 if (CodeObjectVersion >= AMDGPU::AMDHSA_COV5 && STM.supportsWGP())
895 Kern[".workgroup_processor_mode"] =
896 Kern.getDocument()->getNode(ProgramInfo.WgpMode);
897
898 // FIXME: The metadata treats the minimum as 16?
899 Kern[".kernarg_segment_align"] =
900 Kern.getDocument()->getNode(std::max(Align(4), MaxKernArgAlign).value());
901 Kern[".wavefront_size"] =
902 Kern.getDocument()->getNode(STM.getWavefrontSize());
903 Kern[".sgpr_count"] = Kern.getDocument()->getNode(ProgramInfo.NumSGPR);
904 Kern[".vgpr_count"] = Kern.getDocument()->getNode(ProgramInfo.NumVGPR);
905
906 // Only add AGPR count to metadata for supported devices
907 if (STM.hasMAIInsts()) {
908 Kern[".agpr_count"] = Kern.getDocument()->getNode(ProgramInfo.NumAccVGPR);
909 }
910
911 Kern[".max_flat_workgroup_size"] =
912 Kern.getDocument()->getNode(MFI.getMaxFlatWorkGroupSize());
913 Kern[".sgpr_spill_count"] =
914 Kern.getDocument()->getNode(MFI.getNumSpilledSGPRs());
915 Kern[".vgpr_spill_count"] =
916 Kern.getDocument()->getNode(MFI.getNumSpilledVGPRs());
917
918 return Kern;
919}
920
922 return TargetStreamer.EmitHSAMetadata(*HSAMetadataDoc, true);
923}
924
926 const IsaInfo::AMDGPUTargetID &TargetID) {
927 emitVersion();
929 getRootMetadata("amdhsa.kernels") = HSAMetadataDoc->getArrayNode();
930}
931
933 std::string HSAMetadataString;
934 raw_string_ostream StrOS(HSAMetadataString);
935 HSAMetadataDoc->toYAML(StrOS);
936
937 if (DumpHSAMetadata)
938 dump(StrOS.str());
940 verify(StrOS.str());
941}
942
944 const SIProgramInfo &ProgramInfo) {
945 auto &Func = MF.getFunction();
946 auto CodeObjectVersion = AMDGPU::getCodeObjectVersion(*Func.getParent());
947 auto Kern = getHSAKernelProps(MF, ProgramInfo, CodeObjectVersion);
948
949 assert(Func.getCallingConv() == CallingConv::AMDGPU_KERNEL ||
950 Func.getCallingConv() == CallingConv::SPIR_KERNEL);
951
952 auto Kernels =
953 getRootMetadata("amdhsa.kernels").getArray(/*Convert=*/true);
954
955 {
956 Kern[".name"] = Kern.getDocument()->getNode(Func.getName());
957 Kern[".symbol"] = Kern.getDocument()->getNode(
958 (Twine(Func.getName()) + Twine(".kd")).str(), /*Copy=*/true);
959 emitKernelLanguage(Func, Kern);
960 emitKernelAttrs(Func, Kern);
961 emitKernelArgs(MF, Kern);
962 }
963
964 Kernels.push_back(Kern);
965}
966
967//===----------------------------------------------------------------------===//
968// HSAMetadataStreamerV4
969//===----------------------------------------------------------------------===//
970
972 auto Version = HSAMetadataDoc->getArrayNode();
973 Version.push_back(Version.getDocument()->getNode(VersionMajorV4));
974 Version.push_back(Version.getDocument()->getNode(VersionMinorV4));
975 getRootMetadata("amdhsa.version") = Version;
976}
977
979 const IsaInfo::AMDGPUTargetID &TargetID) {
980 getRootMetadata("amdhsa.target") =
981 HSAMetadataDoc->getNode(TargetID.toString(), /*Copy=*/true);
982}
983
985 const IsaInfo::AMDGPUTargetID &TargetID) {
986 emitVersion();
987 emitTargetID(TargetID);
989 getRootMetadata("amdhsa.kernels") = HSAMetadataDoc->getArrayNode();
990}
991
992//===----------------------------------------------------------------------===//
993// HSAMetadataStreamerV5
994//===----------------------------------------------------------------------===//
995
997 auto Version = HSAMetadataDoc->getArrayNode();
998 Version.push_back(Version.getDocument()->getNode(VersionMajorV5));
999 Version.push_back(Version.getDocument()->getNode(VersionMinorV5));
1000 getRootMetadata("amdhsa.version") = Version;
1001}
1002
1004 const MachineFunction &MF, unsigned &Offset, msgpack::ArrayDocNode Args) {
1005 auto &Func = MF.getFunction();
1006 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
1007
1008 // No implicit kernel argument is used.
1009 if (ST.getImplicitArgNumBytes(Func) == 0)
1010 return;
1011
1012 const Module *M = Func.getParent();
1013 auto &DL = M->getDataLayout();
1015
1016 auto Int64Ty = Type::getInt64Ty(Func.getContext());
1017 auto Int32Ty = Type::getInt32Ty(Func.getContext());
1018 auto Int16Ty = Type::getInt16Ty(Func.getContext());
1019
1020 Offset = alignTo(Offset, ST.getAlignmentForImplicitArgPtr());
1021 emitKernelArg(DL, Int32Ty, Align(4), "hidden_block_count_x", Offset, Args);
1022 emitKernelArg(DL, Int32Ty, Align(4), "hidden_block_count_y", Offset, Args);
1023 emitKernelArg(DL, Int32Ty, Align(4), "hidden_block_count_z", Offset, Args);
1024
1025 emitKernelArg(DL, Int16Ty, Align(2), "hidden_group_size_x", Offset, Args);
1026 emitKernelArg(DL, Int16Ty, Align(2), "hidden_group_size_y", Offset, Args);
1027 emitKernelArg(DL, Int16Ty, Align(2), "hidden_group_size_z", Offset, Args);
1028
1029 emitKernelArg(DL, Int16Ty, Align(2), "hidden_remainder_x", Offset, Args);
1030 emitKernelArg(DL, Int16Ty, Align(2), "hidden_remainder_y", Offset, Args);
1031 emitKernelArg(DL, Int16Ty, Align(2), "hidden_remainder_z", Offset, Args);
1032
1033 // Reserved for hidden_tool_correlation_id.
1034 Offset += 8;
1035
1036 Offset += 8; // Reserved.
1037
1038 emitKernelArg(DL, Int64Ty, Align(8), "hidden_global_offset_x", Offset, Args);
1039 emitKernelArg(DL, Int64Ty, Align(8), "hidden_global_offset_y", Offset, Args);
1040 emitKernelArg(DL, Int64Ty, Align(8), "hidden_global_offset_z", Offset, Args);
1041
1042 emitKernelArg(DL, Int16Ty, Align(2), "hidden_grid_dims", Offset, Args);
1043
1044 Offset += 6; // Reserved.
1045 auto Int8PtrTy =
1046 Type::getInt8PtrTy(Func.getContext(), AMDGPUAS::GLOBAL_ADDRESS);
1047
1048 if (M->getNamedMetadata("llvm.printf.fmts")) {
1049 emitKernelArg(DL, Int8PtrTy, Align(8), "hidden_printf_buffer", Offset,
1050 Args);
1051 } else {
1052 Offset += 8; // Skipped.
1053 }
1054
1055 if (!Func.hasFnAttribute("amdgpu-no-hostcall-ptr")) {
1056 emitKernelArg(DL, Int8PtrTy, Align(8), "hidden_hostcall_buffer", Offset,
1057 Args);
1058 } else {
1059 Offset += 8; // Skipped.
1060 }
1061
1062 if (!Func.hasFnAttribute("amdgpu-no-multigrid-sync-arg")) {
1063 emitKernelArg(DL, Int8PtrTy, Align(8), "hidden_multigrid_sync_arg", Offset,
1064 Args);
1065 } else {
1066 Offset += 8; // Skipped.
1067 }
1068
1069 if (!Func.hasFnAttribute("amdgpu-no-heap-ptr"))
1070 emitKernelArg(DL, Int8PtrTy, Align(8), "hidden_heap_v1", Offset, Args);
1071 else
1072 Offset += 8; // Skipped.
1073
1074 if (!Func.hasFnAttribute("amdgpu-no-default-queue")) {
1075 emitKernelArg(DL, Int8PtrTy, Align(8), "hidden_default_queue", Offset,
1076 Args);
1077 } else {
1078 Offset += 8; // Skipped.
1079 }
1080
1081 if (!Func.hasFnAttribute("amdgpu-no-completion-action")) {
1082 emitKernelArg(DL, Int8PtrTy, Align(8), "hidden_completion_action", Offset,
1083 Args);
1084 } else {
1085 Offset += 8; // Skipped.
1086 }
1087
1088 Offset += 72; // Reserved.
1089
1090 // hidden_private_base and hidden_shared_base are only when the subtarget has
1091 // ApertureRegs.
1092 if (!ST.hasApertureRegs()) {
1093 emitKernelArg(DL, Int32Ty, Align(4), "hidden_private_base", Offset, Args);
1094 emitKernelArg(DL, Int32Ty, Align(4), "hidden_shared_base", Offset, Args);
1095 } else {
1096 Offset += 8; // Skipped.
1097 }
1098
1099 if (MFI.hasQueuePtr())
1100 emitKernelArg(DL, Int8PtrTy, Align(8), "hidden_queue_ptr", Offset, Args);
1101}
1102
1104 msgpack::MapDocNode Kern) {
1106
1107 if (Func.getFnAttribute("uniform-work-group-size").getValueAsBool())
1108 Kern[".uniform_work_group_size"] = Kern.getDocument()->getNode(1);
1109}
1110
1111
1112} // end namespace HSAMD
1113} // end namespace AMDGPU
1114} // end namespace llvm
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static std::pair< Type *, Align > getArgumentTypeAlign(const Argument &Arg, const DataLayout &DL)
AMDGPU HSA Metadata Streamer.
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
Given that RA is a live value
std::string Name
uint64_t Size
AMD GCN specific subclass of TargetSubtarget.
#define F(x, y, z)
Definition: MD5.cpp:55
Module.h This file contains the declarations for the Module class.
IntegerType * Int32Ty
#define P(N)
ppc ctr loops verify
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Defines struct to track resource usage and hardware flags for kernels and entry functions.
unsigned getKernArgSegmentSize(const Function &F, Align &MaxAlign) const
unsigned getWavefrontSize() const
virtual bool EmitHSAMetadata(msgpack::Document &HSAMetadata, bool Strict)
Emit HSA Metadata.
void emitHiddenKernelArgs(const MachineFunction &MF, unsigned &Offset, msgpack::ArrayDocNode Args) override
void emitKernelArgs(const MachineFunction &MF, msgpack::MapDocNode Kern)
std::string getTypeName(Type *Ty, bool Signed) const
void begin(const Module &Mod, const IsaInfo::AMDGPUTargetID &TargetID) override
bool emitTo(AMDGPUTargetStreamer &TargetStreamer) override
void emitKernel(const MachineFunction &MF, const SIProgramInfo &ProgramInfo) override
std::unique_ptr< msgpack::Document > HSAMetadataDoc
void emitKernelAttrs(const Function &Func, msgpack::MapDocNode Kern) override
StringRef getValueKind(Type *Ty, StringRef TypeQual, StringRef BaseTypeName) const
std::optional< StringRef > getAccessQualifier(StringRef AccQual) const
void verify(StringRef HSAMetadataString) const
void emitKernelLanguage(const Function &Func, msgpack::MapDocNode Kern)
void emitKernelArg(const Argument &Arg, unsigned &Offset, msgpack::ArrayDocNode Args)
msgpack::ArrayDocNode getWorkGroupDimensions(MDNode *Node) const
std::optional< StringRef > getAddressSpaceQualifier(unsigned AddressSpace) const
msgpack::MapDocNode getHSAKernelProps(const MachineFunction &MF, const SIProgramInfo &ProgramInfo, unsigned CodeObjectVersion) const
void begin(const Module &Mod, const IsaInfo::AMDGPUTargetID &TargetID) override
void emitTargetID(const IsaInfo::AMDGPUTargetID &TargetID)
void emitHiddenKernelArgs(const MachineFunction &MF, unsigned &Offset, msgpack::ArrayDocNode Args) override
void emitKernelAttrs(const Function &Func, msgpack::MapDocNode Kern) override
void emitKernel(const MachineFunction &MF, const SIProgramInfo &ProgramInfo) override
void begin(const Module &Mod, const IsaInfo::AMDGPUTargetID &TargetID) override
bool emitTo(AMDGPUTargetStreamer &TargetStreamer) override
This class represents an incoming formal argument to a Function.
Definition: Argument.h:28
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:110
bool hasMAIInsts() const
Definition: GCNSubtarget.h:754
bool supportsWGP() const
Definition: GCNSubtarget.h:313
bool isXNACKEnabled() const
Definition: GCNSubtarget.h:565
Metadata node.
Definition: Metadata.h:950
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:704
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
Definition: StringRef.h:428
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:69
R Default(T Value)
Definition: StringSwitch.h:182
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
unsigned getIntegerBitWidth() const
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
@ HalfTyID
16-bit floating point type
Definition: Type.h:56
@ FloatTyID
32-bit floating point type
Definition: Type.h:58
@ IntegerTyID
Arbitrary bit width integers.
Definition: Type.h:71
@ FixedVectorTyID
Fixed width SIMD vector type.
Definition: Type.h:76
@ DoubleTyID
64-bit floating point type
Definition: Type.h:59
static IntegerType * getInt16Ty(LLVMContext &C)
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
static IntegerType * getInt32Ty(LLVMContext &C)
static IntegerType * getInt64Ty(LLVMContext &C)
TypeID getTypeID() const
Return the type id for the type.
Definition: Type.h:137
A DocNode that is an array.
ArrayDocNode & getArray(bool Convert=false)
Get an ArrayDocNode for an array node.
Document * getDocument() const
Simple in-memory representation of a document of msgpack objects with ability to find and create arra...
DocNode getNode()
Create a nil node associated with this Document.
ArrayDocNode getArrayNode()
Create an empty Array node associated with this Document.
void toYAML(raw_ostream &OS)
Convert MsgPack Document to YAML text.
bool fromYAML(StringRef S)
Read YAML text into the MsgPack document. Returns false on failure.
A DocNode that is a map.
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:642
std::string & str()
Returns the string's reference.
Definition: raw_ostream.h:660
unsigned LanguageVersion(SourceLanguage L)
Definition: Dwarf.cpp:346
@ REGION_ADDRESS
Address space for region memory. (GDS)
Definition: AMDGPU.h:390
@ LOCAL_ADDRESS
Address space for local memory.
Definition: AMDGPU.h:393
@ CONSTANT_ADDRESS
Address space for constant memory (VTX2).
Definition: AMDGPU.h:392
@ FLAT_ADDRESS
Address space for flat memory.
Definition: AMDGPU.h:388
@ GLOBAL_ADDRESS
Address space for global memory (RAT0, VTX0).
Definition: AMDGPU.h:389
@ PRIVATE_ADDRESS
Address space for private memory.
Definition: AMDGPU.h:394
constexpr char PointeeAlign[]
Key for Kernel::Arg::Metadata::mPointeeAlign.
constexpr char TypeName[]
Key for Kernel::Arg::Metadata::mTypeName.
constexpr char AccQual[]
Key for Kernel::Arg::Metadata::mAccQual.
std::error_code fromString(StringRef String, Metadata &HSAMetadata)
Converts String to HSAMetadata.
constexpr uint32_t VersionMajorV5
HSA metadata major version for code object V5.
constexpr uint32_t VersionMinorV4
HSA metadata minor version for code object V4.
AddressSpaceQualifier
Address space qualifiers.
ValueKind
Value kinds.
std::error_code toString(Metadata HSAMetadata, std::string &String)
Converts HSAMetadata to String.
constexpr uint32_t VersionMajorV3
HSA metadata major version for code object V3.
constexpr uint32_t VersionMinorV5
HSA metadata minor version for code object V5.
constexpr uint32_t VersionMinorV3
HSA metadata minor version for code object V3.
constexpr uint32_t VersionMajorV2
HSA metadata major version for code object V2.
constexpr uint32_t VersionMinorV2
HSA metadata minor version for code object V2.
AccessQualifier
Access qualifiers.
constexpr uint32_t VersionMajorV4
HSA metadata major version for code object V4.
unsigned getCodeObjectVersion(const Module &M)
@ AMDGPU_KERNEL
Used for AMDGPU code object kernels.
Definition: CallingConv.h:197
@ SPIR_KERNEL
Used for SPIR kernel functions.
Definition: CallingConv.h:141
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:440
static cl::opt< bool > VerifyHSAMetadata("amdgpu-verify-hsa-metadata", cl::desc("Verify AMDGPU HSA Metadata"))
AddressSpace
Definition: NVPTXBaseInfo.h:21
static cl::opt< bool > DumpHSAMetadata("amdgpu-dump-hsa-metadata", cl::desc("Dump AMDGPU HSA Metadata"))
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
StringRef getTypeName()
We provide a function which tries to compute the (demangled) name of a type statically.
Definition: TypeName.h:27
@ Mod
The access may modify the value stored in memory.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
constexpr unsigned BitWidth
Definition: BitmaskEnum.h:184
In-memory representation of kernel metadata.
std::vector< Kernel::Metadata > mKernels
Kernels metadata. Required.
std::vector< uint32_t > mVersion
HSA metadata version. Required.
std::vector< std::string > mPrintf
Printf metadata. Optional.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition: Alignment.h:117
Track resource usage for kernels / entry functions.
Definition: SIProgramInfo.h:25