LLVM  4.0.0
SIMachineFunctionInfo.h
Go to the documentation of this file.
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 
27 public:
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 
51 public:
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.
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 
129 
130 public:
131  // FIXME: Make private
133  unsigned PSInputEna;
134  std::map<unsigned, unsigned> LaneVGPRs;
136  unsigned NumUserSGPRs;
137  unsigned NumSystemSGPRs;
138 
139 private:
140  bool HasSpilledSGPRs;
141  bool HasSpilledVGPRs;
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;
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 
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 
237  PrivateSegmentWaveByteOffsetSystemSGPR = getNextSystemSGPR();
238  NumSystemSGPRs += 1;
239  return PrivateSegmentWaveByteOffsetSystemSGPR;
240  }
241 
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 
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 
315  return PrivateMemoryInputPtr;
316  }
317 
318  unsigned getNumUserSGPRs() const {
319  return NumUserSGPRs;
320  }
321 
322  unsigned getNumPreloadedSGPRs() const {
323  return NumUserSGPRs + NumSystemSGPRs;
324  }
325 
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:
479  return WorkGroupIDXSystemSGPR;
480  case 1:
482  return WorkGroupIDYSystemSGPR;
483  case 2:
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:
495  return AMDGPU::VGPR0;
496  case 1:
498  return AMDGPU::VGPR1;
499  case 2:
501  return AMDGPU::VGPR2;
502  }
503  llvm_unreachable("unexpected dimension");
504  }
505 
507  return &BufferPSV;
508  }
509 
511  return &ImagePSV;
512  }
513 };
514 
515 } // End namespace llvm
516 
517 #endif
MachineLoop * L
WorkItemIDZ(false)
Interface definition for SIRegisterInfo.
PrivateMemoryInputPtr(false)
int getDebuggerWorkGroupIDStackObjectIndex(unsigned Dim) const
HasSpilledVGPRs(false)
unsigned getPrivateSegmentWaveByteOffsetSystemSGPR() const
HasNonSpillStackObjects(false)
bool isAliased(const MachineFrameInfo *) const override
Test whether the memory pointed to by this PseudoSourceValue may also be pointed to by an LLVM IR Val...
FlatScratchInit(false)
unsigned addKernargSegmentPtr(const SIRegisterInfo &TRI)
GridWorkgroupCountZ(false)
unsigned getScratchWaveOffsetReg() const
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
unsigned addPrivateMemoryPtr(const SIRegisterInfo &TRI)
PrivateSegmentWaveByteOffset(false)
SIMachineFunctionInfo(const MachineFunction &MF)
const AMDGPUImagePseudoSourceValue * getImagePSV() const
NumSpilledSGPRs(0)
DispatchPtr(false)
unsigned getScratchRSrcReg() const
Returns the physical register reserved for use as the resource descriptor for scratch accesses...
unsigned getMinFlatWorkGroupSize() const
std::pair< unsigned, unsigned > getFlatWorkGroupSizes() const
unsigned getMaxFlatWorkGroupSize() const
void setPrivateSegmentWaveByteOffset(unsigned Reg)
void setDebuggerWorkGroupIDStackObjectIndex(unsigned Dim, int ObjectIdx)
Sets stack object index for Dim's work group ID to ObjectIdx.
const AMDGPUBufferPseudoSourceValue * getBufferPSV() const
void setHasNonSpillStackObjects(bool StackObject=true)
unsigned addDispatchID(const SIRegisterInfo &TRI)
void setDebuggerWorkItemIDStackObjectIndex(unsigned Dim, int ObjectIdx)
Sets stack object index for Dim's work item ID to ObjectIdx.
void setHasSpilledVGPRs(bool Spill=true)
Reg
All possible values of the reg field in the ModR/M byte.
WorkGroupInfo(false)
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
WorkGroupIDZ(false)
unsigned getWorkItemIDVGPR(unsigned Dim) const
WorkItemIDY(false)
int getDebuggerWorkItemIDStackObjectIndex(unsigned Dim) const
unsigned getWorkGroupIDSGPR(unsigned Dim) const
bool isConstant(const MachineFrameInfo *) const override
Test whether the memory pointed to by this PseudoSourceValue has a constant value.
QueuePtr(false)
WorkGroupIDY(false)
GridWorkgroupCountY(false)
void markPSInputAllocated(unsigned Index)
bool isPSInputAllocated(unsigned Index) const
GridWorkgroupCountX(false)
DebuggerWorkItemIDStackObjectIndices({{0, 0, 0}})
HasSpilledSGPRs(false)
unsigned addQueuePtr(const SIRegisterInfo &TRI)
unsigned getPrivateMemoryPtrUserSGPR() const
void setHasSpilledSGPRs(bool Spill=true)
void setScratchWaveOffsetReg(unsigned Reg)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned addDispatchPtr(const SIRegisterInfo &TRI)
bool isConstant(const MachineFrameInfo *) const override
Test whether the memory pointed to by this PseudoSourceValue has a constant value.
bool mayAlias(const MachineFrameInfo *) const override
Return true if the memory pointed to by this PseudoSourceValue can ever alias an LLVM IR Value...
SpilledReg getSpilledReg(MachineFunction *MF, unsigned FrameIndex, unsigned SubIdx)
std::map< unsigned, unsigned > LaneVGPRs
bool isAliased(const MachineFrameInfo *) const override
Test whether the memory pointed to by this PseudoSourceValue may also be pointed to by an LLVM IR Val...
Special value supplied for machine level alias analysis.
WorkGroupIDX(false)
unsigned addPrivateSegmentBuffer(const SIRegisterInfo &TRI)
unsigned addFlatScratchInit(const SIRegisterInfo &TRI)
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
std::pair< unsigned, unsigned > getWavesPerEU() const
KernargSegmentPtr(false)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
NumSpilledVGPRs(0)
LLVM Value Representation.
Definition: Value.h:71
bool mayAlias(const MachineFrameInfo *) const override
Return true if the memory pointed to by this PseudoSourceValue can ever alias an LLVM IR Value...
DispatchID(false)
PrivateSegmentBuffer(false)
WorkItemIDX(false)