12cab237bSDimitry Andric //===- SIMachineFunctionInfo.cpp - SI Machine Function Info ---------------===//
28f0fd8f6SDimitry Andric //
38f0fd8f6SDimitry Andric //                     The LLVM Compiler Infrastructure
48f0fd8f6SDimitry Andric //
58f0fd8f6SDimitry Andric // This file is distributed under the University of Illinois Open Source
68f0fd8f6SDimitry Andric // License. See LICENSE.TXT for details.
78f0fd8f6SDimitry Andric //
88f0fd8f6SDimitry Andric //===----------------------------------------------------------------------===//
98f0fd8f6SDimitry Andric 
108f0fd8f6SDimitry Andric #include "SIMachineFunctionInfo.h"
112cab237bSDimitry Andric #include "AMDGPUArgumentUsageInfo.h"
128f0fd8f6SDimitry Andric #include "AMDGPUSubtarget.h"
132cab237bSDimitry Andric #include "SIRegisterInfo.h"
144ba319b5SDimitry Andric #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
152cab237bSDimitry Andric #include "Utils/AMDGPUBaseInfo.h"
162cab237bSDimitry Andric #include "llvm/ADT/Optional.h"
172cab237bSDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
188f0fd8f6SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
192cab237bSDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
208f0fd8f6SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
212cab237bSDimitry Andric #include "llvm/IR/CallingConv.h"
228f0fd8f6SDimitry Andric #include "llvm/IR/Function.h"
232cab237bSDimitry Andric #include <cassert>
242cab237bSDimitry Andric #include <vector>
258f0fd8f6SDimitry Andric 
268f0fd8f6SDimitry Andric #define MAX_LANES 64
278f0fd8f6SDimitry Andric 
288f0fd8f6SDimitry Andric using namespace llvm;
298f0fd8f6SDimitry Andric 
SIMachineFunctionInfo(const MachineFunction & MF)308f0fd8f6SDimitry Andric SIMachineFunctionInfo::SIMachineFunctionInfo(const MachineFunction &MF)
318f0fd8f6SDimitry Andric   : AMDGPUMachineFunction(MF),
327d523365SDimitry Andric     PrivateSegmentBuffer(false),
337d523365SDimitry Andric     DispatchPtr(false),
347d523365SDimitry Andric     QueuePtr(false),
357d523365SDimitry Andric     KernargSegmentPtr(false),
36d88c1a5aSDimitry Andric     DispatchID(false),
377d523365SDimitry Andric     FlatScratchInit(false),
383ca95b02SDimitry Andric     WorkGroupIDX(false),
397d523365SDimitry Andric     WorkGroupIDY(false),
407d523365SDimitry Andric     WorkGroupIDZ(false),
417d523365SDimitry Andric     WorkGroupInfo(false),
427d523365SDimitry Andric     PrivateSegmentWaveByteOffset(false),
433ca95b02SDimitry Andric     WorkItemIDX(false),
447d523365SDimitry Andric     WorkItemIDY(false),
4598221d2eSDimitry Andric     WorkItemIDZ(false),
462cab237bSDimitry Andric     ImplicitBufferPtr(false),
472cab237bSDimitry Andric     ImplicitArgPtr(false),
484ba319b5SDimitry Andric     GITPtrHigh(0xffffffff),
494ba319b5SDimitry Andric     HighBitsOf32BitAddress(0) {
504ba319b5SDimitry Andric   const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
512cab237bSDimitry Andric   const Function &F = MF.getFunction();
522cab237bSDimitry Andric   FlatWorkGroupSizes = ST.getFlatWorkGroupSizes(F);
532cab237bSDimitry Andric   WavesPerEU = ST.getWavesPerEU(F);
547d523365SDimitry Andric 
554ba319b5SDimitry Andric   Occupancy = getMaxWavesPerEU();
564ba319b5SDimitry Andric   limitOccupancy(MF);
574ba319b5SDimitry Andric   CallingConv::ID CC = F.getCallingConv();
584ba319b5SDimitry Andric 
594ba319b5SDimitry Andric   if (CC == CallingConv::AMDGPU_KERNEL || CC == CallingConv::SPIR_KERNEL) {
604ba319b5SDimitry Andric     if (!F.arg_empty())
614ba319b5SDimitry Andric       KernargSegmentPtr = true;
624ba319b5SDimitry Andric     WorkGroupIDX = true;
634ba319b5SDimitry Andric     WorkItemIDX = true;
644ba319b5SDimitry Andric   } else if (CC == CallingConv::AMDGPU_PS) {
654ba319b5SDimitry Andric     PSInputAddr = AMDGPU::getInitialPSInputAddr(F);
664ba319b5SDimitry Andric   }
674ba319b5SDimitry Andric 
68d8866befSDimitry Andric   if (!isEntryFunction()) {
69d8866befSDimitry Andric     // Non-entry functions have no special inputs for now, other registers
70d8866befSDimitry Andric     // required for scratch access.
71d8866befSDimitry Andric     ScratchRSrcReg = AMDGPU::SGPR0_SGPR1_SGPR2_SGPR3;
72d8866befSDimitry Andric     ScratchWaveOffsetReg = AMDGPU::SGPR4;
73d8866befSDimitry Andric     FrameOffsetReg = AMDGPU::SGPR5;
74edd7eaddSDimitry Andric     StackPtrOffsetReg = AMDGPU::SGPR32;
75b40b48b8SDimitry Andric 
762cab237bSDimitry Andric     ArgInfo.PrivateSegmentBuffer =
772cab237bSDimitry Andric       ArgDescriptor::createRegister(ScratchRSrcReg);
782cab237bSDimitry Andric     ArgInfo.PrivateSegmentWaveByteOffset =
792cab237bSDimitry Andric       ArgDescriptor::createRegister(ScratchWaveOffsetReg);
802cab237bSDimitry Andric 
812cab237bSDimitry Andric     if (F.hasFnAttribute("amdgpu-implicitarg-ptr"))
822cab237bSDimitry Andric       ImplicitArgPtr = true;
832cab237bSDimitry Andric   } else {
844ba319b5SDimitry Andric     if (F.hasFnAttribute("amdgpu-implicitarg-ptr")) {
852cab237bSDimitry Andric       KernargSegmentPtr = true;
864ba319b5SDimitry Andric       MaxKernArgAlign = std::max(ST.getAlignmentForImplicitArgPtr(),
874ba319b5SDimitry Andric                                  MaxKernArgAlign);
88d8866befSDimitry Andric     }
893ca95b02SDimitry Andric   }
907d523365SDimitry Andric 
917a7e6055SDimitry Andric   if (ST.debuggerEmitPrologue()) {
927a7e6055SDimitry Andric     // Enable everything.
93b40b48b8SDimitry Andric     WorkGroupIDX = true;
947a7e6055SDimitry Andric     WorkGroupIDY = true;
957a7e6055SDimitry Andric     WorkGroupIDZ = true;
96b40b48b8SDimitry Andric     WorkItemIDX = true;
977a7e6055SDimitry Andric     WorkItemIDY = true;
987a7e6055SDimitry Andric     WorkItemIDZ = true;
997a7e6055SDimitry Andric   } else {
1002cab237bSDimitry Andric     if (F.hasFnAttribute("amdgpu-work-group-id-x"))
101b40b48b8SDimitry Andric       WorkGroupIDX = true;
102b40b48b8SDimitry Andric 
1032cab237bSDimitry Andric     if (F.hasFnAttribute("amdgpu-work-group-id-y"))
1047d523365SDimitry Andric       WorkGroupIDY = true;
1057d523365SDimitry Andric 
1062cab237bSDimitry Andric     if (F.hasFnAttribute("amdgpu-work-group-id-z"))
1077d523365SDimitry Andric       WorkGroupIDZ = true;
1087d523365SDimitry Andric 
1092cab237bSDimitry Andric     if (F.hasFnAttribute("amdgpu-work-item-id-x"))
110b40b48b8SDimitry Andric       WorkItemIDX = true;
111b40b48b8SDimitry Andric 
1122cab237bSDimitry Andric     if (F.hasFnAttribute("amdgpu-work-item-id-y"))
1137d523365SDimitry Andric       WorkItemIDY = true;
1147d523365SDimitry Andric 
1152cab237bSDimitry Andric     if (F.hasFnAttribute("amdgpu-work-item-id-z"))
1167d523365SDimitry Andric       WorkItemIDZ = true;
1177a7e6055SDimitry Andric   }
1187d523365SDimitry Andric 
119b40b48b8SDimitry Andric   const MachineFrameInfo &FrameInfo = MF.getFrameInfo();
120b40b48b8SDimitry Andric   bool HasStackObjects = FrameInfo.hasStackObjects();
121b40b48b8SDimitry Andric 
122b40b48b8SDimitry Andric   if (isEntryFunction()) {
1233ca95b02SDimitry Andric     // X, XY, and XYZ are the only supported combinations, so make sure Y is
1243ca95b02SDimitry Andric     // enabled if Z is.
1253ca95b02SDimitry Andric     if (WorkItemIDZ)
1263ca95b02SDimitry Andric       WorkItemIDY = true;
1273ca95b02SDimitry Andric 
1287d523365SDimitry Andric     PrivateSegmentWaveByteOffset = true;
1297d523365SDimitry Andric 
1300f5676f4SDimitry Andric     // HS and GS always have the scratch wave offset in SGPR5 on GFX9.
1310f5676f4SDimitry Andric     if (ST.getGeneration() >= AMDGPUSubtarget::GFX9 &&
1320f5676f4SDimitry Andric         (CC == CallingConv::AMDGPU_HS || CC == CallingConv::AMDGPU_GS))
133*b5893f02SDimitry Andric       ArgInfo.PrivateSegmentWaveByteOffset =
134*b5893f02SDimitry Andric           ArgDescriptor::createRegister(AMDGPU::SGPR5);
135b40b48b8SDimitry Andric   }
1360f5676f4SDimitry Andric 
137*b5893f02SDimitry Andric   bool isAmdHsaOrMesa = ST.isAmdHsaOrMesa(F);
138*b5893f02SDimitry Andric   if (isAmdHsaOrMesa) {
1397d523365SDimitry Andric     PrivateSegmentBuffer = true;
1407d523365SDimitry Andric 
1412cab237bSDimitry Andric     if (F.hasFnAttribute("amdgpu-dispatch-ptr"))
1427d523365SDimitry Andric       DispatchPtr = true;
1433ca95b02SDimitry Andric 
1442cab237bSDimitry Andric     if (F.hasFnAttribute("amdgpu-queue-ptr"))
1453ca95b02SDimitry Andric       QueuePtr = true;
146d88c1a5aSDimitry Andric 
1472cab237bSDimitry Andric     if (F.hasFnAttribute("amdgpu-dispatch-id"))
148d88c1a5aSDimitry Andric       DispatchID = true;
1494ba319b5SDimitry Andric   } else if (ST.isMesaGfxShader(F)) {
150edd7eaddSDimitry Andric     ImplicitBufferPtr = true;
1517d523365SDimitry Andric   }
1527d523365SDimitry Andric 
1532cab237bSDimitry Andric   if (F.hasFnAttribute("amdgpu-kernarg-segment-ptr"))
154b40b48b8SDimitry Andric     KernargSegmentPtr = true;
155b40b48b8SDimitry Andric 
156*b5893f02SDimitry Andric   if (ST.hasFlatAddressSpace() && isEntryFunction() && isAmdHsaOrMesa) {
157b40b48b8SDimitry Andric     // TODO: This could be refined a lot. The attribute is a poor way of
158b40b48b8SDimitry Andric     // detecting calls that may require it before argument lowering.
1592cab237bSDimitry Andric     if (HasStackObjects || F.hasFnAttribute("amdgpu-flat-scratch"))
1603ca95b02SDimitry Andric       FlatScratchInit = true;
1617d523365SDimitry Andric   }
1622cab237bSDimitry Andric 
1632cab237bSDimitry Andric   Attribute A = F.getFnAttribute("amdgpu-git-ptr-high");
1642cab237bSDimitry Andric   StringRef S = A.getValueAsString();
1652cab237bSDimitry Andric   if (!S.empty())
1662cab237bSDimitry Andric     S.consumeInteger(0, GITPtrHigh);
1674ba319b5SDimitry Andric 
1684ba319b5SDimitry Andric   A = F.getFnAttribute("amdgpu-32bit-address-high-bits");
1694ba319b5SDimitry Andric   S = A.getValueAsString();
1704ba319b5SDimitry Andric   if (!S.empty())
1714ba319b5SDimitry Andric     S.consumeInteger(0, HighBitsOf32BitAddress);
1724ba319b5SDimitry Andric }
1734ba319b5SDimitry Andric 
limitOccupancy(const MachineFunction & MF)1744ba319b5SDimitry Andric void SIMachineFunctionInfo::limitOccupancy(const MachineFunction &MF) {
1754ba319b5SDimitry Andric   limitOccupancy(getMaxWavesPerEU());
1764ba319b5SDimitry Andric   const GCNSubtarget& ST = MF.getSubtarget<GCNSubtarget>();
1774ba319b5SDimitry Andric   limitOccupancy(ST.getOccupancyWithLocalMemSize(getLDSSize(),
1784ba319b5SDimitry Andric                  MF.getFunction()));
179b40b48b8SDimitry Andric }
1807d523365SDimitry Andric 
addPrivateSegmentBuffer(const SIRegisterInfo & TRI)1817d523365SDimitry Andric unsigned SIMachineFunctionInfo::addPrivateSegmentBuffer(
1827d523365SDimitry Andric   const SIRegisterInfo &TRI) {
1832cab237bSDimitry Andric   ArgInfo.PrivateSegmentBuffer =
1842cab237bSDimitry Andric     ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
1852cab237bSDimitry Andric     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_128RegClass));
1867d523365SDimitry Andric   NumUserSGPRs += 4;
1872cab237bSDimitry Andric   return ArgInfo.PrivateSegmentBuffer.getRegister();
1887d523365SDimitry Andric }
1897d523365SDimitry Andric 
addDispatchPtr(const SIRegisterInfo & TRI)1907d523365SDimitry Andric unsigned SIMachineFunctionInfo::addDispatchPtr(const SIRegisterInfo &TRI) {
1912cab237bSDimitry Andric   ArgInfo.DispatchPtr = ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
1922cab237bSDimitry Andric     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));
1937d523365SDimitry Andric   NumUserSGPRs += 2;
1942cab237bSDimitry Andric   return ArgInfo.DispatchPtr.getRegister();
1957d523365SDimitry Andric }
1967d523365SDimitry Andric 
addQueuePtr(const SIRegisterInfo & TRI)1977d523365SDimitry Andric unsigned SIMachineFunctionInfo::addQueuePtr(const SIRegisterInfo &TRI) {
1982cab237bSDimitry Andric   ArgInfo.QueuePtr = ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
1992cab237bSDimitry Andric     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));
2007d523365SDimitry Andric   NumUserSGPRs += 2;
2012cab237bSDimitry Andric   return ArgInfo.QueuePtr.getRegister();
2027d523365SDimitry Andric }
2037d523365SDimitry Andric 
addKernargSegmentPtr(const SIRegisterInfo & TRI)2047d523365SDimitry Andric unsigned SIMachineFunctionInfo::addKernargSegmentPtr(const SIRegisterInfo &TRI) {
2052cab237bSDimitry Andric   ArgInfo.KernargSegmentPtr
2062cab237bSDimitry Andric     = ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
2072cab237bSDimitry Andric     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));
2087d523365SDimitry Andric   NumUserSGPRs += 2;
2092cab237bSDimitry Andric   return ArgInfo.KernargSegmentPtr.getRegister();
2107d523365SDimitry Andric }
2118f0fd8f6SDimitry Andric 
addDispatchID(const SIRegisterInfo & TRI)212d88c1a5aSDimitry Andric unsigned SIMachineFunctionInfo::addDispatchID(const SIRegisterInfo &TRI) {
2132cab237bSDimitry Andric   ArgInfo.DispatchID = ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
2142cab237bSDimitry Andric     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));
215d88c1a5aSDimitry Andric   NumUserSGPRs += 2;
2162cab237bSDimitry Andric   return ArgInfo.DispatchID.getRegister();
217d88c1a5aSDimitry Andric }
218d88c1a5aSDimitry Andric 
addFlatScratchInit(const SIRegisterInfo & TRI)2193ca95b02SDimitry Andric unsigned SIMachineFunctionInfo::addFlatScratchInit(const SIRegisterInfo &TRI) {
2202cab237bSDimitry Andric   ArgInfo.FlatScratchInit = ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
2212cab237bSDimitry Andric     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));
2223ca95b02SDimitry Andric   NumUserSGPRs += 2;
2232cab237bSDimitry Andric   return ArgInfo.FlatScratchInit.getRegister();
2243ca95b02SDimitry Andric }
2253ca95b02SDimitry Andric 
addImplicitBufferPtr(const SIRegisterInfo & TRI)226edd7eaddSDimitry Andric unsigned SIMachineFunctionInfo::addImplicitBufferPtr(const SIRegisterInfo &TRI) {
2272cab237bSDimitry Andric   ArgInfo.ImplicitBufferPtr = ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
2282cab237bSDimitry Andric     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));
22998221d2eSDimitry Andric   NumUserSGPRs += 2;
2302cab237bSDimitry Andric   return ArgInfo.ImplicitBufferPtr.getRegister();
2312cab237bSDimitry Andric }
2322cab237bSDimitry Andric 
isCalleeSavedReg(const MCPhysReg * CSRegs,MCPhysReg Reg)2332cab237bSDimitry Andric static bool isCalleeSavedReg(const MCPhysReg *CSRegs, MCPhysReg Reg) {
2342cab237bSDimitry Andric   for (unsigned I = 0; CSRegs[I]; ++I) {
2352cab237bSDimitry Andric     if (CSRegs[I] == Reg)
2362cab237bSDimitry Andric       return true;
2372cab237bSDimitry Andric   }
2382cab237bSDimitry Andric 
2392cab237bSDimitry Andric   return false;
24098221d2eSDimitry Andric }
24198221d2eSDimitry Andric 
2427a7e6055SDimitry Andric /// Reserve a slice of a VGPR to support spilling for FrameIndex \p FI.
allocateSGPRSpillToVGPR(MachineFunction & MF,int FI)2437a7e6055SDimitry Andric bool SIMachineFunctionInfo::allocateSGPRSpillToVGPR(MachineFunction &MF,
2447a7e6055SDimitry Andric                                                     int FI) {
2457a7e6055SDimitry Andric   std::vector<SpilledReg> &SpillLanes = SGPRToVGPRSpills[FI];
2463ca95b02SDimitry Andric 
2477a7e6055SDimitry Andric   // This has already been allocated.
2487a7e6055SDimitry Andric   if (!SpillLanes.empty())
2497a7e6055SDimitry Andric     return true;
2507a7e6055SDimitry Andric 
2514ba319b5SDimitry Andric   const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
2523ca95b02SDimitry Andric   const SIRegisterInfo *TRI = ST.getRegisterInfo();
2537a7e6055SDimitry Andric   MachineFrameInfo &FrameInfo = MF.getFrameInfo();
2547a7e6055SDimitry Andric   MachineRegisterInfo &MRI = MF.getRegInfo();
2557a7e6055SDimitry Andric   unsigned WaveSize = ST.getWavefrontSize();
2563ca95b02SDimitry Andric 
2577a7e6055SDimitry Andric   unsigned Size = FrameInfo.getObjectSize(FI);
2587a7e6055SDimitry Andric   assert(Size >= 4 && Size <= 64 && "invalid sgpr spill size");
2597a7e6055SDimitry Andric   assert(TRI->spillSGPRToVGPR() && "not spilling SGPRs to VGPRs");
2608f0fd8f6SDimitry Andric 
2617a7e6055SDimitry Andric   int NumLanes = Size / 4;
2628f0fd8f6SDimitry Andric 
2632cab237bSDimitry Andric   const MCPhysReg *CSRegs = TRI->getCalleeSavedRegs(&MF);
2642cab237bSDimitry Andric 
2657a7e6055SDimitry Andric   // Make sure to handle the case where a wide SGPR spill may span between two
2667a7e6055SDimitry Andric   // VGPRs.
2677a7e6055SDimitry Andric   for (int I = 0; I < NumLanes; ++I, ++NumVGPRSpillLanes) {
2687a7e6055SDimitry Andric     unsigned LaneVGPR;
2697a7e6055SDimitry Andric     unsigned VGPRIndex = (NumVGPRSpillLanes % WaveSize);
2708f0fd8f6SDimitry Andric 
2717a7e6055SDimitry Andric     if (VGPRIndex == 0) {
2727a7e6055SDimitry Andric       LaneVGPR = TRI->findUnusedRegister(MRI, &AMDGPU::VGPR_32RegClass, MF);
2737a7e6055SDimitry Andric       if (LaneVGPR == AMDGPU::NoRegister) {
2742cab237bSDimitry Andric         // We have no VGPRs left for spilling SGPRs. Reset because we will not
2757a7e6055SDimitry Andric         // partially spill the SGPR to VGPRs.
2767a7e6055SDimitry Andric         SGPRToVGPRSpills.erase(FI);
2777a7e6055SDimitry Andric         NumVGPRSpillLanes -= I;
2787a7e6055SDimitry Andric         return false;
2797a7e6055SDimitry Andric       }
2804d0b32cdSDimitry Andric 
2812cab237bSDimitry Andric       Optional<int> CSRSpillFI;
2824ba319b5SDimitry Andric       if ((FrameInfo.hasCalls() || !isEntryFunction()) && CSRegs &&
2834ba319b5SDimitry Andric           isCalleeSavedReg(CSRegs, LaneVGPR)) {
2844ba319b5SDimitry Andric         CSRSpillFI = FrameInfo.CreateSpillStackObject(4, 4);
2852cab237bSDimitry Andric       }
2862cab237bSDimitry Andric 
2872cab237bSDimitry Andric       SpillVGPRs.push_back(SGPRSpillVGPRCSR(LaneVGPR, CSRSpillFI));
2888f0fd8f6SDimitry Andric 
2898f0fd8f6SDimitry Andric       // Add this register as live-in to all blocks to avoid machine verifer
2908f0fd8f6SDimitry Andric       // complaining about use of an undefined physical register.
2917a7e6055SDimitry Andric       for (MachineBasicBlock &BB : MF)
2927a7e6055SDimitry Andric         BB.addLiveIn(LaneVGPR);
2937a7e6055SDimitry Andric     } else {
2942cab237bSDimitry Andric       LaneVGPR = SpillVGPRs.back().VGPR;
2958f0fd8f6SDimitry Andric     }
2968f0fd8f6SDimitry Andric 
2977a7e6055SDimitry Andric     SpillLanes.push_back(SpilledReg(LaneVGPR, VGPRIndex));
2987a7e6055SDimitry Andric   }
2997a7e6055SDimitry Andric 
3007a7e6055SDimitry Andric   return true;
3017a7e6055SDimitry Andric }
3027a7e6055SDimitry Andric 
removeSGPRToVGPRFrameIndices(MachineFrameInfo & MFI)3037a7e6055SDimitry Andric void SIMachineFunctionInfo::removeSGPRToVGPRFrameIndices(MachineFrameInfo &MFI) {
3047a7e6055SDimitry Andric   for (auto &R : SGPRToVGPRSpills)
3057a7e6055SDimitry Andric     MFI.RemoveStackObject(R.first);
3068f0fd8f6SDimitry Andric }
3074ba319b5SDimitry Andric 
3084ba319b5SDimitry Andric 
3094ba319b5SDimitry Andric /// \returns VGPR used for \p Dim' work item ID.
getWorkItemIDVGPR(unsigned Dim) const3104ba319b5SDimitry Andric unsigned SIMachineFunctionInfo::getWorkItemIDVGPR(unsigned Dim) const {
3114ba319b5SDimitry Andric   switch (Dim) {
3124ba319b5SDimitry Andric   case 0:
3134ba319b5SDimitry Andric     assert(hasWorkItemIDX());
3144ba319b5SDimitry Andric     return AMDGPU::VGPR0;
3154ba319b5SDimitry Andric   case 1:
3164ba319b5SDimitry Andric     assert(hasWorkItemIDY());
3174ba319b5SDimitry Andric     return AMDGPU::VGPR1;
3184ba319b5SDimitry Andric   case 2:
3194ba319b5SDimitry Andric     assert(hasWorkItemIDZ());
3204ba319b5SDimitry Andric     return AMDGPU::VGPR2;
3214ba319b5SDimitry Andric   }
3224ba319b5SDimitry Andric   llvm_unreachable("unexpected dimension");
3234ba319b5SDimitry Andric }
3244ba319b5SDimitry Andric 
getNextUserSGPR() const3254ba319b5SDimitry Andric MCPhysReg SIMachineFunctionInfo::getNextUserSGPR() const {
3264ba319b5SDimitry Andric   assert(NumSystemSGPRs == 0 && "System SGPRs must be added after user SGPRs");
3274ba319b5SDimitry Andric   return AMDGPU::SGPR0 + NumUserSGPRs;
3284ba319b5SDimitry Andric }
3294ba319b5SDimitry Andric 
getNextSystemSGPR() const3304ba319b5SDimitry Andric MCPhysReg SIMachineFunctionInfo::getNextSystemSGPR() const {
3314ba319b5SDimitry Andric   return AMDGPU::SGPR0 + NumUserSGPRs + NumSystemSGPRs;
3324ba319b5SDimitry Andric }
333