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