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 
22 namespace llvm {
23 
24 class 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.
28 class 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 
60 public:
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 
69 private:
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 
getNextUserSGPR()96   MCPhysReg getNextUserSGPR() const {
97     assert(NumSystemSGPRs == 0 && "System SGPRs must be added after user SGPRs");
98     return AMDGPU::SGPR0 + NumUserSGPRs;
99   }
100 
getNextSystemSGPR()101   MCPhysReg getNextSystemSGPR() const {
102     return AMDGPU::SGPR0 + NumUserSGPRs + NumSystemSGPRs;
103   }
104 
105 public:
106   struct SpilledReg {
107     unsigned VGPR;
108     int Lane;
SpilledRegSpilledReg109     SpilledReg(unsigned R, int L) : VGPR (R), Lane (L) { }
SpilledRegSpilledReg110     SpilledReg() : VGPR(0), Lane(-1) { }
hasLaneSpilledReg111     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);
hasCalculatedTID()119   bool hasCalculatedTID() const { return TIDReg != AMDGPU::NoRegister; };
getTIDReg()120   unsigned getTIDReg() const { return TIDReg; };
setTIDReg(unsigned Reg)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.
addWorkGroupIDX()130   unsigned addWorkGroupIDX() {
131     WorkGroupIDXSystemSGPR = getNextSystemSGPR();
132     NumSystemSGPRs += 1;
133     return WorkGroupIDXSystemSGPR;
134   }
135 
addWorkGroupIDY()136   unsigned addWorkGroupIDY() {
137     WorkGroupIDYSystemSGPR = getNextSystemSGPR();
138     NumSystemSGPRs += 1;
139     return WorkGroupIDYSystemSGPR;
140   }
141 
addWorkGroupIDZ()142   unsigned addWorkGroupIDZ() {
143     WorkGroupIDZSystemSGPR = getNextSystemSGPR();
144     NumSystemSGPRs += 1;
145     return WorkGroupIDZSystemSGPR;
146   }
147 
addWorkGroupInfo()148   unsigned addWorkGroupInfo() {
149     WorkGroupInfoSystemSGPR = getNextSystemSGPR();
150     NumSystemSGPRs += 1;
151     return WorkGroupInfoSystemSGPR;
152   }
153 
addPrivateSegmentWaveByteOffset()154   unsigned addPrivateSegmentWaveByteOffset() {
155     PrivateSegmentWaveByteOffsetSystemSGPR = getNextSystemSGPR();
156     NumSystemSGPRs += 1;
157     return PrivateSegmentWaveByteOffsetSystemSGPR;
158   }
159 
hasPrivateSegmentBuffer()160   bool hasPrivateSegmentBuffer() const {
161     return PrivateSegmentBuffer;
162   }
163 
hasDispatchPtr()164   bool hasDispatchPtr() const {
165     return DispatchPtr;
166   }
167 
hasQueuePtr()168   bool hasQueuePtr() const {
169     return QueuePtr;
170   }
171 
hasDispatchID()172   bool hasDispatchID() const {
173     return DispatchID;
174   }
175 
hasKernargSegmentPtr()176   bool hasKernargSegmentPtr() const {
177     return KernargSegmentPtr;
178   }
179 
hasFlatScratchInit()180   bool hasFlatScratchInit() const {
181     return FlatScratchInit;
182   }
183 
hasGridWorkgroupCountX()184   bool hasGridWorkgroupCountX() const {
185     return GridWorkgroupCountX;
186   }
187 
hasGridWorkgroupCountY()188   bool hasGridWorkgroupCountY() const {
189     return GridWorkgroupCountY;
190   }
191 
hasGridWorkgroupCountZ()192   bool hasGridWorkgroupCountZ() const {
193     return GridWorkgroupCountZ;
194   }
195 
hasWorkGroupIDX()196   bool hasWorkGroupIDX() const {
197     return WorkGroupIDX;
198   }
199 
hasWorkGroupIDY()200   bool hasWorkGroupIDY() const {
201     return WorkGroupIDY;
202   }
203 
hasWorkGroupIDZ()204   bool hasWorkGroupIDZ() const {
205     return WorkGroupIDZ;
206   }
207 
hasWorkGroupInfo()208   bool hasWorkGroupInfo() const {
209     return WorkGroupInfo;
210   }
211 
hasPrivateSegmentWaveByteOffset()212   bool hasPrivateSegmentWaveByteOffset() const {
213     return PrivateSegmentWaveByteOffset;
214   }
215 
hasWorkItemIDX()216   bool hasWorkItemIDX() const {
217     return WorkItemIDX;
218   }
219 
hasWorkItemIDY()220   bool hasWorkItemIDY() const {
221     return WorkItemIDY;
222   }
223 
hasWorkItemIDZ()224   bool hasWorkItemIDZ() const {
225     return WorkItemIDZ;
226   }
227 
getNumUserSGPRs()228   unsigned getNumUserSGPRs() const {
229     return NumUserSGPRs;
230   }
231 
getNumPreloadedSGPRs()232   unsigned getNumPreloadedSGPRs() const {
233     return NumUserSGPRs + NumSystemSGPRs;
234   }
235 
getPrivateSegmentWaveByteOffsetSystemSGPR()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.
getScratchRSrcReg()242   unsigned getScratchRSrcReg() const {
243     return ScratchRSrcReg;
244   }
245 
setScratchRSrcReg(unsigned Reg)246   void setScratchRSrcReg(unsigned Reg) {
247     assert(Reg != AMDGPU::NoRegister && "Should never be unset");
248     ScratchRSrcReg = Reg;
249   }
250 
getScratchWaveOffsetReg()251   unsigned getScratchWaveOffsetReg() const {
252     return ScratchWaveOffsetReg;
253   }
254 
setScratchWaveOffsetReg(unsigned Reg)255   void setScratchWaveOffsetReg(unsigned Reg) {
256     assert(Reg != AMDGPU::NoRegister && "Should never be unset");
257     ScratchWaveOffsetReg = Reg;
258   }
259 
hasSpilledSGPRs()260   bool hasSpilledSGPRs() const {
261     return HasSpilledSGPRs;
262   }
263 
264   void setHasSpilledSGPRs(bool Spill = true) {
265     HasSpilledSGPRs = Spill;
266   }
267 
hasSpilledVGPRs()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