blob: de76328b52c08ae657285709d142d98f5c01acc3 [file] [log] [blame]
Tom Stellard347ac792015-06-26 21:15:07 +00001//===-- AMDGPUTargetStreamer.cpp - Mips Target Streamer Methods -----------===//
2//
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// This file provides AMDGPU specific target streamer methods.
11//
12//===----------------------------------------------------------------------===//
13
Yaxun Liud6fbe652016-11-10 21:18:49 +000014#include "AMDGPU.h"
Tom Stellard347ac792015-06-26 21:15:07 +000015#include "AMDGPUTargetStreamer.h"
Tom Stellardff7416b2015-06-26 21:58:31 +000016#include "SIDefines.h"
Tom Stellarde135ffd2015-09-25 21:41:28 +000017#include "Utils/AMDGPUBaseInfo.h"
Sam Koltona2e5c882016-09-09 10:08:02 +000018#include "Utils/AMDKernelCodeTUtils.h"
Tom Stellard347ac792015-06-26 21:15:07 +000019#include "llvm/ADT/Twine.h"
Yaxun Liud6fbe652016-11-10 21:18:49 +000020#include "llvm/IR/Constants.h"
21#include "llvm/IR/Function.h"
22#include "llvm/IR/Metadata.h"
23#include "llvm/IR/Module.h"
Tom Stellard347ac792015-06-26 21:15:07 +000024#include "llvm/MC/MCContext.h"
25#include "llvm/MC/MCELFStreamer.h"
Tom Stellardff7416b2015-06-26 21:58:31 +000026#include "llvm/MC/MCObjectFileInfo.h"
Tom Stellard347ac792015-06-26 21:15:07 +000027#include "llvm/MC/MCSectionELF.h"
28#include "llvm/Support/ELF.h"
29#include "llvm/Support/FormattedStream.h"
30
Yaxun Liud6fbe652016-11-10 21:18:49 +000031namespace llvm {
32#include "AMDGPUPTNote.h"
33}
34
Tom Stellard347ac792015-06-26 21:15:07 +000035using namespace llvm;
Yaxun Liud6fbe652016-11-10 21:18:49 +000036using namespace llvm::AMDGPU;
Tom Stellard347ac792015-06-26 21:15:07 +000037
38AMDGPUTargetStreamer::AMDGPUTargetStreamer(MCStreamer &S)
Yaxun Liud6fbe652016-11-10 21:18:49 +000039 : MCTargetStreamer(S) {}
Tom Stellard347ac792015-06-26 21:15:07 +000040
41//===----------------------------------------------------------------------===//
42// AMDGPUTargetAsmStreamer
43//===----------------------------------------------------------------------===//
44
45AMDGPUTargetAsmStreamer::AMDGPUTargetAsmStreamer(MCStreamer &S,
46 formatted_raw_ostream &OS)
47 : AMDGPUTargetStreamer(S), OS(OS) { }
48
49void
50AMDGPUTargetAsmStreamer::EmitDirectiveHSACodeObjectVersion(uint32_t Major,
51 uint32_t Minor) {
52 OS << "\t.hsa_code_object_version " <<
53 Twine(Major) << "," << Twine(Minor) << '\n';
54}
55
56void
57AMDGPUTargetAsmStreamer::EmitDirectiveHSACodeObjectISA(uint32_t Major,
58 uint32_t Minor,
59 uint32_t Stepping,
60 StringRef VendorName,
61 StringRef ArchName) {
62 OS << "\t.hsa_code_object_isa " <<
63 Twine(Major) << "," << Twine(Minor) << "," << Twine(Stepping) <<
64 ",\"" << VendorName << "\",\"" << ArchName << "\"\n";
65
66}
67
Tom Stellardff7416b2015-06-26 21:58:31 +000068void
69AMDGPUTargetAsmStreamer::EmitAMDKernelCodeT(const amd_kernel_code_t &Header) {
Sam Koltona2e5c882016-09-09 10:08:02 +000070 OS << "\t.amd_kernel_code_t\n";
71 dumpAmdKernelCode(&Header, OS, "\t\t");
72 OS << "\t.end_amd_kernel_code_t\n";
Tom Stellardff7416b2015-06-26 21:58:31 +000073}
74
Tom Stellard1e1b05d2015-11-06 11:45:14 +000075void AMDGPUTargetAsmStreamer::EmitAMDGPUSymbolType(StringRef SymbolName,
76 unsigned Type) {
77 switch (Type) {
78 default: llvm_unreachable("Invalid AMDGPU symbol type");
79 case ELF::STT_AMDGPU_HSA_KERNEL:
80 OS << "\t.amdgpu_hsa_kernel " << SymbolName << '\n' ;
81 break;
82 }
83}
84
Tom Stellard00f2f912015-12-02 19:47:57 +000085void AMDGPUTargetAsmStreamer::EmitAMDGPUHsaModuleScopeGlobal(
86 StringRef GlobalName) {
87 OS << "\t.amdgpu_hsa_module_global " << GlobalName << '\n';
88}
89
90void AMDGPUTargetAsmStreamer::EmitAMDGPUHsaProgramScopeGlobal(
91 StringRef GlobalName) {
92 OS << "\t.amdgpu_hsa_program_global " << GlobalName << '\n';
93}
94
Tom Stellard347ac792015-06-26 21:15:07 +000095//===----------------------------------------------------------------------===//
96// AMDGPUTargetELFStreamer
97//===----------------------------------------------------------------------===//
98
99AMDGPUTargetELFStreamer::AMDGPUTargetELFStreamer(MCStreamer &S)
Yaxun Liud6fbe652016-11-10 21:18:49 +0000100 : AMDGPUTargetStreamer(S), Streamer(S) {}
Tom Stellard347ac792015-06-26 21:15:07 +0000101
102MCELFStreamer &AMDGPUTargetELFStreamer::getStreamer() {
103 return static_cast<MCELFStreamer &>(Streamer);
104}
105
106void
107AMDGPUTargetELFStreamer::EmitDirectiveHSACodeObjectVersion(uint32_t Major,
108 uint32_t Minor) {
109 MCStreamer &OS = getStreamer();
Konstantin Zhuravlyov98a3ac72016-10-17 22:40:15 +0000110 MCSectionELF *Note =
Yaxun Liud6fbe652016-11-10 21:18:49 +0000111 OS.getContext().getELFSection(PT_NOTE::NoteName, ELF::SHT_NOTE,
112 ELF::SHF_ALLOC);
Tom Stellard347ac792015-06-26 21:15:07 +0000113
Yaxun Liud6fbe652016-11-10 21:18:49 +0000114 auto NameSZ = sizeof(PT_NOTE::NoteName);
Tom Stellard347ac792015-06-26 21:15:07 +0000115 OS.PushSection();
116 OS.SwitchSection(Note);
Yaxun Liud6fbe652016-11-10 21:18:49 +0000117 OS.EmitIntValue(NameSZ, 4); // namesz
118 OS.EmitIntValue(8, 4); // descz
119 OS.EmitIntValue(PT_NOTE::NT_AMDGPU_HSA_CODE_OBJECT_VERSION, 4); // type
120 OS.EmitBytes(StringRef(PT_NOTE::NoteName, NameSZ)); // name
Konstantin Zhuravlyov521e5ef2016-10-20 18:22:36 +0000121 OS.EmitValueToAlignment(4);
Yaxun Liud6fbe652016-11-10 21:18:49 +0000122 OS.EmitIntValue(Major, 4); // desc
Tom Stellard347ac792015-06-26 21:15:07 +0000123 OS.EmitIntValue(Minor, 4);
124 OS.EmitValueToAlignment(4);
125 OS.PopSection();
126}
127
128void
129AMDGPUTargetELFStreamer::EmitDirectiveHSACodeObjectISA(uint32_t Major,
130 uint32_t Minor,
131 uint32_t Stepping,
132 StringRef VendorName,
133 StringRef ArchName) {
134 MCStreamer &OS = getStreamer();
Konstantin Zhuravlyov98a3ac72016-10-17 22:40:15 +0000135 MCSectionELF *Note =
Yaxun Liud6fbe652016-11-10 21:18:49 +0000136 OS.getContext().getELFSection(PT_NOTE::NoteName, ELF::SHT_NOTE,
137 ELF::SHF_ALLOC);
Tom Stellard347ac792015-06-26 21:15:07 +0000138
Tom Stellard347ac792015-06-26 21:15:07 +0000139 uint16_t VendorNameSize = VendorName.size() + 1;
140 uint16_t ArchNameSize = ArchName.size() + 1;
141 unsigned DescSZ = sizeof(VendorNameSize) + sizeof(ArchNameSize) +
142 sizeof(Major) + sizeof(Minor) + sizeof(Stepping) +
143 VendorNameSize + ArchNameSize;
144
145 OS.PushSection();
146 OS.SwitchSection(Note);
Yaxun Liud6fbe652016-11-10 21:18:49 +0000147 auto NameSZ = sizeof(PT_NOTE::NoteName);
148 OS.EmitIntValue(NameSZ, 4); // namesz
Konstantin Zhuravlyov521e5ef2016-10-20 18:22:36 +0000149 OS.EmitIntValue(DescSZ, 4); // descsz
Yaxun Liud6fbe652016-11-10 21:18:49 +0000150 OS.EmitIntValue(PT_NOTE::NT_AMDGPU_HSA_ISA, 4); // type
151 OS.EmitBytes(StringRef(PT_NOTE::NoteName, NameSZ)); // name
Konstantin Zhuravlyov521e5ef2016-10-20 18:22:36 +0000152 OS.EmitValueToAlignment(4);
153 OS.EmitIntValue(VendorNameSize, 2); // desc
Tom Stellard347ac792015-06-26 21:15:07 +0000154 OS.EmitIntValue(ArchNameSize, 2);
155 OS.EmitIntValue(Major, 4);
156 OS.EmitIntValue(Minor, 4);
157 OS.EmitIntValue(Stepping, 4);
158 OS.EmitBytes(VendorName);
159 OS.EmitIntValue(0, 1); // NULL terminate VendorName
160 OS.EmitBytes(ArchName);
161 OS.EmitIntValue(0, 1); // NULL terminte ArchName
162 OS.EmitValueToAlignment(4);
163 OS.PopSection();
164}
Tom Stellardff7416b2015-06-26 21:58:31 +0000165
166void
167AMDGPUTargetELFStreamer::EmitAMDKernelCodeT(const amd_kernel_code_t &Header) {
168
169 MCStreamer &OS = getStreamer();
170 OS.PushSection();
Tom Stellardff7416b2015-06-26 21:58:31 +0000171 OS.EmitBytes(StringRef((const char*)&Header, sizeof(Header)));
172 OS.PopSection();
173}
Tom Stellard1e1b05d2015-11-06 11:45:14 +0000174
175void AMDGPUTargetELFStreamer::EmitAMDGPUSymbolType(StringRef SymbolName,
176 unsigned Type) {
177 MCSymbolELF *Symbol = cast<MCSymbolELF>(
178 getStreamer().getContext().getOrCreateSymbol(SymbolName));
179 Symbol->setType(ELF::STT_AMDGPU_HSA_KERNEL);
180}
Tom Stellard00f2f912015-12-02 19:47:57 +0000181
182void AMDGPUTargetELFStreamer::EmitAMDGPUHsaModuleScopeGlobal(
183 StringRef GlobalName) {
184
185 MCSymbolELF *Symbol = cast<MCSymbolELF>(
186 getStreamer().getContext().getOrCreateSymbol(GlobalName));
187 Symbol->setType(ELF::STT_OBJECT);
188 Symbol->setBinding(ELF::STB_LOCAL);
189}
190
191void AMDGPUTargetELFStreamer::EmitAMDGPUHsaProgramScopeGlobal(
192 StringRef GlobalName) {
193
194 MCSymbolELF *Symbol = cast<MCSymbolELF>(
195 getStreamer().getContext().getOrCreateSymbol(GlobalName));
196 Symbol->setType(ELF::STT_OBJECT);
197 Symbol->setBinding(ELF::STB_GLOBAL);
198}
Yaxun Liud6fbe652016-11-10 21:18:49 +0000199
200void AMDGPUTargetStreamer::emitRuntimeMDIntValue(RuntimeMD::Key K, uint64_t V,
201 unsigned Size) {
202 auto &S = getStreamer();
203 S.EmitIntValue(K, 1);
204 S.EmitIntValue(V, Size);
205}
206
207void AMDGPUTargetStreamer::emitRuntimeMDStringValue(RuntimeMD::Key K,
208 StringRef R) {
209 auto &S = getStreamer();
210 S.EmitIntValue(K, 1);
211 S.EmitIntValue(R.size(), 4);
212 S.EmitBytes(R);
213}
214
215void AMDGPUTargetStreamer::emitRuntimeMDThreeIntValues(RuntimeMD::Key K,
216 MDNode *Node,
217 unsigned Size) {
218 assert(Node->getNumOperands() == 3);
219
220 auto &S = getStreamer();
221 S.EmitIntValue(K, 1);
222 for (const MDOperand &Op : Node->operands()) {
223 const ConstantInt *CI = mdconst::extract<ConstantInt>(Op);
224 S.EmitIntValue(CI->getZExtValue(), Size);
225 }
226}
227
228void AMDGPUTargetStreamer::emitStartOfRuntimeMetadata(const Module &M) {
229 emitRuntimeMDIntValue(RuntimeMD::KeyMDVersion,
230 RuntimeMD::MDVersion << 8 | RuntimeMD::MDRevision, 2);
231 if (auto MD = M.getNamedMetadata("opencl.ocl.version")) {
232 if (MD->getNumOperands() != 0) {
233 auto Node = MD->getOperand(0);
234 if (Node->getNumOperands() > 1) {
235 emitRuntimeMDIntValue(RuntimeMD::KeyLanguage,
236 RuntimeMD::OpenCL_C, 1);
237 uint16_t Major = mdconst::extract<ConstantInt>(Node->getOperand(0))
238 ->getZExtValue();
239 uint16_t Minor = mdconst::extract<ConstantInt>(Node->getOperand(1))
240 ->getZExtValue();
241 emitRuntimeMDIntValue(RuntimeMD::KeyLanguageVersion,
242 Major * 100 + Minor * 10, 2);
243 }
244 }
245 }
246
247 if (auto MD = M.getNamedMetadata("llvm.printf.fmts")) {
248 for (unsigned I = 0; I < MD->getNumOperands(); ++I) {
249 auto Node = MD->getOperand(I);
250 if (Node->getNumOperands() > 0)
251 emitRuntimeMDStringValue(RuntimeMD::KeyPrintfInfo,
252 cast<MDString>(Node->getOperand(0))->getString());
253 }
254 }
255}
256
257static std::string getOCLTypeName(Type *Ty, bool Signed) {
258 switch (Ty->getTypeID()) {
259 case Type::HalfTyID:
260 return "half";
261 case Type::FloatTyID:
262 return "float";
263 case Type::DoubleTyID:
264 return "double";
265 case Type::IntegerTyID: {
266 if (!Signed)
267 return (Twine('u') + getOCLTypeName(Ty, true)).str();
268 unsigned BW = Ty->getIntegerBitWidth();
269 switch (BW) {
270 case 8:
271 return "char";
272 case 16:
273 return "short";
274 case 32:
275 return "int";
276 case 64:
277 return "long";
278 default:
279 return (Twine('i') + Twine(BW)).str();
280 }
281 }
282 case Type::VectorTyID: {
283 VectorType *VecTy = cast<VectorType>(Ty);
284 Type *EleTy = VecTy->getElementType();
285 unsigned Size = VecTy->getVectorNumElements();
286 return (Twine(getOCLTypeName(EleTy, Signed)) + Twine(Size)).str();
287 }
288 default:
289 return "unknown";
290 }
291}
292
293static RuntimeMD::KernelArg::ValueType getRuntimeMDValueType(
294 Type *Ty, StringRef TypeName) {
295 switch (Ty->getTypeID()) {
296 case Type::HalfTyID:
297 return RuntimeMD::KernelArg::F16;
298 case Type::FloatTyID:
299 return RuntimeMD::KernelArg::F32;
300 case Type::DoubleTyID:
301 return RuntimeMD::KernelArg::F64;
302 case Type::IntegerTyID: {
303 bool Signed = !TypeName.startswith("u");
304 switch (Ty->getIntegerBitWidth()) {
305 case 8:
306 return Signed ? RuntimeMD::KernelArg::I8 : RuntimeMD::KernelArg::U8;
307 case 16:
308 return Signed ? RuntimeMD::KernelArg::I16 : RuntimeMD::KernelArg::U16;
309 case 32:
310 return Signed ? RuntimeMD::KernelArg::I32 : RuntimeMD::KernelArg::U32;
311 case 64:
312 return Signed ? RuntimeMD::KernelArg::I64 : RuntimeMD::KernelArg::U64;
313 default:
314 // Runtime does not recognize other integer types. Report as struct type.
315 return RuntimeMD::KernelArg::Struct;
316 }
317 }
318 case Type::VectorTyID:
319 return getRuntimeMDValueType(Ty->getVectorElementType(), TypeName);
320 case Type::PointerTyID:
321 return getRuntimeMDValueType(Ty->getPointerElementType(), TypeName);
322 default:
323 return RuntimeMD::KernelArg::Struct;
324 }
325}
326
327static RuntimeMD::KernelArg::AddressSpaceQualifer getRuntimeAddrSpace(
328 AMDGPUAS::AddressSpaces A) {
329 switch (A) {
330 case AMDGPUAS::GLOBAL_ADDRESS:
331 return RuntimeMD::KernelArg::Global;
332 case AMDGPUAS::CONSTANT_ADDRESS:
333 return RuntimeMD::KernelArg::Constant;
334 case AMDGPUAS::LOCAL_ADDRESS:
335 return RuntimeMD::KernelArg::Local;
336 case AMDGPUAS::FLAT_ADDRESS:
337 return RuntimeMD::KernelArg::Generic;
338 case AMDGPUAS::REGION_ADDRESS:
339 return RuntimeMD::KernelArg::Region;
340 default:
341 return RuntimeMD::KernelArg::Private;
342 }
343}
344
345void AMDGPUTargetStreamer::emitRuntimeMetadataForKernelArg(const DataLayout &DL,
346 Type *T, RuntimeMD::KernelArg::Kind Kind,
347 StringRef BaseTypeName, StringRef TypeName,
348 StringRef ArgName, StringRef TypeQual, StringRef AccQual) {
349 auto &S = getStreamer();
350
351 // Emit KeyArgBegin.
352 S.EmitIntValue(RuntimeMD::KeyArgBegin, 1);
353
354 // Emit KeyArgSize and KeyArgAlign.
355 emitRuntimeMDIntValue(RuntimeMD::KeyArgSize,
356 DL.getTypeAllocSize(T), 4);
357 emitRuntimeMDIntValue(RuntimeMD::KeyArgAlign,
358 DL.getABITypeAlignment(T), 4);
359 if (auto PT = dyn_cast<PointerType>(T)) {
360 auto ET = PT->getElementType();
361 if (PT->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS && ET->isSized())
362 emitRuntimeMDIntValue(RuntimeMD::KeyArgPointeeAlign,
363 DL.getABITypeAlignment(ET), 4);
364 }
365
366 // Emit KeyArgTypeName.
367 if (!TypeName.empty())
368 emitRuntimeMDStringValue(RuntimeMD::KeyArgTypeName, TypeName);
369
370 // Emit KeyArgName.
371 if (!ArgName.empty())
372 emitRuntimeMDStringValue(RuntimeMD::KeyArgName, ArgName);
373
374 // Emit KeyArgIsVolatile, KeyArgIsRestrict, KeyArgIsConst and KeyArgIsPipe.
375 SmallVector<StringRef, 1> SplitQ;
376 TypeQual.split(SplitQ, " ", -1, false /* Drop empty entry */);
377
378 for (StringRef KeyName : SplitQ) {
379 auto Key = StringSwitch<RuntimeMD::Key>(KeyName)
380 .Case("volatile", RuntimeMD::KeyArgIsVolatile)
381 .Case("restrict", RuntimeMD::KeyArgIsRestrict)
382 .Case("const", RuntimeMD::KeyArgIsConst)
383 .Case("pipe", RuntimeMD::KeyArgIsPipe)
384 .Default(RuntimeMD::KeyNull);
385 S.EmitIntValue(Key, 1);
386 }
387
388 // Emit KeyArgKind.
389 emitRuntimeMDIntValue(RuntimeMD::KeyArgKind, Kind, 1);
390
391 // Emit KeyArgValueType.
392 emitRuntimeMDIntValue(RuntimeMD::KeyArgValueType,
393 getRuntimeMDValueType(T, BaseTypeName), 2);
394
395 // Emit KeyArgAccQual.
396 if (!AccQual.empty()) {
397 auto AQ = StringSwitch<RuntimeMD::KernelArg::AccessQualifer>(AccQual)
398 .Case("read_only", RuntimeMD::KernelArg::ReadOnly)
399 .Case("write_only", RuntimeMD::KernelArg::WriteOnly)
400 .Case("read_write", RuntimeMD::KernelArg::ReadWrite)
401 .Default(RuntimeMD::KernelArg::None);
402 emitRuntimeMDIntValue(RuntimeMD::KeyArgAccQual, AQ, 1);
403 }
404
405 // Emit KeyArgAddrQual.
406 if (auto *PT = dyn_cast<PointerType>(T))
407 emitRuntimeMDIntValue(RuntimeMD::KeyArgAddrQual,
408 getRuntimeAddrSpace(static_cast<AMDGPUAS::AddressSpaces>(
409 PT->getAddressSpace())), 1);
410
411 // Emit KeyArgEnd
412 S.EmitIntValue(RuntimeMD::KeyArgEnd, 1);
413}
414
415void AMDGPUTargetStreamer::emitRuntimeMetadata(const Function &F) {
416 if (!F.getMetadata("kernel_arg_type"))
417 return;
418 auto &S = getStreamer();
419 S.EmitIntValue(RuntimeMD::KeyKernelBegin, 1);
420 emitRuntimeMDStringValue(RuntimeMD::KeyKernelName, F.getName());
421
422 const DataLayout &DL = F.getParent()->getDataLayout();
423 for (auto &Arg : F.args()) {
424 unsigned I = Arg.getArgNo();
425 Type *T = Arg.getType();
426 auto TypeName = dyn_cast<MDString>(F.getMetadata(
427 "kernel_arg_type")->getOperand(I))->getString();
428 auto BaseTypeName = cast<MDString>(F.getMetadata(
429 "kernel_arg_base_type")->getOperand(I))->getString();
430 StringRef ArgName;
431 if (auto ArgNameMD = F.getMetadata("kernel_arg_name"))
432 ArgName = cast<MDString>(ArgNameMD->getOperand(I))->getString();
433 auto TypeQual = cast<MDString>(F.getMetadata(
434 "kernel_arg_type_qual")->getOperand(I))->getString();
435 auto AccQual = cast<MDString>(F.getMetadata(
436 "kernel_arg_access_qual")->getOperand(I))->getString();
437 RuntimeMD::KernelArg::Kind Kind;
438 if (TypeQual.find("pipe") != StringRef::npos)
439 Kind = RuntimeMD::KernelArg::Pipe;
440 else Kind = StringSwitch<RuntimeMD::KernelArg::Kind>(BaseTypeName)
441 .Case("sampler_t", RuntimeMD::KernelArg::Sampler)
442 .Case("queue_t", RuntimeMD::KernelArg::Queue)
443 .Cases("image1d_t", "image1d_array_t", "image1d_buffer_t",
444 "image2d_t" , "image2d_array_t", RuntimeMD::KernelArg::Image)
445 .Cases("image2d_depth_t", "image2d_array_depth_t",
446 "image2d_msaa_t", "image2d_array_msaa_t",
447 "image2d_msaa_depth_t", RuntimeMD::KernelArg::Image)
448 .Cases("image2d_array_msaa_depth_t", "image3d_t",
449 RuntimeMD::KernelArg::Image)
450 .Default(isa<PointerType>(T) ?
451 (T->getPointerAddressSpace() == AMDGPUAS::LOCAL_ADDRESS ?
452 RuntimeMD::KernelArg::DynamicSharedPointer :
453 RuntimeMD::KernelArg::GlobalBuffer) :
454 RuntimeMD::KernelArg::ByValue);
455 emitRuntimeMetadataForKernelArg(DL, T,
456 Kind, BaseTypeName, TypeName, ArgName, TypeQual, AccQual);
457 }
458
459 // Emit hidden kernel arguments for OpenCL kernels.
460 if (F.getParent()->getNamedMetadata("opencl.ocl.version")) {
461 auto Int64T = Type::getInt64Ty(F.getContext());
462 emitRuntimeMetadataForKernelArg(DL, Int64T,
463 RuntimeMD::KernelArg::HiddenGlobalOffsetX);
464 emitRuntimeMetadataForKernelArg(DL, Int64T,
465 RuntimeMD::KernelArg::HiddenGlobalOffsetY);
466 emitRuntimeMetadataForKernelArg(DL, Int64T,
467 RuntimeMD::KernelArg::HiddenGlobalOffsetZ);
468 if (F.getParent()->getNamedMetadata("llvm.printf.fmts")) {
469 auto Int8PtrT = Type::getInt8PtrTy(F.getContext(),
470 RuntimeMD::KernelArg::Global);
471 emitRuntimeMetadataForKernelArg(DL, Int8PtrT,
472 RuntimeMD::KernelArg::HiddenPrintfBuffer);
473 }
474 }
475
476 // Emit KeyReqdWorkGroupSize, KeyWorkGroupSizeHint, and KeyVecTypeHint.
477 if (auto RWGS = F.getMetadata("reqd_work_group_size")) {
478 emitRuntimeMDThreeIntValues(RuntimeMD::KeyReqdWorkGroupSize,
479 RWGS, 4);
480 }
481
482 if (auto WGSH = F.getMetadata("work_group_size_hint")) {
483 emitRuntimeMDThreeIntValues(RuntimeMD::KeyWorkGroupSizeHint,
484 WGSH, 4);
485 }
486
487 if (auto VTH = F.getMetadata("vec_type_hint")) {
488 auto TypeName = getOCLTypeName(cast<ValueAsMetadata>(
489 VTH->getOperand(0))->getType(), mdconst::extract<ConstantInt>(
490 VTH->getOperand(1))->getZExtValue());
491 emitRuntimeMDStringValue(RuntimeMD::KeyVecTypeHint, TypeName);
492 }
493
494 // Emit KeyKernelEnd
495 S.EmitIntValue(RuntimeMD::KeyKernelEnd, 1);
496}
497
498void AMDGPUTargetStreamer::emitRuntimeMetadataAsNoteElement(Module &M) {
499 auto &S = getStreamer();
500 auto &Context = S.getContext();
501
502 auto NameSZ = sizeof(PT_NOTE::NoteName); // Size of note name including trailing null.
503
504 S.PushSection();
505 S.SwitchSection(Context.getELFSection(
506 PT_NOTE::SectionName, ELF::SHT_NOTE, ELF::SHF_ALLOC));
507
508 // Create two labels to mark the beginning and end of the desc field
509 // and a MCExpr to calculate the size of the desc field.
510 auto *DescBegin = Context.createTempSymbol();
511 auto *DescEnd = Context.createTempSymbol();
512 auto *DescSZ = MCBinaryExpr::createSub(
513 MCSymbolRefExpr::create(DescEnd, Context),
514 MCSymbolRefExpr::create(DescBegin, Context), Context);
515
516 // Emit the note element for runtime metadata.
517 // Name and desc should be padded to 4 byte boundary but size of name and
518 // desc should not include padding 0's.
519 S.EmitIntValue(NameSZ, 4); // namesz
520 S.EmitValue(DescSZ, 4); // descz
521 S.EmitIntValue(PT_NOTE::NT_AMDGPU_HSA_RUNTIME_METADATA, 4); // type
522 S.EmitBytes(StringRef(PT_NOTE::NoteName, NameSZ)); // name
523 S.EmitValueToAlignment(4); // padding 0
524 S.EmitLabel(DescBegin);
525 emitRuntimeMetadata(M); // desc
526 S.EmitLabel(DescEnd);
527 S.EmitValueToAlignment(4); // padding 0
528 S.PopSection();
529}
530
531void AMDGPUTargetStreamer::emitRuntimeMetadata(Module &M) {
532 emitStartOfRuntimeMetadata(M);
533 for (auto &F : M.functions())
534 emitRuntimeMetadata(F);
535}
536