1 //===- SIMachineFunctionInfo.h - SIMachineFunctionInfo interface -*- C++ -*-==//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_LIB_TARGET_AMDGPU_SIMACHINEFUNCTIONINFO_H
15 #define LLVM_LIB_TARGET_AMDGPU_SIMACHINEFUNCTIONINFO_H
17 #include "AMDGPUMachineFunction.h"
18 #include "SIRegisterInfo.h"
24 class MachineRegisterInfo;
26 /// This class keeps track of the SPI_SP_INPUT_ADDR config register, which
27 /// tells the hardware which interpolation parameters to load.
28 class SIMachineFunctionInfo final : public AMDGPUMachineFunction {
29 // FIXME: This should be removed and getPreloadedValue moved here.
30 friend struct SIRegisterInfo;
31 void anchor() override;
35 // Registers that may be reserved for spilling purposes. These may be the same
36 // as the input registers.
37 unsigned ScratchRSrcReg;
38 unsigned ScratchWaveOffsetReg;
40 // Input registers setup for the HSA ABI.
41 // User SGPRs in allocation order.
42 unsigned PrivateSegmentBufferUserSGPR;
43 unsigned DispatchPtrUserSGPR;
44 unsigned QueuePtrUserSGPR;
45 unsigned KernargSegmentPtrUserSGPR;
46 unsigned DispatchIDUserSGPR;
47 unsigned FlatScratchInitUserSGPR;
48 unsigned PrivateSegmentSizeUserSGPR;
49 unsigned GridWorkGroupCountXUserSGPR;
50 unsigned GridWorkGroupCountYUserSGPR;
51 unsigned GridWorkGroupCountZUserSGPR;
53 // System SGPRs in allocation order.
54 unsigned WorkGroupIDXSystemSGPR;
55 unsigned WorkGroupIDYSystemSGPR;
56 unsigned WorkGroupIDZSystemSGPR;
57 unsigned WorkGroupInfoSystemSGPR;
58 unsigned PrivateSegmentWaveByteOffsetSystemSGPR;
64 unsigned MaximumWorkGroupSize;
66 // Number of reserved VGPRs for debugger usage.
67 unsigned DebuggerReservedVGPRCount;
68 // Stack object indices for work group IDs.
69 std::array<int, 3> DebuggerWorkGroupIDStackObjectIndices;
70 // Stack object indices for work item IDs.
71 std::array<int, 3> DebuggerWorkItemIDStackObjectIndices;
74 // FIXME: Make private
75 unsigned LDSWaveSpillSize;
77 std::map<unsigned, unsigned> LaneVGPRs;
78 unsigned ScratchOffsetReg;
79 unsigned NumUserSGPRs;
80 unsigned NumSystemSGPRs;
85 bool HasNonSpillStackObjects;
86 bool HasFlatInstructions;
88 unsigned NumSpilledSGPRs;
89 unsigned NumSpilledVGPRs;
91 // Feature bits required for inputs passed in user SGPRs.
92 bool PrivateSegmentBuffer : 1;
96 bool KernargSegmentPtr : 1;
97 bool FlatScratchInit : 1;
98 bool GridWorkgroupCountX : 1;
99 bool GridWorkgroupCountY : 1;
100 bool GridWorkgroupCountZ : 1;
102 // Feature bits required for inputs passed in system SGPRs.
103 bool WorkGroupIDX : 1; // Always initialized.
104 bool WorkGroupIDY : 1;
105 bool WorkGroupIDZ : 1;
106 bool WorkGroupInfo : 1;
107 bool PrivateSegmentWaveByteOffset : 1;
109 bool WorkItemIDX : 1; // Always initialized.
110 bool WorkItemIDY : 1;
111 bool WorkItemIDZ : 1;
113 MCPhysReg getNextUserSGPR() const {
114 assert(NumSystemSGPRs == 0 && "System SGPRs must be added after user SGPRs");
115 return AMDGPU::SGPR0 + NumUserSGPRs;
118 MCPhysReg getNextSystemSGPR() const {
119 return AMDGPU::SGPR0 + NumUserSGPRs + NumSystemSGPRs;
126 SpilledReg(unsigned R, int L) : VGPR (R), Lane (L) { }
127 SpilledReg() : VGPR(AMDGPU::NoRegister), Lane(-1) { }
128 bool hasLane() { return Lane != -1;}
129 bool hasReg() { return VGPR != AMDGPU::NoRegister;}
132 // SIMachineFunctionInfo definition
134 SIMachineFunctionInfo(const MachineFunction &MF);
135 SpilledReg getSpilledReg(MachineFunction *MF, unsigned FrameIndex,
137 bool hasCalculatedTID() const { return TIDReg != AMDGPU::NoRegister; };
138 unsigned getTIDReg() const { return TIDReg; };
139 void setTIDReg(unsigned Reg) { TIDReg = Reg; }
142 unsigned addPrivateSegmentBuffer(const SIRegisterInfo &TRI);
143 unsigned addDispatchPtr(const SIRegisterInfo &TRI);
144 unsigned addQueuePtr(const SIRegisterInfo &TRI);
145 unsigned addKernargSegmentPtr(const SIRegisterInfo &TRI);
146 unsigned addFlatScratchInit(const SIRegisterInfo &TRI);
149 unsigned addWorkGroupIDX() {
150 WorkGroupIDXSystemSGPR = getNextSystemSGPR();
152 return WorkGroupIDXSystemSGPR;
155 unsigned addWorkGroupIDY() {
156 WorkGroupIDYSystemSGPR = getNextSystemSGPR();
158 return WorkGroupIDYSystemSGPR;
161 unsigned addWorkGroupIDZ() {
162 WorkGroupIDZSystemSGPR = getNextSystemSGPR();
164 return WorkGroupIDZSystemSGPR;
167 unsigned addWorkGroupInfo() {
168 WorkGroupInfoSystemSGPR = getNextSystemSGPR();
170 return WorkGroupInfoSystemSGPR;
173 unsigned addPrivateSegmentWaveByteOffset() {
174 PrivateSegmentWaveByteOffsetSystemSGPR = getNextSystemSGPR();
176 return PrivateSegmentWaveByteOffsetSystemSGPR;
179 void setPrivateSegmentWaveByteOffset(unsigned Reg) {
180 PrivateSegmentWaveByteOffsetSystemSGPR = Reg;
183 bool hasPrivateSegmentBuffer() const {
184 return PrivateSegmentBuffer;
187 bool hasDispatchPtr() const {
191 bool hasQueuePtr() const {
195 bool hasDispatchID() const {
199 bool hasKernargSegmentPtr() const {
200 return KernargSegmentPtr;
203 bool hasFlatScratchInit() const {
204 return FlatScratchInit;
207 bool hasGridWorkgroupCountX() const {
208 return GridWorkgroupCountX;
211 bool hasGridWorkgroupCountY() const {
212 return GridWorkgroupCountY;
215 bool hasGridWorkgroupCountZ() const {
216 return GridWorkgroupCountZ;
219 bool hasWorkGroupIDX() const {
223 bool hasWorkGroupIDY() const {
227 bool hasWorkGroupIDZ() const {
231 bool hasWorkGroupInfo() const {
232 return WorkGroupInfo;
235 bool hasPrivateSegmentWaveByteOffset() const {
236 return PrivateSegmentWaveByteOffset;
239 bool hasWorkItemIDX() const {
243 bool hasWorkItemIDY() const {
247 bool hasWorkItemIDZ() const {
251 unsigned getNumUserSGPRs() const {
255 unsigned getNumPreloadedSGPRs() const {
256 return NumUserSGPRs + NumSystemSGPRs;
259 unsigned getPrivateSegmentWaveByteOffsetSystemSGPR() const {
260 return PrivateSegmentWaveByteOffsetSystemSGPR;
263 /// \brief Returns the physical register reserved for use as the resource
264 /// descriptor for scratch accesses.
265 unsigned getScratchRSrcReg() const {
266 return ScratchRSrcReg;
269 void setScratchRSrcReg(unsigned Reg) {
270 assert(Reg != AMDGPU::NoRegister && "Should never be unset");
271 ScratchRSrcReg = Reg;
274 unsigned getScratchWaveOffsetReg() const {
275 return ScratchWaveOffsetReg;
278 void setScratchWaveOffsetReg(unsigned Reg) {
279 assert(Reg != AMDGPU::NoRegister && "Should never be unset");
280 ScratchWaveOffsetReg = Reg;
283 unsigned getQueuePtrUserSGPR() const {
284 return QueuePtrUserSGPR;
287 bool hasSpilledSGPRs() const {
288 return HasSpilledSGPRs;
291 void setHasSpilledSGPRs(bool Spill = true) {
292 HasSpilledSGPRs = Spill;
295 bool hasSpilledVGPRs() const {
296 return HasSpilledVGPRs;
299 void setHasSpilledVGPRs(bool Spill = true) {
300 HasSpilledVGPRs = Spill;
303 bool hasNonSpillStackObjects() const {
304 return HasNonSpillStackObjects;
307 void setHasNonSpillStackObjects(bool StackObject = true) {
308 HasNonSpillStackObjects = StackObject;
311 bool hasFlatInstructions() const {
312 return HasFlatInstructions;
315 void setHasFlatInstructions(bool UseFlat = true) {
316 HasFlatInstructions = UseFlat;
319 unsigned getNumSpilledSGPRs() const {
320 return NumSpilledSGPRs;
323 unsigned getNumSpilledVGPRs() const {
324 return NumSpilledVGPRs;
327 void addToSpilledSGPRs(unsigned num) {
328 NumSpilledSGPRs += num;
331 void addToSpilledVGPRs(unsigned num) {
332 NumSpilledVGPRs += num;
335 unsigned getPSInputAddr() const {
339 bool isPSInputAllocated(unsigned Index) const {
340 return PSInputAddr & (1 << Index);
343 void markPSInputAllocated(unsigned Index) {
344 PSInputAddr |= 1 << Index;
347 bool returnsVoid() const {
351 void setIfReturnsVoid(bool Value) {
355 /// \returns Number of reserved VGPRs for debugger usage.
356 unsigned getDebuggerReservedVGPRCount() const {
357 return DebuggerReservedVGPRCount;
360 /// \returns Stack object index for \p Dim's work group ID.
361 int getDebuggerWorkGroupIDStackObjectIndex(unsigned Dim) const {
363 return DebuggerWorkGroupIDStackObjectIndices[Dim];
366 /// \brief Sets stack object index for \p Dim's work group ID to \p ObjectIdx.
367 void setDebuggerWorkGroupIDStackObjectIndex(unsigned Dim, int ObjectIdx) {
369 DebuggerWorkGroupIDStackObjectIndices[Dim] = ObjectIdx;
372 /// \returns Stack object index for \p Dim's work item ID.
373 int getDebuggerWorkItemIDStackObjectIndex(unsigned Dim) const {
375 return DebuggerWorkItemIDStackObjectIndices[Dim];
378 /// \brief Sets stack object index for \p Dim's work item ID to \p ObjectIdx.
379 void setDebuggerWorkItemIDStackObjectIndex(unsigned Dim, int ObjectIdx) {
381 DebuggerWorkItemIDStackObjectIndices[Dim] = ObjectIdx;
384 /// \returns SGPR used for \p Dim's work group ID.
385 unsigned getWorkGroupIDSGPR(unsigned Dim) const {
388 assert(hasWorkGroupIDX());
389 return WorkGroupIDXSystemSGPR;
391 assert(hasWorkGroupIDY());
392 return WorkGroupIDYSystemSGPR;
394 assert(hasWorkGroupIDZ());
395 return WorkGroupIDZSystemSGPR;
397 llvm_unreachable("unexpected dimension");
400 /// \returns VGPR used for \p Dim' work item ID.
401 unsigned getWorkItemIDVGPR(unsigned Dim) const {
404 assert(hasWorkItemIDX());
405 return AMDGPU::VGPR0;
407 assert(hasWorkItemIDY());
408 return AMDGPU::VGPR1;
410 assert(hasWorkItemIDZ());
411 return AMDGPU::VGPR2;
413 llvm_unreachable("unexpected dimension");
416 unsigned getMaximumWorkGroupSize(const MachineFunction &MF) const;
419 } // End namespace llvm