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 /// 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 final : public AMDGPUMachineFunction { 29 // FIXME: This should be removed and getPreloadedValue moved here. 30 friend class SIRegisterInfo; 31 32 unsigned TIDReg; 33 34 // Registers that may be reserved for spilling purposes. These may be the same 35 // as the input registers. 36 unsigned ScratchRSrcReg; 37 unsigned ScratchWaveOffsetReg; 38 39 // Input registers setup for the HSA ABI. 40 // User SGPRs in allocation order. 41 unsigned PrivateSegmentBufferUserSGPR; 42 unsigned DispatchPtrUserSGPR; 43 unsigned QueuePtrUserSGPR; 44 unsigned KernargSegmentPtrUserSGPR; 45 unsigned DispatchIDUserSGPR; 46 unsigned FlatScratchInitUserSGPR; 47 unsigned PrivateSegmentSizeUserSGPR; 48 unsigned GridWorkGroupCountXUserSGPR; 49 unsigned GridWorkGroupCountYUserSGPR; 50 unsigned GridWorkGroupCountZUserSGPR; 51 52 // System SGPRs in allocation order. 53 unsigned WorkGroupIDXSystemSGPR; 54 unsigned WorkGroupIDYSystemSGPR; 55 unsigned WorkGroupIDZSystemSGPR; 56 unsigned WorkGroupInfoSystemSGPR; 57 unsigned PrivateSegmentWaveByteOffsetSystemSGPR; 58 59 // Graphics info. 60 unsigned PSInputAddr; 61 bool ReturnsVoid; 62 63 // A pair of default/requested minimum/maximum flat work group sizes. 64 // Minimum - first, maximum - second. 65 std::pair<unsigned, unsigned> FlatWorkGroupSizes; 66 67 // A pair of default/requested minimum/maximum number of waves per execution 68 // unit. Minimum - first, maximum - second. 69 std::pair<unsigned, unsigned> WavesPerEU; 70 71 // Stack object indices for work group IDs. 72 std::array<int, 3> DebuggerWorkGroupIDStackObjectIndices; 73 // Stack object indices for work item IDs. 74 std::array<int, 3> DebuggerWorkItemIDStackObjectIndices; 75 76 public: 77 // FIXME: Make private 78 unsigned LDSWaveSpillSize; 79 unsigned PSInputEna; 80 std::map<unsigned, unsigned> LaneVGPRs; 81 unsigned ScratchOffsetReg; 82 unsigned NumUserSGPRs; 83 unsigned NumSystemSGPRs; 84 85 private: 86 bool HasSpilledSGPRs; 87 bool HasSpilledVGPRs; 88 bool HasNonSpillStackObjects; 89 90 unsigned NumSpilledSGPRs; 91 unsigned NumSpilledVGPRs; 92 93 // Feature bits required for inputs passed in user SGPRs. 94 bool PrivateSegmentBuffer : 1; 95 bool DispatchPtr : 1; 96 bool QueuePtr : 1; 97 bool KernargSegmentPtr : 1; 98 bool DispatchID : 1; 99 bool FlatScratchInit : 1; 100 bool GridWorkgroupCountX : 1; 101 bool GridWorkgroupCountY : 1; 102 bool GridWorkgroupCountZ : 1; 103 104 // Feature bits required for inputs passed in system SGPRs. 105 bool WorkGroupIDX : 1; // Always initialized. 106 bool WorkGroupIDY : 1; 107 bool WorkGroupIDZ : 1; 108 bool WorkGroupInfo : 1; 109 bool PrivateSegmentWaveByteOffset : 1; 110 111 bool WorkItemIDX : 1; // Always initialized. 112 bool WorkItemIDY : 1; 113 bool WorkItemIDZ : 1; 114 115 MCPhysReg getNextUserSGPR() const { 116 assert(NumSystemSGPRs == 0 && "System SGPRs must be added after user SGPRs"); 117 return AMDGPU::SGPR0 + NumUserSGPRs; 118 } 119 120 MCPhysReg getNextSystemSGPR() const { 121 return AMDGPU::SGPR0 + NumUserSGPRs + NumSystemSGPRs; 122 } 123 124 public: 125 struct SpilledReg { 126 unsigned VGPR; 127 int Lane; 128 SpilledReg(unsigned R, int L) : VGPR (R), Lane (L) { } 129 SpilledReg() : VGPR(AMDGPU::NoRegister), Lane(-1) { } 130 bool hasLane() { return Lane != -1;} 131 bool hasReg() { return VGPR != AMDGPU::NoRegister;} 132 }; 133 134 // SIMachineFunctionInfo definition 135 136 SIMachineFunctionInfo(const MachineFunction &MF); 137 SpilledReg getSpilledReg(MachineFunction *MF, unsigned FrameIndex, 138 unsigned SubIdx); 139 bool hasCalculatedTID() const { return TIDReg != AMDGPU::NoRegister; }; 140 unsigned getTIDReg() const { return TIDReg; }; 141 void setTIDReg(unsigned Reg) { TIDReg = Reg; } 142 143 // Add user SGPRs. 144 unsigned addPrivateSegmentBuffer(const SIRegisterInfo &TRI); 145 unsigned addDispatchPtr(const SIRegisterInfo &TRI); 146 unsigned addQueuePtr(const SIRegisterInfo &TRI); 147 unsigned addKernargSegmentPtr(const SIRegisterInfo &TRI); 148 unsigned addDispatchID(const SIRegisterInfo &TRI); 149 unsigned addFlatScratchInit(const SIRegisterInfo &TRI); 150 151 // Add system SGPRs. 152 unsigned addWorkGroupIDX() { 153 WorkGroupIDXSystemSGPR = getNextSystemSGPR(); 154 NumSystemSGPRs += 1; 155 return WorkGroupIDXSystemSGPR; 156 } 157 158 unsigned addWorkGroupIDY() { 159 WorkGroupIDYSystemSGPR = getNextSystemSGPR(); 160 NumSystemSGPRs += 1; 161 return WorkGroupIDYSystemSGPR; 162 } 163 164 unsigned addWorkGroupIDZ() { 165 WorkGroupIDZSystemSGPR = getNextSystemSGPR(); 166 NumSystemSGPRs += 1; 167 return WorkGroupIDZSystemSGPR; 168 } 169 170 unsigned addWorkGroupInfo() { 171 WorkGroupInfoSystemSGPR = getNextSystemSGPR(); 172 NumSystemSGPRs += 1; 173 return WorkGroupInfoSystemSGPR; 174 } 175 176 unsigned addPrivateSegmentWaveByteOffset() { 177 PrivateSegmentWaveByteOffsetSystemSGPR = getNextSystemSGPR(); 178 NumSystemSGPRs += 1; 179 return PrivateSegmentWaveByteOffsetSystemSGPR; 180 } 181 182 void setPrivateSegmentWaveByteOffset(unsigned Reg) { 183 PrivateSegmentWaveByteOffsetSystemSGPR = Reg; 184 } 185 186 bool hasPrivateSegmentBuffer() const { 187 return PrivateSegmentBuffer; 188 } 189 190 bool hasDispatchPtr() const { 191 return DispatchPtr; 192 } 193 194 bool hasQueuePtr() const { 195 return QueuePtr; 196 } 197 198 bool hasKernargSegmentPtr() const { 199 return KernargSegmentPtr; 200 } 201 202 bool hasDispatchID() const { 203 return DispatchID; 204 } 205 206 bool hasFlatScratchInit() const { 207 return FlatScratchInit; 208 } 209 210 bool hasGridWorkgroupCountX() const { 211 return GridWorkgroupCountX; 212 } 213 214 bool hasGridWorkgroupCountY() const { 215 return GridWorkgroupCountY; 216 } 217 218 bool hasGridWorkgroupCountZ() const { 219 return GridWorkgroupCountZ; 220 } 221 222 bool hasWorkGroupIDX() const { 223 return WorkGroupIDX; 224 } 225 226 bool hasWorkGroupIDY() const { 227 return WorkGroupIDY; 228 } 229 230 bool hasWorkGroupIDZ() const { 231 return WorkGroupIDZ; 232 } 233 234 bool hasWorkGroupInfo() const { 235 return WorkGroupInfo; 236 } 237 238 bool hasPrivateSegmentWaveByteOffset() const { 239 return PrivateSegmentWaveByteOffset; 240 } 241 242 bool hasWorkItemIDX() const { 243 return WorkItemIDX; 244 } 245 246 bool hasWorkItemIDY() const { 247 return WorkItemIDY; 248 } 249 250 bool hasWorkItemIDZ() const { 251 return WorkItemIDZ; 252 } 253 254 unsigned getNumUserSGPRs() const { 255 return NumUserSGPRs; 256 } 257 258 unsigned getNumPreloadedSGPRs() const { 259 return NumUserSGPRs + NumSystemSGPRs; 260 } 261 262 unsigned getPrivateSegmentWaveByteOffsetSystemSGPR() const { 263 return PrivateSegmentWaveByteOffsetSystemSGPR; 264 } 265 266 /// \brief Returns the physical register reserved for use as the resource 267 /// descriptor for scratch accesses. 268 unsigned getScratchRSrcReg() const { 269 return ScratchRSrcReg; 270 } 271 272 void setScratchRSrcReg(unsigned Reg) { 273 assert(Reg != AMDGPU::NoRegister && "Should never be unset"); 274 ScratchRSrcReg = Reg; 275 } 276 277 unsigned getScratchWaveOffsetReg() const { 278 return ScratchWaveOffsetReg; 279 } 280 281 void setScratchWaveOffsetReg(unsigned Reg) { 282 assert(Reg != AMDGPU::NoRegister && "Should never be unset"); 283 ScratchWaveOffsetReg = Reg; 284 } 285 286 unsigned getQueuePtrUserSGPR() const { 287 return QueuePtrUserSGPR; 288 } 289 290 bool hasSpilledSGPRs() const { 291 return HasSpilledSGPRs; 292 } 293 294 void setHasSpilledSGPRs(bool Spill = true) { 295 HasSpilledSGPRs = Spill; 296 } 297 298 bool hasSpilledVGPRs() const { 299 return HasSpilledVGPRs; 300 } 301 302 void setHasSpilledVGPRs(bool Spill = true) { 303 HasSpilledVGPRs = Spill; 304 } 305 306 bool hasNonSpillStackObjects() const { 307 return HasNonSpillStackObjects; 308 } 309 310 void setHasNonSpillStackObjects(bool StackObject = true) { 311 HasNonSpillStackObjects = StackObject; 312 } 313 314 unsigned getNumSpilledSGPRs() const { 315 return NumSpilledSGPRs; 316 } 317 318 unsigned getNumSpilledVGPRs() const { 319 return NumSpilledVGPRs; 320 } 321 322 void addToSpilledSGPRs(unsigned num) { 323 NumSpilledSGPRs += num; 324 } 325 326 void addToSpilledVGPRs(unsigned num) { 327 NumSpilledVGPRs += num; 328 } 329 330 unsigned getPSInputAddr() const { 331 return PSInputAddr; 332 } 333 334 bool isPSInputAllocated(unsigned Index) const { 335 return PSInputAddr & (1 << Index); 336 } 337 338 void markPSInputAllocated(unsigned Index) { 339 PSInputAddr |= 1 << Index; 340 } 341 342 bool returnsVoid() const { 343 return ReturnsVoid; 344 } 345 346 void setIfReturnsVoid(bool Value) { 347 ReturnsVoid = Value; 348 } 349 350 /// \returns A pair of default/requested minimum/maximum flat work group sizes 351 /// for this function. 352 std::pair<unsigned, unsigned> getFlatWorkGroupSizes() const { 353 return FlatWorkGroupSizes; 354 } 355 356 /// \returns Default/requested minimum flat work group size for this function. 357 unsigned getMinFlatWorkGroupSize() const { 358 return FlatWorkGroupSizes.first; 359 } 360 361 /// \returns Default/requested maximum flat work group size for this function. 362 unsigned getMaxFlatWorkGroupSize() const { 363 return FlatWorkGroupSizes.second; 364 } 365 366 /// \returns A pair of default/requested minimum/maximum number of waves per 367 /// execution unit. 368 std::pair<unsigned, unsigned> getWavesPerEU() const { 369 return WavesPerEU; 370 } 371 372 /// \returns Default/requested minimum number of waves per execution unit. 373 unsigned getMinWavesPerEU() const { 374 return WavesPerEU.first; 375 } 376 377 /// \returns Default/requested maximum number of waves per execution unit. 378 unsigned getMaxWavesPerEU() const { 379 return WavesPerEU.second; 380 } 381 382 /// \returns Stack object index for \p Dim's work group ID. 383 int getDebuggerWorkGroupIDStackObjectIndex(unsigned Dim) const { 384 assert(Dim < 3); 385 return DebuggerWorkGroupIDStackObjectIndices[Dim]; 386 } 387 388 /// \brief Sets stack object index for \p Dim's work group ID to \p ObjectIdx. 389 void setDebuggerWorkGroupIDStackObjectIndex(unsigned Dim, int ObjectIdx) { 390 assert(Dim < 3); 391 DebuggerWorkGroupIDStackObjectIndices[Dim] = ObjectIdx; 392 } 393 394 /// \returns Stack object index for \p Dim's work item ID. 395 int getDebuggerWorkItemIDStackObjectIndex(unsigned Dim) const { 396 assert(Dim < 3); 397 return DebuggerWorkItemIDStackObjectIndices[Dim]; 398 } 399 400 /// \brief Sets stack object index for \p Dim's work item ID to \p ObjectIdx. 401 void setDebuggerWorkItemIDStackObjectIndex(unsigned Dim, int ObjectIdx) { 402 assert(Dim < 3); 403 DebuggerWorkItemIDStackObjectIndices[Dim] = ObjectIdx; 404 } 405 406 /// \returns SGPR used for \p Dim's work group ID. 407 unsigned getWorkGroupIDSGPR(unsigned Dim) const { 408 switch (Dim) { 409 case 0: 410 assert(hasWorkGroupIDX()); 411 return WorkGroupIDXSystemSGPR; 412 case 1: 413 assert(hasWorkGroupIDY()); 414 return WorkGroupIDYSystemSGPR; 415 case 2: 416 assert(hasWorkGroupIDZ()); 417 return WorkGroupIDZSystemSGPR; 418 } 419 llvm_unreachable("unexpected dimension"); 420 } 421 422 /// \returns VGPR used for \p Dim' work item ID. 423 unsigned getWorkItemIDVGPR(unsigned Dim) const { 424 switch (Dim) { 425 case 0: 426 assert(hasWorkItemIDX()); 427 return AMDGPU::VGPR0; 428 case 1: 429 assert(hasWorkItemIDY()); 430 return AMDGPU::VGPR1; 431 case 2: 432 assert(hasWorkItemIDZ()); 433 return AMDGPU::VGPR2; 434 } 435 llvm_unreachable("unexpected dimension"); 436 } 437 }; 438 439 } // End namespace llvm 440 441 #endif 442