xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp (revision 1db9f3b21e39176dd5b67cf8ac378633b172463e)
1 //===-- AMDGPUAsmPrinter.cpp - AMDGPU assembly printer --------------------===//
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 /// \file
10 ///
11 /// The AMDGPUAsmPrinter is used to print both assembly string and also binary
12 /// code.  When passed an MCAsmStreamer it prints assembly and when passed
13 /// an MCObjectStreamer it outputs binary code.
14 //
15 //===----------------------------------------------------------------------===//
16 //
17 
18 #include "AMDGPUAsmPrinter.h"
19 #include "AMDGPU.h"
20 #include "AMDGPUHSAMetadataStreamer.h"
21 #include "AMDGPUResourceUsageAnalysis.h"
22 #include "AMDKernelCodeT.h"
23 #include "GCNSubtarget.h"
24 #include "MCTargetDesc/AMDGPUInstPrinter.h"
25 #include "MCTargetDesc/AMDGPUTargetStreamer.h"
26 #include "R600AsmPrinter.h"
27 #include "SIMachineFunctionInfo.h"
28 #include "TargetInfo/AMDGPUTargetInfo.h"
29 #include "Utils/AMDGPUBaseInfo.h"
30 #include "llvm/Analysis/OptimizationRemarkEmitter.h"
31 #include "llvm/BinaryFormat/ELF.h"
32 #include "llvm/CodeGen/MachineFrameInfo.h"
33 #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
34 #include "llvm/IR/DiagnosticInfo.h"
35 #include "llvm/MC/MCAssembler.h"
36 #include "llvm/MC/MCContext.h"
37 #include "llvm/MC/MCSectionELF.h"
38 #include "llvm/MC/MCStreamer.h"
39 #include "llvm/MC/TargetRegistry.h"
40 #include "llvm/Support/AMDHSAKernelDescriptor.h"
41 #include "llvm/Target/TargetLoweringObjectFile.h"
42 #include "llvm/Target/TargetMachine.h"
43 #include "llvm/TargetParser/TargetParser.h"
44 
45 using namespace llvm;
46 using namespace llvm::AMDGPU;
47 
48 // This should get the default rounding mode from the kernel. We just set the
49 // default here, but this could change if the OpenCL rounding mode pragmas are
50 // used.
51 //
52 // The denormal mode here should match what is reported by the OpenCL runtime
53 // for the CL_FP_DENORM bit from CL_DEVICE_{HALF|SINGLE|DOUBLE}_FP_CONFIG, but
54 // can also be override to flush with the -cl-denorms-are-zero compiler flag.
55 //
56 // AMD OpenCL only sets flush none and reports CL_FP_DENORM for double
57 // precision, and leaves single precision to flush all and does not report
58 // CL_FP_DENORM for CL_DEVICE_SINGLE_FP_CONFIG. Mesa's OpenCL currently reports
59 // CL_FP_DENORM for both.
60 //
61 // FIXME: It seems some instructions do not support single precision denormals
62 // regardless of the mode (exp_*_f32, rcp_*_f32, rsq_*_f32, rsq_*f32, sqrt_f32,
63 // and sin_f32, cos_f32 on most parts).
64 
65 // We want to use these instructions, and using fp32 denormals also causes
66 // instructions to run at the double precision rate for the device so it's
67 // probably best to just report no single precision denormals.
68 static uint32_t getFPMode(SIModeRegisterDefaults Mode) {
69   return FP_ROUND_MODE_SP(FP_ROUND_ROUND_TO_NEAREST) |
70          FP_ROUND_MODE_DP(FP_ROUND_ROUND_TO_NEAREST) |
71          FP_DENORM_MODE_SP(Mode.fpDenormModeSPValue()) |
72          FP_DENORM_MODE_DP(Mode.fpDenormModeDPValue());
73 }
74 
75 static AsmPrinter *
76 createAMDGPUAsmPrinterPass(TargetMachine &tm,
77                            std::unique_ptr<MCStreamer> &&Streamer) {
78   return new AMDGPUAsmPrinter(tm, std::move(Streamer));
79 }
80 
81 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAMDGPUAsmPrinter() {
82   TargetRegistry::RegisterAsmPrinter(getTheR600Target(),
83                                      llvm::createR600AsmPrinterPass);
84   TargetRegistry::RegisterAsmPrinter(getTheGCNTarget(),
85                                      createAMDGPUAsmPrinterPass);
86 }
87 
88 AMDGPUAsmPrinter::AMDGPUAsmPrinter(TargetMachine &TM,
89                                    std::unique_ptr<MCStreamer> Streamer)
90     : AsmPrinter(TM, std::move(Streamer)) {
91   assert(OutStreamer && "AsmPrinter constructed without streamer");
92 }
93 
94 StringRef AMDGPUAsmPrinter::getPassName() const {
95   return "AMDGPU Assembly Printer";
96 }
97 
98 const MCSubtargetInfo *AMDGPUAsmPrinter::getGlobalSTI() const {
99   return TM.getMCSubtargetInfo();
100 }
101 
102 AMDGPUTargetStreamer* AMDGPUAsmPrinter::getTargetStreamer() const {
103   if (!OutStreamer)
104     return nullptr;
105   return static_cast<AMDGPUTargetStreamer*>(OutStreamer->getTargetStreamer());
106 }
107 
108 void AMDGPUAsmPrinter::emitStartOfAsmFile(Module &M) {
109   IsTargetStreamerInitialized = false;
110 }
111 
112 void AMDGPUAsmPrinter::initTargetStreamer(Module &M) {
113   IsTargetStreamerInitialized = true;
114 
115   // TODO: Which one is called first, emitStartOfAsmFile or
116   // emitFunctionBodyStart?
117   if (getTargetStreamer() && !getTargetStreamer()->getTargetID())
118     initializeTargetID(M);
119 
120   if (TM.getTargetTriple().getOS() != Triple::AMDHSA &&
121       TM.getTargetTriple().getOS() != Triple::AMDPAL)
122     return;
123 
124   getTargetStreamer()->EmitDirectiveAMDGCNTarget();
125 
126   if (TM.getTargetTriple().getOS() == Triple::AMDHSA)
127     HSAMetadataStream->begin(M, *getTargetStreamer()->getTargetID());
128 
129   if (TM.getTargetTriple().getOS() == Triple::AMDPAL)
130     getTargetStreamer()->getPALMetadata()->readFromIR(M);
131 }
132 
133 void AMDGPUAsmPrinter::emitEndOfAsmFile(Module &M) {
134   // Init target streamer if it has not yet happened
135   if (!IsTargetStreamerInitialized)
136     initTargetStreamer(M);
137 
138   if (TM.getTargetTriple().getOS() != Triple::AMDHSA)
139     getTargetStreamer()->EmitISAVersion();
140 
141   // Emit HSA Metadata (NT_AMD_AMDGPU_HSA_METADATA).
142   // Emit HSA Metadata (NT_AMD_HSA_METADATA).
143   if (TM.getTargetTriple().getOS() == Triple::AMDHSA) {
144     HSAMetadataStream->end();
145     bool Success = HSAMetadataStream->emitTo(*getTargetStreamer());
146     (void)Success;
147     assert(Success && "Malformed HSA Metadata");
148   }
149 }
150 
151 void AMDGPUAsmPrinter::emitFunctionBodyStart() {
152   const SIMachineFunctionInfo &MFI = *MF->getInfo<SIMachineFunctionInfo>();
153   const GCNSubtarget &STM = MF->getSubtarget<GCNSubtarget>();
154   const Function &F = MF->getFunction();
155 
156   // TODO: Which one is called first, emitStartOfAsmFile or
157   // emitFunctionBodyStart?
158   if (!getTargetStreamer()->getTargetID())
159     initializeTargetID(*F.getParent());
160 
161   const auto &FunctionTargetID = STM.getTargetID();
162   // Make sure function's xnack settings are compatible with module's
163   // xnack settings.
164   if (FunctionTargetID.isXnackSupported() &&
165       FunctionTargetID.getXnackSetting() != IsaInfo::TargetIDSetting::Any &&
166       FunctionTargetID.getXnackSetting() != getTargetStreamer()->getTargetID()->getXnackSetting()) {
167     OutContext.reportError({}, "xnack setting of '" + Twine(MF->getName()) +
168                            "' function does not match module xnack setting");
169     return;
170   }
171   // Make sure function's sramecc settings are compatible with module's
172   // sramecc settings.
173   if (FunctionTargetID.isSramEccSupported() &&
174       FunctionTargetID.getSramEccSetting() != IsaInfo::TargetIDSetting::Any &&
175       FunctionTargetID.getSramEccSetting() != getTargetStreamer()->getTargetID()->getSramEccSetting()) {
176     OutContext.reportError({}, "sramecc setting of '" + Twine(MF->getName()) +
177                            "' function does not match module sramecc setting");
178     return;
179   }
180 
181   if (!MFI.isEntryFunction())
182     return;
183 
184   if (STM.isMesaKernel(F) &&
185       (F.getCallingConv() == CallingConv::AMDGPU_KERNEL ||
186        F.getCallingConv() == CallingConv::SPIR_KERNEL)) {
187     amd_kernel_code_t KernelCode;
188     getAmdKernelCode(KernelCode, CurrentProgramInfo, *MF);
189     getTargetStreamer()->EmitAMDKernelCodeT(KernelCode);
190   }
191 
192   if (STM.isAmdHsaOS())
193     HSAMetadataStream->emitKernel(*MF, CurrentProgramInfo);
194 
195   if (MFI.getNumKernargPreloadedSGPRs() > 0) {
196     assert(AMDGPU::hasKernargPreload(STM));
197     getTargetStreamer()->EmitKernargPreloadHeader(*getGlobalSTI());
198   }
199 }
200 
201 void AMDGPUAsmPrinter::emitFunctionBodyEnd() {
202   const SIMachineFunctionInfo &MFI = *MF->getInfo<SIMachineFunctionInfo>();
203   if (!MFI.isEntryFunction())
204     return;
205 
206   if (TM.getTargetTriple().getOS() != Triple::AMDHSA)
207     return;
208 
209   auto &Streamer = getTargetStreamer()->getStreamer();
210   auto &Context = Streamer.getContext();
211   auto &ObjectFileInfo = *Context.getObjectFileInfo();
212   auto &ReadOnlySection = *ObjectFileInfo.getReadOnlySection();
213 
214   Streamer.pushSection();
215   Streamer.switchSection(&ReadOnlySection);
216 
217   // CP microcode requires the kernel descriptor to be allocated on 64 byte
218   // alignment.
219   Streamer.emitValueToAlignment(Align(64), 0, 1, 0);
220   ReadOnlySection.ensureMinAlignment(Align(64));
221 
222   const GCNSubtarget &STM = MF->getSubtarget<GCNSubtarget>();
223 
224   SmallString<128> KernelName;
225   getNameWithPrefix(KernelName, &MF->getFunction());
226   getTargetStreamer()->EmitAmdhsaKernelDescriptor(
227       STM, KernelName, getAmdhsaKernelDescriptor(*MF, CurrentProgramInfo),
228       CurrentProgramInfo.NumVGPRsForWavesPerEU,
229       CurrentProgramInfo.NumSGPRsForWavesPerEU -
230           IsaInfo::getNumExtraSGPRs(
231               &STM, CurrentProgramInfo.VCCUsed, CurrentProgramInfo.FlatUsed,
232               getTargetStreamer()->getTargetID()->isXnackOnOrAny()),
233       CurrentProgramInfo.VCCUsed, CurrentProgramInfo.FlatUsed,
234       CodeObjectVersion);
235 
236   Streamer.popSection();
237 }
238 
239 void AMDGPUAsmPrinter::emitImplicitDef(const MachineInstr *MI) const {
240   Register RegNo = MI->getOperand(0).getReg();
241 
242   SmallString<128> Str;
243   raw_svector_ostream OS(Str);
244   OS << "implicit-def: "
245      << printReg(RegNo, MF->getSubtarget().getRegisterInfo());
246 
247   if (MI->getAsmPrinterFlags() & AMDGPU::SGPR_SPILL)
248     OS << " : SGPR spill to VGPR lane";
249 
250   OutStreamer->AddComment(OS.str());
251   OutStreamer->addBlankLine();
252 }
253 
254 void AMDGPUAsmPrinter::emitFunctionEntryLabel() {
255   if (TM.getTargetTriple().getOS() == Triple::AMDHSA) {
256     AsmPrinter::emitFunctionEntryLabel();
257     return;
258   }
259 
260   const SIMachineFunctionInfo *MFI = MF->getInfo<SIMachineFunctionInfo>();
261   const GCNSubtarget &STM = MF->getSubtarget<GCNSubtarget>();
262   if (MFI->isEntryFunction() && STM.isAmdHsaOrMesa(MF->getFunction())) {
263     SmallString<128> SymbolName;
264     getNameWithPrefix(SymbolName, &MF->getFunction()),
265     getTargetStreamer()->EmitAMDGPUSymbolType(
266         SymbolName, ELF::STT_AMDGPU_HSA_KERNEL);
267   }
268   if (DumpCodeInstEmitter) {
269     // Disassemble function name label to text.
270     DisasmLines.push_back(MF->getName().str() + ":");
271     DisasmLineMaxLen = std::max(DisasmLineMaxLen, DisasmLines.back().size());
272     HexLines.push_back("");
273   }
274 
275   AsmPrinter::emitFunctionEntryLabel();
276 }
277 
278 void AMDGPUAsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) {
279   if (DumpCodeInstEmitter && !isBlockOnlyReachableByFallthrough(&MBB)) {
280     // Write a line for the basic block label if it is not only fallthrough.
281     DisasmLines.push_back(
282         (Twine("BB") + Twine(getFunctionNumber())
283          + "_" + Twine(MBB.getNumber()) + ":").str());
284     DisasmLineMaxLen = std::max(DisasmLineMaxLen, DisasmLines.back().size());
285     HexLines.push_back("");
286   }
287   AsmPrinter::emitBasicBlockStart(MBB);
288 }
289 
290 void AMDGPUAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
291   if (GV->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS) {
292     if (GV->hasInitializer() && !isa<UndefValue>(GV->getInitializer())) {
293       OutContext.reportError({},
294                              Twine(GV->getName()) +
295                                  ": unsupported initializer for address space");
296       return;
297     }
298 
299     // LDS variables aren't emitted in HSA or PAL yet.
300     const Triple::OSType OS = TM.getTargetTriple().getOS();
301     if (OS == Triple::AMDHSA || OS == Triple::AMDPAL)
302       return;
303 
304     MCSymbol *GVSym = getSymbol(GV);
305 
306     GVSym->redefineIfPossible();
307     if (GVSym->isDefined() || GVSym->isVariable())
308       report_fatal_error("symbol '" + Twine(GVSym->getName()) +
309                          "' is already defined");
310 
311     const DataLayout &DL = GV->getParent()->getDataLayout();
312     uint64_t Size = DL.getTypeAllocSize(GV->getValueType());
313     Align Alignment = GV->getAlign().value_or(Align(4));
314 
315     emitVisibility(GVSym, GV->getVisibility(), !GV->isDeclaration());
316     emitLinkage(GV, GVSym);
317     auto TS = getTargetStreamer();
318     TS->emitAMDGPULDS(GVSym, Size, Alignment);
319     return;
320   }
321 
322   AsmPrinter::emitGlobalVariable(GV);
323 }
324 
325 bool AMDGPUAsmPrinter::doInitialization(Module &M) {
326   CodeObjectVersion = AMDGPU::getCodeObjectVersion(M);
327 
328   if (TM.getTargetTriple().getOS() == Triple::AMDHSA) {
329     switch (CodeObjectVersion) {
330     case AMDGPU::AMDHSA_COV4:
331       HSAMetadataStream.reset(new HSAMD::MetadataStreamerMsgPackV4());
332       break;
333     case AMDGPU::AMDHSA_COV5:
334       HSAMetadataStream.reset(new HSAMD::MetadataStreamerMsgPackV5());
335       break;
336     default:
337       report_fatal_error("Unexpected code object version");
338     }
339   }
340   return AsmPrinter::doInitialization(M);
341 }
342 
343 bool AMDGPUAsmPrinter::doFinalization(Module &M) {
344   // Pad with s_code_end to help tools and guard against instruction prefetch
345   // causing stale data in caches. Arguably this should be done by the linker,
346   // which is why this isn't done for Mesa.
347   const MCSubtargetInfo &STI = *getGlobalSTI();
348   if ((AMDGPU::isGFX10Plus(STI) || AMDGPU::isGFX90A(STI)) &&
349       (STI.getTargetTriple().getOS() == Triple::AMDHSA ||
350        STI.getTargetTriple().getOS() == Triple::AMDPAL)) {
351     OutStreamer->switchSection(getObjFileLowering().getTextSection());
352     getTargetStreamer()->EmitCodeEnd(STI);
353   }
354 
355   return AsmPrinter::doFinalization(M);
356 }
357 
358 // Print comments that apply to both callable functions and entry points.
359 void AMDGPUAsmPrinter::emitCommonFunctionComments(
360     uint32_t NumVGPR, std::optional<uint32_t> NumAGPR, uint32_t TotalNumVGPR,
361     uint32_t NumSGPR, uint64_t ScratchSize, uint64_t CodeSize,
362     const AMDGPUMachineFunction *MFI) {
363   OutStreamer->emitRawComment(" codeLenInByte = " + Twine(CodeSize), false);
364   OutStreamer->emitRawComment(" NumSgprs: " + Twine(NumSGPR), false);
365   OutStreamer->emitRawComment(" NumVgprs: " + Twine(NumVGPR), false);
366   if (NumAGPR) {
367     OutStreamer->emitRawComment(" NumAgprs: " + Twine(*NumAGPR), false);
368     OutStreamer->emitRawComment(" TotalNumVgprs: " + Twine(TotalNumVGPR),
369                                 false);
370   }
371   OutStreamer->emitRawComment(" ScratchSize: " + Twine(ScratchSize), false);
372   OutStreamer->emitRawComment(" MemoryBound: " + Twine(MFI->isMemoryBound()),
373                               false);
374 }
375 
376 uint16_t AMDGPUAsmPrinter::getAmdhsaKernelCodeProperties(
377     const MachineFunction &MF) const {
378   const SIMachineFunctionInfo &MFI = *MF.getInfo<SIMachineFunctionInfo>();
379   uint16_t KernelCodeProperties = 0;
380   const GCNUserSGPRUsageInfo &UserSGPRInfo = MFI.getUserSGPRInfo();
381 
382   if (UserSGPRInfo.hasPrivateSegmentBuffer()) {
383     KernelCodeProperties |=
384         amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER;
385   }
386   if (UserSGPRInfo.hasDispatchPtr()) {
387     KernelCodeProperties |=
388         amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR;
389   }
390   if (UserSGPRInfo.hasQueuePtr() && CodeObjectVersion < AMDGPU::AMDHSA_COV5) {
391     KernelCodeProperties |=
392         amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR;
393   }
394   if (UserSGPRInfo.hasKernargSegmentPtr()) {
395     KernelCodeProperties |=
396         amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR;
397   }
398   if (UserSGPRInfo.hasDispatchID()) {
399     KernelCodeProperties |=
400         amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID;
401   }
402   if (UserSGPRInfo.hasFlatScratchInit()) {
403     KernelCodeProperties |=
404         amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT;
405   }
406   if (MF.getSubtarget<GCNSubtarget>().isWave32()) {
407     KernelCodeProperties |=
408         amdhsa::KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32;
409   }
410 
411   if (CurrentProgramInfo.DynamicCallStack &&
412       CodeObjectVersion >= AMDGPU::AMDHSA_COV5)
413     KernelCodeProperties |= amdhsa::KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK;
414 
415   return KernelCodeProperties;
416 }
417 
418 amdhsa::kernel_descriptor_t AMDGPUAsmPrinter::getAmdhsaKernelDescriptor(
419     const MachineFunction &MF,
420     const SIProgramInfo &PI) const {
421   const GCNSubtarget &STM = MF.getSubtarget<GCNSubtarget>();
422   const Function &F = MF.getFunction();
423   const SIMachineFunctionInfo *Info = MF.getInfo<SIMachineFunctionInfo>();
424 
425   amdhsa::kernel_descriptor_t KernelDescriptor;
426   memset(&KernelDescriptor, 0x0, sizeof(KernelDescriptor));
427 
428   assert(isUInt<32>(PI.ScratchSize));
429   assert(isUInt<32>(PI.getComputePGMRSrc1(STM)));
430   assert(isUInt<32>(PI.getComputePGMRSrc2()));
431 
432   KernelDescriptor.group_segment_fixed_size = PI.LDSSize;
433   KernelDescriptor.private_segment_fixed_size = PI.ScratchSize;
434 
435   Align MaxKernArgAlign;
436   KernelDescriptor.kernarg_size = STM.getKernArgSegmentSize(F, MaxKernArgAlign);
437 
438   KernelDescriptor.compute_pgm_rsrc1 = PI.getComputePGMRSrc1(STM);
439   KernelDescriptor.compute_pgm_rsrc2 = PI.getComputePGMRSrc2();
440   KernelDescriptor.kernel_code_properties = getAmdhsaKernelCodeProperties(MF);
441 
442   assert(STM.hasGFX90AInsts() || CurrentProgramInfo.ComputePGMRSrc3GFX90A == 0);
443   if (STM.hasGFX90AInsts())
444     KernelDescriptor.compute_pgm_rsrc3 =
445       CurrentProgramInfo.ComputePGMRSrc3GFX90A;
446 
447   if (AMDGPU::hasKernargPreload(STM))
448     KernelDescriptor.kernarg_preload =
449         static_cast<uint16_t>(Info->getNumKernargPreloadedSGPRs());
450 
451   return KernelDescriptor;
452 }
453 
454 bool AMDGPUAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
455   // Init target streamer lazily on the first function so that previous passes
456   // can set metadata.
457   if (!IsTargetStreamerInitialized)
458     initTargetStreamer(*MF.getFunction().getParent());
459 
460   ResourceUsage = &getAnalysis<AMDGPUResourceUsageAnalysis>();
461   CurrentProgramInfo = SIProgramInfo();
462 
463   const AMDGPUMachineFunction *MFI = MF.getInfo<AMDGPUMachineFunction>();
464 
465   // The starting address of all shader programs must be 256 bytes aligned.
466   // Regular functions just need the basic required instruction alignment.
467   MF.setAlignment(MFI->isEntryFunction() ? Align(256) : Align(4));
468 
469   SetupMachineFunction(MF);
470 
471   const GCNSubtarget &STM = MF.getSubtarget<GCNSubtarget>();
472   MCContext &Context = getObjFileLowering().getContext();
473   // FIXME: This should be an explicit check for Mesa.
474   if (!STM.isAmdHsaOS() && !STM.isAmdPalOS()) {
475     MCSectionELF *ConfigSection =
476         Context.getELFSection(".AMDGPU.config", ELF::SHT_PROGBITS, 0);
477     OutStreamer->switchSection(ConfigSection);
478   }
479 
480   if (MFI->isModuleEntryFunction()) {
481     getSIProgramInfo(CurrentProgramInfo, MF);
482   }
483 
484   if (STM.isAmdPalOS()) {
485     if (MFI->isEntryFunction())
486       EmitPALMetadata(MF, CurrentProgramInfo);
487     else if (MFI->isModuleEntryFunction())
488       emitPALFunctionMetadata(MF);
489   } else if (!STM.isAmdHsaOS()) {
490     EmitProgramInfoSI(MF, CurrentProgramInfo);
491   }
492 
493   DumpCodeInstEmitter = nullptr;
494   if (STM.dumpCode()) {
495     // For -dumpcode, get the assembler out of the streamer, even if it does
496     // not really want to let us have it. This only works with -filetype=obj.
497     bool SaveFlag = OutStreamer->getUseAssemblerInfoForParsing();
498     OutStreamer->setUseAssemblerInfoForParsing(true);
499     MCAssembler *Assembler = OutStreamer->getAssemblerPtr();
500     OutStreamer->setUseAssemblerInfoForParsing(SaveFlag);
501     if (Assembler)
502       DumpCodeInstEmitter = Assembler->getEmitterPtr();
503   }
504 
505   DisasmLines.clear();
506   HexLines.clear();
507   DisasmLineMaxLen = 0;
508 
509   emitFunctionBody();
510 
511   emitResourceUsageRemarks(MF, CurrentProgramInfo, MFI->isModuleEntryFunction(),
512                            STM.hasMAIInsts());
513 
514   if (isVerbose()) {
515     MCSectionELF *CommentSection =
516         Context.getELFSection(".AMDGPU.csdata", ELF::SHT_PROGBITS, 0);
517     OutStreamer->switchSection(CommentSection);
518 
519     if (!MFI->isEntryFunction()) {
520       OutStreamer->emitRawComment(" Function info:", false);
521       const AMDGPUResourceUsageAnalysis::SIFunctionResourceInfo &Info =
522           ResourceUsage->getResourceInfo(&MF.getFunction());
523       emitCommonFunctionComments(
524           Info.NumVGPR,
525           STM.hasMAIInsts() ? Info.NumAGPR : std::optional<uint32_t>(),
526           Info.getTotalNumVGPRs(STM),
527           Info.getTotalNumSGPRs(MF.getSubtarget<GCNSubtarget>()),
528           Info.PrivateSegmentSize, getFunctionCodeSize(MF), MFI);
529       return false;
530     }
531 
532     OutStreamer->emitRawComment(" Kernel info:", false);
533     emitCommonFunctionComments(
534         CurrentProgramInfo.NumArchVGPR,
535         STM.hasMAIInsts() ? CurrentProgramInfo.NumAccVGPR
536                           : std::optional<uint32_t>(),
537         CurrentProgramInfo.NumVGPR, CurrentProgramInfo.NumSGPR,
538         CurrentProgramInfo.ScratchSize, getFunctionCodeSize(MF), MFI);
539 
540     OutStreamer->emitRawComment(
541       " FloatMode: " + Twine(CurrentProgramInfo.FloatMode), false);
542     OutStreamer->emitRawComment(
543       " IeeeMode: " + Twine(CurrentProgramInfo.IEEEMode), false);
544     OutStreamer->emitRawComment(
545       " LDSByteSize: " + Twine(CurrentProgramInfo.LDSSize) +
546       " bytes/workgroup (compile time only)", false);
547 
548     OutStreamer->emitRawComment(
549       " SGPRBlocks: " + Twine(CurrentProgramInfo.SGPRBlocks), false);
550     OutStreamer->emitRawComment(
551       " VGPRBlocks: " + Twine(CurrentProgramInfo.VGPRBlocks), false);
552 
553     OutStreamer->emitRawComment(
554       " NumSGPRsForWavesPerEU: " +
555       Twine(CurrentProgramInfo.NumSGPRsForWavesPerEU), false);
556     OutStreamer->emitRawComment(
557       " NumVGPRsForWavesPerEU: " +
558       Twine(CurrentProgramInfo.NumVGPRsForWavesPerEU), false);
559 
560     if (STM.hasGFX90AInsts())
561       OutStreamer->emitRawComment(
562         " AccumOffset: " +
563         Twine((CurrentProgramInfo.AccumOffset + 1) * 4), false);
564 
565     OutStreamer->emitRawComment(
566       " Occupancy: " +
567       Twine(CurrentProgramInfo.Occupancy), false);
568 
569     OutStreamer->emitRawComment(
570       " WaveLimiterHint : " + Twine(MFI->needsWaveLimiter()), false);
571 
572     OutStreamer->emitRawComment(" COMPUTE_PGM_RSRC2:SCRATCH_EN: " +
573                                     Twine(CurrentProgramInfo.ScratchEnable),
574                                 false);
575     OutStreamer->emitRawComment(" COMPUTE_PGM_RSRC2:USER_SGPR: " +
576                                     Twine(CurrentProgramInfo.UserSGPR),
577                                 false);
578     OutStreamer->emitRawComment(" COMPUTE_PGM_RSRC2:TRAP_HANDLER: " +
579                                     Twine(CurrentProgramInfo.TrapHandlerEnable),
580                                 false);
581     OutStreamer->emitRawComment(" COMPUTE_PGM_RSRC2:TGID_X_EN: " +
582                                     Twine(CurrentProgramInfo.TGIdXEnable),
583                                 false);
584     OutStreamer->emitRawComment(" COMPUTE_PGM_RSRC2:TGID_Y_EN: " +
585                                     Twine(CurrentProgramInfo.TGIdYEnable),
586                                 false);
587     OutStreamer->emitRawComment(" COMPUTE_PGM_RSRC2:TGID_Z_EN: " +
588                                     Twine(CurrentProgramInfo.TGIdZEnable),
589                                 false);
590     OutStreamer->emitRawComment(" COMPUTE_PGM_RSRC2:TIDIG_COMP_CNT: " +
591                                     Twine(CurrentProgramInfo.TIdIGCompCount),
592                                 false);
593 
594     assert(STM.hasGFX90AInsts() ||
595            CurrentProgramInfo.ComputePGMRSrc3GFX90A == 0);
596     if (STM.hasGFX90AInsts()) {
597       OutStreamer->emitRawComment(
598         " COMPUTE_PGM_RSRC3_GFX90A:ACCUM_OFFSET: " +
599         Twine((AMDHSA_BITS_GET(CurrentProgramInfo.ComputePGMRSrc3GFX90A,
600                                amdhsa::COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET))),
601                                false);
602       OutStreamer->emitRawComment(
603         " COMPUTE_PGM_RSRC3_GFX90A:TG_SPLIT: " +
604         Twine((AMDHSA_BITS_GET(CurrentProgramInfo.ComputePGMRSrc3GFX90A,
605                                amdhsa::COMPUTE_PGM_RSRC3_GFX90A_TG_SPLIT))),
606                                false);
607     }
608   }
609 
610   if (DumpCodeInstEmitter) {
611 
612     OutStreamer->switchSection(
613         Context.getELFSection(".AMDGPU.disasm", ELF::SHT_PROGBITS, 0));
614 
615     for (size_t i = 0; i < DisasmLines.size(); ++i) {
616       std::string Comment = "\n";
617       if (!HexLines[i].empty()) {
618         Comment = std::string(DisasmLineMaxLen - DisasmLines[i].size(), ' ');
619         Comment += " ; " + HexLines[i] + "\n";
620       }
621 
622       OutStreamer->emitBytes(StringRef(DisasmLines[i]));
623       OutStreamer->emitBytes(StringRef(Comment));
624     }
625   }
626 
627   return false;
628 }
629 
630 // TODO: Fold this into emitFunctionBodyStart.
631 void AMDGPUAsmPrinter::initializeTargetID(const Module &M) {
632   // In the beginning all features are either 'Any' or 'NotSupported',
633   // depending on global target features. This will cover empty modules.
634   getTargetStreamer()->initializeTargetID(
635       *getGlobalSTI(), getGlobalSTI()->getFeatureString(), CodeObjectVersion);
636 
637   // If module is empty, we are done.
638   if (M.empty())
639     return;
640 
641   // If module is not empty, need to find first 'Off' or 'On' feature
642   // setting per feature from functions in module.
643   for (auto &F : M) {
644     auto &TSTargetID = getTargetStreamer()->getTargetID();
645     if ((!TSTargetID->isXnackSupported() || TSTargetID->isXnackOnOrOff()) &&
646         (!TSTargetID->isSramEccSupported() || TSTargetID->isSramEccOnOrOff()))
647       break;
648 
649     const GCNSubtarget &STM = TM.getSubtarget<GCNSubtarget>(F);
650     const IsaInfo::AMDGPUTargetID &STMTargetID = STM.getTargetID();
651     if (TSTargetID->isXnackSupported())
652       if (TSTargetID->getXnackSetting() == IsaInfo::TargetIDSetting::Any)
653         TSTargetID->setXnackSetting(STMTargetID.getXnackSetting());
654     if (TSTargetID->isSramEccSupported())
655       if (TSTargetID->getSramEccSetting() == IsaInfo::TargetIDSetting::Any)
656         TSTargetID->setSramEccSetting(STMTargetID.getSramEccSetting());
657   }
658 }
659 
660 uint64_t AMDGPUAsmPrinter::getFunctionCodeSize(const MachineFunction &MF) const {
661   const GCNSubtarget &STM = MF.getSubtarget<GCNSubtarget>();
662   const SIInstrInfo *TII = STM.getInstrInfo();
663 
664   uint64_t CodeSize = 0;
665 
666   for (const MachineBasicBlock &MBB : MF) {
667     for (const MachineInstr &MI : MBB) {
668       // TODO: CodeSize should account for multiple functions.
669 
670       // TODO: Should we count size of debug info?
671       if (MI.isDebugInstr())
672         continue;
673 
674       CodeSize += TII->getInstSizeInBytes(MI);
675     }
676   }
677 
678   return CodeSize;
679 }
680 
681 void AMDGPUAsmPrinter::getSIProgramInfo(SIProgramInfo &ProgInfo,
682                                         const MachineFunction &MF) {
683   const AMDGPUResourceUsageAnalysis::SIFunctionResourceInfo &Info =
684       ResourceUsage->getResourceInfo(&MF.getFunction());
685   const GCNSubtarget &STM = MF.getSubtarget<GCNSubtarget>();
686 
687   ProgInfo.NumArchVGPR = Info.NumVGPR;
688   ProgInfo.NumAccVGPR = Info.NumAGPR;
689   ProgInfo.NumVGPR = Info.getTotalNumVGPRs(STM);
690   ProgInfo.AccumOffset = alignTo(std::max(1, Info.NumVGPR), 4) / 4 - 1;
691   ProgInfo.TgSplit = STM.isTgSplitEnabled();
692   ProgInfo.NumSGPR = Info.NumExplicitSGPR;
693   ProgInfo.ScratchSize = Info.PrivateSegmentSize;
694   ProgInfo.VCCUsed = Info.UsesVCC;
695   ProgInfo.FlatUsed = Info.UsesFlatScratch;
696   ProgInfo.DynamicCallStack = Info.HasDynamicallySizedStack || Info.HasRecursion;
697 
698   const uint64_t MaxScratchPerWorkitem =
699       STM.getMaxWaveScratchSize() / STM.getWavefrontSize();
700   if (ProgInfo.ScratchSize > MaxScratchPerWorkitem) {
701     DiagnosticInfoStackSize DiagStackSize(MF.getFunction(),
702                                           ProgInfo.ScratchSize,
703                                           MaxScratchPerWorkitem, DS_Error);
704     MF.getFunction().getContext().diagnose(DiagStackSize);
705   }
706 
707   const SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();
708 
709   // The calculations related to SGPR/VGPR blocks are
710   // duplicated in part in AMDGPUAsmParser::calculateGPRBlocks, and could be
711   // unified.
712   unsigned ExtraSGPRs = IsaInfo::getNumExtraSGPRs(
713       &STM, ProgInfo.VCCUsed, ProgInfo.FlatUsed,
714       getTargetStreamer()->getTargetID()->isXnackOnOrAny());
715 
716   // Check the addressable register limit before we add ExtraSGPRs.
717   if (STM.getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS &&
718       !STM.hasSGPRInitBug()) {
719     unsigned MaxAddressableNumSGPRs = STM.getAddressableNumSGPRs();
720     if (ProgInfo.NumSGPR > MaxAddressableNumSGPRs) {
721       // This can happen due to a compiler bug or when using inline asm.
722       LLVMContext &Ctx = MF.getFunction().getContext();
723       DiagnosticInfoResourceLimit Diag(
724           MF.getFunction(), "addressable scalar registers", ProgInfo.NumSGPR,
725           MaxAddressableNumSGPRs, DS_Error, DK_ResourceLimit);
726       Ctx.diagnose(Diag);
727       ProgInfo.NumSGPR = MaxAddressableNumSGPRs - 1;
728     }
729   }
730 
731   // Account for extra SGPRs and VGPRs reserved for debugger use.
732   ProgInfo.NumSGPR += ExtraSGPRs;
733 
734   const Function &F = MF.getFunction();
735 
736   // Ensure there are enough SGPRs and VGPRs for wave dispatch, where wave
737   // dispatch registers are function args.
738   unsigned WaveDispatchNumSGPR = 0, WaveDispatchNumVGPR = 0;
739 
740   if (isShader(F.getCallingConv())) {
741     bool IsPixelShader =
742         F.getCallingConv() == CallingConv::AMDGPU_PS && !STM.isAmdHsaOS();
743 
744     // Calculate the number of VGPR registers based on the SPI input registers
745     uint32_t InputEna = 0;
746     uint32_t InputAddr = 0;
747     unsigned LastEna = 0;
748 
749     if (IsPixelShader) {
750       // Note for IsPixelShader:
751       // By this stage, all enabled inputs are tagged in InputAddr as well.
752       // We will use InputAddr to determine whether the input counts against the
753       // vgpr total and only use the InputEnable to determine the last input
754       // that is relevant - if extra arguments are used, then we have to honour
755       // the InputAddr for any intermediate non-enabled inputs.
756       InputEna = MFI->getPSInputEnable();
757       InputAddr = MFI->getPSInputAddr();
758 
759       // We only need to consider input args up to the last used arg.
760       assert((InputEna || InputAddr) &&
761              "PSInputAddr and PSInputEnable should "
762              "never both be 0 for AMDGPU_PS shaders");
763       // There are some rare circumstances where InputAddr is non-zero and
764       // InputEna can be set to 0. In this case we default to setting LastEna
765       // to 1.
766       LastEna = InputEna ? llvm::Log2_32(InputEna) + 1 : 1;
767     }
768 
769     // FIXME: We should be using the number of registers determined during
770     // calling convention lowering to legalize the types.
771     const DataLayout &DL = F.getParent()->getDataLayout();
772     unsigned PSArgCount = 0;
773     unsigned IntermediateVGPR = 0;
774     for (auto &Arg : F.args()) {
775       unsigned NumRegs = (DL.getTypeSizeInBits(Arg.getType()) + 31) / 32;
776       if (Arg.hasAttribute(Attribute::InReg)) {
777         WaveDispatchNumSGPR += NumRegs;
778       } else {
779         // If this is a PS shader and we're processing the PS Input args (first
780         // 16 VGPR), use the InputEna and InputAddr bits to define how many
781         // VGPRs are actually used.
782         // Any extra VGPR arguments are handled as normal arguments (and
783         // contribute to the VGPR count whether they're used or not).
784         if (IsPixelShader && PSArgCount < 16) {
785           if ((1 << PSArgCount) & InputAddr) {
786             if (PSArgCount < LastEna)
787               WaveDispatchNumVGPR += NumRegs;
788             else
789               IntermediateVGPR += NumRegs;
790           }
791           PSArgCount++;
792         } else {
793           // If there are extra arguments we have to include the allocation for
794           // the non-used (but enabled with InputAddr) input arguments
795           if (IntermediateVGPR) {
796             WaveDispatchNumVGPR += IntermediateVGPR;
797             IntermediateVGPR = 0;
798           }
799           WaveDispatchNumVGPR += NumRegs;
800         }
801       }
802     }
803     ProgInfo.NumSGPR = std::max(ProgInfo.NumSGPR, WaveDispatchNumSGPR);
804     ProgInfo.NumArchVGPR = std::max(ProgInfo.NumVGPR, WaveDispatchNumVGPR);
805     ProgInfo.NumVGPR =
806         Info.getTotalNumVGPRs(STM, Info.NumAGPR, ProgInfo.NumArchVGPR);
807   }
808 
809   // Adjust number of registers used to meet default/requested minimum/maximum
810   // number of waves per execution unit request.
811   ProgInfo.NumSGPRsForWavesPerEU = std::max(
812     std::max(ProgInfo.NumSGPR, 1u), STM.getMinNumSGPRs(MFI->getMaxWavesPerEU()));
813   ProgInfo.NumVGPRsForWavesPerEU = std::max(
814     std::max(ProgInfo.NumVGPR, 1u), STM.getMinNumVGPRs(MFI->getMaxWavesPerEU()));
815 
816   if (STM.getGeneration() <= AMDGPUSubtarget::SEA_ISLANDS ||
817       STM.hasSGPRInitBug()) {
818     unsigned MaxAddressableNumSGPRs = STM.getAddressableNumSGPRs();
819     if (ProgInfo.NumSGPR > MaxAddressableNumSGPRs) {
820       // This can happen due to a compiler bug or when using inline asm to use
821       // the registers which are usually reserved for vcc etc.
822       LLVMContext &Ctx = MF.getFunction().getContext();
823       DiagnosticInfoResourceLimit Diag(MF.getFunction(), "scalar registers",
824                                        ProgInfo.NumSGPR, MaxAddressableNumSGPRs,
825                                        DS_Error, DK_ResourceLimit);
826       Ctx.diagnose(Diag);
827       ProgInfo.NumSGPR = MaxAddressableNumSGPRs;
828       ProgInfo.NumSGPRsForWavesPerEU = MaxAddressableNumSGPRs;
829     }
830   }
831 
832   if (STM.hasSGPRInitBug()) {
833     ProgInfo.NumSGPR =
834         AMDGPU::IsaInfo::FIXED_NUM_SGPRS_FOR_INIT_BUG;
835     ProgInfo.NumSGPRsForWavesPerEU =
836         AMDGPU::IsaInfo::FIXED_NUM_SGPRS_FOR_INIT_BUG;
837   }
838 
839   if (MFI->getNumUserSGPRs() > STM.getMaxNumUserSGPRs()) {
840     LLVMContext &Ctx = MF.getFunction().getContext();
841     DiagnosticInfoResourceLimit Diag(MF.getFunction(), "user SGPRs",
842                                      MFI->getNumUserSGPRs(),
843                                      STM.getMaxNumUserSGPRs(), DS_Error);
844     Ctx.diagnose(Diag);
845   }
846 
847   if (MFI->getLDSSize() >
848       static_cast<unsigned>(STM.getAddressableLocalMemorySize())) {
849     LLVMContext &Ctx = MF.getFunction().getContext();
850     DiagnosticInfoResourceLimit Diag(
851         MF.getFunction(), "local memory", MFI->getLDSSize(),
852         STM.getAddressableLocalMemorySize(), DS_Error);
853     Ctx.diagnose(Diag);
854   }
855 
856   ProgInfo.SGPRBlocks = IsaInfo::getNumSGPRBlocks(
857       &STM, ProgInfo.NumSGPRsForWavesPerEU);
858   ProgInfo.VGPRBlocks = IsaInfo::getNumVGPRBlocks(
859       &STM, ProgInfo.NumVGPRsForWavesPerEU);
860 
861   const SIModeRegisterDefaults Mode = MFI->getMode();
862 
863   // Set the value to initialize FP_ROUND and FP_DENORM parts of the mode
864   // register.
865   ProgInfo.FloatMode = getFPMode(Mode);
866 
867   ProgInfo.IEEEMode = Mode.IEEE;
868 
869   // Make clamp modifier on NaN input returns 0.
870   ProgInfo.DX10Clamp = Mode.DX10Clamp;
871 
872   unsigned LDSAlignShift;
873   if (STM.getGeneration() < AMDGPUSubtarget::SEA_ISLANDS) {
874     // LDS is allocated in 64 dword blocks.
875     LDSAlignShift = 8;
876   } else {
877     // LDS is allocated in 128 dword blocks.
878     LDSAlignShift = 9;
879   }
880 
881   ProgInfo.SGPRSpill = MFI->getNumSpilledSGPRs();
882   ProgInfo.VGPRSpill = MFI->getNumSpilledVGPRs();
883 
884   ProgInfo.LDSSize = MFI->getLDSSize();
885   ProgInfo.LDSBlocks =
886       alignTo(ProgInfo.LDSSize, 1ULL << LDSAlignShift) >> LDSAlignShift;
887 
888   // Scratch is allocated in 64-dword or 256-dword blocks.
889   unsigned ScratchAlignShift =
890       STM.getGeneration() >= AMDGPUSubtarget::GFX11 ? 8 : 10;
891   // We need to program the hardware with the amount of scratch memory that
892   // is used by the entire wave.  ProgInfo.ScratchSize is the amount of
893   // scratch memory used per thread.
894   ProgInfo.ScratchBlocks = divideCeil(
895       ProgInfo.ScratchSize * STM.getWavefrontSize(), 1ULL << ScratchAlignShift);
896 
897   if (getIsaVersion(getGlobalSTI()->getCPU()).Major >= 10) {
898     ProgInfo.WgpMode = STM.isCuModeEnabled() ? 0 : 1;
899     ProgInfo.MemOrdered = 1;
900   }
901 
902   // 0 = X, 1 = XY, 2 = XYZ
903   unsigned TIDIGCompCnt = 0;
904   if (MFI->hasWorkItemIDZ())
905     TIDIGCompCnt = 2;
906   else if (MFI->hasWorkItemIDY())
907     TIDIGCompCnt = 1;
908 
909   // The private segment wave byte offset is the last of the system SGPRs. We
910   // initially assumed it was allocated, and may have used it. It shouldn't harm
911   // anything to disable it if we know the stack isn't used here. We may still
912   // have emitted code reading it to initialize scratch, but if that's unused
913   // reading garbage should be OK.
914   ProgInfo.ScratchEnable =
915       ProgInfo.ScratchBlocks > 0 || ProgInfo.DynamicCallStack;
916   ProgInfo.UserSGPR = MFI->getNumUserSGPRs();
917   // For AMDHSA, TRAP_HANDLER must be zero, as it is populated by the CP.
918   ProgInfo.TrapHandlerEnable =
919       STM.isAmdHsaOS() ? 0 : STM.isTrapHandlerEnabled();
920   ProgInfo.TGIdXEnable = MFI->hasWorkGroupIDX();
921   ProgInfo.TGIdYEnable = MFI->hasWorkGroupIDY();
922   ProgInfo.TGIdZEnable = MFI->hasWorkGroupIDZ();
923   ProgInfo.TGSizeEnable = MFI->hasWorkGroupInfo();
924   ProgInfo.TIdIGCompCount = TIDIGCompCnt;
925   ProgInfo.EXCPEnMSB = 0;
926   // For AMDHSA, LDS_SIZE must be zero, as it is populated by the CP.
927   ProgInfo.LdsSize = STM.isAmdHsaOS() ? 0 : ProgInfo.LDSBlocks;
928   ProgInfo.EXCPEnable = 0;
929 
930   if (STM.hasGFX90AInsts()) {
931     AMDHSA_BITS_SET(ProgInfo.ComputePGMRSrc3GFX90A,
932                     amdhsa::COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET,
933                     ProgInfo.AccumOffset);
934     AMDHSA_BITS_SET(ProgInfo.ComputePGMRSrc3GFX90A,
935                     amdhsa::COMPUTE_PGM_RSRC3_GFX90A_TG_SPLIT,
936                     ProgInfo.TgSplit);
937   }
938 
939   ProgInfo.Occupancy = STM.computeOccupancy(MF.getFunction(), ProgInfo.LDSSize,
940                                             ProgInfo.NumSGPRsForWavesPerEU,
941                                             ProgInfo.NumVGPRsForWavesPerEU);
942   const auto [MinWEU, MaxWEU] =
943       AMDGPU::getIntegerPairAttribute(F, "amdgpu-waves-per-eu", {0, 0}, true);
944   if (ProgInfo.Occupancy < MinWEU) {
945     DiagnosticInfoOptimizationFailure Diag(
946         F, F.getSubprogram(),
947         "failed to meet occupancy target given by 'amdgpu-waves-per-eu' in "
948         "'" +
949             F.getName() + "': desired occupancy was " + Twine(MinWEU) +
950             ", final occupancy is " + Twine(ProgInfo.Occupancy));
951     F.getContext().diagnose(Diag);
952   }
953 }
954 
955 static unsigned getRsrcReg(CallingConv::ID CallConv) {
956   switch (CallConv) {
957   default: [[fallthrough]];
958   case CallingConv::AMDGPU_CS: return R_00B848_COMPUTE_PGM_RSRC1;
959   case CallingConv::AMDGPU_LS: return R_00B528_SPI_SHADER_PGM_RSRC1_LS;
960   case CallingConv::AMDGPU_HS: return R_00B428_SPI_SHADER_PGM_RSRC1_HS;
961   case CallingConv::AMDGPU_ES: return R_00B328_SPI_SHADER_PGM_RSRC1_ES;
962   case CallingConv::AMDGPU_GS: return R_00B228_SPI_SHADER_PGM_RSRC1_GS;
963   case CallingConv::AMDGPU_VS: return R_00B128_SPI_SHADER_PGM_RSRC1_VS;
964   case CallingConv::AMDGPU_PS: return R_00B028_SPI_SHADER_PGM_RSRC1_PS;
965   }
966 }
967 
968 void AMDGPUAsmPrinter::EmitProgramInfoSI(const MachineFunction &MF,
969                                          const SIProgramInfo &CurrentProgramInfo) {
970   const SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();
971   const GCNSubtarget &STM = MF.getSubtarget<GCNSubtarget>();
972   unsigned RsrcReg = getRsrcReg(MF.getFunction().getCallingConv());
973 
974   if (AMDGPU::isCompute(MF.getFunction().getCallingConv())) {
975     OutStreamer->emitInt32(R_00B848_COMPUTE_PGM_RSRC1);
976 
977     OutStreamer->emitInt32(CurrentProgramInfo.getComputePGMRSrc1(STM));
978 
979     OutStreamer->emitInt32(R_00B84C_COMPUTE_PGM_RSRC2);
980     OutStreamer->emitInt32(CurrentProgramInfo.getComputePGMRSrc2());
981 
982     OutStreamer->emitInt32(R_00B860_COMPUTE_TMPRING_SIZE);
983     OutStreamer->emitInt32(
984         STM.getGeneration() >= AMDGPUSubtarget::GFX11
985             ? S_00B860_WAVESIZE_GFX11Plus(CurrentProgramInfo.ScratchBlocks)
986             : S_00B860_WAVESIZE_PreGFX11(CurrentProgramInfo.ScratchBlocks));
987 
988     // TODO: Should probably note flat usage somewhere. SC emits a "FlatPtr32 =
989     // 0" comment but I don't see a corresponding field in the register spec.
990   } else {
991     OutStreamer->emitInt32(RsrcReg);
992     OutStreamer->emitIntValue(S_00B028_VGPRS(CurrentProgramInfo.VGPRBlocks) |
993                               S_00B028_SGPRS(CurrentProgramInfo.SGPRBlocks), 4);
994     OutStreamer->emitInt32(R_0286E8_SPI_TMPRING_SIZE);
995     OutStreamer->emitInt32(
996         STM.getGeneration() >= AMDGPUSubtarget::GFX11
997             ? S_0286E8_WAVESIZE_GFX11Plus(CurrentProgramInfo.ScratchBlocks)
998             : S_0286E8_WAVESIZE_PreGFX11(CurrentProgramInfo.ScratchBlocks));
999   }
1000 
1001   if (MF.getFunction().getCallingConv() == CallingConv::AMDGPU_PS) {
1002     OutStreamer->emitInt32(R_00B02C_SPI_SHADER_PGM_RSRC2_PS);
1003     unsigned ExtraLDSSize = STM.getGeneration() >= AMDGPUSubtarget::GFX11
1004                                 ? divideCeil(CurrentProgramInfo.LDSBlocks, 2)
1005                                 : CurrentProgramInfo.LDSBlocks;
1006     OutStreamer->emitInt32(S_00B02C_EXTRA_LDS_SIZE(ExtraLDSSize));
1007     OutStreamer->emitInt32(R_0286CC_SPI_PS_INPUT_ENA);
1008     OutStreamer->emitInt32(MFI->getPSInputEnable());
1009     OutStreamer->emitInt32(R_0286D0_SPI_PS_INPUT_ADDR);
1010     OutStreamer->emitInt32(MFI->getPSInputAddr());
1011   }
1012 
1013   OutStreamer->emitInt32(R_SPILLED_SGPRS);
1014   OutStreamer->emitInt32(MFI->getNumSpilledSGPRs());
1015   OutStreamer->emitInt32(R_SPILLED_VGPRS);
1016   OutStreamer->emitInt32(MFI->getNumSpilledVGPRs());
1017 }
1018 
1019 // This is the equivalent of EmitProgramInfoSI above, but for when the OS type
1020 // is AMDPAL.  It stores each compute/SPI register setting and other PAL
1021 // metadata items into the PALMD::Metadata, combining with any provided by the
1022 // frontend as LLVM metadata. Once all functions are written, the PAL metadata
1023 // is then written as a single block in the .note section.
1024 void AMDGPUAsmPrinter::EmitPALMetadata(const MachineFunction &MF,
1025        const SIProgramInfo &CurrentProgramInfo) {
1026   const SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();
1027   auto CC = MF.getFunction().getCallingConv();
1028   auto MD = getTargetStreamer()->getPALMetadata();
1029 
1030   MD->setEntryPoint(CC, MF.getFunction().getName());
1031   MD->setNumUsedVgprs(CC, CurrentProgramInfo.NumVGPRsForWavesPerEU);
1032 
1033   // Only set AGPRs for supported devices
1034   const GCNSubtarget &STM = MF.getSubtarget<GCNSubtarget>();
1035   if (STM.hasMAIInsts()) {
1036     MD->setNumUsedAgprs(CC, CurrentProgramInfo.NumAccVGPR);
1037   }
1038 
1039   MD->setNumUsedSgprs(CC, CurrentProgramInfo.NumSGPRsForWavesPerEU);
1040   if (MD->getPALMajorVersion() < 3) {
1041     MD->setRsrc1(CC, CurrentProgramInfo.getPGMRSrc1(CC, STM));
1042     if (AMDGPU::isCompute(CC)) {
1043       MD->setRsrc2(CC, CurrentProgramInfo.getComputePGMRSrc2());
1044     } else {
1045       if (CurrentProgramInfo.ScratchBlocks > 0)
1046         MD->setRsrc2(CC, S_00B84C_SCRATCH_EN(1));
1047     }
1048   } else {
1049     MD->setHwStage(CC, ".debug_mode", (bool)CurrentProgramInfo.DebugMode);
1050     MD->setHwStage(CC, ".ieee_mode", (bool)CurrentProgramInfo.IEEEMode);
1051     MD->setHwStage(CC, ".wgp_mode", (bool)CurrentProgramInfo.WgpMode);
1052     MD->setHwStage(CC, ".mem_ordered", (bool)CurrentProgramInfo.MemOrdered);
1053 
1054     if (AMDGPU::isCompute(CC)) {
1055       MD->setHwStage(CC, ".scratch_en", (bool)CurrentProgramInfo.ScratchEnable);
1056       MD->setHwStage(CC, ".trap_present",
1057                      (bool)CurrentProgramInfo.TrapHandlerEnable);
1058 
1059       // EXCPEnMSB?
1060       const unsigned LdsDwGranularity = 128;
1061       MD->setHwStage(CC, ".lds_size",
1062                      (unsigned)(CurrentProgramInfo.LdsSize * LdsDwGranularity *
1063                                 sizeof(uint32_t)));
1064       MD->setHwStage(CC, ".excp_en", CurrentProgramInfo.EXCPEnable);
1065     } else {
1066       MD->setHwStage(CC, ".scratch_en", (bool)CurrentProgramInfo.ScratchEnable);
1067     }
1068   }
1069 
1070   // ScratchSize is in bytes, 16 aligned.
1071   MD->setScratchSize(CC, alignTo(CurrentProgramInfo.ScratchSize, 16));
1072   if (MF.getFunction().getCallingConv() == CallingConv::AMDGPU_PS) {
1073     unsigned ExtraLDSSize = STM.getGeneration() >= AMDGPUSubtarget::GFX11
1074                                 ? divideCeil(CurrentProgramInfo.LDSBlocks, 2)
1075                                 : CurrentProgramInfo.LDSBlocks;
1076     if (MD->getPALMajorVersion() < 3) {
1077       MD->setRsrc2(CC, S_00B02C_EXTRA_LDS_SIZE(ExtraLDSSize));
1078       MD->setSpiPsInputEna(MFI->getPSInputEnable());
1079       MD->setSpiPsInputAddr(MFI->getPSInputAddr());
1080     } else {
1081       // Graphics registers
1082       const unsigned ExtraLdsDwGranularity =
1083           STM.getGeneration() >= AMDGPUSubtarget::GFX11 ? 256 : 128;
1084       MD->setGraphicsRegisters(
1085           ".ps_extra_lds_size",
1086           (unsigned)(ExtraLDSSize * ExtraLdsDwGranularity * sizeof(uint32_t)));
1087 
1088       // Set PsInputEna and PsInputAddr .spi_ps_input_ena and .spi_ps_input_addr
1089       static StringLiteral const PsInputFields[] = {
1090           ".persp_sample_ena",    ".persp_center_ena",
1091           ".persp_centroid_ena",  ".persp_pull_model_ena",
1092           ".linear_sample_ena",   ".linear_center_ena",
1093           ".linear_centroid_ena", ".line_stipple_tex_ena",
1094           ".pos_x_float_ena",     ".pos_y_float_ena",
1095           ".pos_z_float_ena",     ".pos_w_float_ena",
1096           ".front_face_ena",      ".ancillary_ena",
1097           ".sample_coverage_ena", ".pos_fixed_pt_ena"};
1098       unsigned PSInputEna = MFI->getPSInputEnable();
1099       unsigned PSInputAddr = MFI->getPSInputAddr();
1100       for (auto [Idx, Field] : enumerate(PsInputFields)) {
1101         MD->setGraphicsRegisters(".spi_ps_input_ena", Field,
1102                                  (bool)((PSInputEna >> Idx) & 1));
1103         MD->setGraphicsRegisters(".spi_ps_input_addr", Field,
1104                                  (bool)((PSInputAddr >> Idx) & 1));
1105       }
1106     }
1107   }
1108 
1109   // For version 3 and above the wave front size is already set in the metadata
1110   if (MD->getPALMajorVersion() < 3 && STM.isWave32())
1111     MD->setWave32(MF.getFunction().getCallingConv());
1112 }
1113 
1114 void AMDGPUAsmPrinter::emitPALFunctionMetadata(const MachineFunction &MF) {
1115   auto *MD = getTargetStreamer()->getPALMetadata();
1116   const MachineFrameInfo &MFI = MF.getFrameInfo();
1117   StringRef FnName = MF.getFunction().getName();
1118   MD->setFunctionScratchSize(FnName, MFI.getStackSize());
1119   const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
1120 
1121   // Set compute registers
1122   MD->setRsrc1(CallingConv::AMDGPU_CS,
1123                CurrentProgramInfo.getPGMRSrc1(CallingConv::AMDGPU_CS, ST));
1124   MD->setRsrc2(CallingConv::AMDGPU_CS, CurrentProgramInfo.getComputePGMRSrc2());
1125 
1126   // Set optional info
1127   MD->setFunctionLdsSize(FnName, CurrentProgramInfo.LDSSize);
1128   MD->setFunctionNumUsedVgprs(FnName, CurrentProgramInfo.NumVGPRsForWavesPerEU);
1129   MD->setFunctionNumUsedSgprs(FnName, CurrentProgramInfo.NumSGPRsForWavesPerEU);
1130 }
1131 
1132 // This is supposed to be log2(Size)
1133 static amd_element_byte_size_t getElementByteSizeValue(unsigned Size) {
1134   switch (Size) {
1135   case 4:
1136     return AMD_ELEMENT_4_BYTES;
1137   case 8:
1138     return AMD_ELEMENT_8_BYTES;
1139   case 16:
1140     return AMD_ELEMENT_16_BYTES;
1141   default:
1142     llvm_unreachable("invalid private_element_size");
1143   }
1144 }
1145 
1146 void AMDGPUAsmPrinter::getAmdKernelCode(amd_kernel_code_t &Out,
1147                                         const SIProgramInfo &CurrentProgramInfo,
1148                                         const MachineFunction &MF) const {
1149   const Function &F = MF.getFunction();
1150   assert(F.getCallingConv() == CallingConv::AMDGPU_KERNEL ||
1151          F.getCallingConv() == CallingConv::SPIR_KERNEL);
1152 
1153   const SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();
1154   const GCNSubtarget &STM = MF.getSubtarget<GCNSubtarget>();
1155 
1156   AMDGPU::initDefaultAMDKernelCodeT(Out, &STM);
1157 
1158   Out.compute_pgm_resource_registers =
1159       CurrentProgramInfo.getComputePGMRSrc1(STM) |
1160       (CurrentProgramInfo.getComputePGMRSrc2() << 32);
1161   Out.code_properties |= AMD_CODE_PROPERTY_IS_PTR64;
1162 
1163   if (CurrentProgramInfo.DynamicCallStack)
1164     Out.code_properties |= AMD_CODE_PROPERTY_IS_DYNAMIC_CALLSTACK;
1165 
1166   AMD_HSA_BITS_SET(Out.code_properties,
1167                    AMD_CODE_PROPERTY_PRIVATE_ELEMENT_SIZE,
1168                    getElementByteSizeValue(STM.getMaxPrivateElementSize(true)));
1169 
1170   const GCNUserSGPRUsageInfo &UserSGPRInfo = MFI->getUserSGPRInfo();
1171   if (UserSGPRInfo.hasPrivateSegmentBuffer()) {
1172     Out.code_properties |=
1173       AMD_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER;
1174   }
1175 
1176   if (UserSGPRInfo.hasDispatchPtr())
1177     Out.code_properties |= AMD_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR;
1178 
1179   if (UserSGPRInfo.hasQueuePtr() && CodeObjectVersion < AMDGPU::AMDHSA_COV5)
1180     Out.code_properties |= AMD_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR;
1181 
1182   if (UserSGPRInfo.hasKernargSegmentPtr())
1183     Out.code_properties |= AMD_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR;
1184 
1185   if (UserSGPRInfo.hasDispatchID())
1186     Out.code_properties |= AMD_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID;
1187 
1188   if (UserSGPRInfo.hasFlatScratchInit())
1189     Out.code_properties |= AMD_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT;
1190 
1191   if (UserSGPRInfo.hasDispatchPtr())
1192     Out.code_properties |= AMD_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR;
1193 
1194   if (STM.isXNACKEnabled())
1195     Out.code_properties |= AMD_CODE_PROPERTY_IS_XNACK_SUPPORTED;
1196 
1197   Align MaxKernArgAlign;
1198   Out.kernarg_segment_byte_size = STM.getKernArgSegmentSize(F, MaxKernArgAlign);
1199   Out.wavefront_sgpr_count = CurrentProgramInfo.NumSGPR;
1200   Out.workitem_vgpr_count = CurrentProgramInfo.NumVGPR;
1201   Out.workitem_private_segment_byte_size = CurrentProgramInfo.ScratchSize;
1202   Out.workgroup_group_segment_byte_size = CurrentProgramInfo.LDSSize;
1203 
1204   // kernarg_segment_alignment is specified as log of the alignment.
1205   // The minimum alignment is 16.
1206   // FIXME: The metadata treats the minimum as 4?
1207   Out.kernarg_segment_alignment = Log2(std::max(Align(16), MaxKernArgAlign));
1208 }
1209 
1210 bool AMDGPUAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
1211                                        const char *ExtraCode, raw_ostream &O) {
1212   // First try the generic code, which knows about modifiers like 'c' and 'n'.
1213   if (!AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O))
1214     return false;
1215 
1216   if (ExtraCode && ExtraCode[0]) {
1217     if (ExtraCode[1] != 0)
1218       return true; // Unknown modifier.
1219 
1220     switch (ExtraCode[0]) {
1221     case 'r':
1222       break;
1223     default:
1224       return true;
1225     }
1226   }
1227 
1228   // TODO: Should be able to support other operand types like globals.
1229   const MachineOperand &MO = MI->getOperand(OpNo);
1230   if (MO.isReg()) {
1231     AMDGPUInstPrinter::printRegOperand(MO.getReg(), O,
1232                                        *MF->getSubtarget().getRegisterInfo());
1233     return false;
1234   } else if (MO.isImm()) {
1235     int64_t Val = MO.getImm();
1236     if (AMDGPU::isInlinableIntLiteral(Val)) {
1237       O << Val;
1238     } else if (isUInt<16>(Val)) {
1239       O << format("0x%" PRIx16, static_cast<uint16_t>(Val));
1240     } else if (isUInt<32>(Val)) {
1241       O << format("0x%" PRIx32, static_cast<uint32_t>(Val));
1242     } else {
1243       O << format("0x%" PRIx64, static_cast<uint64_t>(Val));
1244     }
1245     return false;
1246   }
1247   return true;
1248 }
1249 
1250 void AMDGPUAsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const {
1251   AU.addRequired<AMDGPUResourceUsageAnalysis>();
1252   AU.addPreserved<AMDGPUResourceUsageAnalysis>();
1253   AsmPrinter::getAnalysisUsage(AU);
1254 }
1255 
1256 void AMDGPUAsmPrinter::emitResourceUsageRemarks(
1257     const MachineFunction &MF, const SIProgramInfo &CurrentProgramInfo,
1258     bool isModuleEntryFunction, bool hasMAIInsts) {
1259   if (!ORE)
1260     return;
1261 
1262   const char *Name = "kernel-resource-usage";
1263   const char *Indent = "    ";
1264 
1265   // If the remark is not specifically enabled, do not output to yaml
1266   LLVMContext &Ctx = MF.getFunction().getContext();
1267   if (!Ctx.getDiagHandlerPtr()->isAnalysisRemarkEnabled(Name))
1268     return;
1269 
1270   auto EmitResourceUsageRemark = [&](StringRef RemarkName,
1271                                      StringRef RemarkLabel, auto Argument) {
1272     // Add an indent for every line besides the line with the kernel name. This
1273     // makes it easier to tell which resource usage go with which kernel since
1274     // the kernel name will always be displayed first.
1275     std::string LabelStr = RemarkLabel.str() + ": ";
1276     if (!RemarkName.equals("FunctionName"))
1277       LabelStr = Indent + LabelStr;
1278 
1279     ORE->emit([&]() {
1280       return MachineOptimizationRemarkAnalysis(Name, RemarkName,
1281                                                MF.getFunction().getSubprogram(),
1282                                                &MF.front())
1283              << LabelStr << ore::NV(RemarkName, Argument);
1284     });
1285   };
1286 
1287   // FIXME: Formatting here is pretty nasty because clang does not accept
1288   // newlines from diagnostics. This forces us to emit multiple diagnostic
1289   // remarks to simulate newlines. If and when clang does accept newlines, this
1290   // formatting should be aggregated into one remark with newlines to avoid
1291   // printing multiple diagnostic location and diag opts.
1292   EmitResourceUsageRemark("FunctionName", "Function Name",
1293                           MF.getFunction().getName());
1294   EmitResourceUsageRemark("NumSGPR", "SGPRs", CurrentProgramInfo.NumSGPR);
1295   EmitResourceUsageRemark("NumVGPR", "VGPRs", CurrentProgramInfo.NumArchVGPR);
1296   if (hasMAIInsts)
1297     EmitResourceUsageRemark("NumAGPR", "AGPRs", CurrentProgramInfo.NumAccVGPR);
1298   EmitResourceUsageRemark("ScratchSize", "ScratchSize [bytes/lane]",
1299                           CurrentProgramInfo.ScratchSize);
1300   StringRef DynamicStackStr =
1301       CurrentProgramInfo.DynamicCallStack ? "True" : "False";
1302   EmitResourceUsageRemark("DynamicStack", "Dynamic Stack", DynamicStackStr);
1303   EmitResourceUsageRemark("Occupancy", "Occupancy [waves/SIMD]",
1304                           CurrentProgramInfo.Occupancy);
1305   EmitResourceUsageRemark("SGPRSpill", "SGPRs Spill",
1306                           CurrentProgramInfo.SGPRSpill);
1307   EmitResourceUsageRemark("VGPRSpill", "VGPRs Spill",
1308                           CurrentProgramInfo.VGPRSpill);
1309   if (isModuleEntryFunction)
1310     EmitResourceUsageRemark("BytesLDS", "LDS Size [bytes/block]",
1311                             CurrentProgramInfo.LDSSize);
1312 }
1313