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
15#ifndef LLVM_LIB_TARGET_R600_SIMACHINEFUNCTIONINFO_H
16#define LLVM_LIB_TARGET_R600_SIMACHINEFUNCTIONINFO_H
17
18#include "AMDGPUMachineFunction.h"
19#include "SIRegisterInfo.h"
20#include <map>
21
22namespace llvm {
23
24class MachineRegisterInfo;
25
26/// This class keeps track of the SPI_SP_INPUT_ADDR config register, which
27/// tells the hardware which interpolation parameters to load.
28class SIMachineFunctionInfo : public AMDGPUMachineFunction {
29  // FIXME: This should be removed and getPreloadedValue moved here.
30  friend struct SIRegisterInfo;
31  void anchor() override;
32
33  unsigned TIDReg;
34
35  // Registers that may be reserved for spilling purposes. These may be the same
36  // as the input registers.
37  unsigned ScratchRSrcReg;
38  unsigned ScratchWaveOffsetReg;
39
40  // Input registers setup for the HSA ABI.
41  // User SGPRs in allocation order.
42  unsigned PrivateSegmentBufferUserSGPR;
43  unsigned DispatchPtrUserSGPR;
44  unsigned QueuePtrUserSGPR;
45  unsigned KernargSegmentPtrUserSGPR;
46  unsigned DispatchIDUserSGPR;
47  unsigned FlatScratchInitUserSGPR;
48  unsigned PrivateSegmentSizeUserSGPR;
49  unsigned GridWorkGroupCountXUserSGPR;
50  unsigned GridWorkGroupCountYUserSGPR;
51  unsigned GridWorkGroupCountZUserSGPR;
52
53  // System SGPRs in allocation order.
54  unsigned WorkGroupIDXSystemSGPR;
55  unsigned WorkGroupIDYSystemSGPR;
56  unsigned WorkGroupIDZSystemSGPR;
57  unsigned WorkGroupInfoSystemSGPR;
58  unsigned PrivateSegmentWaveByteOffsetSystemSGPR;
59
60public:
61  // FIXME: Make private
62  unsigned LDSWaveSpillSize;
63  unsigned PSInputAddr;
64  std::map<unsigned, unsigned> LaneVGPRs;
65  unsigned ScratchOffsetReg;
66  unsigned NumUserSGPRs;
67  unsigned NumSystemSGPRs;
68
69private:
70  bool HasSpilledSGPRs;
71  bool HasSpilledVGPRs;
72
73  // Feature bits required for inputs passed in user SGPRs.
74  bool PrivateSegmentBuffer : 1;
75  bool DispatchPtr : 1;
76  bool QueuePtr : 1;
77  bool DispatchID : 1;
78  bool KernargSegmentPtr : 1;
79  bool FlatScratchInit : 1;
80  bool GridWorkgroupCountX : 1;
81  bool GridWorkgroupCountY : 1;
82  bool GridWorkgroupCountZ : 1;
83
84  // Feature bits required for inputs passed in system SGPRs.
85  bool WorkGroupIDX : 1; // Always initialized.
86  bool WorkGroupIDY : 1;
87  bool WorkGroupIDZ : 1;
88  bool WorkGroupInfo : 1;
89  bool PrivateSegmentWaveByteOffset : 1;
90
91  bool WorkItemIDX : 1; // Always initialized.
92  bool WorkItemIDY : 1;
93  bool WorkItemIDZ : 1;
94
95
96  MCPhysReg getNextUserSGPR() const {
97    assert(NumSystemSGPRs == 0 && "System SGPRs must be added after user SGPRs");
98    return AMDGPU::SGPR0 + NumUserSGPRs;
99  }
100
101  MCPhysReg getNextSystemSGPR() const {
102    return AMDGPU::SGPR0 + NumUserSGPRs + NumSystemSGPRs;
103  }
104
105public:
106  struct SpilledReg {
107    unsigned VGPR;
108    int Lane;
109    SpilledReg(unsigned R, int L) : VGPR (R), Lane (L) { }
110    SpilledReg() : VGPR(0), Lane(-1) { }
111    bool hasLane() { return Lane != -1;}
112  };
113
114  // SIMachineFunctionInfo definition
115
116  SIMachineFunctionInfo(const MachineFunction &MF);
117  SpilledReg getSpilledReg(MachineFunction *MF, unsigned FrameIndex,
118                           unsigned SubIdx);
119  bool hasCalculatedTID() const { return TIDReg != AMDGPU::NoRegister; };
120  unsigned getTIDReg() const { return TIDReg; };
121  void setTIDReg(unsigned Reg) { TIDReg = Reg; }
122
123  // Add user SGPRs.
124  unsigned addPrivateSegmentBuffer(const SIRegisterInfo &TRI);
125  unsigned addDispatchPtr(const SIRegisterInfo &TRI);
126  unsigned addQueuePtr(const SIRegisterInfo &TRI);
127  unsigned addKernargSegmentPtr(const SIRegisterInfo &TRI);
128
129  // Add system SGPRs.
130  unsigned addWorkGroupIDX() {
131    WorkGroupIDXSystemSGPR = getNextSystemSGPR();
132    NumSystemSGPRs += 1;
133    return WorkGroupIDXSystemSGPR;
134  }
135
136  unsigned addWorkGroupIDY() {
137    WorkGroupIDYSystemSGPR = getNextSystemSGPR();
138    NumSystemSGPRs += 1;
139    return WorkGroupIDYSystemSGPR;
140  }
141
142  unsigned addWorkGroupIDZ() {
143    WorkGroupIDZSystemSGPR = getNextSystemSGPR();
144    NumSystemSGPRs += 1;
145    return WorkGroupIDZSystemSGPR;
146  }
147
148  unsigned addWorkGroupInfo() {
149    WorkGroupInfoSystemSGPR = getNextSystemSGPR();
150    NumSystemSGPRs += 1;
151    return WorkGroupInfoSystemSGPR;
152  }
153
154  unsigned addPrivateSegmentWaveByteOffset() {
155    PrivateSegmentWaveByteOffsetSystemSGPR = getNextSystemSGPR();
156    NumSystemSGPRs += 1;
157    return PrivateSegmentWaveByteOffsetSystemSGPR;
158  }
159
160  bool hasPrivateSegmentBuffer() const {
161    return PrivateSegmentBuffer;
162  }
163
164  bool hasDispatchPtr() const {
165    return DispatchPtr;
166  }
167
168  bool hasQueuePtr() const {
169    return QueuePtr;
170  }
171
172  bool hasDispatchID() const {
173    return DispatchID;
174  }
175
176  bool hasKernargSegmentPtr() const {
177    return KernargSegmentPtr;
178  }
179
180  bool hasFlatScratchInit() const {
181    return FlatScratchInit;
182  }
183
184  bool hasGridWorkgroupCountX() const {
185    return GridWorkgroupCountX;
186  }
187
188  bool hasGridWorkgroupCountY() const {
189    return GridWorkgroupCountY;
190  }
191
192  bool hasGridWorkgroupCountZ() const {
193    return GridWorkgroupCountZ;
194  }
195
196  bool hasWorkGroupIDX() const {
197    return WorkGroupIDX;
198  }
199
200  bool hasWorkGroupIDY() const {
201    return WorkGroupIDY;
202  }
203
204  bool hasWorkGroupIDZ() const {
205    return WorkGroupIDZ;
206  }
207
208  bool hasWorkGroupInfo() const {
209    return WorkGroupInfo;
210  }
211
212  bool hasPrivateSegmentWaveByteOffset() const {
213    return PrivateSegmentWaveByteOffset;
214  }
215
216  bool hasWorkItemIDX() const {
217    return WorkItemIDX;
218  }
219
220  bool hasWorkItemIDY() const {
221    return WorkItemIDY;
222  }
223
224  bool hasWorkItemIDZ() const {
225    return WorkItemIDZ;
226  }
227
228  unsigned getNumUserSGPRs() const {
229    return NumUserSGPRs;
230  }
231
232  unsigned getNumPreloadedSGPRs() const {
233    return NumUserSGPRs + NumSystemSGPRs;
234  }
235
236  unsigned getPrivateSegmentWaveByteOffsetSystemSGPR() const {
237    return PrivateSegmentWaveByteOffsetSystemSGPR;
238  }
239
240  /// \brief Returns the physical register reserved for use as the resource
241  /// descriptor for scratch accesses.
242  unsigned getScratchRSrcReg() const {
243    return ScratchRSrcReg;
244  }
245
246  void setScratchRSrcReg(unsigned Reg) {
247    assert(Reg != AMDGPU::NoRegister && "Should never be unset");
248    ScratchRSrcReg = Reg;
249  }
250
251  unsigned getScratchWaveOffsetReg() const {
252    return ScratchWaveOffsetReg;
253  }
254
255  void setScratchWaveOffsetReg(unsigned Reg) {
256    assert(Reg != AMDGPU::NoRegister && "Should never be unset");
257    ScratchWaveOffsetReg = Reg;
258  }
259
260  bool hasSpilledSGPRs() const {
261    return HasSpilledSGPRs;
262  }
263
264  void setHasSpilledSGPRs(bool Spill = true) {
265    HasSpilledSGPRs = Spill;
266  }
267
268  bool hasSpilledVGPRs() const {
269    return HasSpilledVGPRs;
270  }
271
272  void setHasSpilledVGPRs(bool Spill = true) {
273    HasSpilledVGPRs = Spill;
274  }
275
276  unsigned getMaximumWorkGroupSize(const MachineFunction &MF) const;
277};
278
279} // End namespace llvm
280
281
282#endif
283