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 "AMDGPUArgumentUsageInfo.h"
11 #include "AMDGPUTargetMachine.h"
12 #include "AMDGPUSubtarget.h"
13 #include "SIRegisterInfo.h"
14 #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
15 #include "Utils/AMDGPUBaseInfo.h"
16 #include "llvm/ADT/Optional.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/IR/CallingConv.h"
22 #include "llvm/IR/Function.h"
23 #include <cassert>
24 #include <vector>
25 
26 #define MAX_LANES 64
27 
28 using namespace llvm;
29 
30 SIMachineFunctionInfo::SIMachineFunctionInfo(const MachineFunction &MF)
31   : AMDGPUMachineFunction(MF),
32     PrivateSegmentBuffer(false),
33     DispatchPtr(false),
34     QueuePtr(false),
35     KernargSegmentPtr(false),
36     DispatchID(false),
37     FlatScratchInit(false),
38     WorkGroupIDX(false),
39     WorkGroupIDY(false),
40     WorkGroupIDZ(false),
41     WorkGroupInfo(false),
42     PrivateSegmentWaveByteOffset(false),
43     WorkItemIDX(false),
44     WorkItemIDY(false),
45     WorkItemIDZ(false),
46     ImplicitBufferPtr(false),
47     ImplicitArgPtr(false),
48     GITPtrHigh(0xffffffff),
49     HighBitsOf32BitAddress(0),
50     GDSSize(0) {
51   const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
52   const Function &F = MF.getFunction();
53   FlatWorkGroupSizes = ST.getFlatWorkGroupSizes(F);
54   WavesPerEU = ST.getWavesPerEU(F);
55 
56   Occupancy = ST.computeOccupancy(F, getLDSSize());
57   CallingConv::ID CC = F.getCallingConv();
58 
59   // FIXME: Should have analysis or something rather than attribute to detect
60   // calls.
61   const bool HasCalls = F.hasFnAttribute("amdgpu-calls");
62 
63   // Enable all kernel inputs if we have the fixed ABI. Don't bother if we don't
64   // have any calls.
65   const bool UseFixedABI = AMDGPUTargetMachine::EnableFixedFunctionABI &&
66                            (!isEntryFunction() || HasCalls);
67 
68   if (CC == CallingConv::AMDGPU_KERNEL || CC == CallingConv::SPIR_KERNEL) {
69     if (!F.arg_empty())
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     // Non-entry functions have no special inputs for now, other registers
79     // required for scratch access.
80     ScratchRSrcReg = AMDGPU::SGPR0_SGPR1_SGPR2_SGPR3;
81 
82     // TODO: Pick a high register, and shift down, similar to a kernel.
83     FrameOffsetReg = AMDGPU::SGPR33;
84     StackPtrOffsetReg = AMDGPU::SGPR32;
85 
86     ArgInfo.PrivateSegmentBuffer =
87       ArgDescriptor::createRegister(ScratchRSrcReg);
88 
89     if (F.hasFnAttribute("amdgpu-implicitarg-ptr"))
90       ImplicitArgPtr = true;
91   } else {
92     if (F.hasFnAttribute("amdgpu-implicitarg-ptr")) {
93       KernargSegmentPtr = true;
94       MaxKernArgAlign = std::max(ST.getAlignmentForImplicitArgPtr(),
95                                  MaxKernArgAlign);
96     }
97   }
98 
99   if (UseFixedABI) {
100     WorkGroupIDX = true;
101     WorkGroupIDY = true;
102     WorkGroupIDZ = true;
103     WorkItemIDX = true;
104     WorkItemIDY = true;
105     WorkItemIDZ = true;
106     ImplicitArgPtr = true;
107   } else {
108     if (F.hasFnAttribute("amdgpu-work-group-id-x"))
109       WorkGroupIDX = true;
110 
111     if (F.hasFnAttribute("amdgpu-work-group-id-y"))
112       WorkGroupIDY = true;
113 
114     if (F.hasFnAttribute("amdgpu-work-group-id-z"))
115       WorkGroupIDZ = true;
116 
117     if (F.hasFnAttribute("amdgpu-work-item-id-x"))
118       WorkItemIDX = true;
119 
120     if (F.hasFnAttribute("amdgpu-work-item-id-y"))
121       WorkItemIDY = true;
122 
123     if (F.hasFnAttribute("amdgpu-work-item-id-z"))
124       WorkItemIDZ = true;
125   }
126 
127   bool HasStackObjects = F.hasFnAttribute("amdgpu-stack-objects");
128   if (isEntryFunction()) {
129     // X, XY, and XYZ are the only supported combinations, so make sure Y is
130     // enabled if Z is.
131     if (WorkItemIDZ)
132       WorkItemIDY = true;
133 
134     PrivateSegmentWaveByteOffset = true;
135 
136     // HS and GS always have the scratch wave offset in SGPR5 on GFX9.
137     if (ST.getGeneration() >= AMDGPUSubtarget::GFX9 &&
138         (CC == CallingConv::AMDGPU_HS || CC == CallingConv::AMDGPU_GS))
139       ArgInfo.PrivateSegmentWaveByteOffset =
140           ArgDescriptor::createRegister(AMDGPU::SGPR5);
141   }
142 
143   bool isAmdHsaOrMesa = ST.isAmdHsaOrMesa(F);
144   if (isAmdHsaOrMesa) {
145     PrivateSegmentBuffer = true;
146 
147     if (UseFixedABI) {
148       DispatchPtr = true;
149       QueuePtr = true;
150 
151       // FIXME: We don't need this?
152       DispatchID = true;
153     } else {
154       if (F.hasFnAttribute("amdgpu-dispatch-ptr"))
155         DispatchPtr = true;
156 
157       if (F.hasFnAttribute("amdgpu-queue-ptr"))
158         QueuePtr = true;
159 
160       if (F.hasFnAttribute("amdgpu-dispatch-id"))
161         DispatchID = true;
162     }
163   } else if (ST.isMesaGfxShader(F)) {
164     ImplicitBufferPtr = true;
165   }
166 
167   if (UseFixedABI || F.hasFnAttribute("amdgpu-kernarg-segment-ptr"))
168     KernargSegmentPtr = true;
169 
170   if (ST.hasFlatAddressSpace() && isEntryFunction() &&
171       (isAmdHsaOrMesa || ST.enableFlatScratch())) {
172     // TODO: This could be refined a lot. The attribute is a poor way of
173     // detecting calls or stack objects that may require it before argument
174     // lowering.
175     if (HasCalls || HasStackObjects || ST.enableFlatScratch())
176       FlatScratchInit = true;
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   S = F.getFnAttribute("amdgpu-gds-size").getValueAsString();
190   if (!S.empty())
191     S.consumeInteger(0, GDSSize);
192 }
193 
194 void SIMachineFunctionInfo::limitOccupancy(const MachineFunction &MF) {
195   limitOccupancy(getMaxWavesPerEU());
196   const GCNSubtarget& ST = MF.getSubtarget<GCNSubtarget>();
197   limitOccupancy(ST.getOccupancyWithLocalMemSize(getLDSSize(),
198                  MF.getFunction()));
199 }
200 
201 Register SIMachineFunctionInfo::addPrivateSegmentBuffer(
202   const SIRegisterInfo &TRI) {
203   ArgInfo.PrivateSegmentBuffer =
204     ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
205     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SGPR_128RegClass));
206   NumUserSGPRs += 4;
207   return ArgInfo.PrivateSegmentBuffer.getRegister();
208 }
209 
210 Register SIMachineFunctionInfo::addDispatchPtr(const SIRegisterInfo &TRI) {
211   ArgInfo.DispatchPtr = ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
212     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));
213   NumUserSGPRs += 2;
214   return ArgInfo.DispatchPtr.getRegister();
215 }
216 
217 Register SIMachineFunctionInfo::addQueuePtr(const SIRegisterInfo &TRI) {
218   ArgInfo.QueuePtr = ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
219     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));
220   NumUserSGPRs += 2;
221   return ArgInfo.QueuePtr.getRegister();
222 }
223 
224 Register SIMachineFunctionInfo::addKernargSegmentPtr(const SIRegisterInfo &TRI) {
225   ArgInfo.KernargSegmentPtr
226     = ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
227     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));
228   NumUserSGPRs += 2;
229   return ArgInfo.KernargSegmentPtr.getRegister();
230 }
231 
232 Register SIMachineFunctionInfo::addDispatchID(const SIRegisterInfo &TRI) {
233   ArgInfo.DispatchID = ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
234     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));
235   NumUserSGPRs += 2;
236   return ArgInfo.DispatchID.getRegister();
237 }
238 
239 Register SIMachineFunctionInfo::addFlatScratchInit(const SIRegisterInfo &TRI) {
240   ArgInfo.FlatScratchInit = ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
241     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));
242   NumUserSGPRs += 2;
243   return ArgInfo.FlatScratchInit.getRegister();
244 }
245 
246 Register SIMachineFunctionInfo::addImplicitBufferPtr(const SIRegisterInfo &TRI) {
247   ArgInfo.ImplicitBufferPtr = ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
248     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));
249   NumUserSGPRs += 2;
250   return ArgInfo.ImplicitBufferPtr.getRegister();
251 }
252 
253 bool SIMachineFunctionInfo::isCalleeSavedReg(const MCPhysReg *CSRegs,
254                                              MCPhysReg Reg) {
255   for (unsigned I = 0; CSRegs[I]; ++I) {
256     if (CSRegs[I] == Reg)
257       return true;
258   }
259 
260   return false;
261 }
262 
263 /// \p returns true if \p NumLanes slots are available in VGPRs already used for
264 /// SGPR spilling.
265 //
266 // FIXME: This only works after processFunctionBeforeFrameFinalized
267 bool SIMachineFunctionInfo::haveFreeLanesForSGPRSpill(const MachineFunction &MF,
268                                                       unsigned NumNeed) const {
269   const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
270   unsigned WaveSize = ST.getWavefrontSize();
271   return NumVGPRSpillLanes + NumNeed <= WaveSize * SpillVGPRs.size();
272 }
273 
274 /// Reserve a slice of a VGPR to support spilling for FrameIndex \p FI.
275 bool SIMachineFunctionInfo::allocateSGPRSpillToVGPR(MachineFunction &MF,
276                                                     int FI) {
277   std::vector<SpilledReg> &SpillLanes = SGPRToVGPRSpills[FI];
278 
279   // This has already been allocated.
280   if (!SpillLanes.empty())
281     return true;
282 
283   const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
284   const SIRegisterInfo *TRI = ST.getRegisterInfo();
285   MachineFrameInfo &FrameInfo = MF.getFrameInfo();
286   MachineRegisterInfo &MRI = MF.getRegInfo();
287   unsigned WaveSize = ST.getWavefrontSize();
288   SIMachineFunctionInfo *FuncInfo = MF.getInfo<SIMachineFunctionInfo>();
289 
290   unsigned Size = FrameInfo.getObjectSize(FI);
291   unsigned NumLanes = Size / 4;
292 
293   if (NumLanes > WaveSize)
294     return false;
295 
296   assert(Size >= 4 && "invalid sgpr spill size");
297   assert(TRI->spillSGPRToVGPR() && "not spilling SGPRs to VGPRs");
298 
299   const MCPhysReg *CSRegs = MRI.getCalleeSavedRegs();
300 
301   // Make sure to handle the case where a wide SGPR spill may span between two
302   // VGPRs.
303   for (unsigned I = 0; I < NumLanes; ++I, ++NumVGPRSpillLanes) {
304     Register LaneVGPR;
305     unsigned VGPRIndex = (NumVGPRSpillLanes % WaveSize);
306 
307     // Reserve a VGPR (when NumVGPRSpillLanes = 0, WaveSize, 2*WaveSize, ..) and
308     // when one of the two conditions is true:
309     // 1. One reserved VGPR being tracked by VGPRReservedForSGPRSpill is not yet
310     // reserved.
311     // 2. All spill lanes of reserved VGPR(s) are full and another spill lane is
312     // required.
313     if (FuncInfo->VGPRReservedForSGPRSpill && NumVGPRSpillLanes < WaveSize) {
314       assert(FuncInfo->VGPRReservedForSGPRSpill == SpillVGPRs.back().VGPR);
315       LaneVGPR = FuncInfo->VGPRReservedForSGPRSpill;
316     } else if (VGPRIndex == 0) {
317       LaneVGPR = TRI->findUnusedRegister(MRI, &AMDGPU::VGPR_32RegClass, MF);
318       if (LaneVGPR == AMDGPU::NoRegister) {
319         // We have no VGPRs left for spilling SGPRs. Reset because we will not
320         // partially spill the SGPR to VGPRs.
321         SGPRToVGPRSpills.erase(FI);
322         NumVGPRSpillLanes -= I;
323         return false;
324       }
325 
326       Optional<int> CSRSpillFI;
327       if ((FrameInfo.hasCalls() || !isEntryFunction()) && CSRegs &&
328           isCalleeSavedReg(CSRegs, LaneVGPR)) {
329         CSRSpillFI = FrameInfo.CreateSpillStackObject(4, Align(4));
330       }
331 
332       SpillVGPRs.push_back(SGPRSpillVGPRCSR(LaneVGPR, CSRSpillFI));
333 
334       // Add this register as live-in to all blocks to avoid machine verifer
335       // complaining about use of an undefined physical register.
336       for (MachineBasicBlock &BB : MF)
337         BB.addLiveIn(LaneVGPR);
338     } else {
339       LaneVGPR = SpillVGPRs.back().VGPR;
340     }
341 
342     SpillLanes.push_back(SpilledReg(LaneVGPR, VGPRIndex));
343   }
344 
345   return true;
346 }
347 
348 /// Reserve a VGPR for spilling of SGPRs
349 bool SIMachineFunctionInfo::reserveVGPRforSGPRSpills(MachineFunction &MF) {
350   const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
351   const SIRegisterInfo *TRI = ST.getRegisterInfo();
352   SIMachineFunctionInfo *FuncInfo = MF.getInfo<SIMachineFunctionInfo>();
353 
354   Register LaneVGPR = TRI->findUnusedRegister(
355       MF.getRegInfo(), &AMDGPU::VGPR_32RegClass, MF, true);
356   if (LaneVGPR == Register())
357     return false;
358   SpillVGPRs.push_back(SGPRSpillVGPRCSR(LaneVGPR, None));
359   FuncInfo->VGPRReservedForSGPRSpill = LaneVGPR;
360   return true;
361 }
362 
363 /// Reserve AGPRs or VGPRs to support spilling for FrameIndex \p FI.
364 /// Either AGPR is spilled to VGPR to vice versa.
365 /// Returns true if a \p FI can be eliminated completely.
366 bool SIMachineFunctionInfo::allocateVGPRSpillToAGPR(MachineFunction &MF,
367                                                     int FI,
368                                                     bool isAGPRtoVGPR) {
369   MachineRegisterInfo &MRI = MF.getRegInfo();
370   MachineFrameInfo &FrameInfo = MF.getFrameInfo();
371   const GCNSubtarget &ST =  MF.getSubtarget<GCNSubtarget>();
372 
373   assert(ST.hasMAIInsts() && FrameInfo.isSpillSlotObjectIndex(FI));
374 
375   auto &Spill = VGPRToAGPRSpills[FI];
376 
377   // This has already been allocated.
378   if (!Spill.Lanes.empty())
379     return Spill.FullyAllocated;
380 
381   unsigned Size = FrameInfo.getObjectSize(FI);
382   unsigned NumLanes = Size / 4;
383   Spill.Lanes.resize(NumLanes, AMDGPU::NoRegister);
384 
385   const TargetRegisterClass &RC =
386       isAGPRtoVGPR ? AMDGPU::VGPR_32RegClass : AMDGPU::AGPR_32RegClass;
387   auto Regs = RC.getRegisters();
388 
389   auto &SpillRegs = isAGPRtoVGPR ? SpillAGPR : SpillVGPR;
390   const SIRegisterInfo *TRI = ST.getRegisterInfo();
391   Spill.FullyAllocated = true;
392 
393   // FIXME: Move allocation logic out of MachineFunctionInfo and initialize
394   // once.
395   BitVector OtherUsedRegs;
396   OtherUsedRegs.resize(TRI->getNumRegs());
397 
398   const uint32_t *CSRMask =
399       TRI->getCallPreservedMask(MF, MF.getFunction().getCallingConv());
400   if (CSRMask)
401     OtherUsedRegs.setBitsInMask(CSRMask);
402 
403   // TODO: Should include register tuples, but doesn't matter with current
404   // usage.
405   for (MCPhysReg Reg : SpillAGPR)
406     OtherUsedRegs.set(Reg);
407   for (MCPhysReg Reg : SpillVGPR)
408     OtherUsedRegs.set(Reg);
409 
410   SmallVectorImpl<MCPhysReg>::const_iterator NextSpillReg = Regs.begin();
411   for (unsigned I = 0; I < NumLanes; ++I) {
412     NextSpillReg = std::find_if(
413         NextSpillReg, Regs.end(), [&MRI, &OtherUsedRegs](MCPhysReg Reg) {
414           return MRI.isAllocatable(Reg) && !MRI.isPhysRegUsed(Reg) &&
415                  !OtherUsedRegs[Reg];
416         });
417 
418     if (NextSpillReg == Regs.end()) { // Registers exhausted
419       Spill.FullyAllocated = false;
420       break;
421     }
422 
423     OtherUsedRegs.set(*NextSpillReg);
424     SpillRegs.push_back(*NextSpillReg);
425     Spill.Lanes[I] = *NextSpillReg++;
426   }
427 
428   return Spill.FullyAllocated;
429 }
430 
431 void SIMachineFunctionInfo::removeDeadFrameIndices(MachineFrameInfo &MFI) {
432   // The FP & BP spills haven't been inserted yet, so keep them around.
433   for (auto &R : SGPRToVGPRSpills) {
434     if (R.first != FramePointerSaveIndex && R.first != BasePointerSaveIndex)
435       MFI.RemoveStackObject(R.first);
436   }
437 
438   // All other SPGRs must be allocated on the default stack, so reset the stack
439   // ID.
440   for (int i = MFI.getObjectIndexBegin(), e = MFI.getObjectIndexEnd(); i != e;
441        ++i)
442     if (i != FramePointerSaveIndex && i != BasePointerSaveIndex)
443       MFI.setStackID(i, TargetStackID::Default);
444 
445   for (auto &R : VGPRToAGPRSpills) {
446     if (R.second.FullyAllocated)
447       MFI.RemoveStackObject(R.first);
448   }
449 }
450 
451 MCPhysReg SIMachineFunctionInfo::getNextUserSGPR() const {
452   assert(NumSystemSGPRs == 0 && "System SGPRs must be added after user SGPRs");
453   return AMDGPU::SGPR0 + NumUserSGPRs;
454 }
455 
456 MCPhysReg SIMachineFunctionInfo::getNextSystemSGPR() const {
457   return AMDGPU::SGPR0 + NumUserSGPRs + NumSystemSGPRs;
458 }
459 
460 Register
461 SIMachineFunctionInfo::getGITPtrLoReg(const MachineFunction &MF) const {
462   const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
463   if (!ST.isAmdPalOS())
464     return Register();
465   Register GitPtrLo = AMDGPU::SGPR0; // Low GIT address passed in
466   if (ST.hasMergedShaders()) {
467     switch (MF.getFunction().getCallingConv()) {
468     case CallingConv::AMDGPU_HS:
469     case CallingConv::AMDGPU_GS:
470       // Low GIT address is passed in s8 rather than s0 for an LS+HS or
471       // ES+GS merged shader on gfx9+.
472       GitPtrLo = AMDGPU::SGPR8;
473       return GitPtrLo;
474     default:
475       return GitPtrLo;
476     }
477   }
478   return GitPtrLo;
479 }
480 
481 static yaml::StringValue regToString(Register Reg,
482                                      const TargetRegisterInfo &TRI) {
483   yaml::StringValue Dest;
484   {
485     raw_string_ostream OS(Dest.Value);
486     OS << printReg(Reg, &TRI);
487   }
488   return Dest;
489 }
490 
491 static Optional<yaml::SIArgumentInfo>
492 convertArgumentInfo(const AMDGPUFunctionArgInfo &ArgInfo,
493                     const TargetRegisterInfo &TRI) {
494   yaml::SIArgumentInfo AI;
495 
496   auto convertArg = [&](Optional<yaml::SIArgument> &A,
497                         const ArgDescriptor &Arg) {
498     if (!Arg)
499       return false;
500 
501     // Create a register or stack argument.
502     yaml::SIArgument SA = yaml::SIArgument::createArgument(Arg.isRegister());
503     if (Arg.isRegister()) {
504       raw_string_ostream OS(SA.RegisterName.Value);
505       OS << printReg(Arg.getRegister(), &TRI);
506     } else
507       SA.StackOffset = Arg.getStackOffset();
508     // Check and update the optional mask.
509     if (Arg.isMasked())
510       SA.Mask = Arg.getMask();
511 
512     A = SA;
513     return true;
514   };
515 
516   bool Any = false;
517   Any |= convertArg(AI.PrivateSegmentBuffer, ArgInfo.PrivateSegmentBuffer);
518   Any |= convertArg(AI.DispatchPtr, ArgInfo.DispatchPtr);
519   Any |= convertArg(AI.QueuePtr, ArgInfo.QueuePtr);
520   Any |= convertArg(AI.KernargSegmentPtr, ArgInfo.KernargSegmentPtr);
521   Any |= convertArg(AI.DispatchID, ArgInfo.DispatchID);
522   Any |= convertArg(AI.FlatScratchInit, ArgInfo.FlatScratchInit);
523   Any |= convertArg(AI.PrivateSegmentSize, ArgInfo.PrivateSegmentSize);
524   Any |= convertArg(AI.WorkGroupIDX, ArgInfo.WorkGroupIDX);
525   Any |= convertArg(AI.WorkGroupIDY, ArgInfo.WorkGroupIDY);
526   Any |= convertArg(AI.WorkGroupIDZ, ArgInfo.WorkGroupIDZ);
527   Any |= convertArg(AI.WorkGroupInfo, ArgInfo.WorkGroupInfo);
528   Any |= convertArg(AI.PrivateSegmentWaveByteOffset,
529                     ArgInfo.PrivateSegmentWaveByteOffset);
530   Any |= convertArg(AI.ImplicitArgPtr, ArgInfo.ImplicitArgPtr);
531   Any |= convertArg(AI.ImplicitBufferPtr, ArgInfo.ImplicitBufferPtr);
532   Any |= convertArg(AI.WorkItemIDX, ArgInfo.WorkItemIDX);
533   Any |= convertArg(AI.WorkItemIDY, ArgInfo.WorkItemIDY);
534   Any |= convertArg(AI.WorkItemIDZ, ArgInfo.WorkItemIDZ);
535 
536   if (Any)
537     return AI;
538 
539   return None;
540 }
541 
542 yaml::SIMachineFunctionInfo::SIMachineFunctionInfo(
543     const llvm::SIMachineFunctionInfo &MFI, const TargetRegisterInfo &TRI)
544     : ExplicitKernArgSize(MFI.getExplicitKernArgSize()),
545       MaxKernArgAlign(MFI.getMaxKernArgAlign()), LDSSize(MFI.getLDSSize()),
546       DynLDSAlign(MFI.getDynLDSAlign()), IsEntryFunction(MFI.isEntryFunction()),
547       NoSignedZerosFPMath(MFI.hasNoSignedZerosFPMath()),
548       MemoryBound(MFI.isMemoryBound()), WaveLimiter(MFI.needsWaveLimiter()),
549       HasSpilledSGPRs(MFI.hasSpilledSGPRs()),
550       HasSpilledVGPRs(MFI.hasSpilledVGPRs()),
551       HighBitsOf32BitAddress(MFI.get32BitAddressHighBits()),
552       ScratchRSrcReg(regToString(MFI.getScratchRSrcReg(), TRI)),
553       FrameOffsetReg(regToString(MFI.getFrameOffsetReg(), TRI)),
554       StackPtrOffsetReg(regToString(MFI.getStackPtrOffsetReg(), TRI)),
555       ArgInfo(convertArgumentInfo(MFI.getArgInfo(), TRI)), Mode(MFI.getMode()) {
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) {
564   ExplicitKernArgSize = YamlMFI.ExplicitKernArgSize;
565   MaxKernArgAlign = assumeAligned(YamlMFI.MaxKernArgAlign);
566   LDSSize = YamlMFI.LDSSize;
567   DynLDSAlign = YamlMFI.DynLDSAlign;
568   HighBitsOf32BitAddress = YamlMFI.HighBitsOf32BitAddress;
569   IsEntryFunction = YamlMFI.IsEntryFunction;
570   NoSignedZerosFPMath = YamlMFI.NoSignedZerosFPMath;
571   MemoryBound = YamlMFI.MemoryBound;
572   WaveLimiter = YamlMFI.WaveLimiter;
573   HasSpilledSGPRs = YamlMFI.HasSpilledSGPRs;
574   HasSpilledVGPRs = YamlMFI.HasSpilledVGPRs;
575   return false;
576 }
577 
578 // Remove VGPR which was reserved for SGPR spills if there are no spilled SGPRs
579 bool SIMachineFunctionInfo::removeVGPRForSGPRSpill(Register ReservedVGPR,
580                                                    MachineFunction &MF) {
581   for (auto *i = SpillVGPRs.begin(); i < SpillVGPRs.end(); i++) {
582     if (i->VGPR == ReservedVGPR) {
583       SpillVGPRs.erase(i);
584 
585       for (MachineBasicBlock &MBB : MF) {
586         MBB.removeLiveIn(ReservedVGPR);
587         MBB.sortUniqueLiveIns();
588       }
589       this->VGPRReservedForSGPRSpill = AMDGPU::NoRegister;
590       return true;
591     }
592   }
593   return false;
594 }
595