blob: 402324fe6a721ee7d33e54fb9cc97fb96e692120 [file] [log] [blame]
Konstantin Zhuravlyova63b0f92017-10-11 22:18:53 +00001//===--- AMDGPUHSAMetadataStreamer.cpp --------------------------*- C++ -*-===//
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10/// \file
Adrian Prantl5f8f34e42018-05-01 15:54:18 +000011/// AMDGPU HSA Metadata Streamer.
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000012///
13//
14//===----------------------------------------------------------------------===//
15
Konstantin Zhuravlyova63b0f92017-10-11 22:18:53 +000016#include "AMDGPUHSAMetadataStreamer.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000017#include "AMDGPU.h"
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000018#include "llvm/ADT/StringSwitch.h"
19#include "llvm/IR/Constants.h"
20#include "llvm/IR/Module.h"
Konstantin Zhuravlyov1e2b8782017-06-06 18:35:50 +000021#include "llvm/Support/raw_ostream.h"
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000022
23namespace llvm {
24
Konstantin Zhuravlyova63b0f92017-10-11 22:18:53 +000025static cl::opt<bool> DumpHSAMetadata(
26 "amdgpu-dump-hsa-metadata",
27 cl::desc("Dump AMDGPU HSA Metadata"));
28static cl::opt<bool> VerifyHSAMetadata(
29 "amdgpu-verify-hsa-metadata",
30 cl::desc("Verify AMDGPU HSA Metadata"));
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000031
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000032namespace AMDGPU {
Konstantin Zhuravlyova63b0f92017-10-11 22:18:53 +000033namespace HSAMD {
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000034
Konstantin Zhuravlyov516651b2017-10-11 22:59:35 +000035void MetadataStreamer::dump(StringRef HSAMetadataString) const {
36 errs() << "AMDGPU HSA Metadata:\n" << HSAMetadataString << '\n';
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000037}
38
Konstantin Zhuravlyov516651b2017-10-11 22:59:35 +000039void MetadataStreamer::verify(StringRef HSAMetadataString) const {
Konstantin Zhuravlyova63b0f92017-10-11 22:18:53 +000040 errs() << "AMDGPU HSA Metadata Parser Test: ";
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000041
Konstantin Zhuravlyov516651b2017-10-11 22:59:35 +000042 HSAMD::Metadata FromHSAMetadataString;
43 if (fromString(HSAMetadataString, FromHSAMetadataString)) {
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000044 errs() << "FAIL\n";
45 return;
46 }
47
Konstantin Zhuravlyov516651b2017-10-11 22:59:35 +000048 std::string ToHSAMetadataString;
49 if (toString(FromHSAMetadataString, ToHSAMetadataString)) {
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000050 errs() << "FAIL\n";
51 return;
52 }
53
Konstantin Zhuravlyov516651b2017-10-11 22:59:35 +000054 errs() << (HSAMetadataString == ToHSAMetadataString ? "PASS" : "FAIL")
55 << '\n';
56 if (HSAMetadataString != ToHSAMetadataString) {
57 errs() << "Original input: " << HSAMetadataString << '\n'
58 << "Produced output: " << ToHSAMetadataString << '\n';
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000059 }
60}
61
62AccessQualifier MetadataStreamer::getAccessQualifier(StringRef AccQual) const {
63 if (AccQual.empty())
64 return AccessQualifier::Unknown;
65
66 return StringSwitch<AccessQualifier>(AccQual)
67 .Case("read_only", AccessQualifier::ReadOnly)
68 .Case("write_only", AccessQualifier::WriteOnly)
69 .Case("read_write", AccessQualifier::ReadWrite)
70 .Default(AccessQualifier::Default);
71}
72
73AddressSpaceQualifier MetadataStreamer::getAddressSpaceQualifer(
74 unsigned AddressSpace) const {
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000075 if (AddressSpace == AMDGPUASI.PRIVATE_ADDRESS)
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000076 return AddressSpaceQualifier::Private;
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000077 if (AddressSpace == AMDGPUASI.GLOBAL_ADDRESS)
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000078 return AddressSpaceQualifier::Global;
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000079 if (AddressSpace == AMDGPUASI.CONSTANT_ADDRESS)
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000080 return AddressSpaceQualifier::Constant;
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000081 if (AddressSpace == AMDGPUASI.LOCAL_ADDRESS)
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000082 return AddressSpaceQualifier::Local;
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000083 if (AddressSpace == AMDGPUASI.FLAT_ADDRESS)
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000084 return AddressSpaceQualifier::Generic;
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000085 if (AddressSpace == AMDGPUASI.REGION_ADDRESS)
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000086 return AddressSpaceQualifier::Region;
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000087
88 llvm_unreachable("Unknown address space qualifier");
89}
90
91ValueKind MetadataStreamer::getValueKind(Type *Ty, StringRef TypeQual,
92 StringRef BaseTypeName) const {
93 if (TypeQual.find("pipe") != StringRef::npos)
94 return ValueKind::Pipe;
95
96 return StringSwitch<ValueKind>(BaseTypeName)
Konstantin Zhuravlyov54ba4312017-04-25 20:38:26 +000097 .Case("image1d_t", ValueKind::Image)
98 .Case("image1d_array_t", ValueKind::Image)
99 .Case("image1d_buffer_t", ValueKind::Image)
100 .Case("image2d_t", ValueKind::Image)
101 .Case("image2d_array_t", ValueKind::Image)
102 .Case("image2d_array_depth_t", ValueKind::Image)
103 .Case("image2d_array_msaa_t", ValueKind::Image)
104 .Case("image2d_array_msaa_depth_t", ValueKind::Image)
105 .Case("image2d_depth_t", ValueKind::Image)
106 .Case("image2d_msaa_t", ValueKind::Image)
107 .Case("image2d_msaa_depth_t", ValueKind::Image)
108 .Case("image3d_t", ValueKind::Image)
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000109 .Case("sampler_t", ValueKind::Sampler)
110 .Case("queue_t", ValueKind::Queue)
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000111 .Default(isa<PointerType>(Ty) ?
112 (Ty->getPointerAddressSpace() ==
Yaxun Liu1a14bfa2017-03-27 14:04:01 +0000113 AMDGPUASI.LOCAL_ADDRESS ?
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000114 ValueKind::DynamicSharedPointer :
115 ValueKind::GlobalBuffer) :
116 ValueKind::ByValue);
117}
118
119ValueType MetadataStreamer::getValueType(Type *Ty, StringRef TypeName) const {
120 switch (Ty->getTypeID()) {
121 case Type::IntegerTyID: {
122 auto Signed = !TypeName.startswith("u");
123 switch (Ty->getIntegerBitWidth()) {
124 case 8:
125 return Signed ? ValueType::I8 : ValueType::U8;
126 case 16:
127 return Signed ? ValueType::I16 : ValueType::U16;
128 case 32:
129 return Signed ? ValueType::I32 : ValueType::U32;
130 case 64:
131 return Signed ? ValueType::I64 : ValueType::U64;
132 default:
133 return ValueType::Struct;
134 }
135 }
136 case Type::HalfTyID:
137 return ValueType::F16;
138 case Type::FloatTyID:
139 return ValueType::F32;
140 case Type::DoubleTyID:
141 return ValueType::F64;
142 case Type::PointerTyID:
143 return getValueType(Ty->getPointerElementType(), TypeName);
144 case Type::VectorTyID:
145 return getValueType(Ty->getVectorElementType(), TypeName);
146 default:
147 return ValueType::Struct;
148 }
149}
150
151std::string MetadataStreamer::getTypeName(Type *Ty, bool Signed) const {
152 switch (Ty->getTypeID()) {
153 case Type::IntegerTyID: {
154 if (!Signed)
155 return (Twine('u') + getTypeName(Ty, true)).str();
156
157 auto BitWidth = Ty->getIntegerBitWidth();
158 switch (BitWidth) {
159 case 8:
160 return "char";
161 case 16:
162 return "short";
163 case 32:
164 return "int";
165 case 64:
166 return "long";
167 default:
168 return (Twine('i') + Twine(BitWidth)).str();
169 }
170 }
171 case Type::HalfTyID:
172 return "half";
173 case Type::FloatTyID:
174 return "float";
175 case Type::DoubleTyID:
176 return "double";
177 case Type::VectorTyID: {
178 auto VecTy = cast<VectorType>(Ty);
179 auto ElTy = VecTy->getElementType();
180 auto NumElements = VecTy->getVectorNumElements();
181 return (Twine(getTypeName(ElTy, Signed)) + Twine(NumElements)).str();
182 }
183 default:
184 return "unknown";
185 }
186}
187
188std::vector<uint32_t> MetadataStreamer::getWorkGroupDimensions(
189 MDNode *Node) const {
190 std::vector<uint32_t> Dims;
191 if (Node->getNumOperands() != 3)
192 return Dims;
193
194 for (auto &Op : Node->operands())
195 Dims.push_back(mdconst::extract<ConstantInt>(Op)->getZExtValue());
196 return Dims;
197}
198
199void MetadataStreamer::emitVersion() {
Konstantin Zhuravlyova63b0f92017-10-11 22:18:53 +0000200 auto &Version = HSAMetadata.mVersion;
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000201
Konstantin Zhuravlyova63b0f92017-10-11 22:18:53 +0000202 Version.push_back(VersionMajor);
203 Version.push_back(VersionMinor);
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000204}
205
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000206void MetadataStreamer::emitPrintf(const Module &Mod) {
Konstantin Zhuravlyova63b0f92017-10-11 22:18:53 +0000207 auto &Printf = HSAMetadata.mPrintf;
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000208
209 auto Node = Mod.getNamedMetadata("llvm.printf.fmts");
210 if (!Node)
211 return;
212
213 for (auto Op : Node->operands())
214 if (Op->getNumOperands())
215 Printf.push_back(cast<MDString>(Op->getOperand(0))->getString());
216}
217
218void MetadataStreamer::emitKernelLanguage(const Function &Func) {
Konstantin Zhuravlyova63b0f92017-10-11 22:18:53 +0000219 auto &Kernel = HSAMetadata.mKernels.back();
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000220
221 // TODO: What about other languages?
222 auto Node = Func.getParent()->getNamedMetadata("opencl.ocl.version");
223 if (!Node || !Node->getNumOperands())
224 return;
225 auto Op0 = Node->getOperand(0);
226 if (Op0->getNumOperands() <= 1)
227 return;
228
229 Kernel.mLanguage = "OpenCL C";
230 Kernel.mLanguageVersion.push_back(
231 mdconst::extract<ConstantInt>(Op0->getOperand(0))->getZExtValue());
232 Kernel.mLanguageVersion.push_back(
233 mdconst::extract<ConstantInt>(Op0->getOperand(1))->getZExtValue());
234}
235
236void MetadataStreamer::emitKernelAttrs(const Function &Func) {
Konstantin Zhuravlyova63b0f92017-10-11 22:18:53 +0000237 auto &Attrs = HSAMetadata.mKernels.back().mAttrs;
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000238
239 if (auto Node = Func.getMetadata("reqd_work_group_size"))
240 Attrs.mReqdWorkGroupSize = getWorkGroupDimensions(Node);
241 if (auto Node = Func.getMetadata("work_group_size_hint"))
242 Attrs.mWorkGroupSizeHint = getWorkGroupDimensions(Node);
243 if (auto Node = Func.getMetadata("vec_type_hint")) {
244 Attrs.mVecTypeHint = getTypeName(
245 cast<ValueAsMetadata>(Node->getOperand(0))->getType(),
246 mdconst::extract<ConstantInt>(Node->getOperand(1))->getZExtValue());
247 }
Yaxun Liude4b88d2017-10-10 19:39:48 +0000248 if (Func.hasFnAttribute("runtime-handle")) {
249 Attrs.mRuntimeHandle =
250 Func.getFnAttribute("runtime-handle").getValueAsString().str();
251 }
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000252}
253
254void MetadataStreamer::emitKernelArgs(const Function &Func) {
255 for (auto &Arg : Func.args())
256 emitKernelArg(Arg);
257
258 // TODO: What about other languages?
259 if (!Func.getParent()->getNamedMetadata("opencl.ocl.version"))
260 return;
261
262 auto &DL = Func.getParent()->getDataLayout();
263 auto Int64Ty = Type::getInt64Ty(Func.getContext());
264
265 emitKernelArg(DL, Int64Ty, ValueKind::HiddenGlobalOffsetX);
266 emitKernelArg(DL, Int64Ty, ValueKind::HiddenGlobalOffsetY);
267 emitKernelArg(DL, Int64Ty, ValueKind::HiddenGlobalOffsetZ);
268
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000269 auto Int8PtrTy = Type::getInt8PtrTy(Func.getContext(),
Yaxun Liu1a14bfa2017-03-27 14:04:01 +0000270 AMDGPUASI.GLOBAL_ADDRESS);
Konstantin Zhuravlyovc233ae82018-04-05 20:46:04 +0000271
272 // Emit "printf buffer" argument if printf is used, otherwise emit dummy
273 // "none" argument.
274 if (Func.getParent()->getNamedMetadata("llvm.printf.fmts"))
Yaxun Liuc928f2a2017-10-30 14:30:28 +0000275 emitKernelArg(DL, Int8PtrTy, ValueKind::HiddenPrintfBuffer);
Konstantin Zhuravlyovc233ae82018-04-05 20:46:04 +0000276 else
277 emitKernelArg(DL, Int8PtrTy, ValueKind::HiddenNone);
278
279 // Emit "default queue" and "completion action" arguments if enqueue kernel is
280 // used, otherwise emit dummy "none" arguments.
Yaxun Liuc928f2a2017-10-30 14:30:28 +0000281 if (Func.hasFnAttribute("calls-enqueue-kernel")) {
Yaxun Liuc928f2a2017-10-30 14:30:28 +0000282 emitKernelArg(DL, Int8PtrTy, ValueKind::HiddenDefaultQueue);
283 emitKernelArg(DL, Int8PtrTy, ValueKind::HiddenCompletionAction);
Konstantin Zhuravlyovc233ae82018-04-05 20:46:04 +0000284 } else {
285 emitKernelArg(DL, Int8PtrTy, ValueKind::HiddenNone);
286 emitKernelArg(DL, Int8PtrTy, ValueKind::HiddenNone);
Yaxun Liuc928f2a2017-10-30 14:30:28 +0000287 }
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000288}
289
290void MetadataStreamer::emitKernelArg(const Argument &Arg) {
291 auto Func = Arg.getParent();
292 auto ArgNo = Arg.getArgNo();
293 const MDNode *Node;
294
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000295 StringRef Name;
296 Node = Func->getMetadata("kernel_arg_name");
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000297 if (Node && ArgNo < Node->getNumOperands())
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000298 Name = cast<MDString>(Node->getOperand(ArgNo))->getString();
Konstantin Zhuravlyove30f88f2017-12-08 19:22:12 +0000299 else if (Arg.hasName())
300 Name = Arg.getName();
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000301
302 StringRef TypeName;
303 Node = Func->getMetadata("kernel_arg_type");
304 if (Node && ArgNo < Node->getNumOperands())
305 TypeName = cast<MDString>(Node->getOperand(ArgNo))->getString();
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000306
307 StringRef BaseTypeName;
308 Node = Func->getMetadata("kernel_arg_base_type");
309 if (Node && ArgNo < Node->getNumOperands())
310 BaseTypeName = cast<MDString>(Node->getOperand(ArgNo))->getString();
311
312 StringRef AccQual;
Stanislav Mekhanoshineff0bc72017-04-14 19:11:40 +0000313 if (Arg.getType()->isPointerTy() && Arg.onlyReadsMemory() &&
314 Arg.hasNoAliasAttr()) {
315 AccQual = "read_only";
316 } else {
317 Node = Func->getMetadata("kernel_arg_access_qual");
318 if (Node && ArgNo < Node->getNumOperands())
319 AccQual = cast<MDString>(Node->getOperand(ArgNo))->getString();
320 }
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000321
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000322 StringRef TypeQual;
323 Node = Func->getMetadata("kernel_arg_type_qual");
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000324 if (Node && ArgNo < Node->getNumOperands())
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000325 TypeQual = cast<MDString>(Node->getOperand(ArgNo))->getString();
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000326
327 emitKernelArg(Func->getParent()->getDataLayout(), Arg.getType(),
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000328 getValueKind(Arg.getType(), TypeQual, BaseTypeName), Name,
329 TypeName, BaseTypeName, AccQual, TypeQual);
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000330}
331
332void MetadataStreamer::emitKernelArg(const DataLayout &DL, Type *Ty,
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000333 ValueKind ValueKind, StringRef Name,
334 StringRef TypeName, StringRef BaseTypeName,
335 StringRef AccQual, StringRef TypeQual) {
Konstantin Zhuravlyova63b0f92017-10-11 22:18:53 +0000336 HSAMetadata.mKernels.back().mArgs.push_back(Kernel::Arg::Metadata());
337 auto &Arg = HSAMetadata.mKernels.back().mArgs.back();
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000338
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000339 Arg.mName = Name;
340 Arg.mTypeName = TypeName;
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000341 Arg.mSize = DL.getTypeAllocSize(Ty);
342 Arg.mAlign = DL.getABITypeAlignment(Ty);
343 Arg.mValueKind = ValueKind;
344 Arg.mValueType = getValueType(Ty, BaseTypeName);
345
346 if (auto PtrTy = dyn_cast<PointerType>(Ty)) {
347 auto ElTy = PtrTy->getElementType();
Yaxun Liu1a14bfa2017-03-27 14:04:01 +0000348 if (PtrTy->getAddressSpace() == AMDGPUASI.LOCAL_ADDRESS && ElTy->isSized())
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000349 Arg.mPointeeAlign = DL.getABITypeAlignment(ElTy);
350 }
351
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000352 if (auto PtrTy = dyn_cast<PointerType>(Ty))
353 Arg.mAddrSpaceQual = getAddressSpaceQualifer(PtrTy->getAddressSpace());
354
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000355 Arg.mAccQual = getAccessQualifier(AccQual);
356
357 // TODO: Emit Arg.mActualAccQual.
358
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000359 SmallVector<StringRef, 1> SplitTypeQuals;
360 TypeQual.split(SplitTypeQuals, " ", -1, false);
361 for (StringRef Key : SplitTypeQuals) {
362 auto P = StringSwitch<bool*>(Key)
363 .Case("const", &Arg.mIsConst)
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000364 .Case("restrict", &Arg.mIsRestrict)
365 .Case("volatile", &Arg.mIsVolatile)
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000366 .Case("pipe", &Arg.mIsPipe)
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000367 .Default(nullptr);
368 if (P)
369 *P = true;
370 }
Konstantin Zhuravlyova780ffa2017-03-22 23:10:46 +0000371}
372
Konstantin Zhuravlyov4cbb6892017-03-22 23:27:09 +0000373void MetadataStreamer::begin(const Module &Mod) {
Yaxun Liu1a14bfa2017-03-27 14:04:01 +0000374 AMDGPUASI = getAMDGPUAS(Mod);
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000375 emitVersion();
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000376 emitPrintf(Mod);
377}
378
Konstantin Zhuravlyov516651b2017-10-11 22:59:35 +0000379void MetadataStreamer::end() {
380 std::string HSAMetadataString;
Konstantin Zhuravlyov63e87f52017-10-12 17:34:05 +0000381 if (toString(HSAMetadata, HSAMetadataString))
Konstantin Zhuravlyov516651b2017-10-11 22:59:35 +0000382 return;
383
384 if (DumpHSAMetadata)
385 dump(HSAMetadataString);
386 if (VerifyHSAMetadata)
387 verify(HSAMetadataString);
388}
389
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000390void MetadataStreamer::emitKernel(
391 const Function &Func,
392 const Kernel::CodeProps::Metadata &CodeProps,
393 const Kernel::DebugProps::Metadata &DebugProps) {
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000394 if (Func.getCallingConv() != CallingConv::AMDGPU_KERNEL)
395 return;
396
Konstantin Zhuravlyova63b0f92017-10-11 22:18:53 +0000397 HSAMetadata.mKernels.push_back(Kernel::Metadata());
398 auto &Kernel = HSAMetadata.mKernels.back();
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000399
400 Kernel.mName = Func.getName();
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000401 Kernel.mSymbolName = (Twine(Func.getName()) + Twine("@kd")).str();
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000402 emitKernelLanguage(Func);
403 emitKernelAttrs(Func);
404 emitKernelArgs(Func);
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000405 HSAMetadata.mKernels.back().mCodeProps = CodeProps;
406 HSAMetadata.mKernels.back().mDebugProps = DebugProps;
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000407}
408
Konstantin Zhuravlyova63b0f92017-10-11 22:18:53 +0000409} // end namespace HSAMD
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000410} // end namespace AMDGPU
411} // end namespace llvm