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 class AMDGPUImagePseudoSourceValue : public PseudoSourceValue {
28 explicit AMDGPUImagePseudoSourceValue() :
29 PseudoSourceValue(PseudoSourceValue::TargetCustom) { }
31 bool isConstant(const MachineFrameInfo *) const override {
32 // This should probably be true for most images, but we will start by being
37 bool isAliased(const MachineFrameInfo *) const override {
38 // FIXME: If we ever change image intrinsics to accept fat pointers, then
39 // this could be true for some cases.
43 bool mayAlias(const MachineFrameInfo*) const override {
44 // FIXME: If we ever change image intrinsics to accept fat pointers, then
45 // this could be true for some cases.
50 class AMDGPUBufferPseudoSourceValue : public PseudoSourceValue {
52 explicit AMDGPUBufferPseudoSourceValue() :
53 PseudoSourceValue(PseudoSourceValue::TargetCustom) { }
55 bool isConstant(const MachineFrameInfo *) const override {
56 // This should probably be true for most images, but we will start by being
61 bool isAliased(const MachineFrameInfo *) const override {
62 // FIXME: If we ever change image intrinsics to accept fat pointers, then
63 // this could be true for some cases.
67 bool mayAlias(const MachineFrameInfo*) const override {
68 // FIXME: If we ever change image intrinsics to accept fat pointers, then
69 // this could be true for some cases.
74 /// This class keeps track of the SPI_SP_INPUT_ADDR config register, which
75 /// tells the hardware which interpolation parameters to load.
76 class SIMachineFunctionInfo final : public AMDGPUMachineFunction {
77 // FIXME: This should be removed and getPreloadedValue moved here.
78 friend class SIRegisterInfo;
82 // Registers that may be reserved for spilling purposes. These may be the same
83 // as the input registers.
84 unsigned ScratchRSrcReg;
85 unsigned ScratchWaveOffsetReg;
87 // Input registers setup for the HSA ABI.
88 // User SGPRs in allocation order.
89 unsigned PrivateSegmentBufferUserSGPR;
90 unsigned DispatchPtrUserSGPR;
91 unsigned QueuePtrUserSGPR;
92 unsigned KernargSegmentPtrUserSGPR;
93 unsigned DispatchIDUserSGPR;
94 unsigned FlatScratchInitUserSGPR;
95 unsigned PrivateSegmentSizeUserSGPR;
96 unsigned GridWorkGroupCountXUserSGPR;
97 unsigned GridWorkGroupCountYUserSGPR;
98 unsigned GridWorkGroupCountZUserSGPR;
100 // System SGPRs in allocation order.
101 unsigned WorkGroupIDXSystemSGPR;
102 unsigned WorkGroupIDYSystemSGPR;
103 unsigned WorkGroupIDZSystemSGPR;
104 unsigned WorkGroupInfoSystemSGPR;
105 unsigned PrivateSegmentWaveByteOffsetSystemSGPR;
108 unsigned PSInputAddr;
111 // A pair of default/requested minimum/maximum flat work group sizes.
112 // Minimum - first, maximum - second.
113 std::pair<unsigned, unsigned> FlatWorkGroupSizes;
115 // A pair of default/requested minimum/maximum number of waves per execution
116 // unit. Minimum - first, maximum - second.
117 std::pair<unsigned, unsigned> WavesPerEU;
119 // Stack object indices for work group IDs.
120 std::array<int, 3> DebuggerWorkGroupIDStackObjectIndices;
121 // Stack object indices for work item IDs.
122 std::array<int, 3> DebuggerWorkItemIDStackObjectIndices;
124 AMDGPUBufferPseudoSourceValue BufferPSV;
125 AMDGPUImagePseudoSourceValue ImagePSV;
128 // FIXME: Make private
129 unsigned LDSWaveSpillSize;
131 std::map<unsigned, unsigned> LaneVGPRs;
132 unsigned ScratchOffsetReg;
133 unsigned NumUserSGPRs;
134 unsigned NumSystemSGPRs;
137 bool HasSpilledSGPRs;
138 bool HasSpilledVGPRs;
139 bool HasNonSpillStackObjects;
141 unsigned NumSpilledSGPRs;
142 unsigned NumSpilledVGPRs;
144 // Feature bits required for inputs passed in user SGPRs.
145 bool PrivateSegmentBuffer : 1;
146 bool DispatchPtr : 1;
148 bool KernargSegmentPtr : 1;
150 bool FlatScratchInit : 1;
151 bool GridWorkgroupCountX : 1;
152 bool GridWorkgroupCountY : 1;
153 bool GridWorkgroupCountZ : 1;
155 // Feature bits required for inputs passed in system SGPRs.
156 bool WorkGroupIDX : 1; // Always initialized.
157 bool WorkGroupIDY : 1;
158 bool WorkGroupIDZ : 1;
159 bool WorkGroupInfo : 1;
160 bool PrivateSegmentWaveByteOffset : 1;
162 bool WorkItemIDX : 1; // Always initialized.
163 bool WorkItemIDY : 1;
164 bool WorkItemIDZ : 1;
166 MCPhysReg getNextUserSGPR() const {
167 assert(NumSystemSGPRs == 0 && "System SGPRs must be added after user SGPRs");
168 return AMDGPU::SGPR0 + NumUserSGPRs;
171 MCPhysReg getNextSystemSGPR() const {
172 return AMDGPU::SGPR0 + NumUserSGPRs + NumSystemSGPRs;
179 SpilledReg(unsigned R, int L) : VGPR (R), Lane (L) { }
180 SpilledReg() : VGPR(AMDGPU::NoRegister), Lane(-1) { }
181 bool hasLane() { return Lane != -1;}
182 bool hasReg() { return VGPR != AMDGPU::NoRegister;}
185 // SIMachineFunctionInfo definition
187 SIMachineFunctionInfo(const MachineFunction &MF);
188 SpilledReg getSpilledReg(MachineFunction *MF, unsigned FrameIndex,
190 bool hasCalculatedTID() const { return TIDReg != AMDGPU::NoRegister; };
191 unsigned getTIDReg() const { return TIDReg; };
192 void setTIDReg(unsigned Reg) { TIDReg = Reg; }
195 unsigned addPrivateSegmentBuffer(const SIRegisterInfo &TRI);
196 unsigned addDispatchPtr(const SIRegisterInfo &TRI);
197 unsigned addQueuePtr(const SIRegisterInfo &TRI);
198 unsigned addKernargSegmentPtr(const SIRegisterInfo &TRI);
199 unsigned addDispatchID(const SIRegisterInfo &TRI);
200 unsigned addFlatScratchInit(const SIRegisterInfo &TRI);
203 unsigned addWorkGroupIDX() {
204 WorkGroupIDXSystemSGPR = getNextSystemSGPR();
206 return WorkGroupIDXSystemSGPR;
209 unsigned addWorkGroupIDY() {
210 WorkGroupIDYSystemSGPR = getNextSystemSGPR();
212 return WorkGroupIDYSystemSGPR;
215 unsigned addWorkGroupIDZ() {
216 WorkGroupIDZSystemSGPR = getNextSystemSGPR();
218 return WorkGroupIDZSystemSGPR;
221 unsigned addWorkGroupInfo() {
222 WorkGroupInfoSystemSGPR = getNextSystemSGPR();
224 return WorkGroupInfoSystemSGPR;
227 unsigned addPrivateSegmentWaveByteOffset() {
228 PrivateSegmentWaveByteOffsetSystemSGPR = getNextSystemSGPR();
230 return PrivateSegmentWaveByteOffsetSystemSGPR;
233 void setPrivateSegmentWaveByteOffset(unsigned Reg) {
234 PrivateSegmentWaveByteOffsetSystemSGPR = Reg;
237 bool hasPrivateSegmentBuffer() const {
238 return PrivateSegmentBuffer;
241 bool hasDispatchPtr() const {
245 bool hasQueuePtr() const {
249 bool hasKernargSegmentPtr() const {
250 return KernargSegmentPtr;
253 bool hasDispatchID() const {
257 bool hasFlatScratchInit() const {
258 return FlatScratchInit;
261 bool hasGridWorkgroupCountX() const {
262 return GridWorkgroupCountX;
265 bool hasGridWorkgroupCountY() const {
266 return GridWorkgroupCountY;
269 bool hasGridWorkgroupCountZ() const {
270 return GridWorkgroupCountZ;
273 bool hasWorkGroupIDX() const {
277 bool hasWorkGroupIDY() const {
281 bool hasWorkGroupIDZ() const {
285 bool hasWorkGroupInfo() const {
286 return WorkGroupInfo;
289 bool hasPrivateSegmentWaveByteOffset() const {
290 return PrivateSegmentWaveByteOffset;
293 bool hasWorkItemIDX() const {
297 bool hasWorkItemIDY() const {
301 bool hasWorkItemIDZ() const {
305 unsigned getNumUserSGPRs() const {
309 unsigned getNumPreloadedSGPRs() const {
310 return NumUserSGPRs + NumSystemSGPRs;
313 unsigned getPrivateSegmentWaveByteOffsetSystemSGPR() const {
314 return PrivateSegmentWaveByteOffsetSystemSGPR;
317 /// \brief Returns the physical register reserved for use as the resource
318 /// descriptor for scratch accesses.
319 unsigned getScratchRSrcReg() const {
320 return ScratchRSrcReg;
323 void setScratchRSrcReg(unsigned Reg) {
324 assert(Reg != AMDGPU::NoRegister && "Should never be unset");
325 ScratchRSrcReg = Reg;
328 unsigned getScratchWaveOffsetReg() const {
329 return ScratchWaveOffsetReg;
332 void setScratchWaveOffsetReg(unsigned Reg) {
333 assert(Reg != AMDGPU::NoRegister && "Should never be unset");
334 ScratchWaveOffsetReg = Reg;
337 unsigned getQueuePtrUserSGPR() const {
338 return QueuePtrUserSGPR;
341 bool hasSpilledSGPRs() const {
342 return HasSpilledSGPRs;
345 void setHasSpilledSGPRs(bool Spill = true) {
346 HasSpilledSGPRs = Spill;
349 bool hasSpilledVGPRs() const {
350 return HasSpilledVGPRs;
353 void setHasSpilledVGPRs(bool Spill = true) {
354 HasSpilledVGPRs = Spill;
357 bool hasNonSpillStackObjects() const {
358 return HasNonSpillStackObjects;
361 void setHasNonSpillStackObjects(bool StackObject = true) {
362 HasNonSpillStackObjects = StackObject;
365 unsigned getNumSpilledSGPRs() const {
366 return NumSpilledSGPRs;
369 unsigned getNumSpilledVGPRs() const {
370 return NumSpilledVGPRs;
373 void addToSpilledSGPRs(unsigned num) {
374 NumSpilledSGPRs += num;
377 void addToSpilledVGPRs(unsigned num) {
378 NumSpilledVGPRs += num;
381 unsigned getPSInputAddr() const {
385 bool isPSInputAllocated(unsigned Index) const {
386 return PSInputAddr & (1 << Index);
389 void markPSInputAllocated(unsigned Index) {
390 PSInputAddr |= 1 << Index;
393 bool returnsVoid() const {
397 void setIfReturnsVoid(bool Value) {
401 /// \returns A pair of default/requested minimum/maximum flat work group sizes
402 /// for this function.
403 std::pair<unsigned, unsigned> getFlatWorkGroupSizes() const {
404 return FlatWorkGroupSizes;
407 /// \returns Default/requested minimum flat work group size for this function.
408 unsigned getMinFlatWorkGroupSize() const {
409 return FlatWorkGroupSizes.first;
412 /// \returns Default/requested maximum flat work group size for this function.
413 unsigned getMaxFlatWorkGroupSize() const {
414 return FlatWorkGroupSizes.second;
417 /// \returns A pair of default/requested minimum/maximum number of waves per
419 std::pair<unsigned, unsigned> getWavesPerEU() const {
423 /// \returns Default/requested minimum number of waves per execution unit.
424 unsigned getMinWavesPerEU() const {
425 return WavesPerEU.first;
428 /// \returns Default/requested maximum number of waves per execution unit.
429 unsigned getMaxWavesPerEU() const {
430 return WavesPerEU.second;
433 /// \returns Stack object index for \p Dim's work group ID.
434 int getDebuggerWorkGroupIDStackObjectIndex(unsigned Dim) const {
436 return DebuggerWorkGroupIDStackObjectIndices[Dim];
439 /// \brief Sets stack object index for \p Dim's work group ID to \p ObjectIdx.
440 void setDebuggerWorkGroupIDStackObjectIndex(unsigned Dim, int ObjectIdx) {
442 DebuggerWorkGroupIDStackObjectIndices[Dim] = ObjectIdx;
445 /// \returns Stack object index for \p Dim's work item ID.
446 int getDebuggerWorkItemIDStackObjectIndex(unsigned Dim) const {
448 return DebuggerWorkItemIDStackObjectIndices[Dim];
451 /// \brief Sets stack object index for \p Dim's work item ID to \p ObjectIdx.
452 void setDebuggerWorkItemIDStackObjectIndex(unsigned Dim, int ObjectIdx) {
454 DebuggerWorkItemIDStackObjectIndices[Dim] = ObjectIdx;
457 /// \returns SGPR used for \p Dim's work group ID.
458 unsigned getWorkGroupIDSGPR(unsigned Dim) const {
461 assert(hasWorkGroupIDX());
462 return WorkGroupIDXSystemSGPR;
464 assert(hasWorkGroupIDY());
465 return WorkGroupIDYSystemSGPR;
467 assert(hasWorkGroupIDZ());
468 return WorkGroupIDZSystemSGPR;
470 llvm_unreachable("unexpected dimension");
473 /// \returns VGPR used for \p Dim' work item ID.
474 unsigned getWorkItemIDVGPR(unsigned Dim) const {
477 assert(hasWorkItemIDX());
478 return AMDGPU::VGPR0;
480 assert(hasWorkItemIDY());
481 return AMDGPU::VGPR1;
483 assert(hasWorkItemIDZ());
484 return AMDGPU::VGPR2;
486 llvm_unreachable("unexpected dimension");
489 const AMDGPUBufferPseudoSourceValue *getBufferPSV() const {
493 const AMDGPUImagePseudoSourceValue *getImagePSV() const {
498 } // End namespace llvm