xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp (revision 753f127f3ace09432b2baeffd71a308760641a62)
1 //===- SIMachineFunctionInfo.cpp - SI Machine Function Info ---------------===//
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 #include "SIMachineFunctionInfo.h"
10 #include "AMDGPUTargetMachine.h"
11 #include "AMDGPUSubtarget.h"
12 #include "SIRegisterInfo.h"
13 #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
14 #include "Utils/AMDGPUBaseInfo.h"
15 #include "llvm/ADT/Optional.h"
16 #include "llvm/CodeGen/LiveIntervals.h"
17 #include "llvm/CodeGen/MachineBasicBlock.h"
18 #include "llvm/CodeGen/MachineFrameInfo.h"
19 #include "llvm/CodeGen/MachineFunction.h"
20 #include "llvm/CodeGen/MachineRegisterInfo.h"
21 #include "llvm/CodeGen/MIRParser/MIParser.h"
22 #include "llvm/IR/CallingConv.h"
23 #include "llvm/IR/DiagnosticInfo.h"
24 #include "llvm/IR/Function.h"
25 #include <cassert>
26 #include <vector>
27 
28 #define MAX_LANES 64
29 
30 using namespace llvm;
31 
32 SIMachineFunctionInfo::SIMachineFunctionInfo(const MachineFunction &MF)
33   : AMDGPUMachineFunction(MF),
34     BufferPSV(static_cast<const AMDGPUTargetMachine &>(MF.getTarget())),
35     ImagePSV(static_cast<const AMDGPUTargetMachine &>(MF.getTarget())),
36     GWSResourcePSV(static_cast<const AMDGPUTargetMachine &>(MF.getTarget())),
37     PrivateSegmentBuffer(false),
38     DispatchPtr(false),
39     QueuePtr(false),
40     KernargSegmentPtr(false),
41     DispatchID(false),
42     FlatScratchInit(false),
43     WorkGroupIDX(false),
44     WorkGroupIDY(false),
45     WorkGroupIDZ(false),
46     WorkGroupInfo(false),
47     PrivateSegmentWaveByteOffset(false),
48     WorkItemIDX(false),
49     WorkItemIDY(false),
50     WorkItemIDZ(false),
51     ImplicitBufferPtr(false),
52     ImplicitArgPtr(false),
53     GITPtrHigh(0xffffffff),
54     HighBitsOf32BitAddress(0) {
55   const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
56   const Function &F = MF.getFunction();
57   FlatWorkGroupSizes = ST.getFlatWorkGroupSizes(F);
58   WavesPerEU = ST.getWavesPerEU(F);
59 
60   Occupancy = ST.computeOccupancy(F, getLDSSize());
61   CallingConv::ID CC = F.getCallingConv();
62 
63   // FIXME: Should have analysis or something rather than attribute to detect
64   // calls.
65   const bool HasCalls = F.hasFnAttribute("amdgpu-calls");
66 
67   const bool IsKernel = CC == CallingConv::AMDGPU_KERNEL ||
68                         CC == CallingConv::SPIR_KERNEL;
69 
70   if (IsKernel) {
71     if (!F.arg_empty() || ST.getImplicitArgNumBytes(F) != 0)
72       KernargSegmentPtr = true;
73     WorkGroupIDX = true;
74     WorkItemIDX = true;
75   } else if (CC == CallingConv::AMDGPU_PS) {
76     PSInputAddr = AMDGPU::getInitialPSInputAddr(F);
77   }
78 
79   MayNeedAGPRs = ST.hasMAIInsts();
80 
81   if (!isEntryFunction()) {
82     if (CC != CallingConv::AMDGPU_Gfx)
83       ArgInfo = AMDGPUArgumentUsageInfo::FixedABIFunctionInfo;
84 
85     // TODO: Pick a high register, and shift down, similar to a kernel.
86     FrameOffsetReg = AMDGPU::SGPR33;
87     StackPtrOffsetReg = AMDGPU::SGPR32;
88 
89     if (!ST.enableFlatScratch()) {
90       // Non-entry functions have no special inputs for now, other registers
91       // required for scratch access.
92       ScratchRSrcReg = AMDGPU::SGPR0_SGPR1_SGPR2_SGPR3;
93 
94       ArgInfo.PrivateSegmentBuffer =
95         ArgDescriptor::createRegister(ScratchRSrcReg);
96     }
97 
98     if (!F.hasFnAttribute("amdgpu-no-implicitarg-ptr"))
99       ImplicitArgPtr = true;
100   } else {
101     ImplicitArgPtr = false;
102     MaxKernArgAlign = std::max(ST.getAlignmentForImplicitArgPtr(),
103                                MaxKernArgAlign);
104 
105     if (ST.hasGFX90AInsts() &&
106         ST.getMaxNumVGPRs(F) <= AMDGPU::VGPR_32RegClass.getNumRegs() &&
107         !mayUseAGPRs(MF))
108       MayNeedAGPRs = false; // We will select all MAI with VGPR operands.
109   }
110 
111   bool isAmdHsaOrMesa = ST.isAmdHsaOrMesa(F);
112   if (isAmdHsaOrMesa && !ST.enableFlatScratch())
113     PrivateSegmentBuffer = true;
114   else if (ST.isMesaGfxShader(F))
115     ImplicitBufferPtr = true;
116 
117   if (!AMDGPU::isGraphics(CC)) {
118     if (IsKernel || !F.hasFnAttribute("amdgpu-no-workgroup-id-x"))
119       WorkGroupIDX = true;
120 
121     if (!F.hasFnAttribute("amdgpu-no-workgroup-id-y"))
122       WorkGroupIDY = true;
123 
124     if (!F.hasFnAttribute("amdgpu-no-workgroup-id-z"))
125       WorkGroupIDZ = true;
126 
127     if (IsKernel || !F.hasFnAttribute("amdgpu-no-workitem-id-x"))
128       WorkItemIDX = true;
129 
130     if (!F.hasFnAttribute("amdgpu-no-workitem-id-y") &&
131         ST.getMaxWorkitemID(F, 1) != 0)
132       WorkItemIDY = true;
133 
134     if (!F.hasFnAttribute("amdgpu-no-workitem-id-z") &&
135         ST.getMaxWorkitemID(F, 2) != 0)
136       WorkItemIDZ = true;
137 
138     if (!F.hasFnAttribute("amdgpu-no-dispatch-ptr"))
139       DispatchPtr = true;
140 
141     if (!F.hasFnAttribute("amdgpu-no-queue-ptr"))
142       QueuePtr = true;
143 
144     if (!F.hasFnAttribute("amdgpu-no-dispatch-id"))
145       DispatchID = true;
146   }
147 
148   // FIXME: This attribute is a hack, we just need an analysis on the function
149   // to look for allocas.
150   bool HasStackObjects = F.hasFnAttribute("amdgpu-stack-objects");
151 
152   // TODO: This could be refined a lot. The attribute is a poor way of
153   // detecting calls or stack objects that may require it before argument
154   // lowering.
155   if (ST.hasFlatAddressSpace() && isEntryFunction() &&
156       (isAmdHsaOrMesa || ST.enableFlatScratch()) &&
157       (HasCalls || HasStackObjects || ST.enableFlatScratch()) &&
158       !ST.flatScratchIsArchitected()) {
159     FlatScratchInit = true;
160   }
161 
162   if (isEntryFunction()) {
163     // X, XY, and XYZ are the only supported combinations, so make sure Y is
164     // enabled if Z is.
165     if (WorkItemIDZ)
166       WorkItemIDY = true;
167 
168     if (!ST.flatScratchIsArchitected()) {
169       PrivateSegmentWaveByteOffset = true;
170 
171       // HS and GS always have the scratch wave offset in SGPR5 on GFX9.
172       if (ST.getGeneration() >= AMDGPUSubtarget::GFX9 &&
173           (CC == CallingConv::AMDGPU_HS || CC == CallingConv::AMDGPU_GS))
174         ArgInfo.PrivateSegmentWaveByteOffset =
175             ArgDescriptor::createRegister(AMDGPU::SGPR5);
176     }
177   }
178 
179   Attribute A = F.getFnAttribute("amdgpu-git-ptr-high");
180   StringRef S = A.getValueAsString();
181   if (!S.empty())
182     S.consumeInteger(0, GITPtrHigh);
183 
184   A = F.getFnAttribute("amdgpu-32bit-address-high-bits");
185   S = A.getValueAsString();
186   if (!S.empty())
187     S.consumeInteger(0, HighBitsOf32BitAddress);
188 
189   // On GFX908, in order to guarantee copying between AGPRs, we need a scratch
190   // VGPR available at all times. For now, reserve highest available VGPR. After
191   // RA, shift it to the lowest available unused VGPR if the one exist.
192   if (ST.hasMAIInsts() && !ST.hasGFX90AInsts()) {
193     VGPRForAGPRCopy =
194         AMDGPU::VGPR_32RegClass.getRegister(ST.getMaxNumVGPRs(F) - 1);
195   }
196 }
197 
198 MachineFunctionInfo *SIMachineFunctionInfo::clone(
199     BumpPtrAllocator &Allocator, MachineFunction &DestMF,
200     const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB)
201     const {
202   return DestMF.cloneInfo<SIMachineFunctionInfo>(*this);
203 }
204 
205 void SIMachineFunctionInfo::limitOccupancy(const MachineFunction &MF) {
206   limitOccupancy(getMaxWavesPerEU());
207   const GCNSubtarget& ST = MF.getSubtarget<GCNSubtarget>();
208   limitOccupancy(ST.getOccupancyWithLocalMemSize(getLDSSize(),
209                  MF.getFunction()));
210 }
211 
212 Register SIMachineFunctionInfo::addPrivateSegmentBuffer(
213   const SIRegisterInfo &TRI) {
214   ArgInfo.PrivateSegmentBuffer =
215     ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
216     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SGPR_128RegClass));
217   NumUserSGPRs += 4;
218   return ArgInfo.PrivateSegmentBuffer.getRegister();
219 }
220 
221 Register SIMachineFunctionInfo::addDispatchPtr(const SIRegisterInfo &TRI) {
222   ArgInfo.DispatchPtr = ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
223     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));
224   NumUserSGPRs += 2;
225   return ArgInfo.DispatchPtr.getRegister();
226 }
227 
228 Register SIMachineFunctionInfo::addQueuePtr(const SIRegisterInfo &TRI) {
229   ArgInfo.QueuePtr = ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
230     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));
231   NumUserSGPRs += 2;
232   return ArgInfo.QueuePtr.getRegister();
233 }
234 
235 Register SIMachineFunctionInfo::addKernargSegmentPtr(const SIRegisterInfo &TRI) {
236   ArgInfo.KernargSegmentPtr
237     = ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
238     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));
239   NumUserSGPRs += 2;
240   return ArgInfo.KernargSegmentPtr.getRegister();
241 }
242 
243 Register SIMachineFunctionInfo::addDispatchID(const SIRegisterInfo &TRI) {
244   ArgInfo.DispatchID = ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
245     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));
246   NumUserSGPRs += 2;
247   return ArgInfo.DispatchID.getRegister();
248 }
249 
250 Register SIMachineFunctionInfo::addFlatScratchInit(const SIRegisterInfo &TRI) {
251   ArgInfo.FlatScratchInit = ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
252     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));
253   NumUserSGPRs += 2;
254   return ArgInfo.FlatScratchInit.getRegister();
255 }
256 
257 Register SIMachineFunctionInfo::addImplicitBufferPtr(const SIRegisterInfo &TRI) {
258   ArgInfo.ImplicitBufferPtr = ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
259     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));
260   NumUserSGPRs += 2;
261   return ArgInfo.ImplicitBufferPtr.getRegister();
262 }
263 
264 bool SIMachineFunctionInfo::isCalleeSavedReg(const MCPhysReg *CSRegs,
265                                              MCPhysReg Reg) {
266   for (unsigned I = 0; CSRegs[I]; ++I) {
267     if (CSRegs[I] == Reg)
268       return true;
269   }
270 
271   return false;
272 }
273 
274 /// \p returns true if \p NumLanes slots are available in VGPRs already used for
275 /// SGPR spilling.
276 //
277 // FIXME: This only works after processFunctionBeforeFrameFinalized
278 bool SIMachineFunctionInfo::haveFreeLanesForSGPRSpill(const MachineFunction &MF,
279                                                       unsigned NumNeed) const {
280   const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
281   unsigned WaveSize = ST.getWavefrontSize();
282   return NumVGPRSpillLanes + NumNeed <= WaveSize * SpillVGPRs.size();
283 }
284 
285 /// Reserve a slice of a VGPR to support spilling for FrameIndex \p FI.
286 bool SIMachineFunctionInfo::allocateSGPRSpillToVGPR(MachineFunction &MF,
287                                                     int FI) {
288   std::vector<SIRegisterInfo::SpilledReg> &SpillLanes = SGPRToVGPRSpills[FI];
289 
290   // This has already been allocated.
291   if (!SpillLanes.empty())
292     return true;
293 
294   const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
295   const SIRegisterInfo *TRI = ST.getRegisterInfo();
296   MachineFrameInfo &FrameInfo = MF.getFrameInfo();
297   MachineRegisterInfo &MRI = MF.getRegInfo();
298   unsigned WaveSize = ST.getWavefrontSize();
299 
300   unsigned Size = FrameInfo.getObjectSize(FI);
301   unsigned NumLanes = Size / 4;
302 
303   if (NumLanes > WaveSize)
304     return false;
305 
306   assert(Size >= 4 && "invalid sgpr spill size");
307   assert(TRI->spillSGPRToVGPR() && "not spilling SGPRs to VGPRs");
308 
309   // Make sure to handle the case where a wide SGPR spill may span between two
310   // VGPRs.
311   for (unsigned I = 0; I < NumLanes; ++I, ++NumVGPRSpillLanes) {
312     Register LaneVGPR;
313     unsigned VGPRIndex = (NumVGPRSpillLanes % WaveSize);
314 
315     if (VGPRIndex == 0) {
316       LaneVGPR = TRI->findUnusedRegister(MRI, &AMDGPU::VGPR_32RegClass, MF);
317       if (LaneVGPR == AMDGPU::NoRegister) {
318         // We have no VGPRs left for spilling SGPRs. Reset because we will not
319         // partially spill the SGPR to VGPRs.
320         SGPRToVGPRSpills.erase(FI);
321         NumVGPRSpillLanes -= I;
322 
323         // FIXME: We can run out of free registers with split allocation if
324         // IPRA is enabled and a called function already uses every VGPR.
325 #if 0
326         DiagnosticInfoResourceLimit DiagOutOfRegs(MF.getFunction(),
327                                                   "VGPRs for SGPR spilling",
328                                                   0, DS_Error);
329         MF.getFunction().getContext().diagnose(DiagOutOfRegs);
330 #endif
331         return false;
332       }
333 
334       Optional<int> SpillFI;
335       // We need to preserve inactive lanes, so always save, even caller-save
336       // registers.
337       if (!isEntryFunction()) {
338         SpillFI = FrameInfo.CreateSpillStackObject(4, Align(4));
339       }
340 
341       SpillVGPRs.push_back(SGPRSpillVGPR(LaneVGPR, SpillFI));
342 
343       // Add this register as live-in to all blocks to avoid machine verifier
344       // complaining about use of an undefined physical register.
345       for (MachineBasicBlock &BB : MF)
346         BB.addLiveIn(LaneVGPR);
347     } else {
348       LaneVGPR = SpillVGPRs.back().VGPR;
349     }
350 
351     SpillLanes.push_back(SIRegisterInfo::SpilledReg(LaneVGPR, VGPRIndex));
352   }
353 
354   return true;
355 }
356 
357 /// Reserve AGPRs or VGPRs to support spilling for FrameIndex \p FI.
358 /// Either AGPR is spilled to VGPR to vice versa.
359 /// Returns true if a \p FI can be eliminated completely.
360 bool SIMachineFunctionInfo::allocateVGPRSpillToAGPR(MachineFunction &MF,
361                                                     int FI,
362                                                     bool isAGPRtoVGPR) {
363   MachineRegisterInfo &MRI = MF.getRegInfo();
364   MachineFrameInfo &FrameInfo = MF.getFrameInfo();
365   const GCNSubtarget &ST =  MF.getSubtarget<GCNSubtarget>();
366 
367   assert(ST.hasMAIInsts() && FrameInfo.isSpillSlotObjectIndex(FI));
368 
369   auto &Spill = VGPRToAGPRSpills[FI];
370 
371   // This has already been allocated.
372   if (!Spill.Lanes.empty())
373     return Spill.FullyAllocated;
374 
375   unsigned Size = FrameInfo.getObjectSize(FI);
376   unsigned NumLanes = Size / 4;
377   Spill.Lanes.resize(NumLanes, AMDGPU::NoRegister);
378 
379   const TargetRegisterClass &RC =
380       isAGPRtoVGPR ? AMDGPU::VGPR_32RegClass : AMDGPU::AGPR_32RegClass;
381   auto Regs = RC.getRegisters();
382 
383   auto &SpillRegs = isAGPRtoVGPR ? SpillAGPR : SpillVGPR;
384   const SIRegisterInfo *TRI = ST.getRegisterInfo();
385   Spill.FullyAllocated = true;
386 
387   // FIXME: Move allocation logic out of MachineFunctionInfo and initialize
388   // once.
389   BitVector OtherUsedRegs;
390   OtherUsedRegs.resize(TRI->getNumRegs());
391 
392   const uint32_t *CSRMask =
393       TRI->getCallPreservedMask(MF, MF.getFunction().getCallingConv());
394   if (CSRMask)
395     OtherUsedRegs.setBitsInMask(CSRMask);
396 
397   // TODO: Should include register tuples, but doesn't matter with current
398   // usage.
399   for (MCPhysReg Reg : SpillAGPR)
400     OtherUsedRegs.set(Reg);
401   for (MCPhysReg Reg : SpillVGPR)
402     OtherUsedRegs.set(Reg);
403 
404   SmallVectorImpl<MCPhysReg>::const_iterator NextSpillReg = Regs.begin();
405   for (int I = NumLanes - 1; I >= 0; --I) {
406     NextSpillReg = std::find_if(
407         NextSpillReg, Regs.end(), [&MRI, &OtherUsedRegs](MCPhysReg Reg) {
408           return MRI.isAllocatable(Reg) && !MRI.isPhysRegUsed(Reg) &&
409                  !OtherUsedRegs[Reg];
410         });
411 
412     if (NextSpillReg == Regs.end()) { // Registers exhausted
413       Spill.FullyAllocated = false;
414       break;
415     }
416 
417     OtherUsedRegs.set(*NextSpillReg);
418     SpillRegs.push_back(*NextSpillReg);
419     Spill.Lanes[I] = *NextSpillReg++;
420   }
421 
422   return Spill.FullyAllocated;
423 }
424 
425 bool SIMachineFunctionInfo::removeDeadFrameIndices(
426     MachineFrameInfo &MFI, bool ResetSGPRSpillStackIDs) {
427   // Remove dead frame indices from function frame, however keep FP & BP since
428   // spills for them haven't been inserted yet. And also make sure to remove the
429   // frame indices from `SGPRToVGPRSpills` data structure, otherwise, it could
430   // result in an unexpected side effect and bug, in case of any re-mapping of
431   // freed frame indices by later pass(es) like "stack slot coloring".
432   for (auto &R : make_early_inc_range(SGPRToVGPRSpills)) {
433     if (R.first != FramePointerSaveIndex && R.first != BasePointerSaveIndex) {
434       MFI.RemoveStackObject(R.first);
435       SGPRToVGPRSpills.erase(R.first);
436     }
437   }
438 
439   bool HaveSGPRToMemory = false;
440 
441   if (ResetSGPRSpillStackIDs) {
442     // All other SPGRs must be allocated on the default stack, so reset the
443     // stack ID.
444     for (int i = MFI.getObjectIndexBegin(), e = MFI.getObjectIndexEnd(); i != e;
445          ++i) {
446       if (i != FramePointerSaveIndex && i != BasePointerSaveIndex) {
447         if (MFI.getStackID(i) == TargetStackID::SGPRSpill) {
448           MFI.setStackID(i, TargetStackID::Default);
449           HaveSGPRToMemory = true;
450         }
451       }
452     }
453   }
454 
455   for (auto &R : VGPRToAGPRSpills) {
456     if (R.second.IsDead)
457       MFI.RemoveStackObject(R.first);
458   }
459 
460   return HaveSGPRToMemory;
461 }
462 
463 void SIMachineFunctionInfo::allocateWWMReservedSpillSlots(
464     MachineFrameInfo &MFI, const SIRegisterInfo &TRI) {
465   assert(WWMReservedFrameIndexes.empty());
466 
467   WWMReservedFrameIndexes.resize(WWMReservedRegs.size());
468 
469   int I = 0;
470   for (Register VGPR : WWMReservedRegs) {
471     const TargetRegisterClass *RC = TRI.getPhysRegClass(VGPR);
472     WWMReservedFrameIndexes[I++] = MFI.CreateSpillStackObject(
473         TRI.getSpillSize(*RC), TRI.getSpillAlign(*RC));
474   }
475 }
476 
477 int SIMachineFunctionInfo::getScavengeFI(MachineFrameInfo &MFI,
478                                          const SIRegisterInfo &TRI) {
479   if (ScavengeFI)
480     return *ScavengeFI;
481   if (isEntryFunction()) {
482     ScavengeFI = MFI.CreateFixedObject(
483         TRI.getSpillSize(AMDGPU::SGPR_32RegClass), 0, false);
484   } else {
485     ScavengeFI = MFI.CreateStackObject(
486         TRI.getSpillSize(AMDGPU::SGPR_32RegClass),
487         TRI.getSpillAlign(AMDGPU::SGPR_32RegClass), false);
488   }
489   return *ScavengeFI;
490 }
491 
492 MCPhysReg SIMachineFunctionInfo::getNextUserSGPR() const {
493   assert(NumSystemSGPRs == 0 && "System SGPRs must be added after user SGPRs");
494   return AMDGPU::SGPR0 + NumUserSGPRs;
495 }
496 
497 MCPhysReg SIMachineFunctionInfo::getNextSystemSGPR() const {
498   return AMDGPU::SGPR0 + NumUserSGPRs + NumSystemSGPRs;
499 }
500 
501 Register
502 SIMachineFunctionInfo::getGITPtrLoReg(const MachineFunction &MF) const {
503   const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
504   if (!ST.isAmdPalOS())
505     return Register();
506   Register GitPtrLo = AMDGPU::SGPR0; // Low GIT address passed in
507   if (ST.hasMergedShaders()) {
508     switch (MF.getFunction().getCallingConv()) {
509     case CallingConv::AMDGPU_HS:
510     case CallingConv::AMDGPU_GS:
511       // Low GIT address is passed in s8 rather than s0 for an LS+HS or
512       // ES+GS merged shader on gfx9+.
513       GitPtrLo = AMDGPU::SGPR8;
514       return GitPtrLo;
515     default:
516       return GitPtrLo;
517     }
518   }
519   return GitPtrLo;
520 }
521 
522 static yaml::StringValue regToString(Register Reg,
523                                      const TargetRegisterInfo &TRI) {
524   yaml::StringValue Dest;
525   {
526     raw_string_ostream OS(Dest.Value);
527     OS << printReg(Reg, &TRI);
528   }
529   return Dest;
530 }
531 
532 static Optional<yaml::SIArgumentInfo>
533 convertArgumentInfo(const AMDGPUFunctionArgInfo &ArgInfo,
534                     const TargetRegisterInfo &TRI) {
535   yaml::SIArgumentInfo AI;
536 
537   auto convertArg = [&](Optional<yaml::SIArgument> &A,
538                         const ArgDescriptor &Arg) {
539     if (!Arg)
540       return false;
541 
542     // Create a register or stack argument.
543     yaml::SIArgument SA = yaml::SIArgument::createArgument(Arg.isRegister());
544     if (Arg.isRegister()) {
545       raw_string_ostream OS(SA.RegisterName.Value);
546       OS << printReg(Arg.getRegister(), &TRI);
547     } else
548       SA.StackOffset = Arg.getStackOffset();
549     // Check and update the optional mask.
550     if (Arg.isMasked())
551       SA.Mask = Arg.getMask();
552 
553     A = SA;
554     return true;
555   };
556 
557   bool Any = false;
558   Any |= convertArg(AI.PrivateSegmentBuffer, ArgInfo.PrivateSegmentBuffer);
559   Any |= convertArg(AI.DispatchPtr, ArgInfo.DispatchPtr);
560   Any |= convertArg(AI.QueuePtr, ArgInfo.QueuePtr);
561   Any |= convertArg(AI.KernargSegmentPtr, ArgInfo.KernargSegmentPtr);
562   Any |= convertArg(AI.DispatchID, ArgInfo.DispatchID);
563   Any |= convertArg(AI.FlatScratchInit, ArgInfo.FlatScratchInit);
564   Any |= convertArg(AI.PrivateSegmentSize, ArgInfo.PrivateSegmentSize);
565   Any |= convertArg(AI.WorkGroupIDX, ArgInfo.WorkGroupIDX);
566   Any |= convertArg(AI.WorkGroupIDY, ArgInfo.WorkGroupIDY);
567   Any |= convertArg(AI.WorkGroupIDZ, ArgInfo.WorkGroupIDZ);
568   Any |= convertArg(AI.WorkGroupInfo, ArgInfo.WorkGroupInfo);
569   Any |= convertArg(AI.PrivateSegmentWaveByteOffset,
570                     ArgInfo.PrivateSegmentWaveByteOffset);
571   Any |= convertArg(AI.ImplicitArgPtr, ArgInfo.ImplicitArgPtr);
572   Any |= convertArg(AI.ImplicitBufferPtr, ArgInfo.ImplicitBufferPtr);
573   Any |= convertArg(AI.WorkItemIDX, ArgInfo.WorkItemIDX);
574   Any |= convertArg(AI.WorkItemIDY, ArgInfo.WorkItemIDY);
575   Any |= convertArg(AI.WorkItemIDZ, ArgInfo.WorkItemIDZ);
576 
577   if (Any)
578     return AI;
579 
580   return None;
581 }
582 
583 yaml::SIMachineFunctionInfo::SIMachineFunctionInfo(
584     const llvm::SIMachineFunctionInfo &MFI, const TargetRegisterInfo &TRI,
585     const llvm::MachineFunction &MF)
586     : ExplicitKernArgSize(MFI.getExplicitKernArgSize()),
587       MaxKernArgAlign(MFI.getMaxKernArgAlign()), LDSSize(MFI.getLDSSize()),
588       GDSSize(MFI.getGDSSize()),
589       DynLDSAlign(MFI.getDynLDSAlign()), IsEntryFunction(MFI.isEntryFunction()),
590       NoSignedZerosFPMath(MFI.hasNoSignedZerosFPMath()),
591       MemoryBound(MFI.isMemoryBound()), WaveLimiter(MFI.needsWaveLimiter()),
592       HasSpilledSGPRs(MFI.hasSpilledSGPRs()),
593       HasSpilledVGPRs(MFI.hasSpilledVGPRs()),
594       HighBitsOf32BitAddress(MFI.get32BitAddressHighBits()),
595       Occupancy(MFI.getOccupancy()),
596       ScratchRSrcReg(regToString(MFI.getScratchRSrcReg(), TRI)),
597       FrameOffsetReg(regToString(MFI.getFrameOffsetReg(), TRI)),
598       StackPtrOffsetReg(regToString(MFI.getStackPtrOffsetReg(), TRI)),
599       BytesInStackArgArea(MFI.getBytesInStackArgArea()),
600       ReturnsVoid(MFI.returnsVoid()),
601       ArgInfo(convertArgumentInfo(MFI.getArgInfo(), TRI)), Mode(MFI.getMode()) {
602   for (Register Reg : MFI.WWMReservedRegs)
603     WWMReservedRegs.push_back(regToString(Reg, TRI));
604 
605   if (MFI.getVGPRForAGPRCopy())
606     VGPRForAGPRCopy = regToString(MFI.getVGPRForAGPRCopy(), TRI);
607   auto SFI = MFI.getOptionalScavengeFI();
608   if (SFI)
609     ScavengeFI = yaml::FrameIndex(*SFI, MF.getFrameInfo());
610 }
611 
612 void yaml::SIMachineFunctionInfo::mappingImpl(yaml::IO &YamlIO) {
613   MappingTraits<SIMachineFunctionInfo>::mapping(YamlIO, *this);
614 }
615 
616 bool SIMachineFunctionInfo::initializeBaseYamlFields(
617     const yaml::SIMachineFunctionInfo &YamlMFI, const MachineFunction &MF,
618     PerFunctionMIParsingState &PFS, SMDiagnostic &Error, SMRange &SourceRange) {
619   ExplicitKernArgSize = YamlMFI.ExplicitKernArgSize;
620   MaxKernArgAlign = YamlMFI.MaxKernArgAlign;
621   LDSSize = YamlMFI.LDSSize;
622   GDSSize = YamlMFI.GDSSize;
623   DynLDSAlign = YamlMFI.DynLDSAlign;
624   HighBitsOf32BitAddress = YamlMFI.HighBitsOf32BitAddress;
625   Occupancy = YamlMFI.Occupancy;
626   IsEntryFunction = YamlMFI.IsEntryFunction;
627   NoSignedZerosFPMath = YamlMFI.NoSignedZerosFPMath;
628   MemoryBound = YamlMFI.MemoryBound;
629   WaveLimiter = YamlMFI.WaveLimiter;
630   HasSpilledSGPRs = YamlMFI.HasSpilledSGPRs;
631   HasSpilledVGPRs = YamlMFI.HasSpilledVGPRs;
632   BytesInStackArgArea = YamlMFI.BytesInStackArgArea;
633   ReturnsVoid = YamlMFI.ReturnsVoid;
634 
635   if (YamlMFI.ScavengeFI) {
636     auto FIOrErr = YamlMFI.ScavengeFI->getFI(MF.getFrameInfo());
637     if (!FIOrErr) {
638       // Create a diagnostic for a the frame index.
639       const MemoryBuffer &Buffer =
640           *PFS.SM->getMemoryBuffer(PFS.SM->getMainFileID());
641 
642       Error = SMDiagnostic(*PFS.SM, SMLoc(), Buffer.getBufferIdentifier(), 1, 1,
643                            SourceMgr::DK_Error, toString(FIOrErr.takeError()),
644                            "", None, None);
645       SourceRange = YamlMFI.ScavengeFI->SourceRange;
646       return true;
647     }
648     ScavengeFI = *FIOrErr;
649   } else {
650     ScavengeFI = None;
651   }
652   return false;
653 }
654 
655 bool SIMachineFunctionInfo::mayUseAGPRs(const MachineFunction &MF) const {
656   for (const BasicBlock &BB : MF.getFunction()) {
657     for (const Instruction &I : BB) {
658       const auto *CB = dyn_cast<CallBase>(&I);
659       if (!CB)
660         continue;
661 
662       if (CB->isInlineAsm()) {
663         const InlineAsm *IA = dyn_cast<InlineAsm>(CB->getCalledOperand());
664         for (const auto &CI : IA->ParseConstraints()) {
665           for (StringRef Code : CI.Codes) {
666             Code.consume_front("{");
667             if (Code.startswith("a"))
668               return true;
669           }
670         }
671         continue;
672       }
673 
674       const Function *Callee =
675           dyn_cast<Function>(CB->getCalledOperand()->stripPointerCasts());
676       if (!Callee)
677         return true;
678 
679       if (Callee->getIntrinsicID() == Intrinsic::not_intrinsic)
680         return true;
681     }
682   }
683 
684   return false;
685 }
686 
687 bool SIMachineFunctionInfo::usesAGPRs(const MachineFunction &MF) const {
688   if (UsesAGPRs)
689     return *UsesAGPRs;
690 
691   if (!mayNeedAGPRs()) {
692     UsesAGPRs = false;
693     return false;
694   }
695 
696   if (!AMDGPU::isEntryFunctionCC(MF.getFunction().getCallingConv()) ||
697       MF.getFrameInfo().hasCalls()) {
698     UsesAGPRs = true;
699     return true;
700   }
701 
702   const MachineRegisterInfo &MRI = MF.getRegInfo();
703 
704   for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
705     const Register Reg = Register::index2VirtReg(I);
706     const TargetRegisterClass *RC = MRI.getRegClassOrNull(Reg);
707     if (RC && SIRegisterInfo::isAGPRClass(RC)) {
708       UsesAGPRs = true;
709       return true;
710     } else if (!RC && !MRI.use_empty(Reg) && MRI.getType(Reg).isValid()) {
711       // Defer caching UsesAGPRs, function might not yet been regbank selected.
712       return true;
713     }
714   }
715 
716   for (MCRegister Reg : AMDGPU::AGPR_32RegClass) {
717     if (MRI.isPhysRegUsed(Reg)) {
718       UsesAGPRs = true;
719       return true;
720     }
721   }
722 
723   UsesAGPRs = false;
724   return false;
725 }
726