LLVM  10.0.0svn
AMDGPUTargetStreamer.cpp
Go to the documentation of this file.
1 //===-- AMDGPUTargetStreamer.cpp - Mips Target Streamer Methods -----------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file provides AMDGPU specific target streamer methods.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "AMDGPUTargetStreamer.h"
14 #include "AMDGPU.h"
15 #include "SIDefines.h"
16 #include "Utils/AMDGPUBaseInfo.h"
18 #include "llvm/ADT/Twine.h"
20 #include "llvm/BinaryFormat/ELF.h"
21 #include "llvm/IR/Constants.h"
22 #include "llvm/IR/Function.h"
23 #include "llvm/IR/Metadata.h"
24 #include "llvm/IR/Module.h"
25 #include "llvm/MC/MCContext.h"
26 #include "llvm/MC/MCELFStreamer.h"
28 #include "llvm/MC/MCSectionELF.h"
31 
32 namespace llvm {
33 #include "AMDGPUPTNote.h"
34 }
35 
36 using namespace llvm;
37 using namespace llvm::AMDGPU;
38 using namespace llvm::AMDGPU::HSAMD;
39 
40 //===----------------------------------------------------------------------===//
41 // AMDGPUTargetStreamer
42 //===----------------------------------------------------------------------===//
43 
45  HSAMD::Metadata HSAMetadata;
46  if (HSAMD::fromString(HSAMetadataString, HSAMetadata))
47  return false;
48 
49  return EmitHSAMetadata(HSAMetadata);
50 }
51 
53  msgpack::Document HSAMetadataDoc;
54  if (!HSAMetadataDoc.fromYAML(HSAMetadataString))
55  return false;
56  return EmitHSAMetadata(HSAMetadataDoc, false);
57 }
58 
60  AMDGPU::GPUKind AK;
61 
62  switch (ElfMach) {
63  case ELF::EF_AMDGPU_MACH_R600_R600: AK = GK_R600; break;
64  case ELF::EF_AMDGPU_MACH_R600_R630: AK = GK_R630; break;
65  case ELF::EF_AMDGPU_MACH_R600_RS880: AK = GK_RS880; break;
66  case ELF::EF_AMDGPU_MACH_R600_RV670: AK = GK_RV670; break;
67  case ELF::EF_AMDGPU_MACH_R600_RV710: AK = GK_RV710; break;
68  case ELF::EF_AMDGPU_MACH_R600_RV730: AK = GK_RV730; break;
69  case ELF::EF_AMDGPU_MACH_R600_RV770: AK = GK_RV770; break;
70  case ELF::EF_AMDGPU_MACH_R600_CEDAR: AK = GK_CEDAR; break;
74  case ELF::EF_AMDGPU_MACH_R600_SUMO: AK = GK_SUMO; break;
75  case ELF::EF_AMDGPU_MACH_R600_BARTS: AK = GK_BARTS; break;
78  case ELF::EF_AMDGPU_MACH_R600_TURKS: AK = GK_TURKS; break;
99  case ELF::EF_AMDGPU_MACH_NONE: AK = GK_NONE; break;
100  }
101 
102  StringRef GPUName = getArchNameAMDGCN(AK);
103  if (GPUName != "")
104  return GPUName;
105  return getArchNameR600(AK);
106 }
107 
110  if (AK == AMDGPU::GPUKind::GK_NONE)
111  AK = parseArchR600(GPU);
112 
113  switch (AK) {
150  case GK_NONE: return ELF::EF_AMDGPU_MACH_NONE;
151  }
152 
153  llvm_unreachable("unknown GPU");
154 }
155 
156 //===----------------------------------------------------------------------===//
157 // AMDGPUTargetAsmStreamer
158 //===----------------------------------------------------------------------===//
159 
162  : AMDGPUTargetStreamer(S), OS(OS) { }
163 
164 // A hook for emitting stuff at the end.
165 // We use it for emitting the accumulated PAL metadata as directives.
167  std::string S;
168  getPALMetadata()->toString(S);
169  OS << S;
170 }
171 
173  OS << "\t.amdgcn_target \"" << Target << "\"\n";
174 }
175 
177  uint32_t Major, uint32_t Minor) {
178  OS << "\t.hsa_code_object_version " <<
179  Twine(Major) << "," << Twine(Minor) << '\n';
180 }
181 
182 void
184  uint32_t Minor,
185  uint32_t Stepping,
186  StringRef VendorName,
187  StringRef ArchName) {
188  OS << "\t.hsa_code_object_isa " <<
189  Twine(Major) << "," << Twine(Minor) << "," << Twine(Stepping) <<
190  ",\"" << VendorName << "\",\"" << ArchName << "\"\n";
191 
192 }
193 
194 void
196  OS << "\t.amd_kernel_code_t\n";
197  dumpAmdKernelCode(&Header, OS, "\t\t");
198  OS << "\t.end_amd_kernel_code_t\n";
199 }
200 
202  unsigned Type) {
203  switch (Type) {
204  default: llvm_unreachable("Invalid AMDGPU symbol type");
206  OS << "\t.amdgpu_hsa_kernel " << SymbolName << '\n' ;
207  break;
208  }
209 }
210 
212  unsigned Align) {
213  OS << "\t.amdgpu_lds " << Symbol->getName() << ", " << Size << ", " << Align
214  << '\n';
215 }
216 
218  OS << "\t.amd_amdgpu_isa \"" << IsaVersionString << "\"\n";
219  return true;
220 }
221 
223  const AMDGPU::HSAMD::Metadata &HSAMetadata) {
224  std::string HSAMetadataString;
225  if (HSAMD::toString(HSAMetadata, HSAMetadataString))
226  return false;
227 
228  OS << '\t' << AssemblerDirectiveBegin << '\n';
229  OS << HSAMetadataString << '\n';
230  OS << '\t' << AssemblerDirectiveEnd << '\n';
231  return true;
232 }
233 
235  msgpack::Document &HSAMetadataDoc, bool Strict) {
237  if (!Verifier.verify(HSAMetadataDoc.getRoot()))
238  return false;
239 
240  std::string HSAMetadataString;
241  raw_string_ostream StrOS(HSAMetadataString);
242  HSAMetadataDoc.toYAML(StrOS);
243 
244  OS << '\t' << V3::AssemblerDirectiveBegin << '\n';
245  OS << StrOS.str() << '\n';
246  OS << '\t' << V3::AssemblerDirectiveEnd << '\n';
247  return true;
248 }
249 
251  const uint32_t Encoded_s_code_end = 0xbf9f0000;
252  OS << "\t.p2alignl 6, " << Encoded_s_code_end << '\n';
253  OS << "\t.fill 48, 4, " << Encoded_s_code_end << '\n';
254  return true;
255 }
256 
258  const MCSubtargetInfo &STI, StringRef KernelName,
259  const amdhsa::kernel_descriptor_t &KD, uint64_t NextVGPR, uint64_t NextSGPR,
260  bool ReserveVCC, bool ReserveFlatScr, bool ReserveXNACK) {
261  IsaVersion IVersion = getIsaVersion(STI.getCPU());
262 
263  OS << "\t.amdhsa_kernel " << KernelName << '\n';
264 
265 #define PRINT_FIELD(STREAM, DIRECTIVE, KERNEL_DESC, MEMBER_NAME, FIELD_NAME) \
266  STREAM << "\t\t" << DIRECTIVE << " " \
267  << AMDHSA_BITS_GET(KERNEL_DESC.MEMBER_NAME, FIELD_NAME) << '\n';
268 
269  OS << "\t\t.amdhsa_group_segment_fixed_size " << KD.group_segment_fixed_size
270  << '\n';
271  OS << "\t\t.amdhsa_private_segment_fixed_size "
272  << KD.private_segment_fixed_size << '\n';
273 
274  PRINT_FIELD(OS, ".amdhsa_user_sgpr_private_segment_buffer", KD,
275  kernel_code_properties,
276  amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER);
277  PRINT_FIELD(OS, ".amdhsa_user_sgpr_dispatch_ptr", KD,
278  kernel_code_properties,
279  amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR);
280  PRINT_FIELD(OS, ".amdhsa_user_sgpr_queue_ptr", KD,
281  kernel_code_properties,
282  amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR);
283  PRINT_FIELD(OS, ".amdhsa_user_sgpr_kernarg_segment_ptr", KD,
284  kernel_code_properties,
285  amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR);
286  PRINT_FIELD(OS, ".amdhsa_user_sgpr_dispatch_id", KD,
287  kernel_code_properties,
288  amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID);
289  PRINT_FIELD(OS, ".amdhsa_user_sgpr_flat_scratch_init", KD,
290  kernel_code_properties,
291  amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT);
292  PRINT_FIELD(OS, ".amdhsa_user_sgpr_private_segment_size", KD,
293  kernel_code_properties,
294  amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE);
295  if (IVersion.Major >= 10)
296  PRINT_FIELD(OS, ".amdhsa_wavefront_size32", KD,
297  kernel_code_properties,
298  amdhsa::KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32);
299  PRINT_FIELD(
300  OS, ".amdhsa_system_sgpr_private_segment_wavefront_offset", KD,
301  compute_pgm_rsrc2,
302  amdhsa::COMPUTE_PGM_RSRC2_ENABLE_SGPR_PRIVATE_SEGMENT_WAVEFRONT_OFFSET);
303  PRINT_FIELD(OS, ".amdhsa_system_sgpr_workgroup_id_x", KD,
304  compute_pgm_rsrc2,
305  amdhsa::COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X);
306  PRINT_FIELD(OS, ".amdhsa_system_sgpr_workgroup_id_y", KD,
307  compute_pgm_rsrc2,
308  amdhsa::COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y);
309  PRINT_FIELD(OS, ".amdhsa_system_sgpr_workgroup_id_z", KD,
310  compute_pgm_rsrc2,
311  amdhsa::COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z);
312  PRINT_FIELD(OS, ".amdhsa_system_sgpr_workgroup_info", KD,
313  compute_pgm_rsrc2,
314  amdhsa::COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO);
315  PRINT_FIELD(OS, ".amdhsa_system_vgpr_workitem_id", KD,
316  compute_pgm_rsrc2,
317  amdhsa::COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID);
318 
319  // These directives are required.
320  OS << "\t\t.amdhsa_next_free_vgpr " << NextVGPR << '\n';
321  OS << "\t\t.amdhsa_next_free_sgpr " << NextSGPR << '\n';
322 
323  if (!ReserveVCC)
324  OS << "\t\t.amdhsa_reserve_vcc " << ReserveVCC << '\n';
325  if (IVersion.Major >= 7 && !ReserveFlatScr)
326  OS << "\t\t.amdhsa_reserve_flat_scratch " << ReserveFlatScr << '\n';
327  if (IVersion.Major >= 8 && ReserveXNACK != hasXNACK(STI))
328  OS << "\t\t.amdhsa_reserve_xnack_mask " << ReserveXNACK << '\n';
329 
330  PRINT_FIELD(OS, ".amdhsa_float_round_mode_32", KD,
331  compute_pgm_rsrc1,
332  amdhsa::COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32);
333  PRINT_FIELD(OS, ".amdhsa_float_round_mode_16_64", KD,
334  compute_pgm_rsrc1,
335  amdhsa::COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64);
336  PRINT_FIELD(OS, ".amdhsa_float_denorm_mode_32", KD,
337  compute_pgm_rsrc1,
338  amdhsa::COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32);
339  PRINT_FIELD(OS, ".amdhsa_float_denorm_mode_16_64", KD,
340  compute_pgm_rsrc1,
341  amdhsa::COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64);
342  PRINT_FIELD(OS, ".amdhsa_dx10_clamp", KD,
343  compute_pgm_rsrc1,
344  amdhsa::COMPUTE_PGM_RSRC1_ENABLE_DX10_CLAMP);
345  PRINT_FIELD(OS, ".amdhsa_ieee_mode", KD,
346  compute_pgm_rsrc1,
347  amdhsa::COMPUTE_PGM_RSRC1_ENABLE_IEEE_MODE);
348  if (IVersion.Major >= 9)
349  PRINT_FIELD(OS, ".amdhsa_fp16_overflow", KD,
350  compute_pgm_rsrc1,
351  amdhsa::COMPUTE_PGM_RSRC1_FP16_OVFL);
352  if (IVersion.Major >= 10) {
353  PRINT_FIELD(OS, ".amdhsa_workgroup_processor_mode", KD,
354  compute_pgm_rsrc1,
355  amdhsa::COMPUTE_PGM_RSRC1_WGP_MODE);
356  PRINT_FIELD(OS, ".amdhsa_memory_ordered", KD,
357  compute_pgm_rsrc1,
358  amdhsa::COMPUTE_PGM_RSRC1_MEM_ORDERED);
359  PRINT_FIELD(OS, ".amdhsa_forward_progress", KD,
360  compute_pgm_rsrc1,
361  amdhsa::COMPUTE_PGM_RSRC1_FWD_PROGRESS);
362  }
363  PRINT_FIELD(
364  OS, ".amdhsa_exception_fp_ieee_invalid_op", KD,
365  compute_pgm_rsrc2,
366  amdhsa::COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION);
367  PRINT_FIELD(OS, ".amdhsa_exception_fp_denorm_src", KD,
368  compute_pgm_rsrc2,
369  amdhsa::COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE);
370  PRINT_FIELD(
371  OS, ".amdhsa_exception_fp_ieee_div_zero", KD,
372  compute_pgm_rsrc2,
373  amdhsa::COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO);
374  PRINT_FIELD(OS, ".amdhsa_exception_fp_ieee_overflow", KD,
375  compute_pgm_rsrc2,
376  amdhsa::COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW);
377  PRINT_FIELD(OS, ".amdhsa_exception_fp_ieee_underflow", KD,
378  compute_pgm_rsrc2,
379  amdhsa::COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW);
380  PRINT_FIELD(OS, ".amdhsa_exception_fp_ieee_inexact", KD,
381  compute_pgm_rsrc2,
382  amdhsa::COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT);
383  PRINT_FIELD(OS, ".amdhsa_exception_int_div_zero", KD,
384  compute_pgm_rsrc2,
385  amdhsa::COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO);
386 #undef PRINT_FIELD
387 
388  OS << "\t.end_amdhsa_kernel\n";
389 }
390 
391 //===----------------------------------------------------------------------===//
392 // AMDGPUTargetELFStreamer
393 //===----------------------------------------------------------------------===//
394 
396  MCStreamer &S, const MCSubtargetInfo &STI)
397  : AMDGPUTargetStreamer(S), Streamer(S) {
399  unsigned EFlags = MCA.getELFHeaderEFlags();
400 
401  EFlags &= ~ELF::EF_AMDGPU_MACH;
402  EFlags |= getElfMach(STI.getCPU());
403 
404  EFlags &= ~ELF::EF_AMDGPU_XNACK;
405  if (AMDGPU::hasXNACK(STI))
406  EFlags |= ELF::EF_AMDGPU_XNACK;
407 
408  EFlags &= ~ELF::EF_AMDGPU_SRAM_ECC;
409  if (AMDGPU::hasSRAMECC(STI))
410  EFlags |= ELF::EF_AMDGPU_SRAM_ECC;
411 
412  MCA.setELFHeaderEFlags(EFlags);
413 }
414 
416  return static_cast<MCELFStreamer &>(Streamer);
417 }
418 
419 // A hook for emitting stuff at the end.
420 // We use it for emitting the accumulated PAL metadata as a .note record.
422  std::string Blob;
423  const char *Vendor = getPALMetadata()->getVendor();
424  unsigned Type = getPALMetadata()->getType();
425  getPALMetadata()->toBlob(Type, Blob);
426  if (Blob.empty())
427  return;
428  EmitNote(Vendor, MCConstantExpr::create(Blob.size(), getContext()), Type,
429  [&](MCELFStreamer &OS) { OS.EmitBytes(Blob); });
430 }
431 
432 void AMDGPUTargetELFStreamer::EmitNote(
433  StringRef Name, const MCExpr *DescSZ, unsigned NoteType,
434  function_ref<void(MCELFStreamer &)> EmitDesc) {
435  auto &S = getStreamer();
436  auto &Context = S.getContext();
437 
438  auto NameSZ = Name.size() + 1;
439 
440  S.PushSection();
441  S.SwitchSection(Context.getELFSection(
443  S.EmitIntValue(NameSZ, 4); // namesz
444  S.EmitValue(DescSZ, 4); // descz
445  S.EmitIntValue(NoteType, 4); // type
446  S.EmitBytes(Name); // name
447  S.EmitValueToAlignment(4, 0, 1, 0); // padding 0
448  EmitDesc(S); // desc
449  S.EmitValueToAlignment(4, 0, 1, 0); // padding 0
450  S.PopSection();
451 }
452 
454 
456  uint32_t Major, uint32_t Minor) {
457 
460  OS.EmitIntValue(Major, 4);
461  OS.EmitIntValue(Minor, 4);
462  });
463 }
464 
465 void
467  uint32_t Minor,
468  uint32_t Stepping,
469  StringRef VendorName,
470  StringRef ArchName) {
471  uint16_t VendorNameSize = VendorName.size() + 1;
472  uint16_t ArchNameSize = ArchName.size() + 1;
473 
474  unsigned DescSZ = sizeof(VendorNameSize) + sizeof(ArchNameSize) +
475  sizeof(Major) + sizeof(Minor) + sizeof(Stepping) +
476  VendorNameSize + ArchNameSize;
477 
480  OS.EmitIntValue(VendorNameSize, 2);
481  OS.EmitIntValue(ArchNameSize, 2);
482  OS.EmitIntValue(Major, 4);
483  OS.EmitIntValue(Minor, 4);
484  OS.EmitIntValue(Stepping, 4);
485  OS.EmitBytes(VendorName);
486  OS.EmitIntValue(0, 1); // NULL terminate VendorName
487  OS.EmitBytes(ArchName);
488  OS.EmitIntValue(0, 1); // NULL terminte ArchName
489  });
490 }
491 
492 void
494 
495  MCStreamer &OS = getStreamer();
496  OS.PushSection();
497  OS.EmitBytes(StringRef((const char*)&Header, sizeof(Header)));
498  OS.PopSection();
499 }
500 
502  unsigned Type) {
503  MCSymbolELF *Symbol = cast<MCSymbolELF>(
504  getStreamer().getContext().getOrCreateSymbol(SymbolName));
505  Symbol->setType(Type);
506 }
507 
509  unsigned Align) {
510  assert(isPowerOf2_32(Align));
511 
512  MCSymbolELF *SymbolELF = cast<MCSymbolELF>(Symbol);
513  SymbolELF->setType(ELF::STT_OBJECT);
514 
515  if (!SymbolELF->isBindingSet()) {
516  SymbolELF->setBinding(ELF::STB_GLOBAL);
517  SymbolELF->setExternal(true);
518  }
519 
520  if (SymbolELF->declareCommon(Size, Align, true)) {
521  report_fatal_error("Symbol: " + Symbol->getName() +
522  " redeclared as different type");
523  }
524 
525  SymbolELF->setIndex(ELF::SHN_AMDGPU_LDS);
526  SymbolELF->setSize(MCConstantExpr::create(Size, getContext()));
527 }
528 
530  // Create two labels to mark the beginning and end of the desc field
531  // and a MCExpr to calculate the size of the desc field.
532  auto &Context = getContext();
533  auto *DescBegin = Context.createTempSymbol();
534  auto *DescEnd = Context.createTempSymbol();
535  auto *DescSZ = MCBinaryExpr::createSub(
538 
540  [&](MCELFStreamer &OS) {
541  OS.EmitLabel(DescBegin);
542  OS.EmitBytes(IsaVersionString);
543  OS.EmitLabel(DescEnd);
544  });
545  return true;
546 }
547 
549  bool Strict) {
551  if (!Verifier.verify(HSAMetadataDoc.getRoot()))
552  return false;
553 
554  std::string HSAMetadataString;
555  HSAMetadataDoc.writeToBlob(HSAMetadataString);
556 
557  // Create two labels to mark the beginning and end of the desc field
558  // and a MCExpr to calculate the size of the desc field.
559  auto &Context = getContext();
560  auto *DescBegin = Context.createTempSymbol();
561  auto *DescEnd = Context.createTempSymbol();
562  auto *DescSZ = MCBinaryExpr::createSub(
565 
567  [&](MCELFStreamer &OS) {
568  OS.EmitLabel(DescBegin);
569  OS.EmitBytes(HSAMetadataString);
570  OS.EmitLabel(DescEnd);
571  });
572  return true;
573 }
574 
576  const AMDGPU::HSAMD::Metadata &HSAMetadata) {
577  std::string HSAMetadataString;
578  if (HSAMD::toString(HSAMetadata, HSAMetadataString))
579  return false;
580 
581  // Create two labels to mark the beginning and end of the desc field
582  // and a MCExpr to calculate the size of the desc field.
583  auto &Context = getContext();
584  auto *DescBegin = Context.createTempSymbol();
585  auto *DescEnd = Context.createTempSymbol();
586  auto *DescSZ = MCBinaryExpr::createSub(
589 
591  [&](MCELFStreamer &OS) {
592  OS.EmitLabel(DescBegin);
593  OS.EmitBytes(HSAMetadataString);
594  OS.EmitLabel(DescEnd);
595  });
596  return true;
597 }
598 
600  const uint32_t Encoded_s_code_end = 0xbf9f0000;
601 
602  MCStreamer &OS = getStreamer();
603  OS.PushSection();
604  OS.EmitValueToAlignment(64, Encoded_s_code_end, 4);
605  for (unsigned I = 0; I < 48; ++I)
606  OS.EmitIntValue(Encoded_s_code_end, 4);
607  OS.PopSection();
608  return true;
609 }
610 
612  const MCSubtargetInfo &STI, StringRef KernelName,
613  const amdhsa::kernel_descriptor_t &KernelDescriptor, uint64_t NextVGPR,
614  uint64_t NextSGPR, bool ReserveVCC, bool ReserveFlatScr,
615  bool ReserveXNACK) {
616  auto &Streamer = getStreamer();
617  auto &Context = Streamer.getContext();
618 
619  MCSymbolELF *KernelCodeSymbol = cast<MCSymbolELF>(
620  Context.getOrCreateSymbol(Twine(KernelName)));
621  MCSymbolELF *KernelDescriptorSymbol = cast<MCSymbolELF>(
622  Context.getOrCreateSymbol(Twine(KernelName) + Twine(".kd")));
623 
624  // Copy kernel descriptor symbol's binding, other and visibility from the
625  // kernel code symbol.
626  KernelDescriptorSymbol->setBinding(KernelCodeSymbol->getBinding());
627  KernelDescriptorSymbol->setOther(KernelCodeSymbol->getOther());
628  KernelDescriptorSymbol->setVisibility(KernelCodeSymbol->getVisibility());
629  // Kernel descriptor symbol's type and size are fixed.
630  KernelDescriptorSymbol->setType(ELF::STT_OBJECT);
631  KernelDescriptorSymbol->setSize(
632  MCConstantExpr::create(sizeof(KernelDescriptor), Context));
633 
634  // The visibility of the kernel code symbol must be protected or less to allow
635  // static relocations from the kernel descriptor to be used.
636  if (KernelCodeSymbol->getVisibility() == ELF::STV_DEFAULT)
637  KernelCodeSymbol->setVisibility(ELF::STV_PROTECTED);
638 
639  Streamer.EmitLabel(KernelDescriptorSymbol);
640  Streamer.EmitBytes(StringRef(
641  (const char*)&(KernelDescriptor),
642  offsetof(amdhsa::kernel_descriptor_t, kernel_code_entry_byte_offset)));
643  // FIXME: Remove the use of VK_AMDGPU_REL64 in the expression below. The
644  // expression being created is:
645  // (start of kernel code) - (start of kernel descriptor)
646  // It implies R_AMDGPU_REL64, but ends up being R_AMDGPU_ABS64.
649  KernelCodeSymbol, MCSymbolRefExpr::VK_AMDGPU_REL64, Context),
651  KernelDescriptorSymbol, MCSymbolRefExpr::VK_None, Context),
652  Context),
653  sizeof(KernelDescriptor.kernel_code_entry_byte_offset));
654  Streamer.EmitBytes(StringRef(
655  (const char*)&(KernelDescriptor) +
656  offsetof(amdhsa::kernel_descriptor_t, kernel_code_entry_byte_offset) +
657  sizeof(KernelDescriptor.kernel_code_entry_byte_offset),
658  sizeof(KernelDescriptor) -
659  offsetof(amdhsa::kernel_descriptor_t, kernel_code_entry_byte_offset) -
660  sizeof(KernelDescriptor.kernel_code_entry_byte_offset)));
661 }
void setELFHeaderEFlags(unsigned Flags)
Definition: MCAssembler.h:255
In-memory representation of HSA metadata.
void toBlob(unsigned Type, std::string &S)
void EmitBytes(StringRef Data) override
Emit the bytes in Data into the output.
DocNode & getRoot()
Get ref to the document&#39;s root element.
LLVMContext & Context
bool EmitHSAMetadata(msgpack::Document &HSAMetadata, bool Strict) override
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:331
StringRef getArchNameR600(GPUKind AK)
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:139
This class represents lattice values for constants.
Definition: AllocatorList.h:23
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
unsigned getVisibility() const
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
void EmitAmdhsaKernelDescriptor(const MCSubtargetInfo &STI, StringRef KernelName, const amdhsa::kernel_descriptor_t &KernelDescriptor, uint64_t NextVGPR, uint64_t NextSGPR, bool ReserveVCC, bool ReserveFlatScr, bool ReserveXNACK) override
formatted_raw_ostream - A raw_ostream that wraps another one and keeps track of line and column posit...
void toYAML(raw_ostream &OS)
Convert MsgPack Document to YAML text.
void emitAMDGPULDS(MCSymbol *Sym, unsigned Size, unsigned Align) override
bool declareCommon(uint64_t Size, unsigned Align, bool Target=false)
Declare this symbol as being &#39;common&#39;.
Definition: MCSymbol.h:374
unsigned getBinding() const
Definition: MCSymbolELF.cpp:66
virtual void EmitBytes(StringRef Data)
Emit the bytes in Data into the output.
This file contains the declarations for metadata subclasses.
void setVisibility(unsigned Visibility)
An efficient, type-erasing, non-owning reference to a callable.
Definition: STLExtras.h:116
virtual bool EmitHSAMetadataV2(StringRef HSAMetadataString)
Instruction set architecture version.
Definition: TargetParser.h:136
void PushSection()
Save the current and previous section on the section stack.
Definition: MCStreamer.h:366
virtual bool EmitHSAMetadataV3(StringRef HSAMetadataString)
void EmitDirectiveHSACodeObjectISA(uint32_t Major, uint32_t Minor, uint32_t Stepping, StringRef VendorName, StringRef ArchName) override
void EmitDirectiveHSACodeObjectISA(uint32_t Major, uint32_t Minor, uint32_t Stepping, StringRef VendorName, StringRef ArchName) override
#define PRINT_FIELD(STREAM, DIRECTIVE, KERNEL_DESC, MEMBER_NAME, FIELD_NAME)
MCContext & getContext() const
Definition: MCStreamer.h:251
Verifier for AMDGPU HSA metadata.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
void setExternal(bool Value) const
Definition: MCSymbol.h:406
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:80
AMD Kernel Code Object (amd_kernel_code_t).
const char * getVendor() const
void toString(std::string &S)
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
static StringRef getArchNameFromElfMach(unsigned ElfMach)
StringRef getArchNameAMDGCN(GPUKind AK)
bool fromYAML(StringRef S)
Read YAML text into the MsgPack document. Returns false on failure.
std::error_code fromString(std::string String, Metadata &HSAMetadata)
Converts String to HSAMetadata.
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:554
bool isBindingSet() const
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:130
unsigned getOther() const
virtual void EmitIntValue(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers...
Definition: MCStreamer.cpp:128
void EmitValue(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:159
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false)
Definition: MCExpr.cpp:169
bool hasSRAMECC(const MCSubtargetInfo &STI)
const char NoteNameV3[]
Definition: AMDGPUPTNote.h:26
bool verify(msgpack::DocNode &HSAMetadataRoot)
Verify given HSA metadata.
Streaming machine code generation interface.
Definition: MCStreamer.h:189
constexpr char AssemblerDirectiveBegin[]
HSA metadata beginning assembler directive.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition: MathExtras.h:428
AMDGPUPALMetadata * getPALMetadata()
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
GPUKind
GPU kinds supported by the AMDGPU target.
Definition: TargetParser.h:80
void setSize(const MCExpr *SS)
Definition: MCSymbolELF.h:22
void EmitDirectiveHSACodeObjectVersion(uint32_t Major, uint32_t Minor) override
static unsigned getElfMach(StringRef GPU)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
GPUKind parseArchAMDGCN(StringRef CPU)
MCAssembler & getAssembler()
#define offsetof(TYPE, MEMBER)
virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value=0, unsigned ValueSize=1, unsigned MaxBytesToEmit=0)
Emit some number of copies of Value until the byte alignment ByteAlignment is reached.
AMDGPUTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS)
constexpr char AssemblerDirectiveEnd[]
HSA metadata ending assembler directive.
unsigned getELFHeaderEFlags() const
ELF e_header flags.
Definition: MCAssembler.h:254
std::string & str()
Flushes the stream contents to the target string and returns the string&#39;s reference.
Definition: raw_ostream.h:519
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:40
void setType(unsigned Type) const
Definition: MCSymbolELF.cpp:94
IsaVersion getIsaVersion(StringRef GPU)
void EmitAMDGPUSymbolType(StringRef SymbolName, unsigned Type) override
Enums and constants for AMDGPU PT_NOTE sections.
std::string toString(WasmSymbolType type)
Definition: Wasm.cpp:11
void EmitAmdhsaKernelDescriptor(const MCSubtargetInfo &STI, StringRef KernelName, const amdhsa::kernel_descriptor_t &KernelDescriptor, uint64_t NextVGPR, uint64_t NextSGPR, bool ReserveVCC, bool ReserveFlatScr, bool ReserveXNACK) override
MCContext & getContext() const
void emitAMDGPULDS(MCSymbol *Sym, unsigned Size, unsigned Align) override
Module.h This file contains the declarations for the Module class.
void writeToBlob(std::string &Blob)
Write a MsgPack document to a binary MsgPack blob.
void EmitAMDKernelCodeT(const amd_kernel_code_t &Header) override
MCStreamer & Streamer
Definition: MCStreamer.h:86
void setBinding(unsigned Binding) const
Definition: MCSymbolELF.cpp:41
const char NoteNameV2[]
Definition: AMDGPUPTNote.h:25
void EmitDirectiveAMDGCNTarget(StringRef Target) override
void EmitDirectiveHSACodeObjectVersion(uint32_t Major, uint32_t Minor) override
StringRef getCPU() const
Target - Wrapper for Target specific information.
bool EmitISAVersion(StringRef IsaVersionString) override
Simple in-memory representation of a document of msgpack objects with ability to find and create arra...
void EmitDirectiveAMDGCNTarget(StringRef Target) override
void EmitAMDGPUSymbolType(StringRef SymbolName, unsigned Type) override
This is a verifier for AMDGPU HSA metadata, which can verify both well-typed metadata and untyped met...
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Definition: MCContext.cpp:129
bool EmitHSAMetadata(msgpack::Document &HSAMetadata, bool Strict) override
bool hasXNACK(const MCSubtargetInfo &STI)
verify safepoint Safepoint IR Verifier
bool EmitISAVersion(StringRef IsaVersionString) override
#define I(x, y, z)
Definition: MD5.cpp:58
Generic base class for all target subtargets.
uint32_t Size
Definition: Profile.cpp:46
AMDGPUTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI)
void EmitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc()) override
Emit a label for Symbol into the current section.
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:204
void EmitAMDKernelCodeT(const amd_kernel_code_t &Header) override
void dumpAmdKernelCode(const amd_kernel_code_t *C, raw_ostream &OS, const char *tab)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:503
bool PopSection()
Restore the current and previous section from the section stack.
Definition: MCStreamer.h:375
virtual void EmitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Definition: MCStreamer.cpp:397
const char SectionName[]
Definition: AMDGPUPTNote.h:23
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
GPUKind parseArchR600(StringRef CPU)
void setIndex(uint32_t Value) const
Set the (implementation defined) index.
Definition: MCSymbol.h:318