]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h
Merge libc++ r291274, and update the library Makefile.
[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 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;
99
100   // System SGPRs in allocation order.
101   unsigned WorkGroupIDXSystemSGPR;
102   unsigned WorkGroupIDYSystemSGPR;
103   unsigned WorkGroupIDZSystemSGPR;
104   unsigned WorkGroupInfoSystemSGPR;
105   unsigned PrivateSegmentWaveByteOffsetSystemSGPR;
106
107   // Graphics info.
108   unsigned PSInputAddr;
109   bool ReturnsVoid;
110
111   // A pair of default/requested minimum/maximum flat work group sizes.
112   // Minimum - first, maximum - second.
113   std::pair<unsigned, unsigned> FlatWorkGroupSizes;
114
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;
118
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;
123
124   AMDGPUBufferPseudoSourceValue BufferPSV;
125   AMDGPUImagePseudoSourceValue ImagePSV;
126
127 public:
128   // FIXME: Make private
129   unsigned LDSWaveSpillSize;
130   unsigned PSInputEna;
131   std::map<unsigned, unsigned> LaneVGPRs;
132   unsigned ScratchOffsetReg;
133   unsigned NumUserSGPRs;
134   unsigned NumSystemSGPRs;
135
136 private:
137   bool HasSpilledSGPRs;
138   bool HasSpilledVGPRs;
139   bool HasNonSpillStackObjects;
140
141   unsigned NumSpilledSGPRs;
142   unsigned NumSpilledVGPRs;
143
144   // Feature bits required for inputs passed in user SGPRs.
145   bool PrivateSegmentBuffer : 1;
146   bool DispatchPtr : 1;
147   bool QueuePtr : 1;
148   bool KernargSegmentPtr : 1;
149   bool DispatchID : 1;
150   bool FlatScratchInit : 1;
151   bool GridWorkgroupCountX : 1;
152   bool GridWorkgroupCountY : 1;
153   bool GridWorkgroupCountZ : 1;
154
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;
161
162   bool WorkItemIDX : 1; // Always initialized.
163   bool WorkItemIDY : 1;
164   bool WorkItemIDZ : 1;
165
166   MCPhysReg getNextUserSGPR() const {
167     assert(NumSystemSGPRs == 0 && "System SGPRs must be added after user SGPRs");
168     return AMDGPU::SGPR0 + NumUserSGPRs;
169   }
170
171   MCPhysReg getNextSystemSGPR() const {
172     return AMDGPU::SGPR0 + NumUserSGPRs + NumSystemSGPRs;
173   }
174
175 public:
176   struct SpilledReg {
177     unsigned VGPR;
178     int Lane;
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;}
183   };
184
185   // SIMachineFunctionInfo definition
186
187   SIMachineFunctionInfo(const MachineFunction &MF);
188   SpilledReg getSpilledReg(MachineFunction *MF, unsigned FrameIndex,
189                            unsigned SubIdx);
190   bool hasCalculatedTID() const { return TIDReg != AMDGPU::NoRegister; };
191   unsigned getTIDReg() const { return TIDReg; };
192   void setTIDReg(unsigned Reg) { TIDReg = Reg; }
193
194   // Add user SGPRs.
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);
201
202   // Add system SGPRs.
203   unsigned addWorkGroupIDX() {
204     WorkGroupIDXSystemSGPR = getNextSystemSGPR();
205     NumSystemSGPRs += 1;
206     return WorkGroupIDXSystemSGPR;
207   }
208
209   unsigned addWorkGroupIDY() {
210     WorkGroupIDYSystemSGPR = getNextSystemSGPR();
211     NumSystemSGPRs += 1;
212     return WorkGroupIDYSystemSGPR;
213   }
214
215   unsigned addWorkGroupIDZ() {
216     WorkGroupIDZSystemSGPR = getNextSystemSGPR();
217     NumSystemSGPRs += 1;
218     return WorkGroupIDZSystemSGPR;
219   }
220
221   unsigned addWorkGroupInfo() {
222     WorkGroupInfoSystemSGPR = getNextSystemSGPR();
223     NumSystemSGPRs += 1;
224     return WorkGroupInfoSystemSGPR;
225   }
226
227   unsigned addPrivateSegmentWaveByteOffset() {
228     PrivateSegmentWaveByteOffsetSystemSGPR = getNextSystemSGPR();
229     NumSystemSGPRs += 1;
230     return PrivateSegmentWaveByteOffsetSystemSGPR;
231   }
232
233   void setPrivateSegmentWaveByteOffset(unsigned Reg) {
234     PrivateSegmentWaveByteOffsetSystemSGPR = Reg;
235   }
236
237   bool hasPrivateSegmentBuffer() const {
238     return PrivateSegmentBuffer;
239   }
240
241   bool hasDispatchPtr() const {
242     return DispatchPtr;
243   }
244
245   bool hasQueuePtr() const {
246     return QueuePtr;
247   }
248
249   bool hasKernargSegmentPtr() const {
250     return KernargSegmentPtr;
251   }
252
253   bool hasDispatchID() const {
254     return DispatchID;
255   }
256
257   bool hasFlatScratchInit() const {
258     return FlatScratchInit;
259   }
260
261   bool hasGridWorkgroupCountX() const {
262     return GridWorkgroupCountX;
263   }
264
265   bool hasGridWorkgroupCountY() const {
266     return GridWorkgroupCountY;
267   }
268
269   bool hasGridWorkgroupCountZ() const {
270     return GridWorkgroupCountZ;
271   }
272
273   bool hasWorkGroupIDX() const {
274     return WorkGroupIDX;
275   }
276
277   bool hasWorkGroupIDY() const {
278     return WorkGroupIDY;
279   }
280
281   bool hasWorkGroupIDZ() const {
282     return WorkGroupIDZ;
283   }
284
285   bool hasWorkGroupInfo() const {
286     return WorkGroupInfo;
287   }
288
289   bool hasPrivateSegmentWaveByteOffset() const {
290     return PrivateSegmentWaveByteOffset;
291   }
292
293   bool hasWorkItemIDX() const {
294     return WorkItemIDX;
295   }
296
297   bool hasWorkItemIDY() const {
298     return WorkItemIDY;
299   }
300
301   bool hasWorkItemIDZ() const {
302     return WorkItemIDZ;
303   }
304
305   unsigned getNumUserSGPRs() const {
306     return NumUserSGPRs;
307   }
308
309   unsigned getNumPreloadedSGPRs() const {
310     return NumUserSGPRs + NumSystemSGPRs;
311   }
312
313   unsigned getPrivateSegmentWaveByteOffsetSystemSGPR() const {
314     return PrivateSegmentWaveByteOffsetSystemSGPR;
315   }
316
317   /// \brief Returns the physical register reserved for use as the resource
318   /// descriptor for scratch accesses.
319   unsigned getScratchRSrcReg() const {
320     return ScratchRSrcReg;
321   }
322
323   void setScratchRSrcReg(unsigned Reg) {
324     assert(Reg != AMDGPU::NoRegister && "Should never be unset");
325     ScratchRSrcReg = Reg;
326   }
327
328   unsigned getScratchWaveOffsetReg() const {
329     return ScratchWaveOffsetReg;
330   }
331
332   void setScratchWaveOffsetReg(unsigned Reg) {
333     assert(Reg != AMDGPU::NoRegister && "Should never be unset");
334     ScratchWaveOffsetReg = Reg;
335   }
336
337   unsigned getQueuePtrUserSGPR() const {
338     return QueuePtrUserSGPR;
339   }
340
341   bool hasSpilledSGPRs() const {
342     return HasSpilledSGPRs;
343   }
344
345   void setHasSpilledSGPRs(bool Spill = true) {
346     HasSpilledSGPRs = Spill;
347   }
348
349   bool hasSpilledVGPRs() const {
350     return HasSpilledVGPRs;
351   }
352
353   void setHasSpilledVGPRs(bool Spill = true) {
354     HasSpilledVGPRs = Spill;
355   }
356
357   bool hasNonSpillStackObjects() const {
358     return HasNonSpillStackObjects;
359   }
360
361   void setHasNonSpillStackObjects(bool StackObject = true) {
362     HasNonSpillStackObjects = StackObject;
363   }
364
365   unsigned getNumSpilledSGPRs() const {
366     return NumSpilledSGPRs;
367   }
368
369   unsigned getNumSpilledVGPRs() const {
370     return NumSpilledVGPRs;
371   }
372
373   void addToSpilledSGPRs(unsigned num) {
374     NumSpilledSGPRs += num;
375   }
376
377   void addToSpilledVGPRs(unsigned num) {
378     NumSpilledVGPRs += num;
379   }
380
381   unsigned getPSInputAddr() const {
382     return PSInputAddr;
383   }
384
385   bool isPSInputAllocated(unsigned Index) const {
386     return PSInputAddr & (1 << Index);
387   }
388
389   void markPSInputAllocated(unsigned Index) {
390     PSInputAddr |= 1 << Index;
391   }
392
393   bool returnsVoid() const {
394     return ReturnsVoid;
395   }
396
397   void setIfReturnsVoid(bool Value) {
398     ReturnsVoid = Value;
399   }
400
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;
405   }
406
407   /// \returns Default/requested minimum flat work group size for this function.
408   unsigned getMinFlatWorkGroupSize() const {
409     return FlatWorkGroupSizes.first;
410   }
411
412   /// \returns Default/requested maximum flat work group size for this function.
413   unsigned getMaxFlatWorkGroupSize() const {
414     return FlatWorkGroupSizes.second;
415   }
416
417   /// \returns A pair of default/requested minimum/maximum number of waves per
418   /// execution unit.
419   std::pair<unsigned, unsigned> getWavesPerEU() const {
420     return WavesPerEU;
421   }
422
423   /// \returns Default/requested minimum number of waves per execution unit.
424   unsigned getMinWavesPerEU() const {
425     return WavesPerEU.first;
426   }
427
428   /// \returns Default/requested maximum number of waves per execution unit.
429   unsigned getMaxWavesPerEU() const {
430     return WavesPerEU.second;
431   }
432
433   /// \returns Stack object index for \p Dim's work group ID.
434   int getDebuggerWorkGroupIDStackObjectIndex(unsigned Dim) const {
435     assert(Dim < 3);
436     return DebuggerWorkGroupIDStackObjectIndices[Dim];
437   }
438
439   /// \brief Sets stack object index for \p Dim's work group ID to \p ObjectIdx.
440   void setDebuggerWorkGroupIDStackObjectIndex(unsigned Dim, int ObjectIdx) {
441     assert(Dim < 3);
442     DebuggerWorkGroupIDStackObjectIndices[Dim] = ObjectIdx;
443   }
444
445   /// \returns Stack object index for \p Dim's work item ID.
446   int getDebuggerWorkItemIDStackObjectIndex(unsigned Dim) const {
447     assert(Dim < 3);
448     return DebuggerWorkItemIDStackObjectIndices[Dim];
449   }
450
451   /// \brief Sets stack object index for \p Dim's work item ID to \p ObjectIdx.
452   void setDebuggerWorkItemIDStackObjectIndex(unsigned Dim, int ObjectIdx) {
453     assert(Dim < 3);
454     DebuggerWorkItemIDStackObjectIndices[Dim] = ObjectIdx;
455   }
456
457   /// \returns SGPR used for \p Dim's work group ID.
458   unsigned getWorkGroupIDSGPR(unsigned Dim) const {
459     switch (Dim) {
460     case 0:
461       assert(hasWorkGroupIDX());
462       return WorkGroupIDXSystemSGPR;
463     case 1:
464       assert(hasWorkGroupIDY());
465       return WorkGroupIDYSystemSGPR;
466     case 2:
467       assert(hasWorkGroupIDZ());
468       return WorkGroupIDZSystemSGPR;
469     }
470     llvm_unreachable("unexpected dimension");
471   }
472
473   /// \returns VGPR used for \p Dim' work item ID.
474   unsigned getWorkItemIDVGPR(unsigned Dim) const {
475     switch (Dim) {
476     case 0:
477       assert(hasWorkItemIDX());
478       return AMDGPU::VGPR0;
479     case 1:
480       assert(hasWorkItemIDY());
481       return AMDGPU::VGPR1;
482     case 2:
483       assert(hasWorkItemIDZ());
484       return AMDGPU::VGPR2;
485     }
486     llvm_unreachable("unexpected dimension");
487   }
488
489   const AMDGPUBufferPseudoSourceValue *getBufferPSV() const {
490     return &BufferPSV;
491   }
492
493   const AMDGPUImagePseudoSourceValue *getImagePSV() const {
494     return &ImagePSV;
495   }
496 };
497
498 } // End namespace llvm
499
500 #endif