1 //===-- AMDGPUAsmPrinter.cpp - AMDGPU Assebly printer  --------------------===//
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 /// \file
11 ///
12 /// The AMDGPUAsmPrinter is used to print both assembly string and also binary
13 /// code.  When passed an MCAsmStreamer it prints assembly and when passed
14 /// an MCObjectStreamer it outputs binary code.
15 //
16 //===----------------------------------------------------------------------===//
17 //
18 
19 #include "AMDGPUAsmPrinter.h"
20 #include "AMDGPU.h"
21 #include "AMDGPUSubtarget.h"
22 #include "AMDGPUTargetMachine.h"
23 #include "InstPrinter/AMDGPUInstPrinter.h"
24 #include "MCTargetDesc/AMDGPUTargetStreamer.h"
25 #include "R600Defines.h"
26 #include "R600MachineFunctionInfo.h"
27 #include "R600RegisterInfo.h"
28 #include "SIDefines.h"
29 #include "SIInstrInfo.h"
30 #include "SIMachineFunctionInfo.h"
31 #include "SIRegisterInfo.h"
32 #include "Utils/AMDGPUBaseInfo.h"
33 #include "llvm/BinaryFormat/ELF.h"
34 #include "llvm/CodeGen/MachineFrameInfo.h"
35 #include "llvm/IR/DiagnosticInfo.h"
36 #include "llvm/MC/MCContext.h"
37 #include "llvm/MC/MCSectionELF.h"
38 #include "llvm/MC/MCStreamer.h"
39 #include "llvm/Support/AMDGPUMetadata.h"
40 #include "llvm/Support/MathExtras.h"
41 #include "llvm/Support/TargetRegistry.h"
42 #include "llvm/Target/TargetLoweringObjectFile.h"
43 
44 using namespace llvm;
45 using namespace llvm::AMDGPU;
46 
47 // TODO: This should get the default rounding mode from the kernel. We just set
48 // the default here, but this could change if the OpenCL rounding mode pragmas
49 // are used.
50 //
51 // The denormal mode here should match what is reported by the OpenCL runtime
52 // for the CL_FP_DENORM bit from CL_DEVICE_{HALF|SINGLE|DOUBLE}_FP_CONFIG, but
53 // can also be override to flush with the -cl-denorms-are-zero compiler flag.
54 //
55 // AMD OpenCL only sets flush none and reports CL_FP_DENORM for double
56 // precision, and leaves single precision to flush all and does not report
57 // CL_FP_DENORM for CL_DEVICE_SINGLE_FP_CONFIG. Mesa's OpenCL currently reports
58 // CL_FP_DENORM for both.
59 //
60 // FIXME: It seems some instructions do not support single precision denormals
61 // regardless of the mode (exp_*_f32, rcp_*_f32, rsq_*_f32, rsq_*f32, sqrt_f32,
62 // and sin_f32, cos_f32 on most parts).
63 
64 // We want to use these instructions, and using fp32 denormals also causes
65 // instructions to run at the double precision rate for the device so it's
66 // probably best to just report no single precision denormals.
67 static uint32_t getFPMode(const MachineFunction &F) {
68   const SISubtarget& ST = F.getSubtarget<SISubtarget>();
69   // TODO: Is there any real use for the flush in only / flush out only modes?
70 
71   uint32_t FP32Denormals =
72     ST.hasFP32Denormals() ? FP_DENORM_FLUSH_NONE : FP_DENORM_FLUSH_IN_FLUSH_OUT;
73 
74   uint32_t FP64Denormals =
75     ST.hasFP64Denormals() ? FP_DENORM_FLUSH_NONE : FP_DENORM_FLUSH_IN_FLUSH_OUT;
76 
77   return FP_ROUND_MODE_SP(FP_ROUND_ROUND_TO_NEAREST) |
78          FP_ROUND_MODE_DP(FP_ROUND_ROUND_TO_NEAREST) |
79          FP_DENORM_MODE_SP(FP32Denormals) |
80          FP_DENORM_MODE_DP(FP64Denormals);
81 }
82 
83 static AsmPrinter *
84 createAMDGPUAsmPrinterPass(TargetMachine &tm,
85                            std::unique_ptr<MCStreamer> &&Streamer) {
86   return new AMDGPUAsmPrinter(tm, std::move(Streamer));
87 }
88 
89 extern "C" void LLVMInitializeAMDGPUAsmPrinter() {
90   TargetRegistry::RegisterAsmPrinter(getTheAMDGPUTarget(),
91                                      createAMDGPUAsmPrinterPass);
92   TargetRegistry::RegisterAsmPrinter(getTheGCNTarget(),
93                                      createAMDGPUAsmPrinterPass);
94 }
95 
96 AMDGPUAsmPrinter::AMDGPUAsmPrinter(TargetMachine &TM,
97                                    std::unique_ptr<MCStreamer> Streamer)
98   : AsmPrinter(TM, std::move(Streamer)) {
99     AMDGPUASI = static_cast<AMDGPUTargetMachine*>(&TM)->getAMDGPUAS();
100   }
101 
102 StringRef AMDGPUAsmPrinter::getPassName() const {
103   return "AMDGPU Assembly Printer";
104 }
105 
106 const MCSubtargetInfo* AMDGPUAsmPrinter::getSTI() const {
107   return TM.getMCSubtargetInfo();
108 }
109 
110 AMDGPUTargetStreamer& AMDGPUAsmPrinter::getTargetStreamer() const {
111   return static_cast<AMDGPUTargetStreamer&>(*OutStreamer->getTargetStreamer());
112 }
113 
114 void AMDGPUAsmPrinter::EmitStartOfAsmFile(Module &M) {
115   AMDGPU::IsaInfo::IsaVersion ISA =
116       AMDGPU::IsaInfo::getIsaVersion(getSTI()->getFeatureBits());
117 
118   if (TM.getTargetTriple().getOS() == Triple::AMDPAL) {
119     readPALMetadata(M);
120     // AMDPAL wants an HSA_ISA .note.
121     getTargetStreamer().EmitDirectiveHSACodeObjectISA(
122         ISA.Major, ISA.Minor, ISA.Stepping, "AMD", "AMDGPU");
123   }
124   if (TM.getTargetTriple().getOS() != Triple::AMDHSA)
125     return;
126 
127   getTargetStreamer().EmitDirectiveHSACodeObjectVersion(2, 1);
128   getTargetStreamer().EmitDirectiveHSACodeObjectISA(
129       ISA.Major, ISA.Minor, ISA.Stepping, "AMD", "AMDGPU");
130 
131   HSAMetadataStream.begin(M);
132 }
133 
134 void AMDGPUAsmPrinter::EmitEndOfAsmFile(Module &M) {
135   if (TM.getTargetTriple().getOS() == Triple::AMDPAL) {
136     // Copy the PAL metadata from the map where we collected it into a vector,
137     // then write it as a .note.
138     PALMD::Metadata PALMetadataVector;
139     for (auto i : PALMetadataMap) {
140       PALMetadataVector.push_back(i.first);
141       PALMetadataVector.push_back(i.second);
142     }
143     getTargetStreamer().EmitPALMetadata(PALMetadataVector);
144   }
145 
146   if (TM.getTargetTriple().getOS() != Triple::AMDHSA)
147     return;
148 
149   HSAMetadataStream.end();
150   getTargetStreamer().EmitHSAMetadata(HSAMetadataStream.getHSAMetadata());
151 }
152 
153 bool AMDGPUAsmPrinter::isBlockOnlyReachableByFallthrough(
154   const MachineBasicBlock *MBB) const {
155   if (!AsmPrinter::isBlockOnlyReachableByFallthrough(MBB))
156     return false;
157 
158   if (MBB->empty())
159     return true;
160 
161   // If this is a block implementing a long branch, an expression relative to
162   // the start of the block is needed.  to the start of the block.
163   // XXX - Is there a smarter way to check this?
164   return (MBB->back().getOpcode() != AMDGPU::S_SETPC_B64);
165 }
166 
167 void AMDGPUAsmPrinter::EmitFunctionBodyStart() {
168   const AMDGPUMachineFunction *MFI = MF->getInfo<AMDGPUMachineFunction>();
169   if (!MFI->isEntryFunction())
170     return;
171 
172   const AMDGPUSubtarget &STM = MF->getSubtarget<AMDGPUSubtarget>();
173   amd_kernel_code_t KernelCode;
174   if (STM.isAmdCodeObjectV2(*MF)) {
175     getAmdKernelCode(KernelCode, CurrentProgramInfo, *MF);
176 
177     OutStreamer->SwitchSection(getObjFileLowering().getTextSection());
178     getTargetStreamer().EmitAMDKernelCodeT(KernelCode);
179   }
180 
181   if (TM.getTargetTriple().getOS() != Triple::AMDHSA)
182     return;
183 
184   HSAMetadataStream.emitKernel(*MF->getFunction(), KernelCode);
185 }
186 
187 void AMDGPUAsmPrinter::EmitFunctionEntryLabel() {
188   const SIMachineFunctionInfo *MFI = MF->getInfo<SIMachineFunctionInfo>();
189   const AMDGPUSubtarget &STM = MF->getSubtarget<AMDGPUSubtarget>();
190   if (MFI->isEntryFunction() && STM.isAmdCodeObjectV2(*MF)) {
191     SmallString<128> SymbolName;
192     getNameWithPrefix(SymbolName, MF->getFunction()),
193     getTargetStreamer().EmitAMDGPUSymbolType(
194         SymbolName, ELF::STT_AMDGPU_HSA_KERNEL);
195   }
196 
197   AsmPrinter::EmitFunctionEntryLabel();
198 }
199 
200 void AMDGPUAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
201 
202   // Group segment variables aren't emitted in HSA.
203   if (AMDGPU::isGroupSegment(GV, AMDGPUASI))
204     return;
205 
206   AsmPrinter::EmitGlobalVariable(GV);
207 }
208 
209 bool AMDGPUAsmPrinter::doFinalization(Module &M) {
210   CallGraphResourceInfo.clear();
211   return AsmPrinter::doFinalization(M);
212 }
213 
214 // For the amdpal OS type, read the amdgpu.pal.metadata supplied by the
215 // frontend into our PALMetadataMap, ready for per-function modification.  It
216 // is a NamedMD containing an MDTuple containing a number of MDNodes each of
217 // which is an integer value, and each two integer values forms a key=value
218 // pair that we store as PALMetadataMap[key]=value in the map.
219 void AMDGPUAsmPrinter::readPALMetadata(Module &M) {
220   auto NamedMD = M.getNamedMetadata("amdgpu.pal.metadata");
221   if (!NamedMD || !NamedMD->getNumOperands())
222     return;
223   auto Tuple = dyn_cast<MDTuple>(NamedMD->getOperand(0));
224   if (!Tuple)
225     return;
226   for (unsigned I = 0, E = Tuple->getNumOperands() & -2; I != E; I += 2) {
227     auto Key = mdconst::dyn_extract<ConstantInt>(Tuple->getOperand(I));
228     auto Val = mdconst::dyn_extract<ConstantInt>(Tuple->getOperand(I + 1));
229     if (!Key || !Val)
230       continue;
231     PALMetadataMap[Key->getZExtValue()] = Val->getZExtValue();
232   }
233 }
234 
235 // Print comments that apply to both callable functions and entry points.
236 void AMDGPUAsmPrinter::emitCommonFunctionComments(
237   uint32_t NumVGPR,
238   uint32_t NumSGPR,
239   uint32_t ScratchSize,
240   uint64_t CodeSize) {
241   OutStreamer->emitRawComment(" codeLenInByte = " + Twine(CodeSize), false);
242   OutStreamer->emitRawComment(" NumSgprs: " + Twine(NumSGPR), false);
243   OutStreamer->emitRawComment(" NumVgprs: " + Twine(NumVGPR), false);
244   OutStreamer->emitRawComment(" ScratchSize: " + Twine(ScratchSize), false);
245 }
246 
247 bool AMDGPUAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
248   CurrentProgramInfo = SIProgramInfo();
249 
250   const AMDGPUMachineFunction *MFI = MF.getInfo<AMDGPUMachineFunction>();
251 
252   // The starting address of all shader programs must be 256 bytes aligned.
253   // Regular functions just need the basic required instruction alignment.
254   MF.setAlignment(MFI->isEntryFunction() ? 8 : 2);
255 
256   SetupMachineFunction(MF);
257 
258   const AMDGPUSubtarget &STM = MF.getSubtarget<AMDGPUSubtarget>();
259   MCContext &Context = getObjFileLowering().getContext();
260   if (!STM.isAmdHsaOS()) {
261     MCSectionELF *ConfigSection =
262         Context.getELFSection(".AMDGPU.config", ELF::SHT_PROGBITS, 0);
263     OutStreamer->SwitchSection(ConfigSection);
264   }
265 
266   if (STM.getGeneration() >= AMDGPUSubtarget::SOUTHERN_ISLANDS) {
267     if (MFI->isEntryFunction()) {
268       getSIProgramInfo(CurrentProgramInfo, MF);
269     } else {
270       auto I = CallGraphResourceInfo.insert(
271         std::make_pair(MF.getFunction(), SIFunctionResourceInfo()));
272       SIFunctionResourceInfo &Info = I.first->second;
273       assert(I.second && "should only be called once per function");
274       Info = analyzeResourceUsage(MF);
275     }
276 
277     if (STM.isAmdPalOS())
278       EmitPALMetadata(MF, CurrentProgramInfo);
279     if (!STM.isAmdHsaOS()) {
280       EmitProgramInfoSI(MF, CurrentProgramInfo);
281     }
282   } else {
283     EmitProgramInfoR600(MF);
284   }
285 
286   DisasmLines.clear();
287   HexLines.clear();
288   DisasmLineMaxLen = 0;
289 
290   EmitFunctionBody();
291 
292   if (isVerbose()) {
293     MCSectionELF *CommentSection =
294         Context.getELFSection(".AMDGPU.csdata", ELF::SHT_PROGBITS, 0);
295     OutStreamer->SwitchSection(CommentSection);
296 
297     if (STM.getGeneration() >= AMDGPUSubtarget::SOUTHERN_ISLANDS) {
298       if (!MFI->isEntryFunction()) {
299         OutStreamer->emitRawComment(" Function info:", false);
300         SIFunctionResourceInfo &Info = CallGraphResourceInfo[MF.getFunction()];
301         emitCommonFunctionComments(
302           Info.NumVGPR,
303           Info.getTotalNumSGPRs(MF.getSubtarget<SISubtarget>()),
304           Info.PrivateSegmentSize,
305           getFunctionCodeSize(MF));
306         return false;
307       }
308 
309       OutStreamer->emitRawComment(" Kernel info:", false);
310       emitCommonFunctionComments(CurrentProgramInfo.NumVGPR,
311                                  CurrentProgramInfo.NumSGPR,
312                                  CurrentProgramInfo.ScratchSize,
313                                  getFunctionCodeSize(MF));
314 
315       OutStreamer->emitRawComment(
316         " FloatMode: " + Twine(CurrentProgramInfo.FloatMode), false);
317       OutStreamer->emitRawComment(
318         " IeeeMode: " + Twine(CurrentProgramInfo.IEEEMode), false);
319       OutStreamer->emitRawComment(
320         " LDSByteSize: " + Twine(CurrentProgramInfo.LDSSize) +
321         " bytes/workgroup (compile time only)", false);
322 
323       OutStreamer->emitRawComment(
324         " SGPRBlocks: " + Twine(CurrentProgramInfo.SGPRBlocks), false);
325       OutStreamer->emitRawComment(
326         " VGPRBlocks: " + Twine(CurrentProgramInfo.VGPRBlocks), false);
327 
328       OutStreamer->emitRawComment(
329         " NumSGPRsForWavesPerEU: " +
330         Twine(CurrentProgramInfo.NumSGPRsForWavesPerEU), false);
331       OutStreamer->emitRawComment(
332         " NumVGPRsForWavesPerEU: " +
333         Twine(CurrentProgramInfo.NumVGPRsForWavesPerEU), false);
334 
335       OutStreamer->emitRawComment(
336         " ReservedVGPRFirst: " + Twine(CurrentProgramInfo.ReservedVGPRFirst),
337         false);
338       OutStreamer->emitRawComment(
339         " ReservedVGPRCount: " + Twine(CurrentProgramInfo.ReservedVGPRCount),
340         false);
341 
342       if (MF.getSubtarget<SISubtarget>().debuggerEmitPrologue()) {
343         OutStreamer->emitRawComment(
344           " DebuggerWavefrontPrivateSegmentOffsetSGPR: s" +
345           Twine(CurrentProgramInfo.DebuggerWavefrontPrivateSegmentOffsetSGPR), false);
346         OutStreamer->emitRawComment(
347           " DebuggerPrivateSegmentBufferSGPR: s" +
348           Twine(CurrentProgramInfo.DebuggerPrivateSegmentBufferSGPR), false);
349       }
350 
351       OutStreamer->emitRawComment(
352         " COMPUTE_PGM_RSRC2:USER_SGPR: " +
353         Twine(G_00B84C_USER_SGPR(CurrentProgramInfo.ComputePGMRSrc2)), false);
354       OutStreamer->emitRawComment(
355         " COMPUTE_PGM_RSRC2:TRAP_HANDLER: " +
356         Twine(G_00B84C_TRAP_HANDLER(CurrentProgramInfo.ComputePGMRSrc2)), false);
357       OutStreamer->emitRawComment(
358         " COMPUTE_PGM_RSRC2:TGID_X_EN: " +
359         Twine(G_00B84C_TGID_X_EN(CurrentProgramInfo.ComputePGMRSrc2)), false);
360       OutStreamer->emitRawComment(
361         " COMPUTE_PGM_RSRC2:TGID_Y_EN: " +
362         Twine(G_00B84C_TGID_Y_EN(CurrentProgramInfo.ComputePGMRSrc2)), false);
363       OutStreamer->emitRawComment(
364         " COMPUTE_PGM_RSRC2:TGID_Z_EN: " +
365         Twine(G_00B84C_TGID_Z_EN(CurrentProgramInfo.ComputePGMRSrc2)), false);
366       OutStreamer->emitRawComment(
367         " COMPUTE_PGM_RSRC2:TIDIG_COMP_CNT: " +
368         Twine(G_00B84C_TIDIG_COMP_CNT(CurrentProgramInfo.ComputePGMRSrc2)),
369         false);
370     } else {
371       R600MachineFunctionInfo *MFI = MF.getInfo<R600MachineFunctionInfo>();
372       OutStreamer->emitRawComment(
373         Twine("SQ_PGM_RESOURCES:STACK_SIZE = " + Twine(MFI->CFStackSize)));
374     }
375   }
376 
377   if (STM.dumpCode()) {
378 
379     OutStreamer->SwitchSection(
380         Context.getELFSection(".AMDGPU.disasm", ELF::SHT_NOTE, 0));
381 
382     for (size_t i = 0; i < DisasmLines.size(); ++i) {
383       std::string Comment(DisasmLineMaxLen - DisasmLines[i].size(), ' ');
384       Comment += " ; " + HexLines[i] + "\n";
385 
386       OutStreamer->EmitBytes(StringRef(DisasmLines[i]));
387       OutStreamer->EmitBytes(StringRef(Comment));
388     }
389   }
390 
391   return false;
392 }
393 
394 void AMDGPUAsmPrinter::EmitProgramInfoR600(const MachineFunction &MF) {
395   unsigned MaxGPR = 0;
396   bool killPixel = false;
397   const R600Subtarget &STM = MF.getSubtarget<R600Subtarget>();
398   const R600RegisterInfo *RI = STM.getRegisterInfo();
399   const R600MachineFunctionInfo *MFI = MF.getInfo<R600MachineFunctionInfo>();
400 
401   for (const MachineBasicBlock &MBB : MF) {
402     for (const MachineInstr &MI : MBB) {
403       if (MI.getOpcode() == AMDGPU::KILLGT)
404         killPixel = true;
405       unsigned numOperands = MI.getNumOperands();
406       for (unsigned op_idx = 0; op_idx < numOperands; op_idx++) {
407         const MachineOperand &MO = MI.getOperand(op_idx);
408         if (!MO.isReg())
409           continue;
410         unsigned HWReg = RI->getHWRegIndex(MO.getReg());
411 
412         // Register with value > 127 aren't GPR
413         if (HWReg > 127)
414           continue;
415         MaxGPR = std::max(MaxGPR, HWReg);
416       }
417     }
418   }
419 
420   unsigned RsrcReg;
421   if (STM.getGeneration() >= R600Subtarget::EVERGREEN) {
422     // Evergreen / Northern Islands
423     switch (MF.getFunction()->getCallingConv()) {
424     default: LLVM_FALLTHROUGH;
425     case CallingConv::AMDGPU_CS: RsrcReg = R_0288D4_SQ_PGM_RESOURCES_LS; break;
426     case CallingConv::AMDGPU_GS: RsrcReg = R_028878_SQ_PGM_RESOURCES_GS; break;
427     case CallingConv::AMDGPU_PS: RsrcReg = R_028844_SQ_PGM_RESOURCES_PS; break;
428     case CallingConv::AMDGPU_VS: RsrcReg = R_028860_SQ_PGM_RESOURCES_VS; break;
429     }
430   } else {
431     // R600 / R700
432     switch (MF.getFunction()->getCallingConv()) {
433     default: LLVM_FALLTHROUGH;
434     case CallingConv::AMDGPU_GS: LLVM_FALLTHROUGH;
435     case CallingConv::AMDGPU_CS: LLVM_FALLTHROUGH;
436     case CallingConv::AMDGPU_VS: RsrcReg = R_028868_SQ_PGM_RESOURCES_VS; break;
437     case CallingConv::AMDGPU_PS: RsrcReg = R_028850_SQ_PGM_RESOURCES_PS; break;
438     }
439   }
440 
441   OutStreamer->EmitIntValue(RsrcReg, 4);
442   OutStreamer->EmitIntValue(S_NUM_GPRS(MaxGPR + 1) |
443                            S_STACK_SIZE(MFI->CFStackSize), 4);
444   OutStreamer->EmitIntValue(R_02880C_DB_SHADER_CONTROL, 4);
445   OutStreamer->EmitIntValue(S_02880C_KILL_ENABLE(killPixel), 4);
446 
447   if (AMDGPU::isCompute(MF.getFunction()->getCallingConv())) {
448     OutStreamer->EmitIntValue(R_0288E8_SQ_LDS_ALLOC, 4);
449     OutStreamer->EmitIntValue(alignTo(MFI->getLDSSize(), 4) >> 2, 4);
450   }
451 }
452 
453 uint64_t AMDGPUAsmPrinter::getFunctionCodeSize(const MachineFunction &MF) const {
454   const SISubtarget &STM = MF.getSubtarget<SISubtarget>();
455   const SIInstrInfo *TII = STM.getInstrInfo();
456 
457   uint64_t CodeSize = 0;
458 
459   for (const MachineBasicBlock &MBB : MF) {
460     for (const MachineInstr &MI : MBB) {
461       // TODO: CodeSize should account for multiple functions.
462 
463       // TODO: Should we count size of debug info?
464       if (MI.isDebugValue())
465         continue;
466 
467       CodeSize += TII->getInstSizeInBytes(MI);
468     }
469   }
470 
471   return CodeSize;
472 }
473 
474 static bool hasAnyNonFlatUseOfReg(const MachineRegisterInfo &MRI,
475                                   const SIInstrInfo &TII,
476                                   unsigned Reg) {
477   for (const MachineOperand &UseOp : MRI.reg_operands(Reg)) {
478     if (!UseOp.isImplicit() || !TII.isFLAT(*UseOp.getParent()))
479       return true;
480   }
481 
482   return false;
483 }
484 
485 static unsigned getNumExtraSGPRs(const SISubtarget &ST,
486                                  bool VCCUsed,
487                                  bool FlatScrUsed) {
488   unsigned ExtraSGPRs = 0;
489   if (VCCUsed)
490     ExtraSGPRs = 2;
491 
492   if (ST.getGeneration() < SISubtarget::VOLCANIC_ISLANDS) {
493     if (FlatScrUsed)
494       ExtraSGPRs = 4;
495   } else {
496     if (ST.isXNACKEnabled())
497       ExtraSGPRs = 4;
498 
499     if (FlatScrUsed)
500       ExtraSGPRs = 6;
501   }
502 
503   return ExtraSGPRs;
504 }
505 
506 int32_t AMDGPUAsmPrinter::SIFunctionResourceInfo::getTotalNumSGPRs(
507   const SISubtarget &ST) const {
508   return NumExplicitSGPR + getNumExtraSGPRs(ST, UsesVCC, UsesFlatScratch);
509 }
510 
511 AMDGPUAsmPrinter::SIFunctionResourceInfo AMDGPUAsmPrinter::analyzeResourceUsage(
512   const MachineFunction &MF) const {
513   SIFunctionResourceInfo Info;
514 
515   const SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();
516   const SISubtarget &ST = MF.getSubtarget<SISubtarget>();
517   const MachineFrameInfo &FrameInfo = MF.getFrameInfo();
518   const MachineRegisterInfo &MRI = MF.getRegInfo();
519   const SIInstrInfo *TII = ST.getInstrInfo();
520   const SIRegisterInfo &TRI = TII->getRegisterInfo();
521 
522   Info.UsesFlatScratch = MRI.isPhysRegUsed(AMDGPU::FLAT_SCR_LO) ||
523                          MRI.isPhysRegUsed(AMDGPU::FLAT_SCR_HI);
524 
525   // Even if FLAT_SCRATCH is implicitly used, it has no effect if flat
526   // instructions aren't used to access the scratch buffer. Inline assembly may
527   // need it though.
528   //
529   // If we only have implicit uses of flat_scr on flat instructions, it is not
530   // really needed.
531   if (Info.UsesFlatScratch && !MFI->hasFlatScratchInit() &&
532       (!hasAnyNonFlatUseOfReg(MRI, *TII, AMDGPU::FLAT_SCR) &&
533        !hasAnyNonFlatUseOfReg(MRI, *TII, AMDGPU::FLAT_SCR_LO) &&
534        !hasAnyNonFlatUseOfReg(MRI, *TII, AMDGPU::FLAT_SCR_HI))) {
535     Info.UsesFlatScratch = false;
536   }
537 
538   Info.HasDynamicallySizedStack = FrameInfo.hasVarSizedObjects();
539   Info.PrivateSegmentSize = FrameInfo.getStackSize();
540 
541 
542   Info.UsesVCC = MRI.isPhysRegUsed(AMDGPU::VCC_LO) ||
543                  MRI.isPhysRegUsed(AMDGPU::VCC_HI);
544 
545   // If there are no calls, MachineRegisterInfo can tell us the used register
546   // count easily.
547   // A tail call isn't considered a call for MachineFrameInfo's purposes.
548   if (!FrameInfo.hasCalls() && !FrameInfo.hasTailCall()) {
549     MCPhysReg HighestVGPRReg = AMDGPU::NoRegister;
550     for (MCPhysReg Reg : reverse(AMDGPU::VGPR_32RegClass.getRegisters())) {
551       if (MRI.isPhysRegUsed(Reg)) {
552         HighestVGPRReg = Reg;
553         break;
554       }
555     }
556 
557     MCPhysReg HighestSGPRReg = AMDGPU::NoRegister;
558     for (MCPhysReg Reg : reverse(AMDGPU::SGPR_32RegClass.getRegisters())) {
559       if (MRI.isPhysRegUsed(Reg)) {
560         HighestSGPRReg = Reg;
561         break;
562       }
563     }
564 
565     // We found the maximum register index. They start at 0, so add one to get the
566     // number of registers.
567     Info.NumVGPR = HighestVGPRReg == AMDGPU::NoRegister ? 0 :
568       TRI.getHWRegIndex(HighestVGPRReg) + 1;
569     Info.NumExplicitSGPR = HighestSGPRReg == AMDGPU::NoRegister ? 0 :
570       TRI.getHWRegIndex(HighestSGPRReg) + 1;
571 
572     return Info;
573   }
574 
575   int32_t MaxVGPR = -1;
576   int32_t MaxSGPR = -1;
577   uint32_t CalleeFrameSize = 0;
578 
579   for (const MachineBasicBlock &MBB : MF) {
580     for (const MachineInstr &MI : MBB) {
581       // TODO: Check regmasks? Do they occur anywhere except calls?
582       for (const MachineOperand &MO : MI.operands()) {
583         unsigned Width = 0;
584         bool IsSGPR = false;
585 
586         if (!MO.isReg())
587           continue;
588 
589         unsigned Reg = MO.getReg();
590         switch (Reg) {
591         case AMDGPU::EXEC:
592         case AMDGPU::EXEC_LO:
593         case AMDGPU::EXEC_HI:
594         case AMDGPU::SCC:
595         case AMDGPU::M0:
596         case AMDGPU::SRC_SHARED_BASE:
597         case AMDGPU::SRC_SHARED_LIMIT:
598         case AMDGPU::SRC_PRIVATE_BASE:
599         case AMDGPU::SRC_PRIVATE_LIMIT:
600           continue;
601 
602         case AMDGPU::NoRegister:
603           assert(MI.isDebugValue());
604           continue;
605 
606         case AMDGPU::VCC:
607         case AMDGPU::VCC_LO:
608         case AMDGPU::VCC_HI:
609           Info.UsesVCC = true;
610           continue;
611 
612         case AMDGPU::FLAT_SCR:
613         case AMDGPU::FLAT_SCR_LO:
614         case AMDGPU::FLAT_SCR_HI:
615           continue;
616 
617         case AMDGPU::TBA:
618         case AMDGPU::TBA_LO:
619         case AMDGPU::TBA_HI:
620         case AMDGPU::TMA:
621         case AMDGPU::TMA_LO:
622         case AMDGPU::TMA_HI:
623           llvm_unreachable("trap handler registers should not be used");
624 
625         default:
626           break;
627         }
628 
629         if (AMDGPU::SReg_32RegClass.contains(Reg)) {
630           assert(!AMDGPU::TTMP_32RegClass.contains(Reg) &&
631                  "trap handler registers should not be used");
632           IsSGPR = true;
633           Width = 1;
634         } else if (AMDGPU::VGPR_32RegClass.contains(Reg)) {
635           IsSGPR = false;
636           Width = 1;
637         } else if (AMDGPU::SReg_64RegClass.contains(Reg)) {
638           assert(!AMDGPU::TTMP_64RegClass.contains(Reg) &&
639                  "trap handler registers should not be used");
640           IsSGPR = true;
641           Width = 2;
642         } else if (AMDGPU::VReg_64RegClass.contains(Reg)) {
643           IsSGPR = false;
644           Width = 2;
645         } else if (AMDGPU::VReg_96RegClass.contains(Reg)) {
646           IsSGPR = false;
647           Width = 3;
648         } else if (AMDGPU::SReg_128RegClass.contains(Reg)) {
649           IsSGPR = true;
650           Width = 4;
651         } else if (AMDGPU::VReg_128RegClass.contains(Reg)) {
652           IsSGPR = false;
653           Width = 4;
654         } else if (AMDGPU::SReg_256RegClass.contains(Reg)) {
655           IsSGPR = true;
656           Width = 8;
657         } else if (AMDGPU::VReg_256RegClass.contains(Reg)) {
658           IsSGPR = false;
659           Width = 8;
660         } else if (AMDGPU::SReg_512RegClass.contains(Reg)) {
661           IsSGPR = true;
662           Width = 16;
663         } else if (AMDGPU::VReg_512RegClass.contains(Reg)) {
664           IsSGPR = false;
665           Width = 16;
666         } else {
667           llvm_unreachable("Unknown register class");
668         }
669         unsigned HWReg = TRI.getHWRegIndex(Reg);
670         int MaxUsed = HWReg + Width - 1;
671         if (IsSGPR) {
672           MaxSGPR = MaxUsed > MaxSGPR ? MaxUsed : MaxSGPR;
673         } else {
674           MaxVGPR = MaxUsed > MaxVGPR ? MaxUsed : MaxVGPR;
675         }
676       }
677 
678       if (MI.isCall()) {
679         // Pseudo used just to encode the underlying global. Is there a better
680         // way to track this?
681 
682         const MachineOperand *CalleeOp
683           = TII->getNamedOperand(MI, AMDGPU::OpName::callee);
684         const Function *Callee = cast<Function>(CalleeOp->getGlobal());
685         if (Callee->isDeclaration()) {
686           // If this is a call to an external function, we can't do much. Make
687           // conservative guesses.
688 
689           // 48 SGPRs - vcc, - flat_scr, -xnack
690           int MaxSGPRGuess = 47 - getNumExtraSGPRs(ST, true,
691                                                    ST.hasFlatAddressSpace());
692           MaxSGPR = std::max(MaxSGPR, MaxSGPRGuess);
693           MaxVGPR = std::max(MaxVGPR, 23);
694 
695           CalleeFrameSize = std::max(CalleeFrameSize, 16384u);
696           Info.UsesVCC = true;
697           Info.UsesFlatScratch = ST.hasFlatAddressSpace();
698           Info.HasDynamicallySizedStack = true;
699         } else {
700           // We force CodeGen to run in SCC order, so the callee's register
701           // usage etc. should be the cumulative usage of all callees.
702           auto I = CallGraphResourceInfo.find(Callee);
703           assert(I != CallGraphResourceInfo.end() &&
704                  "callee should have been handled before caller");
705 
706           MaxSGPR = std::max(I->second.NumExplicitSGPR - 1, MaxSGPR);
707           MaxVGPR = std::max(I->second.NumVGPR - 1, MaxVGPR);
708           CalleeFrameSize
709             = std::max(I->second.PrivateSegmentSize, CalleeFrameSize);
710           Info.UsesVCC |= I->second.UsesVCC;
711           Info.UsesFlatScratch |= I->second.UsesFlatScratch;
712           Info.HasDynamicallySizedStack |= I->second.HasDynamicallySizedStack;
713           Info.HasRecursion |= I->second.HasRecursion;
714         }
715 
716         if (!Callee->doesNotRecurse())
717           Info.HasRecursion = true;
718       }
719     }
720   }
721 
722   Info.NumExplicitSGPR = MaxSGPR + 1;
723   Info.NumVGPR = MaxVGPR + 1;
724   Info.PrivateSegmentSize += CalleeFrameSize;
725 
726   return Info;
727 }
728 
729 void AMDGPUAsmPrinter::getSIProgramInfo(SIProgramInfo &ProgInfo,
730                                         const MachineFunction &MF) {
731   SIFunctionResourceInfo Info = analyzeResourceUsage(MF);
732 
733   ProgInfo.NumVGPR = Info.NumVGPR;
734   ProgInfo.NumSGPR = Info.NumExplicitSGPR;
735   ProgInfo.ScratchSize = Info.PrivateSegmentSize;
736   ProgInfo.VCCUsed = Info.UsesVCC;
737   ProgInfo.FlatUsed = Info.UsesFlatScratch;
738   ProgInfo.DynamicCallStack = Info.HasDynamicallySizedStack || Info.HasRecursion;
739 
740   const SISubtarget &STM = MF.getSubtarget<SISubtarget>();
741   const SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();
742   const SIInstrInfo *TII = STM.getInstrInfo();
743   const SIRegisterInfo *RI = &TII->getRegisterInfo();
744 
745   unsigned ExtraSGPRs = getNumExtraSGPRs(STM,
746                                          ProgInfo.VCCUsed,
747                                          ProgInfo.FlatUsed);
748   unsigned ExtraVGPRs = STM.getReservedNumVGPRs(MF);
749 
750   // Check the addressable register limit before we add ExtraSGPRs.
751   if (STM.getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS &&
752       !STM.hasSGPRInitBug()) {
753     unsigned MaxAddressableNumSGPRs = STM.getAddressableNumSGPRs();
754     if (ProgInfo.NumSGPR > MaxAddressableNumSGPRs) {
755       // This can happen due to a compiler bug or when using inline asm.
756       LLVMContext &Ctx = MF.getFunction()->getContext();
757       DiagnosticInfoResourceLimit Diag(*MF.getFunction(),
758                                        "addressable scalar registers",
759                                        ProgInfo.NumSGPR, DS_Error,
760                                        DK_ResourceLimit,
761                                        MaxAddressableNumSGPRs);
762       Ctx.diagnose(Diag);
763       ProgInfo.NumSGPR = MaxAddressableNumSGPRs - 1;
764     }
765   }
766 
767   // Account for extra SGPRs and VGPRs reserved for debugger use.
768   ProgInfo.NumSGPR += ExtraSGPRs;
769   ProgInfo.NumVGPR += ExtraVGPRs;
770 
771   // Adjust number of registers used to meet default/requested minimum/maximum
772   // number of waves per execution unit request.
773   ProgInfo.NumSGPRsForWavesPerEU = std::max(
774     std::max(ProgInfo.NumSGPR, 1u), STM.getMinNumSGPRs(MFI->getMaxWavesPerEU()));
775   ProgInfo.NumVGPRsForWavesPerEU = std::max(
776     std::max(ProgInfo.NumVGPR, 1u), STM.getMinNumVGPRs(MFI->getMaxWavesPerEU()));
777 
778   if (STM.getGeneration() <= AMDGPUSubtarget::SEA_ISLANDS ||
779       STM.hasSGPRInitBug()) {
780     unsigned MaxAddressableNumSGPRs = STM.getAddressableNumSGPRs();
781     if (ProgInfo.NumSGPR > MaxAddressableNumSGPRs) {
782       // This can happen due to a compiler bug or when using inline asm to use
783       // the registers which are usually reserved for vcc etc.
784       LLVMContext &Ctx = MF.getFunction()->getContext();
785       DiagnosticInfoResourceLimit Diag(*MF.getFunction(),
786                                        "scalar registers",
787                                        ProgInfo.NumSGPR, DS_Error,
788                                        DK_ResourceLimit,
789                                        MaxAddressableNumSGPRs);
790       Ctx.diagnose(Diag);
791       ProgInfo.NumSGPR = MaxAddressableNumSGPRs;
792       ProgInfo.NumSGPRsForWavesPerEU = MaxAddressableNumSGPRs;
793     }
794   }
795 
796   if (STM.hasSGPRInitBug()) {
797     ProgInfo.NumSGPR =
798         AMDGPU::IsaInfo::FIXED_NUM_SGPRS_FOR_INIT_BUG;
799     ProgInfo.NumSGPRsForWavesPerEU =
800         AMDGPU::IsaInfo::FIXED_NUM_SGPRS_FOR_INIT_BUG;
801   }
802 
803   if (MFI->getNumUserSGPRs() > STM.getMaxNumUserSGPRs()) {
804     LLVMContext &Ctx = MF.getFunction()->getContext();
805     DiagnosticInfoResourceLimit Diag(*MF.getFunction(), "user SGPRs",
806                                      MFI->getNumUserSGPRs(), DS_Error);
807     Ctx.diagnose(Diag);
808   }
809 
810   if (MFI->getLDSSize() > static_cast<unsigned>(STM.getLocalMemorySize())) {
811     LLVMContext &Ctx = MF.getFunction()->getContext();
812     DiagnosticInfoResourceLimit Diag(*MF.getFunction(), "local memory",
813                                      MFI->getLDSSize(), DS_Error);
814     Ctx.diagnose(Diag);
815   }
816 
817   // SGPRBlocks is actual number of SGPR blocks minus 1.
818   ProgInfo.SGPRBlocks = alignTo(ProgInfo.NumSGPRsForWavesPerEU,
819                                 STM.getSGPREncodingGranule());
820   ProgInfo.SGPRBlocks = ProgInfo.SGPRBlocks / STM.getSGPREncodingGranule() - 1;
821 
822   // VGPRBlocks is actual number of VGPR blocks minus 1.
823   ProgInfo.VGPRBlocks = alignTo(ProgInfo.NumVGPRsForWavesPerEU,
824                                 STM.getVGPREncodingGranule());
825   ProgInfo.VGPRBlocks = ProgInfo.VGPRBlocks / STM.getVGPREncodingGranule() - 1;
826 
827   // Record first reserved VGPR and number of reserved VGPRs.
828   ProgInfo.ReservedVGPRFirst = STM.debuggerReserveRegs() ? ProgInfo.NumVGPR : 0;
829   ProgInfo.ReservedVGPRCount = STM.getReservedNumVGPRs(MF);
830 
831   // Update DebuggerWavefrontPrivateSegmentOffsetSGPR and
832   // DebuggerPrivateSegmentBufferSGPR fields if "amdgpu-debugger-emit-prologue"
833   // attribute was requested.
834   if (STM.debuggerEmitPrologue()) {
835     ProgInfo.DebuggerWavefrontPrivateSegmentOffsetSGPR =
836       RI->getHWRegIndex(MFI->getScratchWaveOffsetReg());
837     ProgInfo.DebuggerPrivateSegmentBufferSGPR =
838       RI->getHWRegIndex(MFI->getScratchRSrcReg());
839   }
840 
841   // Set the value to initialize FP_ROUND and FP_DENORM parts of the mode
842   // register.
843   ProgInfo.FloatMode = getFPMode(MF);
844 
845   ProgInfo.IEEEMode = STM.enableIEEEBit(MF);
846 
847   // Make clamp modifier on NaN input returns 0.
848   ProgInfo.DX10Clamp = STM.enableDX10Clamp();
849 
850   unsigned LDSAlignShift;
851   if (STM.getGeneration() < SISubtarget::SEA_ISLANDS) {
852     // LDS is allocated in 64 dword blocks.
853     LDSAlignShift = 8;
854   } else {
855     // LDS is allocated in 128 dword blocks.
856     LDSAlignShift = 9;
857   }
858 
859   unsigned LDSSpillSize =
860     MFI->getLDSWaveSpillSize() * MFI->getMaxFlatWorkGroupSize();
861 
862   ProgInfo.LDSSize = MFI->getLDSSize() + LDSSpillSize;
863   ProgInfo.LDSBlocks =
864       alignTo(ProgInfo.LDSSize, 1ULL << LDSAlignShift) >> LDSAlignShift;
865 
866   // Scratch is allocated in 256 dword blocks.
867   unsigned ScratchAlignShift = 10;
868   // We need to program the hardware with the amount of scratch memory that
869   // is used by the entire wave.  ProgInfo.ScratchSize is the amount of
870   // scratch memory used per thread.
871   ProgInfo.ScratchBlocks =
872       alignTo(ProgInfo.ScratchSize * STM.getWavefrontSize(),
873               1ULL << ScratchAlignShift) >>
874       ScratchAlignShift;
875 
876   ProgInfo.ComputePGMRSrc1 =
877       S_00B848_VGPRS(ProgInfo.VGPRBlocks) |
878       S_00B848_SGPRS(ProgInfo.SGPRBlocks) |
879       S_00B848_PRIORITY(ProgInfo.Priority) |
880       S_00B848_FLOAT_MODE(ProgInfo.FloatMode) |
881       S_00B848_PRIV(ProgInfo.Priv) |
882       S_00B848_DX10_CLAMP(ProgInfo.DX10Clamp) |
883       S_00B848_DEBUG_MODE(ProgInfo.DebugMode) |
884       S_00B848_IEEE_MODE(ProgInfo.IEEEMode);
885 
886   // 0 = X, 1 = XY, 2 = XYZ
887   unsigned TIDIGCompCnt = 0;
888   if (MFI->hasWorkItemIDZ())
889     TIDIGCompCnt = 2;
890   else if (MFI->hasWorkItemIDY())
891     TIDIGCompCnt = 1;
892 
893   ProgInfo.ComputePGMRSrc2 =
894       S_00B84C_SCRATCH_EN(ProgInfo.ScratchBlocks > 0) |
895       S_00B84C_USER_SGPR(MFI->getNumUserSGPRs()) |
896       S_00B84C_TRAP_HANDLER(STM.isTrapHandlerEnabled()) |
897       S_00B84C_TGID_X_EN(MFI->hasWorkGroupIDX()) |
898       S_00B84C_TGID_Y_EN(MFI->hasWorkGroupIDY()) |
899       S_00B84C_TGID_Z_EN(MFI->hasWorkGroupIDZ()) |
900       S_00B84C_TG_SIZE_EN(MFI->hasWorkGroupInfo()) |
901       S_00B84C_TIDIG_COMP_CNT(TIDIGCompCnt) |
902       S_00B84C_EXCP_EN_MSB(0) |
903       // For AMDHSA, LDS_SIZE must be zero, as it is populated by the CP.
904       S_00B84C_LDS_SIZE(STM.isAmdHsaOS() ? 0 : ProgInfo.LDSBlocks) |
905       S_00B84C_EXCP_EN(0);
906 }
907 
908 static unsigned getRsrcReg(CallingConv::ID CallConv) {
909   switch (CallConv) {
910   default: LLVM_FALLTHROUGH;
911   case CallingConv::AMDGPU_CS: return R_00B848_COMPUTE_PGM_RSRC1;
912   case CallingConv::AMDGPU_LS: return R_00B528_SPI_SHADER_PGM_RSRC1_LS;
913   case CallingConv::AMDGPU_HS: return R_00B428_SPI_SHADER_PGM_RSRC1_HS;
914   case CallingConv::AMDGPU_ES: return R_00B328_SPI_SHADER_PGM_RSRC1_ES;
915   case CallingConv::AMDGPU_GS: return R_00B228_SPI_SHADER_PGM_RSRC1_GS;
916   case CallingConv::AMDGPU_VS: return R_00B128_SPI_SHADER_PGM_RSRC1_VS;
917   case CallingConv::AMDGPU_PS: return R_00B028_SPI_SHADER_PGM_RSRC1_PS;
918   }
919 }
920 
921 void AMDGPUAsmPrinter::EmitProgramInfoSI(const MachineFunction &MF,
922                                          const SIProgramInfo &CurrentProgramInfo) {
923   const SISubtarget &STM = MF.getSubtarget<SISubtarget>();
924   const SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();
925   unsigned RsrcReg = getRsrcReg(MF.getFunction()->getCallingConv());
926 
927   if (AMDGPU::isCompute(MF.getFunction()->getCallingConv())) {
928     OutStreamer->EmitIntValue(R_00B848_COMPUTE_PGM_RSRC1, 4);
929 
930     OutStreamer->EmitIntValue(CurrentProgramInfo.ComputePGMRSrc1, 4);
931 
932     OutStreamer->EmitIntValue(R_00B84C_COMPUTE_PGM_RSRC2, 4);
933     OutStreamer->EmitIntValue(CurrentProgramInfo.ComputePGMRSrc2, 4);
934 
935     OutStreamer->EmitIntValue(R_00B860_COMPUTE_TMPRING_SIZE, 4);
936     OutStreamer->EmitIntValue(S_00B860_WAVESIZE(CurrentProgramInfo.ScratchBlocks), 4);
937 
938     // TODO: Should probably note flat usage somewhere. SC emits a "FlatPtr32 =
939     // 0" comment but I don't see a corresponding field in the register spec.
940   } else {
941     OutStreamer->EmitIntValue(RsrcReg, 4);
942     OutStreamer->EmitIntValue(S_00B028_VGPRS(CurrentProgramInfo.VGPRBlocks) |
943                               S_00B028_SGPRS(CurrentProgramInfo.SGPRBlocks), 4);
944     unsigned Rsrc2Val = 0;
945     if (STM.isVGPRSpillingEnabled(*MF.getFunction())) {
946       OutStreamer->EmitIntValue(R_0286E8_SPI_TMPRING_SIZE, 4);
947       OutStreamer->EmitIntValue(S_0286E8_WAVESIZE(CurrentProgramInfo.ScratchBlocks), 4);
948       if (TM.getTargetTriple().getOS() == Triple::AMDPAL)
949         Rsrc2Val = S_00B84C_SCRATCH_EN(CurrentProgramInfo.ScratchBlocks > 0);
950     }
951     if (MF.getFunction()->getCallingConv() == CallingConv::AMDGPU_PS) {
952       OutStreamer->EmitIntValue(R_0286CC_SPI_PS_INPUT_ENA, 4);
953       OutStreamer->EmitIntValue(MFI->getPSInputEnable(), 4);
954       OutStreamer->EmitIntValue(R_0286D0_SPI_PS_INPUT_ADDR, 4);
955       OutStreamer->EmitIntValue(MFI->getPSInputAddr(), 4);
956       Rsrc2Val |= S_00B02C_EXTRA_LDS_SIZE(CurrentProgramInfo.LDSBlocks);
957     }
958     if (Rsrc2Val) {
959       OutStreamer->EmitIntValue(RsrcReg + 4 /*rsrc2*/, 4);
960       OutStreamer->EmitIntValue(Rsrc2Val, 4);
961     }
962   }
963 
964   OutStreamer->EmitIntValue(R_SPILLED_SGPRS, 4);
965   OutStreamer->EmitIntValue(MFI->getNumSpilledSGPRs(), 4);
966   OutStreamer->EmitIntValue(R_SPILLED_VGPRS, 4);
967   OutStreamer->EmitIntValue(MFI->getNumSpilledVGPRs(), 4);
968 }
969 
970 // This is the equivalent of EmitProgramInfoSI above, but for when the OS type
971 // is AMDPAL.  It stores each compute/SPI register setting and other PAL
972 // metadata items into the PALMetadataMap, combining with any provided by the
973 // frontend as LLVM metadata. Once all functions are written, PALMetadataMap is
974 // then written as a single block in the .note section.
975 void AMDGPUAsmPrinter::EmitPALMetadata(const MachineFunction &MF,
976        const SIProgramInfo &CurrentProgramInfo) {
977   const SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();
978   // Given the calling convention, calculate the register number for rsrc1. In
979   // principle the register number could change in future hardware, but we know
980   // it is the same for gfx6-9 (except that LS and ES don't exist on gfx9), so
981   // we can use the same fixed value that .AMDGPU.config has for Mesa. Note
982   // that we use a register number rather than a byte offset, so we need to
983   // divide by 4.
984   unsigned Rsrc1Reg = getRsrcReg(MF.getFunction()->getCallingConv()) / 4;
985   unsigned Rsrc2Reg = Rsrc1Reg + 1;
986   // Also calculate the PAL metadata key for *S_SCRATCH_SIZE. It can be used
987   // with a constant offset to access any non-register shader-specific PAL
988   // metadata key.
989   unsigned ScratchSizeKey = PALMD::Key::CS_SCRATCH_SIZE;
990   switch (MF.getFunction()->getCallingConv()) {
991     case CallingConv::AMDGPU_PS:
992       ScratchSizeKey = PALMD::Key::PS_SCRATCH_SIZE;
993       break;
994     case CallingConv::AMDGPU_VS:
995       ScratchSizeKey = PALMD::Key::VS_SCRATCH_SIZE;
996       break;
997     case CallingConv::AMDGPU_GS:
998       ScratchSizeKey = PALMD::Key::GS_SCRATCH_SIZE;
999       break;
1000     case CallingConv::AMDGPU_ES:
1001       ScratchSizeKey = PALMD::Key::ES_SCRATCH_SIZE;
1002       break;
1003     case CallingConv::AMDGPU_HS:
1004       ScratchSizeKey = PALMD::Key::HS_SCRATCH_SIZE;
1005       break;
1006     case CallingConv::AMDGPU_LS:
1007       ScratchSizeKey = PALMD::Key::LS_SCRATCH_SIZE;
1008       break;
1009   }
1010   unsigned NumUsedVgprsKey = ScratchSizeKey +
1011       PALMD::Key::VS_NUM_USED_VGPRS - PALMD::Key::VS_SCRATCH_SIZE;
1012   unsigned NumUsedSgprsKey = ScratchSizeKey +
1013       PALMD::Key::VS_NUM_USED_SGPRS - PALMD::Key::VS_SCRATCH_SIZE;
1014   PALMetadataMap[NumUsedVgprsKey] = CurrentProgramInfo.NumVGPRsForWavesPerEU;
1015   PALMetadataMap[NumUsedSgprsKey] = CurrentProgramInfo.NumSGPRsForWavesPerEU;
1016   if (AMDGPU::isCompute(MF.getFunction()->getCallingConv())) {
1017     PALMetadataMap[Rsrc1Reg] |= CurrentProgramInfo.ComputePGMRSrc1;
1018     PALMetadataMap[Rsrc2Reg] |= CurrentProgramInfo.ComputePGMRSrc2;
1019     // ScratchSize is in bytes, 16 aligned.
1020     PALMetadataMap[ScratchSizeKey] |=
1021         alignTo(CurrentProgramInfo.ScratchSize, 16);
1022   } else {
1023     PALMetadataMap[Rsrc1Reg] |= S_00B028_VGPRS(CurrentProgramInfo.VGPRBlocks) |
1024         S_00B028_SGPRS(CurrentProgramInfo.SGPRBlocks);
1025     if (CurrentProgramInfo.ScratchBlocks > 0)
1026       PALMetadataMap[Rsrc2Reg] |= S_00B84C_SCRATCH_EN(1);
1027     // ScratchSize is in bytes, 16 aligned.
1028     PALMetadataMap[ScratchSizeKey] |=
1029         alignTo(CurrentProgramInfo.ScratchSize, 16);
1030   }
1031   if (MF.getFunction()->getCallingConv() == CallingConv::AMDGPU_PS) {
1032     PALMetadataMap[Rsrc2Reg] |=
1033         S_00B02C_EXTRA_LDS_SIZE(CurrentProgramInfo.LDSBlocks);
1034     PALMetadataMap[R_0286CC_SPI_PS_INPUT_ENA / 4] |= MFI->getPSInputEnable();
1035     PALMetadataMap[R_0286D0_SPI_PS_INPUT_ADDR / 4] |= MFI->getPSInputAddr();
1036   }
1037 }
1038 
1039 // This is supposed to be log2(Size)
1040 static amd_element_byte_size_t getElementByteSizeValue(unsigned Size) {
1041   switch (Size) {
1042   case 4:
1043     return AMD_ELEMENT_4_BYTES;
1044   case 8:
1045     return AMD_ELEMENT_8_BYTES;
1046   case 16:
1047     return AMD_ELEMENT_16_BYTES;
1048   default:
1049     llvm_unreachable("invalid private_element_size");
1050   }
1051 }
1052 
1053 void AMDGPUAsmPrinter::getAmdKernelCode(amd_kernel_code_t &Out,
1054                                         const SIProgramInfo &CurrentProgramInfo,
1055                                         const MachineFunction &MF) const {
1056   const SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();
1057   const SISubtarget &STM = MF.getSubtarget<SISubtarget>();
1058 
1059   AMDGPU::initDefaultAMDKernelCodeT(Out, STM.getFeatureBits());
1060 
1061   Out.compute_pgm_resource_registers =
1062       CurrentProgramInfo.ComputePGMRSrc1 |
1063       (CurrentProgramInfo.ComputePGMRSrc2 << 32);
1064   Out.code_properties = AMD_CODE_PROPERTY_IS_PTR64;
1065 
1066   if (CurrentProgramInfo.DynamicCallStack)
1067     Out.code_properties |= AMD_CODE_PROPERTY_IS_DYNAMIC_CALLSTACK;
1068 
1069   AMD_HSA_BITS_SET(Out.code_properties,
1070                    AMD_CODE_PROPERTY_PRIVATE_ELEMENT_SIZE,
1071                    getElementByteSizeValue(STM.getMaxPrivateElementSize()));
1072 
1073   if (MFI->hasPrivateSegmentBuffer()) {
1074     Out.code_properties |=
1075       AMD_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER;
1076   }
1077 
1078   if (MFI->hasDispatchPtr())
1079     Out.code_properties |= AMD_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR;
1080 
1081   if (MFI->hasQueuePtr())
1082     Out.code_properties |= AMD_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR;
1083 
1084   if (MFI->hasKernargSegmentPtr())
1085     Out.code_properties |= AMD_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR;
1086 
1087   if (MFI->hasDispatchID())
1088     Out.code_properties |= AMD_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID;
1089 
1090   if (MFI->hasFlatScratchInit())
1091     Out.code_properties |= AMD_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT;
1092 
1093   if (MFI->hasGridWorkgroupCountX()) {
1094     Out.code_properties |=
1095       AMD_CODE_PROPERTY_ENABLE_SGPR_GRID_WORKGROUP_COUNT_X;
1096   }
1097 
1098   if (MFI->hasGridWorkgroupCountY()) {
1099     Out.code_properties |=
1100       AMD_CODE_PROPERTY_ENABLE_SGPR_GRID_WORKGROUP_COUNT_Y;
1101   }
1102 
1103   if (MFI->hasGridWorkgroupCountZ()) {
1104     Out.code_properties |=
1105       AMD_CODE_PROPERTY_ENABLE_SGPR_GRID_WORKGROUP_COUNT_Z;
1106   }
1107 
1108   if (MFI->hasDispatchPtr())
1109     Out.code_properties |= AMD_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR;
1110 
1111   if (STM.debuggerSupported())
1112     Out.code_properties |= AMD_CODE_PROPERTY_IS_DEBUG_SUPPORTED;
1113 
1114   if (STM.isXNACKEnabled())
1115     Out.code_properties |= AMD_CODE_PROPERTY_IS_XNACK_SUPPORTED;
1116 
1117   // FIXME: Should use getKernArgSize
1118   Out.kernarg_segment_byte_size =
1119     STM.getKernArgSegmentSize(MF, MFI->getABIArgOffset());
1120   Out.wavefront_sgpr_count = CurrentProgramInfo.NumSGPR;
1121   Out.workitem_vgpr_count = CurrentProgramInfo.NumVGPR;
1122   Out.workitem_private_segment_byte_size = CurrentProgramInfo.ScratchSize;
1123   Out.workgroup_group_segment_byte_size = CurrentProgramInfo.LDSSize;
1124   Out.reserved_vgpr_first = CurrentProgramInfo.ReservedVGPRFirst;
1125   Out.reserved_vgpr_count = CurrentProgramInfo.ReservedVGPRCount;
1126 
1127   // These alignment values are specified in powers of two, so alignment =
1128   // 2^n.  The minimum alignment is 2^4 = 16.
1129   Out.kernarg_segment_alignment = std::max((size_t)4,
1130       countTrailingZeros(MFI->getMaxKernArgAlign()));
1131 
1132   if (STM.debuggerEmitPrologue()) {
1133     Out.debug_wavefront_private_segment_offset_sgpr =
1134       CurrentProgramInfo.DebuggerWavefrontPrivateSegmentOffsetSGPR;
1135     Out.debug_private_segment_buffer_sgpr =
1136       CurrentProgramInfo.DebuggerPrivateSegmentBufferSGPR;
1137   }
1138 }
1139 
1140 bool AMDGPUAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
1141                                        unsigned AsmVariant,
1142                                        const char *ExtraCode, raw_ostream &O) {
1143   // First try the generic code, which knows about modifiers like 'c' and 'n'.
1144   if (!AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O))
1145     return false;
1146 
1147   if (ExtraCode && ExtraCode[0]) {
1148     if (ExtraCode[1] != 0)
1149       return true; // Unknown modifier.
1150 
1151     switch (ExtraCode[0]) {
1152     case 'r':
1153       break;
1154     default:
1155       return true;
1156     }
1157   }
1158 
1159   // TODO: Should be able to support other operand types like globals.
1160   const MachineOperand &MO = MI->getOperand(OpNo);
1161   if (MO.isReg()) {
1162     AMDGPUInstPrinter::printRegOperand(MO.getReg(), O,
1163                                        *MF->getSubtarget().getRegisterInfo());
1164     return false;
1165   }
1166 
1167   return true;
1168 }
1169