]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp
Merge llvm-project main llvmorg-17-init-19304-gd0b54bb50e51
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / lib / Target / AMDGPU / SIMachineFunctionInfo.cpp
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/CodeGen/LiveIntervals.h"
16 #include "llvm/CodeGen/MachineBasicBlock.h"
17 #include "llvm/CodeGen/MachineFrameInfo.h"
18 #include "llvm/CodeGen/MachineFunction.h"
19 #include "llvm/CodeGen/MachineRegisterInfo.h"
20 #include "llvm/CodeGen/MIRParser/MIParser.h"
21 #include "llvm/IR/CallingConv.h"
22 #include "llvm/IR/DiagnosticInfo.h"
23 #include "llvm/IR/Function.h"
24 #include <cassert>
25 #include <optional>
26 #include <vector>
27
28 #define MAX_LANES 64
29
30 using namespace llvm;
31
32 const GCNTargetMachine &getTM(const GCNSubtarget *STI) {
33   const SITargetLowering *TLI = STI->getTargetLowering();
34   return static_cast<const GCNTargetMachine &>(TLI->getTargetMachine());
35 }
36
37 SIMachineFunctionInfo::SIMachineFunctionInfo(const Function &F,
38                                              const GCNSubtarget *STI)
39   : AMDGPUMachineFunction(F, *STI),
40     Mode(F),
41     GWSResourcePSV(getTM(STI)),
42     PrivateSegmentBuffer(false),
43     DispatchPtr(false),
44     QueuePtr(false),
45     KernargSegmentPtr(false),
46     DispatchID(false),
47     FlatScratchInit(false),
48     WorkGroupIDX(false),
49     WorkGroupIDY(false),
50     WorkGroupIDZ(false),
51     WorkGroupInfo(false),
52     LDSKernelId(false),
53     PrivateSegmentWaveByteOffset(false),
54     WorkItemIDX(false),
55     WorkItemIDY(false),
56     WorkItemIDZ(false),
57     ImplicitBufferPtr(false),
58     ImplicitArgPtr(false),
59     GITPtrHigh(0xffffffff),
60     HighBitsOf32BitAddress(0) {
61   const GCNSubtarget &ST = *static_cast<const GCNSubtarget *>(STI);
62   FlatWorkGroupSizes = ST.getFlatWorkGroupSizes(F);
63   WavesPerEU = ST.getWavesPerEU(F);
64
65   Occupancy = ST.computeOccupancy(F, getLDSSize());
66   CallingConv::ID CC = F.getCallingConv();
67
68   VRegFlags.reserve(1024);
69
70   // FIXME: Should have analysis or something rather than attribute to detect
71   // calls.
72   const bool HasCalls = F.hasFnAttribute("amdgpu-calls");
73
74   const bool IsKernel = CC == CallingConv::AMDGPU_KERNEL ||
75                         CC == CallingConv::SPIR_KERNEL;
76
77   if (IsKernel) {
78     if (!F.arg_empty() || ST.getImplicitArgNumBytes(F) != 0)
79       KernargSegmentPtr = true;
80     WorkGroupIDX = true;
81     WorkItemIDX = true;
82   } else if (CC == CallingConv::AMDGPU_PS) {
83     PSInputAddr = AMDGPU::getInitialPSInputAddr(F);
84   }
85
86   MayNeedAGPRs = ST.hasMAIInsts();
87
88   if (!isEntryFunction()) {
89     if (CC != CallingConv::AMDGPU_Gfx)
90       ArgInfo = AMDGPUArgumentUsageInfo::FixedABIFunctionInfo;
91
92     // TODO: Pick a high register, and shift down, similar to a kernel.
93     FrameOffsetReg = AMDGPU::SGPR33;
94     StackPtrOffsetReg = AMDGPU::SGPR32;
95
96     if (!ST.enableFlatScratch()) {
97       // Non-entry functions have no special inputs for now, other registers
98       // required for scratch access.
99       ScratchRSrcReg = AMDGPU::SGPR0_SGPR1_SGPR2_SGPR3;
100
101       ArgInfo.PrivateSegmentBuffer =
102         ArgDescriptor::createRegister(ScratchRSrcReg);
103     }
104
105     if (!F.hasFnAttribute("amdgpu-no-implicitarg-ptr"))
106       ImplicitArgPtr = true;
107   } else {
108     ImplicitArgPtr = false;
109     MaxKernArgAlign = std::max(ST.getAlignmentForImplicitArgPtr(),
110                                MaxKernArgAlign);
111
112     if (ST.hasGFX90AInsts() &&
113         ST.getMaxNumVGPRs(F) <= AMDGPU::VGPR_32RegClass.getNumRegs() &&
114         !mayUseAGPRs(F))
115       MayNeedAGPRs = false; // We will select all MAI with VGPR operands.
116   }
117
118   bool isAmdHsaOrMesa = ST.isAmdHsaOrMesa(F);
119   if (isAmdHsaOrMesa && !ST.enableFlatScratch())
120     PrivateSegmentBuffer = true;
121   else if (ST.isMesaGfxShader(F))
122     ImplicitBufferPtr = true;
123
124   if (!AMDGPU::isGraphics(CC) ||
125       (CC == CallingConv::AMDGPU_CS && ST.hasArchitectedSGPRs())) {
126     if (IsKernel || !F.hasFnAttribute("amdgpu-no-workgroup-id-x"))
127       WorkGroupIDX = true;
128
129     if (!F.hasFnAttribute("amdgpu-no-workgroup-id-y"))
130       WorkGroupIDY = true;
131
132     if (!F.hasFnAttribute("amdgpu-no-workgroup-id-z"))
133       WorkGroupIDZ = true;
134   }
135
136   if (!AMDGPU::isGraphics(CC)) {
137     if (IsKernel || !F.hasFnAttribute("amdgpu-no-workitem-id-x"))
138       WorkItemIDX = true;
139
140     if (!F.hasFnAttribute("amdgpu-no-workitem-id-y") &&
141         ST.getMaxWorkitemID(F, 1) != 0)
142       WorkItemIDY = true;
143
144     if (!F.hasFnAttribute("amdgpu-no-workitem-id-z") &&
145         ST.getMaxWorkitemID(F, 2) != 0)
146       WorkItemIDZ = true;
147
148     if (!F.hasFnAttribute("amdgpu-no-dispatch-ptr"))
149       DispatchPtr = true;
150
151     if (!F.hasFnAttribute("amdgpu-no-queue-ptr"))
152       QueuePtr = true;
153
154     if (!F.hasFnAttribute("amdgpu-no-dispatch-id"))
155       DispatchID = true;
156
157     if (!IsKernel && !F.hasFnAttribute("amdgpu-no-lds-kernel-id"))
158       LDSKernelId = true;
159   }
160
161   // FIXME: This attribute is a hack, we just need an analysis on the function
162   // to look for allocas.
163   bool HasStackObjects = F.hasFnAttribute("amdgpu-stack-objects");
164
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 (ST.hasFlatAddressSpace() && isEntryFunction() &&
169       (isAmdHsaOrMesa || ST.enableFlatScratch()) &&
170       (HasCalls || HasStackObjects || ST.enableFlatScratch()) &&
171       !ST.flatScratchIsArchitected()) {
172     FlatScratchInit = true;
173   }
174
175   if (isEntryFunction()) {
176     // X, XY, and XYZ are the only supported combinations, so make sure Y is
177     // enabled if Z is.
178     if (WorkItemIDZ)
179       WorkItemIDY = true;
180
181     if (!ST.flatScratchIsArchitected()) {
182       PrivateSegmentWaveByteOffset = true;
183
184       // HS and GS always have the scratch wave offset in SGPR5 on GFX9.
185       if (ST.getGeneration() >= AMDGPUSubtarget::GFX9 &&
186           (CC == CallingConv::AMDGPU_HS || CC == CallingConv::AMDGPU_GS))
187         ArgInfo.PrivateSegmentWaveByteOffset =
188             ArgDescriptor::createRegister(AMDGPU::SGPR5);
189     }
190   }
191
192   Attribute A = F.getFnAttribute("amdgpu-git-ptr-high");
193   StringRef S = A.getValueAsString();
194   if (!S.empty())
195     S.consumeInteger(0, GITPtrHigh);
196
197   A = F.getFnAttribute("amdgpu-32bit-address-high-bits");
198   S = A.getValueAsString();
199   if (!S.empty())
200     S.consumeInteger(0, HighBitsOf32BitAddress);
201
202   // On GFX908, in order to guarantee copying between AGPRs, we need a scratch
203   // VGPR available at all times. For now, reserve highest available VGPR. After
204   // RA, shift it to the lowest available unused VGPR if the one exist.
205   if (ST.hasMAIInsts() && !ST.hasGFX90AInsts()) {
206     VGPRForAGPRCopy =
207         AMDGPU::VGPR_32RegClass.getRegister(ST.getMaxNumVGPRs(F) - 1);
208   }
209 }
210
211 MachineFunctionInfo *SIMachineFunctionInfo::clone(
212     BumpPtrAllocator &Allocator, MachineFunction &DestMF,
213     const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB)
214     const {
215   return DestMF.cloneInfo<SIMachineFunctionInfo>(*this);
216 }
217
218 void SIMachineFunctionInfo::limitOccupancy(const MachineFunction &MF) {
219   limitOccupancy(getMaxWavesPerEU());
220   const GCNSubtarget& ST = MF.getSubtarget<GCNSubtarget>();
221   limitOccupancy(ST.getOccupancyWithLocalMemSize(getLDSSize(),
222                  MF.getFunction()));
223 }
224
225 Register SIMachineFunctionInfo::addPrivateSegmentBuffer(
226   const SIRegisterInfo &TRI) {
227   ArgInfo.PrivateSegmentBuffer =
228     ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
229     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SGPR_128RegClass));
230   NumUserSGPRs += 4;
231   return ArgInfo.PrivateSegmentBuffer.getRegister();
232 }
233
234 Register SIMachineFunctionInfo::addDispatchPtr(const SIRegisterInfo &TRI) {
235   ArgInfo.DispatchPtr = ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
236     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));
237   NumUserSGPRs += 2;
238   return ArgInfo.DispatchPtr.getRegister();
239 }
240
241 Register SIMachineFunctionInfo::addQueuePtr(const SIRegisterInfo &TRI) {
242   ArgInfo.QueuePtr = ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
243     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));
244   NumUserSGPRs += 2;
245   return ArgInfo.QueuePtr.getRegister();
246 }
247
248 Register SIMachineFunctionInfo::addKernargSegmentPtr(const SIRegisterInfo &TRI) {
249   ArgInfo.KernargSegmentPtr
250     = ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
251     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));
252   NumUserSGPRs += 2;
253   return ArgInfo.KernargSegmentPtr.getRegister();
254 }
255
256 Register SIMachineFunctionInfo::addDispatchID(const SIRegisterInfo &TRI) {
257   ArgInfo.DispatchID = ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
258     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));
259   NumUserSGPRs += 2;
260   return ArgInfo.DispatchID.getRegister();
261 }
262
263 Register SIMachineFunctionInfo::addFlatScratchInit(const SIRegisterInfo &TRI) {
264   ArgInfo.FlatScratchInit = ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
265     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));
266   NumUserSGPRs += 2;
267   return ArgInfo.FlatScratchInit.getRegister();
268 }
269
270 Register SIMachineFunctionInfo::addImplicitBufferPtr(const SIRegisterInfo &TRI) {
271   ArgInfo.ImplicitBufferPtr = ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
272     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));
273   NumUserSGPRs += 2;
274   return ArgInfo.ImplicitBufferPtr.getRegister();
275 }
276
277 Register SIMachineFunctionInfo::addLDSKernelId() {
278   ArgInfo.LDSKernelId = ArgDescriptor::createRegister(getNextUserSGPR());
279   NumUserSGPRs += 1;
280   return ArgInfo.LDSKernelId.getRegister();
281 }
282
283 void SIMachineFunctionInfo::allocateWWMSpill(MachineFunction &MF, Register VGPR,
284                                              uint64_t Size, Align Alignment) {
285   // Skip if it is an entry function or the register is already added.
286   if (isEntryFunction() || WWMSpills.count(VGPR))
287     return;
288
289   WWMSpills.insert(std::make_pair(
290       VGPR, MF.getFrameInfo().CreateSpillStackObject(Size, Alignment)));
291 }
292
293 // Separate out the callee-saved and scratch registers.
294 void SIMachineFunctionInfo::splitWWMSpillRegisters(
295     MachineFunction &MF,
296     SmallVectorImpl<std::pair<Register, int>> &CalleeSavedRegs,
297     SmallVectorImpl<std::pair<Register, int>> &ScratchRegs) const {
298   const MCPhysReg *CSRegs = MF.getRegInfo().getCalleeSavedRegs();
299   for (auto &Reg : WWMSpills) {
300     if (isCalleeSavedReg(CSRegs, Reg.first))
301       CalleeSavedRegs.push_back(Reg);
302     else
303       ScratchRegs.push_back(Reg);
304   }
305 }
306
307 bool SIMachineFunctionInfo::isCalleeSavedReg(const MCPhysReg *CSRegs,
308                                              MCPhysReg Reg) const {
309   for (unsigned I = 0; CSRegs[I]; ++I) {
310     if (CSRegs[I] == Reg)
311       return true;
312   }
313
314   return false;
315 }
316
317 bool SIMachineFunctionInfo::allocateVirtualVGPRForSGPRSpills(
318     MachineFunction &MF, int FI, unsigned LaneIndex) {
319   MachineRegisterInfo &MRI = MF.getRegInfo();
320   Register LaneVGPR;
321   if (!LaneIndex) {
322     LaneVGPR = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
323     SpillVGPRs.push_back(LaneVGPR);
324   } else {
325     LaneVGPR = SpillVGPRs.back();
326   }
327
328   SGPRSpillsToVirtualVGPRLanes[FI].push_back(
329       SIRegisterInfo::SpilledReg(LaneVGPR, LaneIndex));
330   return true;
331 }
332
333 bool SIMachineFunctionInfo::allocatePhysicalVGPRForSGPRSpills(
334     MachineFunction &MF, int FI, unsigned LaneIndex) {
335   const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
336   const SIRegisterInfo *TRI = ST.getRegisterInfo();
337   MachineRegisterInfo &MRI = MF.getRegInfo();
338   Register LaneVGPR;
339   if (!LaneIndex) {
340     LaneVGPR = TRI->findUnusedRegister(MRI, &AMDGPU::VGPR_32RegClass, MF);
341     if (LaneVGPR == AMDGPU::NoRegister) {
342       // We have no VGPRs left for spilling SGPRs. Reset because we will not
343       // partially spill the SGPR to VGPRs.
344       SGPRSpillsToPhysicalVGPRLanes.erase(FI);
345       return false;
346     }
347
348     allocateWWMSpill(MF, LaneVGPR);
349     reserveWWMRegister(LaneVGPR);
350     for (MachineBasicBlock &MBB : MF) {
351       MBB.addLiveIn(LaneVGPR);
352       MBB.sortUniqueLiveIns();
353     }
354   } else {
355     LaneVGPR = WWMReservedRegs.back();
356   }
357
358   SGPRSpillsToPhysicalVGPRLanes[FI].push_back(
359       SIRegisterInfo::SpilledReg(LaneVGPR, LaneIndex));
360   return true;
361 }
362
363 bool SIMachineFunctionInfo::allocateSGPRSpillToVGPRLane(MachineFunction &MF,
364                                                         int FI,
365                                                         bool IsPrologEpilog) {
366   std::vector<SIRegisterInfo::SpilledReg> &SpillLanes =
367       IsPrologEpilog ? SGPRSpillsToPhysicalVGPRLanes[FI]
368                      : SGPRSpillsToVirtualVGPRLanes[FI];
369
370   // This has already been allocated.
371   if (!SpillLanes.empty())
372     return true;
373
374   const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
375   MachineFrameInfo &FrameInfo = MF.getFrameInfo();
376   unsigned WaveSize = ST.getWavefrontSize();
377
378   unsigned Size = FrameInfo.getObjectSize(FI);
379   unsigned NumLanes = Size / 4;
380
381   if (NumLanes > WaveSize)
382     return false;
383
384   assert(Size >= 4 && "invalid sgpr spill size");
385   assert(ST.getRegisterInfo()->spillSGPRToVGPR() &&
386          "not spilling SGPRs to VGPRs");
387
388   unsigned &NumSpillLanes =
389       IsPrologEpilog ? NumPhysicalVGPRSpillLanes : NumVirtualVGPRSpillLanes;
390
391   for (unsigned I = 0; I < NumLanes; ++I, ++NumSpillLanes) {
392     unsigned LaneIndex = (NumSpillLanes % WaveSize);
393
394     bool Allocated = IsPrologEpilog
395                          ? allocatePhysicalVGPRForSGPRSpills(MF, FI, LaneIndex)
396                          : allocateVirtualVGPRForSGPRSpills(MF, FI, LaneIndex);
397     if (!Allocated) {
398       NumSpillLanes -= I;
399       return false;
400     }
401   }
402
403   return true;
404 }
405
406 /// Reserve AGPRs or VGPRs to support spilling for FrameIndex \p FI.
407 /// Either AGPR is spilled to VGPR to vice versa.
408 /// Returns true if a \p FI can be eliminated completely.
409 bool SIMachineFunctionInfo::allocateVGPRSpillToAGPR(MachineFunction &MF,
410                                                     int FI,
411                                                     bool isAGPRtoVGPR) {
412   MachineRegisterInfo &MRI = MF.getRegInfo();
413   MachineFrameInfo &FrameInfo = MF.getFrameInfo();
414   const GCNSubtarget &ST =  MF.getSubtarget<GCNSubtarget>();
415
416   assert(ST.hasMAIInsts() && FrameInfo.isSpillSlotObjectIndex(FI));
417
418   auto &Spill = VGPRToAGPRSpills[FI];
419
420   // This has already been allocated.
421   if (!Spill.Lanes.empty())
422     return Spill.FullyAllocated;
423
424   unsigned Size = FrameInfo.getObjectSize(FI);
425   unsigned NumLanes = Size / 4;
426   Spill.Lanes.resize(NumLanes, AMDGPU::NoRegister);
427
428   const TargetRegisterClass &RC =
429       isAGPRtoVGPR ? AMDGPU::VGPR_32RegClass : AMDGPU::AGPR_32RegClass;
430   auto Regs = RC.getRegisters();
431
432   auto &SpillRegs = isAGPRtoVGPR ? SpillAGPR : SpillVGPR;
433   const SIRegisterInfo *TRI = ST.getRegisterInfo();
434   Spill.FullyAllocated = true;
435
436   // FIXME: Move allocation logic out of MachineFunctionInfo and initialize
437   // once.
438   BitVector OtherUsedRegs;
439   OtherUsedRegs.resize(TRI->getNumRegs());
440
441   const uint32_t *CSRMask =
442       TRI->getCallPreservedMask(MF, MF.getFunction().getCallingConv());
443   if (CSRMask)
444     OtherUsedRegs.setBitsInMask(CSRMask);
445
446   // TODO: Should include register tuples, but doesn't matter with current
447   // usage.
448   for (MCPhysReg Reg : SpillAGPR)
449     OtherUsedRegs.set(Reg);
450   for (MCPhysReg Reg : SpillVGPR)
451     OtherUsedRegs.set(Reg);
452
453   SmallVectorImpl<MCPhysReg>::const_iterator NextSpillReg = Regs.begin();
454   for (int I = NumLanes - 1; I >= 0; --I) {
455     NextSpillReg = std::find_if(
456         NextSpillReg, Regs.end(), [&MRI, &OtherUsedRegs](MCPhysReg Reg) {
457           return MRI.isAllocatable(Reg) && !MRI.isPhysRegUsed(Reg) &&
458                  !OtherUsedRegs[Reg];
459         });
460
461     if (NextSpillReg == Regs.end()) { // Registers exhausted
462       Spill.FullyAllocated = false;
463       break;
464     }
465
466     OtherUsedRegs.set(*NextSpillReg);
467     SpillRegs.push_back(*NextSpillReg);
468     MRI.reserveReg(*NextSpillReg, TRI);
469     Spill.Lanes[I] = *NextSpillReg++;
470   }
471
472   return Spill.FullyAllocated;
473 }
474
475 bool SIMachineFunctionInfo::removeDeadFrameIndices(
476     MachineFrameInfo &MFI, bool ResetSGPRSpillStackIDs) {
477   // Remove dead frame indices from function frame, however keep FP & BP since
478   // spills for them haven't been inserted yet. And also make sure to remove the
479   // frame indices from `SGPRSpillsToVirtualVGPRLanes` data structure,
480   // otherwise, it could result in an unexpected side effect and bug, in case of
481   // any re-mapping of freed frame indices by later pass(es) like "stack slot
482   // coloring".
483   for (auto &R : make_early_inc_range(SGPRSpillsToVirtualVGPRLanes)) {
484     MFI.RemoveStackObject(R.first);
485     SGPRSpillsToVirtualVGPRLanes.erase(R.first);
486   }
487
488   // Remove the dead frame indices of CSR SGPRs which are spilled to physical
489   // VGPR lanes during SILowerSGPRSpills pass.
490   if (!ResetSGPRSpillStackIDs) {
491     for (auto &R : make_early_inc_range(SGPRSpillsToPhysicalVGPRLanes)) {
492       MFI.RemoveStackObject(R.first);
493       SGPRSpillsToPhysicalVGPRLanes.erase(R.first);
494     }
495   }
496   bool HaveSGPRToMemory = false;
497
498   if (ResetSGPRSpillStackIDs) {
499     // All other SGPRs must be allocated on the default stack, so reset the
500     // stack ID.
501     for (int I = MFI.getObjectIndexBegin(), E = MFI.getObjectIndexEnd(); I != E;
502          ++I) {
503       if (!checkIndexInPrologEpilogSGPRSpills(I)) {
504         if (MFI.getStackID(I) == TargetStackID::SGPRSpill) {
505           MFI.setStackID(I, TargetStackID::Default);
506           HaveSGPRToMemory = true;
507         }
508       }
509     }
510   }
511
512   for (auto &R : VGPRToAGPRSpills) {
513     if (R.second.IsDead)
514       MFI.RemoveStackObject(R.first);
515   }
516
517   return HaveSGPRToMemory;
518 }
519
520 int SIMachineFunctionInfo::getScavengeFI(MachineFrameInfo &MFI,
521                                          const SIRegisterInfo &TRI) {
522   if (ScavengeFI)
523     return *ScavengeFI;
524   if (isEntryFunction()) {
525     ScavengeFI = MFI.CreateFixedObject(
526         TRI.getSpillSize(AMDGPU::SGPR_32RegClass), 0, false);
527   } else {
528     ScavengeFI = MFI.CreateStackObject(
529         TRI.getSpillSize(AMDGPU::SGPR_32RegClass),
530         TRI.getSpillAlign(AMDGPU::SGPR_32RegClass), false);
531   }
532   return *ScavengeFI;
533 }
534
535 MCPhysReg SIMachineFunctionInfo::getNextUserSGPR() const {
536   assert(NumSystemSGPRs == 0 && "System SGPRs must be added after user SGPRs");
537   return AMDGPU::SGPR0 + NumUserSGPRs;
538 }
539
540 MCPhysReg SIMachineFunctionInfo::getNextSystemSGPR() const {
541   return AMDGPU::SGPR0 + NumUserSGPRs + NumSystemSGPRs;
542 }
543
544 void SIMachineFunctionInfo::MRI_NoteNewVirtualRegister(Register Reg) {
545   VRegFlags.grow(Reg);
546 }
547
548 void SIMachineFunctionInfo::MRI_NoteCloneVirtualRegister(Register NewReg,
549                                                          Register SrcReg) {
550   VRegFlags.grow(NewReg);
551   VRegFlags[NewReg] = VRegFlags[SrcReg];
552 }
553
554 Register
555 SIMachineFunctionInfo::getGITPtrLoReg(const MachineFunction &MF) const {
556   const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
557   if (!ST.isAmdPalOS())
558     return Register();
559   Register GitPtrLo = AMDGPU::SGPR0; // Low GIT address passed in
560   if (ST.hasMergedShaders()) {
561     switch (MF.getFunction().getCallingConv()) {
562     case CallingConv::AMDGPU_HS:
563     case CallingConv::AMDGPU_GS:
564       // Low GIT address is passed in s8 rather than s0 for an LS+HS or
565       // ES+GS merged shader on gfx9+.
566       GitPtrLo = AMDGPU::SGPR8;
567       return GitPtrLo;
568     default:
569       return GitPtrLo;
570     }
571   }
572   return GitPtrLo;
573 }
574
575 static yaml::StringValue regToString(Register Reg,
576                                      const TargetRegisterInfo &TRI) {
577   yaml::StringValue Dest;
578   {
579     raw_string_ostream OS(Dest.Value);
580     OS << printReg(Reg, &TRI);
581   }
582   return Dest;
583 }
584
585 static std::optional<yaml::SIArgumentInfo>
586 convertArgumentInfo(const AMDGPUFunctionArgInfo &ArgInfo,
587                     const TargetRegisterInfo &TRI) {
588   yaml::SIArgumentInfo AI;
589
590   auto convertArg = [&](std::optional<yaml::SIArgument> &A,
591                         const ArgDescriptor &Arg) {
592     if (!Arg)
593       return false;
594
595     // Create a register or stack argument.
596     yaml::SIArgument SA = yaml::SIArgument::createArgument(Arg.isRegister());
597     if (Arg.isRegister()) {
598       raw_string_ostream OS(SA.RegisterName.Value);
599       OS << printReg(Arg.getRegister(), &TRI);
600     } else
601       SA.StackOffset = Arg.getStackOffset();
602     // Check and update the optional mask.
603     if (Arg.isMasked())
604       SA.Mask = Arg.getMask();
605
606     A = SA;
607     return true;
608   };
609
610   bool Any = false;
611   Any |= convertArg(AI.PrivateSegmentBuffer, ArgInfo.PrivateSegmentBuffer);
612   Any |= convertArg(AI.DispatchPtr, ArgInfo.DispatchPtr);
613   Any |= convertArg(AI.QueuePtr, ArgInfo.QueuePtr);
614   Any |= convertArg(AI.KernargSegmentPtr, ArgInfo.KernargSegmentPtr);
615   Any |= convertArg(AI.DispatchID, ArgInfo.DispatchID);
616   Any |= convertArg(AI.FlatScratchInit, ArgInfo.FlatScratchInit);
617   Any |= convertArg(AI.LDSKernelId, ArgInfo.LDSKernelId);
618   Any |= convertArg(AI.PrivateSegmentSize, ArgInfo.PrivateSegmentSize);
619   Any |= convertArg(AI.WorkGroupIDX, ArgInfo.WorkGroupIDX);
620   Any |= convertArg(AI.WorkGroupIDY, ArgInfo.WorkGroupIDY);
621   Any |= convertArg(AI.WorkGroupIDZ, ArgInfo.WorkGroupIDZ);
622   Any |= convertArg(AI.WorkGroupInfo, ArgInfo.WorkGroupInfo);
623   Any |= convertArg(AI.PrivateSegmentWaveByteOffset,
624                     ArgInfo.PrivateSegmentWaveByteOffset);
625   Any |= convertArg(AI.ImplicitArgPtr, ArgInfo.ImplicitArgPtr);
626   Any |= convertArg(AI.ImplicitBufferPtr, ArgInfo.ImplicitBufferPtr);
627   Any |= convertArg(AI.WorkItemIDX, ArgInfo.WorkItemIDX);
628   Any |= convertArg(AI.WorkItemIDY, ArgInfo.WorkItemIDY);
629   Any |= convertArg(AI.WorkItemIDZ, ArgInfo.WorkItemIDZ);
630
631   if (Any)
632     return AI;
633
634   return std::nullopt;
635 }
636
637 yaml::SIMachineFunctionInfo::SIMachineFunctionInfo(
638     const llvm::SIMachineFunctionInfo &MFI, const TargetRegisterInfo &TRI,
639     const llvm::MachineFunction &MF)
640     : ExplicitKernArgSize(MFI.getExplicitKernArgSize()),
641       MaxKernArgAlign(MFI.getMaxKernArgAlign()), LDSSize(MFI.getLDSSize()),
642       GDSSize(MFI.getGDSSize()),
643       DynLDSAlign(MFI.getDynLDSAlign()), IsEntryFunction(MFI.isEntryFunction()),
644       NoSignedZerosFPMath(MFI.hasNoSignedZerosFPMath()),
645       MemoryBound(MFI.isMemoryBound()), WaveLimiter(MFI.needsWaveLimiter()),
646       HasSpilledSGPRs(MFI.hasSpilledSGPRs()),
647       HasSpilledVGPRs(MFI.hasSpilledVGPRs()),
648       HighBitsOf32BitAddress(MFI.get32BitAddressHighBits()),
649       Occupancy(MFI.getOccupancy()),
650       ScratchRSrcReg(regToString(MFI.getScratchRSrcReg(), TRI)),
651       FrameOffsetReg(regToString(MFI.getFrameOffsetReg(), TRI)),
652       StackPtrOffsetReg(regToString(MFI.getStackPtrOffsetReg(), TRI)),
653       BytesInStackArgArea(MFI.getBytesInStackArgArea()),
654       ReturnsVoid(MFI.returnsVoid()),
655       ArgInfo(convertArgumentInfo(MFI.getArgInfo(), TRI)),
656       PSInputAddr(MFI.getPSInputAddr()),
657       PSInputEnable(MFI.getPSInputEnable()),
658       Mode(MFI.getMode()) {
659   for (Register Reg : MFI.getWWMReservedRegs())
660     WWMReservedRegs.push_back(regToString(Reg, TRI));
661
662   if (MFI.getLongBranchReservedReg())
663     LongBranchReservedReg = regToString(MFI.getLongBranchReservedReg(), TRI);
664   if (MFI.getVGPRForAGPRCopy())
665     VGPRForAGPRCopy = regToString(MFI.getVGPRForAGPRCopy(), TRI);
666
667   if (MFI.getSGPRForEXECCopy())
668     SGPRForEXECCopy = regToString(MFI.getSGPRForEXECCopy(), TRI);
669
670   auto SFI = MFI.getOptionalScavengeFI();
671   if (SFI)
672     ScavengeFI = yaml::FrameIndex(*SFI, MF.getFrameInfo());
673 }
674
675 void yaml::SIMachineFunctionInfo::mappingImpl(yaml::IO &YamlIO) {
676   MappingTraits<SIMachineFunctionInfo>::mapping(YamlIO, *this);
677 }
678
679 bool SIMachineFunctionInfo::initializeBaseYamlFields(
680     const yaml::SIMachineFunctionInfo &YamlMFI, const MachineFunction &MF,
681     PerFunctionMIParsingState &PFS, SMDiagnostic &Error, SMRange &SourceRange) {
682   ExplicitKernArgSize = YamlMFI.ExplicitKernArgSize;
683   MaxKernArgAlign = YamlMFI.MaxKernArgAlign;
684   LDSSize = YamlMFI.LDSSize;
685   GDSSize = YamlMFI.GDSSize;
686   DynLDSAlign = YamlMFI.DynLDSAlign;
687   PSInputAddr = YamlMFI.PSInputAddr;
688   PSInputEnable = YamlMFI.PSInputEnable;
689   HighBitsOf32BitAddress = YamlMFI.HighBitsOf32BitAddress;
690   Occupancy = YamlMFI.Occupancy;
691   IsEntryFunction = YamlMFI.IsEntryFunction;
692   NoSignedZerosFPMath = YamlMFI.NoSignedZerosFPMath;
693   MemoryBound = YamlMFI.MemoryBound;
694   WaveLimiter = YamlMFI.WaveLimiter;
695   HasSpilledSGPRs = YamlMFI.HasSpilledSGPRs;
696   HasSpilledVGPRs = YamlMFI.HasSpilledVGPRs;
697   BytesInStackArgArea = YamlMFI.BytesInStackArgArea;
698   ReturnsVoid = YamlMFI.ReturnsVoid;
699
700   if (YamlMFI.ScavengeFI) {
701     auto FIOrErr = YamlMFI.ScavengeFI->getFI(MF.getFrameInfo());
702     if (!FIOrErr) {
703       // Create a diagnostic for a the frame index.
704       const MemoryBuffer &Buffer =
705           *PFS.SM->getMemoryBuffer(PFS.SM->getMainFileID());
706
707       Error = SMDiagnostic(*PFS.SM, SMLoc(), Buffer.getBufferIdentifier(), 1, 1,
708                            SourceMgr::DK_Error, toString(FIOrErr.takeError()),
709                            "", std::nullopt, std::nullopt);
710       SourceRange = YamlMFI.ScavengeFI->SourceRange;
711       return true;
712     }
713     ScavengeFI = *FIOrErr;
714   } else {
715     ScavengeFI = std::nullopt;
716   }
717   return false;
718 }
719
720 bool SIMachineFunctionInfo::mayUseAGPRs(const Function &F) const {
721   for (const BasicBlock &BB : F) {
722     for (const Instruction &I : BB) {
723       const auto *CB = dyn_cast<CallBase>(&I);
724       if (!CB)
725         continue;
726
727       if (CB->isInlineAsm()) {
728         const InlineAsm *IA = dyn_cast<InlineAsm>(CB->getCalledOperand());
729         for (const auto &CI : IA->ParseConstraints()) {
730           for (StringRef Code : CI.Codes) {
731             Code.consume_front("{");
732             if (Code.startswith("a"))
733               return true;
734           }
735         }
736         continue;
737       }
738
739       const Function *Callee =
740           dyn_cast<Function>(CB->getCalledOperand()->stripPointerCasts());
741       if (!Callee)
742         return true;
743
744       if (Callee->getIntrinsicID() == Intrinsic::not_intrinsic)
745         return true;
746     }
747   }
748
749   return false;
750 }
751
752 bool SIMachineFunctionInfo::usesAGPRs(const MachineFunction &MF) const {
753   if (UsesAGPRs)
754     return *UsesAGPRs;
755
756   if (!mayNeedAGPRs()) {
757     UsesAGPRs = false;
758     return false;
759   }
760
761   if (!AMDGPU::isEntryFunctionCC(MF.getFunction().getCallingConv()) ||
762       MF.getFrameInfo().hasCalls()) {
763     UsesAGPRs = true;
764     return true;
765   }
766
767   const MachineRegisterInfo &MRI = MF.getRegInfo();
768
769   for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
770     const Register Reg = Register::index2VirtReg(I);
771     const TargetRegisterClass *RC = MRI.getRegClassOrNull(Reg);
772     if (RC && SIRegisterInfo::isAGPRClass(RC)) {
773       UsesAGPRs = true;
774       return true;
775     } else if (!RC && !MRI.use_empty(Reg) && MRI.getType(Reg).isValid()) {
776       // Defer caching UsesAGPRs, function might not yet been regbank selected.
777       return true;
778     }
779   }
780
781   for (MCRegister Reg : AMDGPU::AGPR_32RegClass) {
782     if (MRI.isPhysRegUsed(Reg)) {
783       UsesAGPRs = true;
784       return true;
785     }
786   }
787
788   UsesAGPRs = false;
789   return false;
790 }