38 ArgAlign =
DL.getABITypeAlign(Ty);
40 return std::pair(Ty, *ArgAlign);
47 EnqueuedBlock.
getMetadata(LLVMContext::MD_associated);
55 RuntimeHandle->getSection() !=
".amdgpu.kernel.runtime.handle")
61 return Name.str().str();
73 errs() <<
"AMDGPU HSA Metadata:\n" << HSAMetadataString <<
'\n';
77 errs() <<
"AMDGPU HSA Metadata Parser Test: ";
81 if (!FromHSAMetadataString.
fromYAML(HSAMetadataString)) {
86 std::string ToHSAMetadataString;
88 FromHSAMetadataString.
toYAML(StrOS);
90 errs() << (HSAMetadataString == StrOS.
str() ?
"PASS" :
"FAIL") <<
'\n';
91 if (HSAMetadataString != ToHSAMetadataString) {
92 errs() <<
"Original input: " << HSAMetadataString <<
'\n'
93 <<
"Produced output: " << StrOS.
str() <<
'\n';
97std::optional<StringRef>
100 .Case(
"read_only",
StringRef(
"read_only"))
133 .
Case(
"image1d_t",
"image")
134 .
Case(
"image1d_array_t",
"image")
135 .
Case(
"image1d_buffer_t",
"image")
136 .
Case(
"image2d_t",
"image")
137 .
Case(
"image2d_array_t",
"image")
138 .
Case(
"image2d_array_depth_t",
"image")
139 .
Case(
"image2d_array_msaa_t",
"image")
140 .
Case(
"image2d_array_msaa_depth_t",
"image")
141 .
Case(
"image2d_depth_t",
"image")
142 .
Case(
"image2d_msaa_t",
"image")
143 .
Case(
"image2d_msaa_depth_t",
"image")
144 .
Case(
"image3d_t",
"image")
145 .
Case(
"sampler_t",
"sampler")
146 .
Case(
"queue_t",
"queue")
149 ?
"dynamic_shared_pointer"
156 switch (Ty->getTypeID()) {
161 auto BitWidth = Ty->getIntegerBitWidth();
183 auto *ElTy = VecTy->getElementType();
184 auto NumElements = VecTy->getNumElements();
195 if (
Node->getNumOperands() != 3)
198 for (
auto &
Op :
Node->operands())
199 Dims.push_back(Dims.getDocument()->getNode(
217 auto *
Node =
Mod.getNamedMetadata(
"llvm.printf.fmts");
222 for (
auto *
Op :
Node->operands())
223 if (
Op->getNumOperands())
224 Printf.push_back(Printf.getDocument()->getNode(
232 auto *
Node = Func.getParent()->getNamedMetadata(
"opencl.ocl.version");
233 if (!
Node || !
Node->getNumOperands())
235 auto *Op0 =
Node->getOperand(0);
236 if (Op0->getNumOperands() <= 1)
245 Kern[
".language_version"] = LanguageVersion;
252 if (
auto *
Node = Func.getMetadata(
"reqd_work_group_size"))
254 if (
auto *
Node = Func.getMetadata(
"work_group_size_hint"))
256 if (
auto *
Node = Func.getMetadata(
"vec_type_hint")) {
265 if (!HandleName.empty()) {
266 Kern[
".device_enqueue_symbol"] =
270 if (Func.hasFnAttribute(
"device-init"))
272 else if (Func.hasFnAttribute(
"device-fini"))
281 for (
auto &Arg : Func.args()) {
282 if (Arg.hasAttribute(
"amdgpu-hidden-argument"))
290 Kern[
".args"] = Args;
301 Node = Func->getMetadata(
"kernel_arg_name");
302 if (
Node && ArgNo < Node->getNumOperands())
308 Node = Func->getMetadata(
"kernel_arg_type");
309 if (
Node && ArgNo < Node->getNumOperands())
313 Node = Func->getMetadata(
"kernel_arg_base_type");
314 if (
Node && ArgNo < Node->getNumOperands())
321 ActAccQual =
"read_only";
323 ActAccQual =
"write_only";
327 Node = Func->getMetadata(
"kernel_arg_access_qual");
328 if (
Node && ArgNo < Node->getNumOperands())
332 Node = Func->getMetadata(
"kernel_arg_type_qual");
333 if (
Node && ArgNo < Node->getNumOperands())
354 PointeeAlign, Name, TypeName, BaseTypeName, ActAccQual,
363 auto Arg = Args.getDocument()->getMapNode();
366 Arg[
".name"] = Arg.getDocument()->getNode(Name,
true);
367 if (!TypeName.empty())
368 Arg[
".type_name"] = Arg.getDocument()->getNode(TypeName,
true);
369 auto Size =
DL.getTypeAllocSize(Ty);
370 Arg[
".size"] = Arg.getDocument()->getNode(
Size);
372 Arg[
".offset"] = Arg.getDocument()->getNode(
Offset);
374 Arg[
".value_kind"] = Arg.getDocument()->getNode(
ValueKind,
true);
376 Arg[
".pointee_align"] = Arg.getDocument()->getNode(PointeeAlign->value());
382 Arg[
".address_space"] = Arg.getDocument()->getNode(*Qualifier,
386 Arg[
".access"] = Arg.getDocument()->getNode(*AQ,
true);
389 Arg[
".actual_access"] = Arg.getDocument()->getNode(*AAQ,
true);
392 TypeQual.
split(SplitTypeQuals,
" ", -1,
false);
395 Arg[
".is_const"] = Arg.getDocument()->getNode(
true);
396 else if (
Key ==
"restrict")
397 Arg[
".is_restrict"] = Arg.getDocument()->getNode(
true);
398 else if (
Key ==
"volatile")
399 Arg[
".is_volatile"] = Arg.getDocument()->getNode(
true);
400 else if (
Key ==
"pipe")
401 Arg[
".is_pipe"] = Arg.getDocument()->getNode(
true);
412 unsigned HiddenArgNumBytes = ST.getImplicitArgNumBytes(Func);
413 if (!HiddenArgNumBytes)
416 const Module *M = Func.getParent();
417 auto &
DL = M->getDataLayout();
422 if (HiddenArgNumBytes >= 8)
425 if (HiddenArgNumBytes >= 16)
428 if (HiddenArgNumBytes >= 24)
435 if (HiddenArgNumBytes >= 32) {
439 if (M->getNamedMetadata(
"llvm.printf.fmts"))
442 else if (!Func.hasFnAttribute(
"amdgpu-no-hostcall-ptr"))
451 if (HiddenArgNumBytes >= 40) {
452 if (!Func.hasFnAttribute(
"amdgpu-no-default-queue")) {
460 if (HiddenArgNumBytes >= 48) {
461 if (!Func.hasFnAttribute(
"amdgpu-no-completion-action")) {
470 if (HiddenArgNumBytes >= 56) {
471 if (!Func.hasFnAttribute(
"amdgpu-no-multigrid-sync-arg")) {
483 unsigned CodeObjectVersion)
const {
490 Align MaxKernArgAlign;
491 Kern[
".kernarg_segment_size"] = Kern.getDocument()->getNode(
493 Kern[
".group_segment_fixed_size"] =
494 Kern.getDocument()->getNode(ProgramInfo.
LDSSize);
495 DelayedExprs->assignDocNode(Kern[
".private_segment_fixed_size"],
498 DelayedExprs->assignDocNode(Kern[
".uses_dynamic_stack"],
504 Kern[
".workgroup_processor_mode"] =
505 Kern.getDocument()->getNode(ProgramInfo.
WgpMode);
508 Kern[
".kernarg_segment_align"] =
509 Kern.getDocument()->getNode(std::max(
Align(4), MaxKernArgAlign).value());
510 Kern[
".wavefront_size"] =
518 if (STM.hasMAIInsts()) {
523 Kern[
".max_flat_workgroup_size"] =
524 Kern.getDocument()->getNode(MFI.getMaxFlatWorkGroupSize());
526 uint32_t NumWGY = MFI.getMaxNumWorkGroupsY();
527 uint32_t NumWGZ = MFI.getMaxNumWorkGroupsZ();
528 uint32_t NumWGX = MFI.getMaxNumWorkGroupsX();
531 if (NumWGX != std::numeric_limits<uint32_t>::max() && NumWGX != 0)
532 Kern[
".max_num_workgroups_x"] = Kern.getDocument()->getNode(NumWGX);
534 if (NumWGY != std::numeric_limits<uint32_t>::max() && NumWGY != 0)
535 Kern[
".max_num_workgroups_y"] = Kern.getDocument()->getNode(NumWGY);
537 if (NumWGZ != std::numeric_limits<uint32_t>::max() && NumWGZ != 0)
538 Kern[
".max_num_workgroups_z"] = Kern.getDocument()->getNode(NumWGZ);
540 Kern[
".sgpr_spill_count"] =
541 Kern.getDocument()->getNode(MFI.getNumSpilledSGPRs());
542 Kern[
".vgpr_spill_count"] =
543 Kern.getDocument()->getNode(MFI.getNumSpilledVGPRs());
564 std::string HSAMetadataString;
568 if (
CLOpts.dump_hsa_metadata)
570 if (
CLOpts.verify_hsa_metadata)
581 auto CodeObjectVersion =
590 Kern[
".name"] = Kern.getDocument()->getNode(Func.getName());
591 Kern[
".symbol"] = Kern.getDocument()->getNode(
592 (
Twine(Func.getName()) +
Twine(
".kd")).str(),
true);
598 Kernels.push_back(Kern);
618 if (ST.getImplicitArgNumBytes(Func) == 0)
621 const Module *M = Func.getParent();
622 auto &
DL = M->getDataLayout();
657 if (M->getNamedMetadata(
"llvm.printf.fmts")) {
664 if (!Func.hasFnAttribute(
"amdgpu-no-hostcall-ptr")) {
671 if (!Func.hasFnAttribute(
"amdgpu-no-multigrid-sync-arg")) {
678 if (!Func.hasFnAttribute(
"amdgpu-no-heap-ptr"))
683 if (!Func.hasFnAttribute(
"amdgpu-no-default-queue")) {
690 if (!Func.hasFnAttribute(
"amdgpu-no-completion-action")) {
709 if (!ST.hasApertureRegs()) {
726 if (Func.hasFnAttribute(
"uniform-work-group-size"))
748 if (Attr.isFixedDims()) {
753 Kern[
".cluster_dims"] = ClusterDimsNode;
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
AMD GCN specific subclass of TargetSubtarget.
Module.h This file contains the declarations for the Module class.
Defines struct to track resource usage and hardware flags for kernels and entry functions.
bool isDynamicLDSUsed() const
unsigned getKernArgSegmentSize(const Function &F, Align &MaxAlign) const
unsigned getWavefrontSize() const
TargetLoweringObjectFile * getObjFileLowering() const override
virtual bool EmitHSAMetadata(msgpack::Document &HSAMetadata, bool Strict)
Emit HSA Metadata.
std::string toString() const
This class represents an incoming formal argument to a Function.
LLVM_ABI Type * getParamByRefType() const
If this is a byref argument, return its type.
LLVM_ABI bool hasNoAliasAttr() const
Return true if this argument has the noalias attribute.
LLVM_ABI bool hasByRefAttr() const
Return true if this argument has the byref attribute.
LLVM_ABI bool onlyReadsMemory() const
Return true if this argument has the readonly or readnone attribute.
LLVM_ABI bool hasAttribute(Attribute::AttrKind Kind) const
Check if an argument has a given attribute.
const Function * getParent() const
unsigned getArgNo() const
Return the index of this formal argument in its containing function.
LLVM_ABI MaybeAlign getParamAlign() const
If this is a byval or inalloca argument, return its alignment.
A parsed version of the target data layout string in and methods for querying it.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this GlobalObject.
const MDOperand & getOperand(unsigned I) const
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...
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
A Module instance is used to store all the information related to an LLVM module.
static LLVM_ABI PointerType * get(LLVMContext &C, unsigned AddressSpace)
This constructs an opaque pointer to an object in a numbered address space.
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
GCNUserSGPRUsageInfo & getUserSGPRInfo()
AMDGPU::ClusterDimsAttr getClusterDims() const
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Mangler & getMangler() const
void getNameWithPrefix(SmallVectorImpl< char > &Name, const GlobalValue *GV, Mangler &Mang, bool MayAlwaysUsePrivate=false) const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
bool isPointerTy() const
True if this is an instance of PointerType.
@ HalfTyID
16-bit floating point type
@ FloatTyID
32-bit floating point type
@ IntegerTyID
Arbitrary bit width integers.
@ FixedVectorTyID
Fixed width SIMD vector type.
@ DoubleTyID
64-bit floating point type
static LLVM_ABI IntegerType * getInt16Ty(LLVMContext &C)
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
A DocNode that is an array.
void push_back(DocNode N)
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.
LLVM_ABI void toYAML(raw_ostream &OS)
Convert MsgPack Document to YAML text.
LLVM_ABI bool fromYAML(StringRef S)
Read YAML text into the MsgPack document. Returns false on failure.
A raw_ostream that writes to an std::string.
std::string & str()
Returns the string's reference.
@ REGION_ADDRESS
Address space for region memory. (GDS)
@ LOCAL_ADDRESS
Address space for local memory.
@ CONSTANT_ADDRESS
Address space for constant memory (VTX2).
@ FLAT_ADDRESS
Address space for flat memory.
@ GLOBAL_ADDRESS
Address space for global memory (RAT0, VTX0).
@ PRIVATE_ADDRESS
Address space for private memory.
constexpr uint32_t VersionMajorV5
HSA metadata major version for code object V5.
constexpr uint32_t VersionMinorV4
HSA metadata minor version for code object V4.
constexpr uint32_t VersionMinorV5
HSA metadata minor version for code object V5.
constexpr uint32_t VersionMinorV6
HSA metadata minor version for code object V6.
constexpr uint32_t VersionMajorV6
HSA metadata major version for code object V6.
constexpr uint32_t VersionMajorV4
HSA metadata major version for code object V4.
unsigned getAMDHSACodeObjectVersion(const Module &M)
@ AMDGPU_KERNEL
Used for AMDGPU code object kernels.
@ SPIR_KERNEL
Used for SPIR kernel functions.
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_GET_TYPE_NAME_CONSTEXPR StringRef getTypeName()
We provide a function which tries to compute the (demangled) name of a type statically.
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Mod
The access may modify the value stored in memory.
DWARFExpression::Operation Op
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
This struct is a compact representation of a valid (non-zero power of two) alignment.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
Track resource usage for kernels / entry functions.
const MCExpr * NumAccVGPR
const MCExpr * DynamicCallStack
const MCExpr * ScratchSize