blob: fadc833e0142287424eb223c7b0043778cd1f0a7 [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"
Scott Linder2ad2c182018-07-10 17:31:32 +000017#include "AMDGPU.h"
18#include "AMDGPUSubtarget.h"
19#include "SIMachineFunctionInfo.h"
20#include "SIProgramInfo.h"
Konstantin Zhuravlyovf0badd52018-07-10 16:12:51 +000021#include "Utils/AMDGPUBaseInfo.h"
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000022#include "llvm/ADT/StringSwitch.h"
23#include "llvm/IR/Constants.h"
24#include "llvm/IR/Module.h"
Konstantin Zhuravlyov1e2b8782017-06-06 18:35:50 +000025#include "llvm/Support/raw_ostream.h"
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000026
27namespace llvm {
28
Konstantin Zhuravlyova63b0f92017-10-11 22:18:53 +000029static cl::opt<bool> DumpHSAMetadata(
30 "amdgpu-dump-hsa-metadata",
31 cl::desc("Dump AMDGPU HSA Metadata"));
32static cl::opt<bool> VerifyHSAMetadata(
33 "amdgpu-verify-hsa-metadata",
34 cl::desc("Verify AMDGPU HSA Metadata"));
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000035
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000036namespace AMDGPU {
Konstantin Zhuravlyova63b0f92017-10-11 22:18:53 +000037namespace HSAMD {
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000038
Konstantin Zhuravlyov516651b2017-10-11 22:59:35 +000039void MetadataStreamer::dump(StringRef HSAMetadataString) const {
40 errs() << "AMDGPU HSA Metadata:\n" << HSAMetadataString << '\n';
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000041}
42
Konstantin Zhuravlyov516651b2017-10-11 22:59:35 +000043void MetadataStreamer::verify(StringRef HSAMetadataString) const {
Konstantin Zhuravlyova63b0f92017-10-11 22:18:53 +000044 errs() << "AMDGPU HSA Metadata Parser Test: ";
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000045
Konstantin Zhuravlyov516651b2017-10-11 22:59:35 +000046 HSAMD::Metadata FromHSAMetadataString;
47 if (fromString(HSAMetadataString, FromHSAMetadataString)) {
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000048 errs() << "FAIL\n";
49 return;
50 }
51
Konstantin Zhuravlyov516651b2017-10-11 22:59:35 +000052 std::string ToHSAMetadataString;
53 if (toString(FromHSAMetadataString, ToHSAMetadataString)) {
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000054 errs() << "FAIL\n";
55 return;
56 }
57
Konstantin Zhuravlyov516651b2017-10-11 22:59:35 +000058 errs() << (HSAMetadataString == ToHSAMetadataString ? "PASS" : "FAIL")
59 << '\n';
60 if (HSAMetadataString != ToHSAMetadataString) {
61 errs() << "Original input: " << HSAMetadataString << '\n'
62 << "Produced output: " << ToHSAMetadataString << '\n';
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000063 }
64}
65
66AccessQualifier MetadataStreamer::getAccessQualifier(StringRef AccQual) const {
67 if (AccQual.empty())
68 return AccessQualifier::Unknown;
69
70 return StringSwitch<AccessQualifier>(AccQual)
71 .Case("read_only", AccessQualifier::ReadOnly)
72 .Case("write_only", AccessQualifier::WriteOnly)
73 .Case("read_write", AccessQualifier::ReadWrite)
74 .Default(AccessQualifier::Default);
75}
76
77AddressSpaceQualifier MetadataStreamer::getAddressSpaceQualifer(
78 unsigned AddressSpace) const {
Matt Arsenaultb9986742018-09-10 02:23:30 +000079 switch (AddressSpace) {
80 case AMDGPUAS::PRIVATE_ADDRESS:
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000081 return AddressSpaceQualifier::Private;
Matt Arsenaultb9986742018-09-10 02:23:30 +000082 case AMDGPUAS::GLOBAL_ADDRESS:
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000083 return AddressSpaceQualifier::Global;
Matt Arsenaultb9986742018-09-10 02:23:30 +000084 case AMDGPUAS::CONSTANT_ADDRESS:
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000085 return AddressSpaceQualifier::Constant;
Matt Arsenaultb9986742018-09-10 02:23:30 +000086 case AMDGPUAS::LOCAL_ADDRESS:
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000087 return AddressSpaceQualifier::Local;
Matt Arsenaultb9986742018-09-10 02:23:30 +000088 case AMDGPUAS::FLAT_ADDRESS:
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000089 return AddressSpaceQualifier::Generic;
Matt Arsenaultb9986742018-09-10 02:23:30 +000090 case AMDGPUAS::REGION_ADDRESS:
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000091 return AddressSpaceQualifier::Region;
Matt Arsenaultb9986742018-09-10 02:23:30 +000092 default:
93 return AddressSpaceQualifier::Unknown;
94 }
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000095}
96
97ValueKind MetadataStreamer::getValueKind(Type *Ty, StringRef TypeQual,
98 StringRef BaseTypeName) const {
99 if (TypeQual.find("pipe") != StringRef::npos)
100 return ValueKind::Pipe;
101
102 return StringSwitch<ValueKind>(BaseTypeName)
Konstantin Zhuravlyov54ba4312017-04-25 20:38:26 +0000103 .Case("image1d_t", ValueKind::Image)
104 .Case("image1d_array_t", ValueKind::Image)
105 .Case("image1d_buffer_t", ValueKind::Image)
106 .Case("image2d_t", ValueKind::Image)
107 .Case("image2d_array_t", ValueKind::Image)
108 .Case("image2d_array_depth_t", ValueKind::Image)
109 .Case("image2d_array_msaa_t", ValueKind::Image)
110 .Case("image2d_array_msaa_depth_t", ValueKind::Image)
111 .Case("image2d_depth_t", ValueKind::Image)
112 .Case("image2d_msaa_t", ValueKind::Image)
113 .Case("image2d_msaa_depth_t", ValueKind::Image)
114 .Case("image3d_t", ValueKind::Image)
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000115 .Case("sampler_t", ValueKind::Sampler)
116 .Case("queue_t", ValueKind::Queue)
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000117 .Default(isa<PointerType>(Ty) ?
118 (Ty->getPointerAddressSpace() ==
Matt Arsenault0da63502018-08-31 05:49:54 +0000119 AMDGPUAS::LOCAL_ADDRESS ?
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000120 ValueKind::DynamicSharedPointer :
121 ValueKind::GlobalBuffer) :
122 ValueKind::ByValue);
123}
124
125ValueType MetadataStreamer::getValueType(Type *Ty, StringRef TypeName) const {
126 switch (Ty->getTypeID()) {
127 case Type::IntegerTyID: {
128 auto Signed = !TypeName.startswith("u");
129 switch (Ty->getIntegerBitWidth()) {
130 case 8:
131 return Signed ? ValueType::I8 : ValueType::U8;
132 case 16:
133 return Signed ? ValueType::I16 : ValueType::U16;
134 case 32:
135 return Signed ? ValueType::I32 : ValueType::U32;
136 case 64:
137 return Signed ? ValueType::I64 : ValueType::U64;
138 default:
139 return ValueType::Struct;
140 }
141 }
142 case Type::HalfTyID:
143 return ValueType::F16;
144 case Type::FloatTyID:
145 return ValueType::F32;
146 case Type::DoubleTyID:
147 return ValueType::F64;
148 case Type::PointerTyID:
149 return getValueType(Ty->getPointerElementType(), TypeName);
150 case Type::VectorTyID:
151 return getValueType(Ty->getVectorElementType(), TypeName);
152 default:
153 return ValueType::Struct;
154 }
155}
156
157std::string MetadataStreamer::getTypeName(Type *Ty, bool Signed) const {
158 switch (Ty->getTypeID()) {
159 case Type::IntegerTyID: {
160 if (!Signed)
161 return (Twine('u') + getTypeName(Ty, true)).str();
162
163 auto BitWidth = Ty->getIntegerBitWidth();
164 switch (BitWidth) {
165 case 8:
166 return "char";
167 case 16:
168 return "short";
169 case 32:
170 return "int";
171 case 64:
172 return "long";
173 default:
174 return (Twine('i') + Twine(BitWidth)).str();
175 }
176 }
177 case Type::HalfTyID:
178 return "half";
179 case Type::FloatTyID:
180 return "float";
181 case Type::DoubleTyID:
182 return "double";
183 case Type::VectorTyID: {
184 auto VecTy = cast<VectorType>(Ty);
185 auto ElTy = VecTy->getElementType();
186 auto NumElements = VecTy->getVectorNumElements();
187 return (Twine(getTypeName(ElTy, Signed)) + Twine(NumElements)).str();
188 }
189 default:
190 return "unknown";
191 }
192}
193
194std::vector<uint32_t> MetadataStreamer::getWorkGroupDimensions(
195 MDNode *Node) const {
196 std::vector<uint32_t> Dims;
197 if (Node->getNumOperands() != 3)
198 return Dims;
199
200 for (auto &Op : Node->operands())
201 Dims.push_back(mdconst::extract<ConstantInt>(Op)->getZExtValue());
202 return Dims;
203}
204
Scott Linder2ad2c182018-07-10 17:31:32 +0000205Kernel::CodeProps::Metadata MetadataStreamer::getHSACodeProps(
206 const MachineFunction &MF,
207 const SIProgramInfo &ProgramInfo) const {
Tom Stellard5bfbae52018-07-11 20:59:01 +0000208 const GCNSubtarget &STM = MF.getSubtarget<GCNSubtarget>();
Scott Linder2ad2c182018-07-10 17:31:32 +0000209 const SIMachineFunctionInfo &MFI = *MF.getInfo<SIMachineFunctionInfo>();
210 HSAMD::Kernel::CodeProps::Metadata HSACodeProps;
211 const Function &F = MF.getFunction();
212
Matt Arsenault4bec7d42018-07-20 09:05:08 +0000213 assert(F.getCallingConv() == CallingConv::AMDGPU_KERNEL ||
214 F.getCallingConv() == CallingConv::SPIR_KERNEL);
Scott Linder2ad2c182018-07-10 17:31:32 +0000215
Matt Arsenault4bec7d42018-07-20 09:05:08 +0000216 unsigned MaxKernArgAlign;
217 HSACodeProps.mKernargSegmentSize = STM.getKernArgSegmentSize(F,
218 MaxKernArgAlign);
Scott Linder2ad2c182018-07-10 17:31:32 +0000219 HSACodeProps.mGroupSegmentFixedSize = ProgramInfo.LDSSize;
220 HSACodeProps.mPrivateSegmentFixedSize = ProgramInfo.ScratchSize;
Matt Arsenault4bec7d42018-07-20 09:05:08 +0000221 HSACodeProps.mKernargSegmentAlign = std::max(MaxKernArgAlign, 4u);
Scott Linder2ad2c182018-07-10 17:31:32 +0000222 HSACodeProps.mWavefrontSize = STM.getWavefrontSize();
223 HSACodeProps.mNumSGPRs = ProgramInfo.NumSGPR;
224 HSACodeProps.mNumVGPRs = ProgramInfo.NumVGPR;
225 HSACodeProps.mMaxFlatWorkGroupSize = MFI.getMaxFlatWorkGroupSize();
226 HSACodeProps.mIsDynamicCallStack = ProgramInfo.DynamicCallStack;
227 HSACodeProps.mIsXNACKEnabled = STM.isXNACKEnabled();
228 HSACodeProps.mNumSpilledSGPRs = MFI.getNumSpilledSGPRs();
229 HSACodeProps.mNumSpilledVGPRs = MFI.getNumSpilledVGPRs();
230
231 return HSACodeProps;
232}
233
234Kernel::DebugProps::Metadata MetadataStreamer::getHSADebugProps(
235 const MachineFunction &MF,
236 const SIProgramInfo &ProgramInfo) const {
Tom Stellard5bfbae52018-07-11 20:59:01 +0000237 const GCNSubtarget &STM = MF.getSubtarget<GCNSubtarget>();
Scott Linder2ad2c182018-07-10 17:31:32 +0000238 HSAMD::Kernel::DebugProps::Metadata HSADebugProps;
239
240 if (!STM.debuggerSupported())
241 return HSADebugProps;
242
243 HSADebugProps.mDebuggerABIVersion.push_back(1);
244 HSADebugProps.mDebuggerABIVersion.push_back(0);
245
246 if (STM.debuggerEmitPrologue()) {
247 HSADebugProps.mPrivateSegmentBufferSGPR =
248 ProgramInfo.DebuggerPrivateSegmentBufferSGPR;
249 HSADebugProps.mWavefrontPrivateSegmentOffsetSGPR =
250 ProgramInfo.DebuggerWavefrontPrivateSegmentOffsetSGPR;
251 }
252
253 return HSADebugProps;
254}
255
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000256void MetadataStreamer::emitVersion() {
Konstantin Zhuravlyova63b0f92017-10-11 22:18:53 +0000257 auto &Version = HSAMetadata.mVersion;
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000258
Konstantin Zhuravlyova63b0f92017-10-11 22:18:53 +0000259 Version.push_back(VersionMajor);
260 Version.push_back(VersionMinor);
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000261}
262
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000263void MetadataStreamer::emitPrintf(const Module &Mod) {
Konstantin Zhuravlyova63b0f92017-10-11 22:18:53 +0000264 auto &Printf = HSAMetadata.mPrintf;
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000265
266 auto Node = Mod.getNamedMetadata("llvm.printf.fmts");
267 if (!Node)
268 return;
269
270 for (auto Op : Node->operands())
271 if (Op->getNumOperands())
272 Printf.push_back(cast<MDString>(Op->getOperand(0))->getString());
273}
274
275void MetadataStreamer::emitKernelLanguage(const Function &Func) {
Konstantin Zhuravlyova63b0f92017-10-11 22:18:53 +0000276 auto &Kernel = HSAMetadata.mKernels.back();
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000277
278 // TODO: What about other languages?
279 auto Node = Func.getParent()->getNamedMetadata("opencl.ocl.version");
280 if (!Node || !Node->getNumOperands())
281 return;
282 auto Op0 = Node->getOperand(0);
283 if (Op0->getNumOperands() <= 1)
284 return;
285
286 Kernel.mLanguage = "OpenCL C";
287 Kernel.mLanguageVersion.push_back(
288 mdconst::extract<ConstantInt>(Op0->getOperand(0))->getZExtValue());
289 Kernel.mLanguageVersion.push_back(
290 mdconst::extract<ConstantInt>(Op0->getOperand(1))->getZExtValue());
291}
292
293void MetadataStreamer::emitKernelAttrs(const Function &Func) {
Konstantin Zhuravlyova63b0f92017-10-11 22:18:53 +0000294 auto &Attrs = HSAMetadata.mKernels.back().mAttrs;
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000295
296 if (auto Node = Func.getMetadata("reqd_work_group_size"))
297 Attrs.mReqdWorkGroupSize = getWorkGroupDimensions(Node);
298 if (auto Node = Func.getMetadata("work_group_size_hint"))
299 Attrs.mWorkGroupSizeHint = getWorkGroupDimensions(Node);
300 if (auto Node = Func.getMetadata("vec_type_hint")) {
301 Attrs.mVecTypeHint = getTypeName(
302 cast<ValueAsMetadata>(Node->getOperand(0))->getType(),
303 mdconst::extract<ConstantInt>(Node->getOperand(1))->getZExtValue());
304 }
Yaxun Liude4b88d2017-10-10 19:39:48 +0000305 if (Func.hasFnAttribute("runtime-handle")) {
306 Attrs.mRuntimeHandle =
307 Func.getFnAttribute("runtime-handle").getValueAsString().str();
308 }
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000309}
310
311void MetadataStreamer::emitKernelArgs(const Function &Func) {
312 for (auto &Arg : Func.args())
313 emitKernelArg(Arg);
314
Konstantin Zhuravlyovf0badd52018-07-10 16:12:51 +0000315 emitHiddenKernelArgs(Func);
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000316}
317
318void MetadataStreamer::emitKernelArg(const Argument &Arg) {
319 auto Func = Arg.getParent();
320 auto ArgNo = Arg.getArgNo();
321 const MDNode *Node;
322
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000323 StringRef Name;
324 Node = Func->getMetadata("kernel_arg_name");
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000325 if (Node && ArgNo < Node->getNumOperands())
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000326 Name = cast<MDString>(Node->getOperand(ArgNo))->getString();
Konstantin Zhuravlyove30f88f2017-12-08 19:22:12 +0000327 else if (Arg.hasName())
328 Name = Arg.getName();
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000329
330 StringRef TypeName;
331 Node = Func->getMetadata("kernel_arg_type");
332 if (Node && ArgNo < Node->getNumOperands())
333 TypeName = cast<MDString>(Node->getOperand(ArgNo))->getString();
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000334
335 StringRef BaseTypeName;
336 Node = Func->getMetadata("kernel_arg_base_type");
337 if (Node && ArgNo < Node->getNumOperands())
338 BaseTypeName = cast<MDString>(Node->getOperand(ArgNo))->getString();
339
340 StringRef AccQual;
Stanislav Mekhanoshineff0bc72017-04-14 19:11:40 +0000341 if (Arg.getType()->isPointerTy() && Arg.onlyReadsMemory() &&
342 Arg.hasNoAliasAttr()) {
343 AccQual = "read_only";
344 } else {
345 Node = Func->getMetadata("kernel_arg_access_qual");
346 if (Node && ArgNo < Node->getNumOperands())
347 AccQual = cast<MDString>(Node->getOperand(ArgNo))->getString();
348 }
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000349
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000350 StringRef TypeQual;
351 Node = Func->getMetadata("kernel_arg_type_qual");
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000352 if (Node && ArgNo < Node->getNumOperands())
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000353 TypeQual = cast<MDString>(Node->getOperand(ArgNo))->getString();
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000354
Matt Arsenault73eeb422018-06-25 14:29:04 +0000355 Type *Ty = Arg.getType();
356 const DataLayout &DL = Func->getParent()->getDataLayout();
357
358 unsigned PointeeAlign = 0;
359 if (auto PtrTy = dyn_cast<PointerType>(Ty)) {
Matt Arsenault0da63502018-08-31 05:49:54 +0000360 if (PtrTy->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS) {
Matt Arsenault73eeb422018-06-25 14:29:04 +0000361 PointeeAlign = Arg.getParamAlignment();
362 if (PointeeAlign == 0)
363 PointeeAlign = DL.getABITypeAlignment(PtrTy->getElementType());
364 }
365 }
366
367 emitKernelArg(DL, Ty, getValueKind(Arg.getType(), TypeQual, BaseTypeName),
368 PointeeAlign, Name, TypeName, BaseTypeName, AccQual, TypeQual);
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000369}
370
371void MetadataStreamer::emitKernelArg(const DataLayout &DL, Type *Ty,
Matt Arsenault73eeb422018-06-25 14:29:04 +0000372 ValueKind ValueKind,
373 unsigned PointeeAlign,
374 StringRef Name,
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000375 StringRef TypeName, StringRef BaseTypeName,
376 StringRef AccQual, StringRef TypeQual) {
Konstantin Zhuravlyova63b0f92017-10-11 22:18:53 +0000377 HSAMetadata.mKernels.back().mArgs.push_back(Kernel::Arg::Metadata());
378 auto &Arg = HSAMetadata.mKernels.back().mArgs.back();
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000379
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000380 Arg.mName = Name;
381 Arg.mTypeName = TypeName;
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000382 Arg.mSize = DL.getTypeAllocSize(Ty);
383 Arg.mAlign = DL.getABITypeAlignment(Ty);
384 Arg.mValueKind = ValueKind;
385 Arg.mValueType = getValueType(Ty, BaseTypeName);
Matt Arsenault73eeb422018-06-25 14:29:04 +0000386 Arg.mPointeeAlign = PointeeAlign;
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000387
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000388 if (auto PtrTy = dyn_cast<PointerType>(Ty))
389 Arg.mAddrSpaceQual = getAddressSpaceQualifer(PtrTy->getAddressSpace());
390
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000391 Arg.mAccQual = getAccessQualifier(AccQual);
392
393 // TODO: Emit Arg.mActualAccQual.
394
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000395 SmallVector<StringRef, 1> SplitTypeQuals;
396 TypeQual.split(SplitTypeQuals, " ", -1, false);
397 for (StringRef Key : SplitTypeQuals) {
398 auto P = StringSwitch<bool*>(Key)
399 .Case("const", &Arg.mIsConst)
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000400 .Case("restrict", &Arg.mIsRestrict)
401 .Case("volatile", &Arg.mIsVolatile)
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000402 .Case("pipe", &Arg.mIsPipe)
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000403 .Default(nullptr);
404 if (P)
405 *P = true;
406 }
Konstantin Zhuravlyova780ffa2017-03-22 23:10:46 +0000407}
408
Konstantin Zhuravlyovf0badd52018-07-10 16:12:51 +0000409void MetadataStreamer::emitHiddenKernelArgs(const Function &Func) {
410 int HiddenArgNumBytes =
411 getIntegerAttribute(Func, "amdgpu-implicitarg-num-bytes", 0);
412
413 if (!HiddenArgNumBytes)
414 return;
415
416 auto &DL = Func.getParent()->getDataLayout();
417 auto Int64Ty = Type::getInt64Ty(Func.getContext());
418
419 if (HiddenArgNumBytes >= 8)
420 emitKernelArg(DL, Int64Ty, ValueKind::HiddenGlobalOffsetX);
421 if (HiddenArgNumBytes >= 16)
422 emitKernelArg(DL, Int64Ty, ValueKind::HiddenGlobalOffsetY);
423 if (HiddenArgNumBytes >= 24)
424 emitKernelArg(DL, Int64Ty, ValueKind::HiddenGlobalOffsetZ);
425
426 auto Int8PtrTy = Type::getInt8PtrTy(Func.getContext(),
Matt Arsenault0da63502018-08-31 05:49:54 +0000427 AMDGPUAS::GLOBAL_ADDRESS);
Konstantin Zhuravlyovf0badd52018-07-10 16:12:51 +0000428
429 // Emit "printf buffer" argument if printf is used, otherwise emit dummy
430 // "none" argument.
431 if (HiddenArgNumBytes >= 32) {
432 if (Func.getParent()->getNamedMetadata("llvm.printf.fmts"))
433 emitKernelArg(DL, Int8PtrTy, ValueKind::HiddenPrintfBuffer);
434 else
435 emitKernelArg(DL, Int8PtrTy, ValueKind::HiddenNone);
436 }
437
438 // Emit "default queue" and "completion action" arguments if enqueue kernel is
439 // used, otherwise emit dummy "none" arguments.
440 if (HiddenArgNumBytes >= 48) {
441 if (Func.hasFnAttribute("calls-enqueue-kernel")) {
442 emitKernelArg(DL, Int8PtrTy, ValueKind::HiddenDefaultQueue);
443 emitKernelArg(DL, Int8PtrTy, ValueKind::HiddenCompletionAction);
444 } else {
445 emitKernelArg(DL, Int8PtrTy, ValueKind::HiddenNone);
446 emitKernelArg(DL, Int8PtrTy, ValueKind::HiddenNone);
447 }
448 }
449}
450
Konstantin Zhuravlyov4cbb6892017-03-22 23:27:09 +0000451void MetadataStreamer::begin(const Module &Mod) {
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000452 emitVersion();
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000453 emitPrintf(Mod);
454}
455
Konstantin Zhuravlyov516651b2017-10-11 22:59:35 +0000456void MetadataStreamer::end() {
457 std::string HSAMetadataString;
Konstantin Zhuravlyov63e87f52017-10-12 17:34:05 +0000458 if (toString(HSAMetadata, HSAMetadataString))
Konstantin Zhuravlyov516651b2017-10-11 22:59:35 +0000459 return;
460
461 if (DumpHSAMetadata)
462 dump(HSAMetadataString);
463 if (VerifyHSAMetadata)
464 verify(HSAMetadataString);
465}
466
Scott Linder2ad2c182018-07-10 17:31:32 +0000467void MetadataStreamer::emitKernel(const MachineFunction &MF, const SIProgramInfo &ProgramInfo) {
468 auto &Func = MF.getFunction();
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000469 if (Func.getCallingConv() != CallingConv::AMDGPU_KERNEL)
470 return;
471
Matt Arsenault4bec7d42018-07-20 09:05:08 +0000472 auto CodeProps = getHSACodeProps(MF, ProgramInfo);
473 auto DebugProps = getHSADebugProps(MF, ProgramInfo);
474
Konstantin Zhuravlyova63b0f92017-10-11 22:18:53 +0000475 HSAMetadata.mKernels.push_back(Kernel::Metadata());
476 auto &Kernel = HSAMetadata.mKernels.back();
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000477
478 Kernel.mName = Func.getName();
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000479 Kernel.mSymbolName = (Twine(Func.getName()) + Twine("@kd")).str();
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000480 emitKernelLanguage(Func);
481 emitKernelAttrs(Func);
482 emitKernelArgs(Func);
Konstantin Zhuravlyova01d8b02017-10-14 19:03:51 +0000483 HSAMetadata.mKernels.back().mCodeProps = CodeProps;
484 HSAMetadata.mKernels.back().mDebugProps = DebugProps;
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000485}
486
Konstantin Zhuravlyova63b0f92017-10-11 22:18:53 +0000487} // end namespace HSAMD
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000488} // end namespace AMDGPU
489} // end namespace llvm