blob: 5a6dfb28b5059744815ef9071e90b6bd8d3a4983 [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
Konstantin Zhuravlyova63b0f92017-10-11 22:18:53 +000011/// \brief 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);
Yaxun Liuc928f2a2017-10-30 14:30:28 +0000271 auto CallsPrintf = Func.getParent()->getNamedMetadata("llvm.printf.fmts");
272 if (CallsPrintf)
273 emitKernelArg(DL, Int8PtrTy, ValueKind::HiddenPrintfBuffer);
274 if (Func.hasFnAttribute("calls-enqueue-kernel")) {
275 if (!CallsPrintf) {
276 // Emit a dummy argument so that the remaining hidden arguments
277 // have a fixed position relative to the first hidden argument.
278 // This is to facilitate library code to access hidden arguments.
279 emitKernelArg(DL, Int8PtrTy, ValueKind::HiddenNone);
280 }
281 emitKernelArg(DL, Int8PtrTy, ValueKind::HiddenDefaultQueue);
282 emitKernelArg(DL, Int8PtrTy, ValueKind::HiddenCompletionAction);
283 }
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000284}
285
286void MetadataStreamer::emitKernelArg(const Argument &Arg) {
287 auto Func = Arg.getParent();
288 auto ArgNo = Arg.getArgNo();
289 const MDNode *Node;
290
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000291 StringRef Name;
292 Node = Func->getMetadata("kernel_arg_name");
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000293 if (Node && ArgNo < Node->getNumOperands())
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000294 Name = cast<MDString>(Node->getOperand(ArgNo))->getString();
295
296 StringRef TypeName;
297 Node = Func->getMetadata("kernel_arg_type");
298 if (Node && ArgNo < Node->getNumOperands())
299 TypeName = cast<MDString>(Node->getOperand(ArgNo))->getString();
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000300
301 StringRef BaseTypeName;
302 Node = Func->getMetadata("kernel_arg_base_type");
303 if (Node && ArgNo < Node->getNumOperands())
304 BaseTypeName = cast<MDString>(Node->getOperand(ArgNo))->getString();
305
306 StringRef AccQual;
Stanislav Mekhanoshineff0bc72017-04-14 19:11:40 +0000307 if (Arg.getType()->isPointerTy() && Arg.onlyReadsMemory() &&
308 Arg.hasNoAliasAttr()) {
309 AccQual = "read_only";
310 } else {
311 Node = Func->getMetadata("kernel_arg_access_qual");
312 if (Node && ArgNo < Node->getNumOperands())
313 AccQual = cast<MDString>(Node->getOperand(ArgNo))->getString();
314 }
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000315
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000316 StringRef TypeQual;
317 Node = Func->getMetadata("kernel_arg_type_qual");
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000318 if (Node && ArgNo < Node->getNumOperands())
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000319 TypeQual = cast<MDString>(Node->getOperand(ArgNo))->getString();
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000320
321 emitKernelArg(Func->getParent()->getDataLayout(), Arg.getType(),
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000322 getValueKind(Arg.getType(), TypeQual, BaseTypeName), Name,
323 TypeName, BaseTypeName, AccQual, TypeQual);
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000324}
325
326void MetadataStreamer::emitKernelArg(const DataLayout &DL, Type *Ty,
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000327 ValueKind ValueKind, StringRef Name,
328 StringRef TypeName, StringRef BaseTypeName,
329 StringRef AccQual, StringRef TypeQual) {
Konstantin Zhuravlyova63b0f92017-10-11 22:18:53 +0000330 HSAMetadata.mKernels.back().mArgs.push_back(Kernel::Arg::Metadata());
331 auto &Arg = HSAMetadata.mKernels.back().mArgs.back();
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000332
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000333 Arg.mName = Name;
334 Arg.mTypeName = TypeName;
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000335 Arg.mSize = DL.getTypeAllocSize(Ty);
336 Arg.mAlign = DL.getABITypeAlignment(Ty);
337 Arg.mValueKind = ValueKind;
338 Arg.mValueType = getValueType(Ty, BaseTypeName);
339
340 if (auto PtrTy = dyn_cast<PointerType>(Ty)) {
341 auto ElTy = PtrTy->getElementType();
Yaxun Liu1a14bfa2017-03-27 14:04:01 +0000342 if (PtrTy->getAddressSpace() == AMDGPUASI.LOCAL_ADDRESS && ElTy->isSized())
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000343 Arg.mPointeeAlign = DL.getABITypeAlignment(ElTy);
344 }
345
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000346 if (auto PtrTy = dyn_cast<PointerType>(Ty))
347 Arg.mAddrSpaceQual = getAddressSpaceQualifer(PtrTy->getAddressSpace());
348
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000349 Arg.mAccQual = getAccessQualifier(AccQual);
350
351 // TODO: Emit Arg.mActualAccQual.
352
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000353 SmallVector<StringRef, 1> SplitTypeQuals;
354 TypeQual.split(SplitTypeQuals, " ", -1, false);
355 for (StringRef Key : SplitTypeQuals) {
356 auto P = StringSwitch<bool*>(Key)
357 .Case("const", &Arg.mIsConst)
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000358 .Case("restrict", &Arg.mIsRestrict)
359 .Case("volatile", &Arg.mIsVolatile)
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000360 .Case("pipe", &Arg.mIsPipe)
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000361 .Default(nullptr);
362 if (P)
363 *P = true;
364 }
Konstantin Zhuravlyova780ffa2017-03-22 23:10:46 +0000365}
366
Konstantin Zhuravlyov4cbb6892017-03-22 23:27:09 +0000367void MetadataStreamer::begin(const Module &Mod) {
Yaxun Liu1a14bfa2017-03-27 14:04:01 +0000368 AMDGPUASI = getAMDGPUAS(Mod);
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000369 emitVersion();
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000370 emitPrintf(Mod);
371}
372
Konstantin Zhuravlyov516651b2017-10-11 22:59:35 +0000373void MetadataStreamer::end() {
374 std::string HSAMetadataString;
Konstantin Zhuravlyov63e87f52017-10-12 17:34:05 +0000375 if (toString(HSAMetadata, HSAMetadataString))
Konstantin Zhuravlyov516651b2017-10-11 22:59:35 +0000376 return;
377
378 if (DumpHSAMetadata)
379 dump(HSAMetadataString);
380 if (VerifyHSAMetadata)
381 verify(HSAMetadataString);
382}
383
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000384void MetadataStreamer::emitKernel(
385 const Function &Func,
386 const Kernel::CodeProps::Metadata &CodeProps,
387 const Kernel::DebugProps::Metadata &DebugProps) {
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000388 if (Func.getCallingConv() != CallingConv::AMDGPU_KERNEL)
389 return;
390
Konstantin Zhuravlyova63b0f92017-10-11 22:18:53 +0000391 HSAMetadata.mKernels.push_back(Kernel::Metadata());
392 auto &Kernel = HSAMetadata.mKernels.back();
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000393
394 Kernel.mName = Func.getName();
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000395 Kernel.mSymbolName = (Twine(Func.getName()) + Twine("@kd")).str();
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000396 emitKernelLanguage(Func);
397 emitKernelAttrs(Func);
398 emitKernelArgs(Func);
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000399 HSAMetadata.mKernels.back().mCodeProps = CodeProps;
400 HSAMetadata.mKernels.back().mDebugProps = DebugProps;
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000401}
402
Konstantin Zhuravlyova63b0f92017-10-11 22:18:53 +0000403} // end namespace HSAMD
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000404} // end namespace AMDGPU
405} // end namespace llvm