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