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