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