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