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