]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h
Merge ^/head r314178 through r314269.
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / AMDGPU / SIMachineFunctionInfo.h
1 //===- SIMachineFunctionInfo.h - SIMachineFunctionInfo interface -*- C++ -*-==//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 /// \file
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_LIB_TARGET_AMDGPU_SIMACHINEFUNCTIONINFO_H
15 #define LLVM_LIB_TARGET_AMDGPU_SIMACHINEFUNCTIONINFO_H
16
17 #include "AMDGPUMachineFunction.h"
18 #include "SIRegisterInfo.h"
19 #include <array>
20 #include <map>
21
22 namespace llvm {
23
24 class MachineRegisterInfo;
25
26 class AMDGPUImagePseudoSourceValue : public PseudoSourceValue {
27 public:
28   explicit AMDGPUImagePseudoSourceValue() :
29     PseudoSourceValue(PseudoSourceValue::TargetCustom) { }
30
31   bool isConstant(const MachineFrameInfo *) const override {
32     // This should probably be true for most images, but we will start by being
33     // conservative.
34     return false;
35   }
36
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.
40     return false;
41   }
42
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.
46     return false;
47   }
48 };
49
50 class AMDGPUBufferPseudoSourceValue : public PseudoSourceValue {
51 public:
52   explicit AMDGPUBufferPseudoSourceValue() :
53     PseudoSourceValue(PseudoSourceValue::TargetCustom) { }
54
55   bool isConstant(const MachineFrameInfo *) const override {
56     // This should probably be true for most images, but we will start by being
57     // conservative.
58     return false;
59   }
60
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.
64     return false;
65   }
66
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.
70     return false;
71   }
72 };
73
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;
79
80   unsigned TIDReg;
81
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;
86
87   // Input registers for non-HSA ABI
88   unsigned PrivateMemoryPtrUserSGPR;
89
90   // Input registers setup for the HSA ABI.
91   // User SGPRs in allocation order.
92   unsigned PrivateSegmentBufferUserSGPR;
93   unsigned DispatchPtrUserSGPR;
94   unsigned QueuePtrUserSGPR;
95   unsigned KernargSegmentPtrUserSGPR;
96   unsigned DispatchIDUserSGPR;
97   unsigned FlatScratchInitUserSGPR;
98   unsigned PrivateSegmentSizeUserSGPR;
99   unsigned GridWorkGroupCountXUserSGPR;
100   unsigned GridWorkGroupCountYUserSGPR;
101   unsigned GridWorkGroupCountZUserSGPR;
102
103   // System SGPRs in allocation order.
104   unsigned WorkGroupIDXSystemSGPR;
105   unsigned WorkGroupIDYSystemSGPR;
106   unsigned WorkGroupIDZSystemSGPR;
107   unsigned WorkGroupInfoSystemSGPR;
108   unsigned PrivateSegmentWaveByteOffsetSystemSGPR;
109
110   // Graphics info.
111   unsigned PSInputAddr;
112   bool ReturnsVoid;
113
114   // A pair of default/requested minimum/maximum flat work group sizes.
115   // Minimum - first, maximum - second.
116   std::pair<unsigned, unsigned> FlatWorkGroupSizes;
117
118   // A pair of default/requested minimum/maximum number of waves per execution
119   // unit. Minimum - first, maximum - second.
120   std::pair<unsigned, unsigned> WavesPerEU;
121
122   // Stack object indices for work group IDs.
123   std::array<int, 3> DebuggerWorkGroupIDStackObjectIndices;
124   // Stack object indices for work item IDs.
125   std::array<int, 3> DebuggerWorkItemIDStackObjectIndices;
126
127   AMDGPUBufferPseudoSourceValue BufferPSV;
128   AMDGPUImagePseudoSourceValue ImagePSV;
129
130 public:
131   // FIXME: Make private
132   unsigned LDSWaveSpillSize;
133   unsigned PSInputEna;
134   std::map<unsigned, unsigned> LaneVGPRs;
135   unsigned ScratchOffsetReg;
136   unsigned NumUserSGPRs;
137   unsigned NumSystemSGPRs;
138
139 private:
140   bool HasSpilledSGPRs;
141   bool HasSpilledVGPRs;
142   bool HasNonSpillStackObjects;
143
144   unsigned NumSpilledSGPRs;
145   unsigned NumSpilledVGPRs;
146
147   // Feature bits required for inputs passed in user SGPRs.
148   bool PrivateSegmentBuffer : 1;
149   bool DispatchPtr : 1;
150   bool QueuePtr : 1;
151   bool KernargSegmentPtr : 1;
152   bool DispatchID : 1;
153   bool FlatScratchInit : 1;
154   bool GridWorkgroupCountX : 1;
155   bool GridWorkgroupCountY : 1;
156   bool GridWorkgroupCountZ : 1;
157
158   // Feature bits required for inputs passed in system SGPRs.
159   bool WorkGroupIDX : 1; // Always initialized.
160   bool WorkGroupIDY : 1;
161   bool WorkGroupIDZ : 1;
162   bool WorkGroupInfo : 1;
163   bool PrivateSegmentWaveByteOffset : 1;
164
165   bool WorkItemIDX : 1; // Always initialized.
166   bool WorkItemIDY : 1;
167   bool WorkItemIDZ : 1;
168
169   // Private memory buffer
170   // Compute directly in sgpr[0:1]
171   // Other shaders indirect 64-bits at sgpr[0:1]
172   bool PrivateMemoryInputPtr : 1;
173
174   MCPhysReg getNextUserSGPR() const {
175     assert(NumSystemSGPRs == 0 && "System SGPRs must be added after user SGPRs");
176     return AMDGPU::SGPR0 + NumUserSGPRs;
177   }
178
179   MCPhysReg getNextSystemSGPR() const {
180     return AMDGPU::SGPR0 + NumUserSGPRs + NumSystemSGPRs;
181   }
182
183 public:
184   struct SpilledReg {
185     unsigned VGPR;
186     int Lane;
187     SpilledReg(unsigned R, int L) : VGPR (R), Lane (L) { }
188     SpilledReg() : VGPR(AMDGPU::NoRegister), Lane(-1) { }
189     bool hasLane() { return Lane != -1;}
190     bool hasReg() { return VGPR != AMDGPU::NoRegister;}
191   };
192
193   // SIMachineFunctionInfo definition
194
195   SIMachineFunctionInfo(const MachineFunction &MF);
196   SpilledReg getSpilledReg(MachineFunction *MF, unsigned FrameIndex,
197                            unsigned SubIdx);
198   bool hasCalculatedTID() const { return TIDReg != AMDGPU::NoRegister; };
199   unsigned getTIDReg() const { return TIDReg; };
200   void setTIDReg(unsigned Reg) { TIDReg = Reg; }
201
202   // Add user SGPRs.
203   unsigned addPrivateSegmentBuffer(const SIRegisterInfo &TRI);
204   unsigned addDispatchPtr(const SIRegisterInfo &TRI);
205   unsigned addQueuePtr(const SIRegisterInfo &TRI);
206   unsigned addKernargSegmentPtr(const SIRegisterInfo &TRI);
207   unsigned addDispatchID(const SIRegisterInfo &TRI);
208   unsigned addFlatScratchInit(const SIRegisterInfo &TRI);
209   unsigned addPrivateMemoryPtr(const SIRegisterInfo &TRI);
210
211   // Add system SGPRs.
212   unsigned addWorkGroupIDX() {
213     WorkGroupIDXSystemSGPR = getNextSystemSGPR();
214     NumSystemSGPRs += 1;
215     return WorkGroupIDXSystemSGPR;
216   }
217
218   unsigned addWorkGroupIDY() {
219     WorkGroupIDYSystemSGPR = getNextSystemSGPR();
220     NumSystemSGPRs += 1;
221     return WorkGroupIDYSystemSGPR;
222   }
223
224   unsigned addWorkGroupIDZ() {
225     WorkGroupIDZSystemSGPR = getNextSystemSGPR();
226     NumSystemSGPRs += 1;
227     return WorkGroupIDZSystemSGPR;
228   }
229
230   unsigned addWorkGroupInfo() {
231     WorkGroupInfoSystemSGPR = getNextSystemSGPR();
232     NumSystemSGPRs += 1;
233     return WorkGroupInfoSystemSGPR;
234   }
235
236   unsigned addPrivateSegmentWaveByteOffset() {
237     PrivateSegmentWaveByteOffsetSystemSGPR = getNextSystemSGPR();
238     NumSystemSGPRs += 1;
239     return PrivateSegmentWaveByteOffsetSystemSGPR;
240   }
241
242   void setPrivateSegmentWaveByteOffset(unsigned Reg) {
243     PrivateSegmentWaveByteOffsetSystemSGPR = Reg;
244   }
245
246   bool hasPrivateSegmentBuffer() const {
247     return PrivateSegmentBuffer;
248   }
249
250   bool hasDispatchPtr() const {
251     return DispatchPtr;
252   }
253
254   bool hasQueuePtr() const {
255     return QueuePtr;
256   }
257
258   bool hasKernargSegmentPtr() const {
259     return KernargSegmentPtr;
260   }
261
262   bool hasDispatchID() const {
263     return DispatchID;
264   }
265
266   bool hasFlatScratchInit() const {
267     return FlatScratchInit;
268   }
269
270   bool hasGridWorkgroupCountX() const {
271     return GridWorkgroupCountX;
272   }
273
274   bool hasGridWorkgroupCountY() const {
275     return GridWorkgroupCountY;
276   }
277
278   bool hasGridWorkgroupCountZ() const {
279     return GridWorkgroupCountZ;
280   }
281
282   bool hasWorkGroupIDX() const {
283     return WorkGroupIDX;
284   }
285
286   bool hasWorkGroupIDY() const {
287     return WorkGroupIDY;
288   }
289
290   bool hasWorkGroupIDZ() const {
291     return WorkGroupIDZ;
292   }
293
294   bool hasWorkGroupInfo() const {
295     return WorkGroupInfo;
296   }
297
298   bool hasPrivateSegmentWaveByteOffset() const {
299     return PrivateSegmentWaveByteOffset;
300   }
301
302   bool hasWorkItemIDX() const {
303     return WorkItemIDX;
304   }
305
306   bool hasWorkItemIDY() const {
307     return WorkItemIDY;
308   }
309
310   bool hasWorkItemIDZ() const {
311     return WorkItemIDZ;
312   }
313
314   bool hasPrivateMemoryInputPtr() const {
315     return PrivateMemoryInputPtr;
316   }
317
318   unsigned getNumUserSGPRs() const {
319     return NumUserSGPRs;
320   }
321
322   unsigned getNumPreloadedSGPRs() const {
323     return NumUserSGPRs + NumSystemSGPRs;
324   }
325
326   unsigned getPrivateSegmentWaveByteOffsetSystemSGPR() const {
327     return PrivateSegmentWaveByteOffsetSystemSGPR;
328   }
329
330   /// \brief Returns the physical register reserved for use as the resource
331   /// descriptor for scratch accesses.
332   unsigned getScratchRSrcReg() const {
333     return ScratchRSrcReg;
334   }
335
336   void setScratchRSrcReg(unsigned Reg) {
337     assert(Reg != AMDGPU::NoRegister && "Should never be unset");
338     ScratchRSrcReg = Reg;
339   }
340
341   unsigned getScratchWaveOffsetReg() const {
342     return ScratchWaveOffsetReg;
343   }
344
345   void setScratchWaveOffsetReg(unsigned Reg) {
346     assert(Reg != AMDGPU::NoRegister && "Should never be unset");
347     ScratchWaveOffsetReg = Reg;
348   }
349
350   unsigned getQueuePtrUserSGPR() const {
351     return QueuePtrUserSGPR;
352   }
353
354   unsigned getPrivateMemoryPtrUserSGPR() const {
355     return PrivateMemoryPtrUserSGPR;
356   }
357
358   bool hasSpilledSGPRs() const {
359     return HasSpilledSGPRs;
360   }
361
362   void setHasSpilledSGPRs(bool Spill = true) {
363     HasSpilledSGPRs = Spill;
364   }
365
366   bool hasSpilledVGPRs() const {
367     return HasSpilledVGPRs;
368   }
369
370   void setHasSpilledVGPRs(bool Spill = true) {
371     HasSpilledVGPRs = Spill;
372   }
373
374   bool hasNonSpillStackObjects() const {
375     return HasNonSpillStackObjects;
376   }
377
378   void setHasNonSpillStackObjects(bool StackObject = true) {
379     HasNonSpillStackObjects = StackObject;
380   }
381
382   unsigned getNumSpilledSGPRs() const {
383     return NumSpilledSGPRs;
384   }
385
386   unsigned getNumSpilledVGPRs() const {
387     return NumSpilledVGPRs;
388   }
389
390   void addToSpilledSGPRs(unsigned num) {
391     NumSpilledSGPRs += num;
392   }
393
394   void addToSpilledVGPRs(unsigned num) {
395     NumSpilledVGPRs += num;
396   }
397
398   unsigned getPSInputAddr() const {
399     return PSInputAddr;
400   }
401
402   bool isPSInputAllocated(unsigned Index) const {
403     return PSInputAddr & (1 << Index);
404   }
405
406   void markPSInputAllocated(unsigned Index) {
407     PSInputAddr |= 1 << Index;
408   }
409
410   bool returnsVoid() const {
411     return ReturnsVoid;
412   }
413
414   void setIfReturnsVoid(bool Value) {
415     ReturnsVoid = Value;
416   }
417
418   /// \returns A pair of default/requested minimum/maximum flat work group sizes
419   /// for this function.
420   std::pair<unsigned, unsigned> getFlatWorkGroupSizes() const {
421     return FlatWorkGroupSizes;
422   }
423
424   /// \returns Default/requested minimum flat work group size for this function.
425   unsigned getMinFlatWorkGroupSize() const {
426     return FlatWorkGroupSizes.first;
427   }
428
429   /// \returns Default/requested maximum flat work group size for this function.
430   unsigned getMaxFlatWorkGroupSize() const {
431     return FlatWorkGroupSizes.second;
432   }
433
434   /// \returns A pair of default/requested minimum/maximum number of waves per
435   /// execution unit.
436   std::pair<unsigned, unsigned> getWavesPerEU() const {
437     return WavesPerEU;
438   }
439
440   /// \returns Default/requested minimum number of waves per execution unit.
441   unsigned getMinWavesPerEU() const {
442     return WavesPerEU.first;
443   }
444
445   /// \returns Default/requested maximum number of waves per execution unit.
446   unsigned getMaxWavesPerEU() const {
447     return WavesPerEU.second;
448   }
449
450   /// \returns Stack object index for \p Dim's work group ID.
451   int getDebuggerWorkGroupIDStackObjectIndex(unsigned Dim) const {
452     assert(Dim < 3);
453     return DebuggerWorkGroupIDStackObjectIndices[Dim];
454   }
455
456   /// \brief Sets stack object index for \p Dim's work group ID to \p ObjectIdx.
457   void setDebuggerWorkGroupIDStackObjectIndex(unsigned Dim, int ObjectIdx) {
458     assert(Dim < 3);
459     DebuggerWorkGroupIDStackObjectIndices[Dim] = ObjectIdx;
460   }
461
462   /// \returns Stack object index for \p Dim's work item ID.
463   int getDebuggerWorkItemIDStackObjectIndex(unsigned Dim) const {
464     assert(Dim < 3);
465     return DebuggerWorkItemIDStackObjectIndices[Dim];
466   }
467
468   /// \brief Sets stack object index for \p Dim's work item ID to \p ObjectIdx.
469   void setDebuggerWorkItemIDStackObjectIndex(unsigned Dim, int ObjectIdx) {
470     assert(Dim < 3);
471     DebuggerWorkItemIDStackObjectIndices[Dim] = ObjectIdx;
472   }
473
474   /// \returns SGPR used for \p Dim's work group ID.
475   unsigned getWorkGroupIDSGPR(unsigned Dim) const {
476     switch (Dim) {
477     case 0:
478       assert(hasWorkGroupIDX());
479       return WorkGroupIDXSystemSGPR;
480     case 1:
481       assert(hasWorkGroupIDY());
482       return WorkGroupIDYSystemSGPR;
483     case 2:
484       assert(hasWorkGroupIDZ());
485       return WorkGroupIDZSystemSGPR;
486     }
487     llvm_unreachable("unexpected dimension");
488   }
489
490   /// \returns VGPR used for \p Dim' work item ID.
491   unsigned getWorkItemIDVGPR(unsigned Dim) const {
492     switch (Dim) {
493     case 0:
494       assert(hasWorkItemIDX());
495       return AMDGPU::VGPR0;
496     case 1:
497       assert(hasWorkItemIDY());
498       return AMDGPU::VGPR1;
499     case 2:
500       assert(hasWorkItemIDZ());
501       return AMDGPU::VGPR2;
502     }
503     llvm_unreachable("unexpected dimension");
504   }
505
506   const AMDGPUBufferPseudoSourceValue *getBufferPSV() const {
507     return &BufferPSV;
508   }
509
510   const AMDGPUImagePseudoSourceValue *getImagePSV() const {
511     return &ImagePSV;
512   }
513 };
514
515 } // End namespace llvm
516
517 #endif