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 <map> 20 21 namespace llvm { 22 23 class MachineRegisterInfo; 24 25 /// This class keeps track of the SPI_SP_INPUT_ADDR config register, which 26 /// tells the hardware which interpolation parameters to load. 27 class SIMachineFunctionInfo final : public AMDGPUMachineFunction { 28 // FIXME: This should be removed and getPreloadedValue moved here. 29 friend struct SIRegisterInfo; 30 void anchor() override; 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 unsigned MaximumWorkGroupSize; 64 65 // Number of reserved VGPRs for trap handler usage. 66 unsigned DebuggerReserveTrapVGPRCount; 67 68 public: 69 // FIXME: Make private 70 unsigned LDSWaveSpillSize; 71 unsigned PSInputEna; 72 std::map<unsigned, unsigned> LaneVGPRs; 73 unsigned ScratchOffsetReg; 74 unsigned NumUserSGPRs; 75 unsigned NumSystemSGPRs; 76 77 private: 78 bool HasSpilledSGPRs; 79 bool HasSpilledVGPRs; 80 bool HasNonSpillStackObjects; 81 bool HasFlatInstructions; 82 83 // Feature bits required for inputs passed in user SGPRs. 84 bool PrivateSegmentBuffer : 1; 85 bool DispatchPtr : 1; 86 bool QueuePtr : 1; 87 bool DispatchID : 1; 88 bool KernargSegmentPtr : 1; 89 bool FlatScratchInit : 1; 90 bool GridWorkgroupCountX : 1; 91 bool GridWorkgroupCountY : 1; 92 bool GridWorkgroupCountZ : 1; 93 94 // Feature bits required for inputs passed in system SGPRs. 95 bool WorkGroupIDX : 1; // Always initialized. 96 bool WorkGroupIDY : 1; 97 bool WorkGroupIDZ : 1; 98 bool WorkGroupInfo : 1; 99 bool PrivateSegmentWaveByteOffset : 1; 100 101 bool WorkItemIDX : 1; // Always initialized. 102 bool WorkItemIDY : 1; 103 bool WorkItemIDZ : 1; 104 105 106 MCPhysReg getNextUserSGPR() const { 107 assert(NumSystemSGPRs == 0 && "System SGPRs must be added after user SGPRs"); 108 return AMDGPU::SGPR0 + NumUserSGPRs; 109 } 110 111 MCPhysReg getNextSystemSGPR() const { 112 return AMDGPU::SGPR0 + NumUserSGPRs + NumSystemSGPRs; 113 } 114 115 public: 116 struct SpilledReg { 117 unsigned VGPR; 118 int Lane; 119 SpilledReg(unsigned R, int L) : VGPR (R), Lane (L) { } 120 SpilledReg() : VGPR(AMDGPU::NoRegister), Lane(-1) { } 121 bool hasLane() { return Lane != -1;} 122 bool hasReg() { return VGPR != AMDGPU::NoRegister;} 123 }; 124 125 // SIMachineFunctionInfo definition 126 127 SIMachineFunctionInfo(const MachineFunction &MF); 128 SpilledReg getSpilledReg(MachineFunction *MF, unsigned FrameIndex, 129 unsigned SubIdx); 130 bool hasCalculatedTID() const { return TIDReg != AMDGPU::NoRegister; }; 131 unsigned getTIDReg() const { return TIDReg; }; 132 void setTIDReg(unsigned Reg) { TIDReg = Reg; } 133 134 // Add user SGPRs. 135 unsigned addPrivateSegmentBuffer(const SIRegisterInfo &TRI); 136 unsigned addDispatchPtr(const SIRegisterInfo &TRI); 137 unsigned addQueuePtr(const SIRegisterInfo &TRI); 138 unsigned addKernargSegmentPtr(const SIRegisterInfo &TRI); 139 unsigned addFlatScratchInit(const SIRegisterInfo &TRI); 140 141 // Add system SGPRs. 142 unsigned addWorkGroupIDX() { 143 WorkGroupIDXSystemSGPR = getNextSystemSGPR(); 144 NumSystemSGPRs += 1; 145 return WorkGroupIDXSystemSGPR; 146 } 147 148 unsigned addWorkGroupIDY() { 149 WorkGroupIDYSystemSGPR = getNextSystemSGPR(); 150 NumSystemSGPRs += 1; 151 return WorkGroupIDYSystemSGPR; 152 } 153 154 unsigned addWorkGroupIDZ() { 155 WorkGroupIDZSystemSGPR = getNextSystemSGPR(); 156 NumSystemSGPRs += 1; 157 return WorkGroupIDZSystemSGPR; 158 } 159 160 unsigned addWorkGroupInfo() { 161 WorkGroupInfoSystemSGPR = getNextSystemSGPR(); 162 NumSystemSGPRs += 1; 163 return WorkGroupInfoSystemSGPR; 164 } 165 166 unsigned addPrivateSegmentWaveByteOffset() { 167 PrivateSegmentWaveByteOffsetSystemSGPR = getNextSystemSGPR(); 168 NumSystemSGPRs += 1; 169 return PrivateSegmentWaveByteOffsetSystemSGPR; 170 } 171 172 void setPrivateSegmentWaveByteOffset(unsigned Reg) { 173 PrivateSegmentWaveByteOffsetSystemSGPR = Reg; 174 } 175 176 bool hasPrivateSegmentBuffer() const { 177 return PrivateSegmentBuffer; 178 } 179 180 bool hasDispatchPtr() const { 181 return DispatchPtr; 182 } 183 184 bool hasQueuePtr() const { 185 return QueuePtr; 186 } 187 188 bool hasDispatchID() const { 189 return DispatchID; 190 } 191 192 bool hasKernargSegmentPtr() const { 193 return KernargSegmentPtr; 194 } 195 196 bool hasFlatScratchInit() const { 197 return FlatScratchInit; 198 } 199 200 bool hasGridWorkgroupCountX() const { 201 return GridWorkgroupCountX; 202 } 203 204 bool hasGridWorkgroupCountY() const { 205 return GridWorkgroupCountY; 206 } 207 208 bool hasGridWorkgroupCountZ() const { 209 return GridWorkgroupCountZ; 210 } 211 212 bool hasWorkGroupIDX() const { 213 return WorkGroupIDX; 214 } 215 216 bool hasWorkGroupIDY() const { 217 return WorkGroupIDY; 218 } 219 220 bool hasWorkGroupIDZ() const { 221 return WorkGroupIDZ; 222 } 223 224 bool hasWorkGroupInfo() const { 225 return WorkGroupInfo; 226 } 227 228 bool hasPrivateSegmentWaveByteOffset() const { 229 return PrivateSegmentWaveByteOffset; 230 } 231 232 bool hasWorkItemIDX() const { 233 return WorkItemIDX; 234 } 235 236 bool hasWorkItemIDY() const { 237 return WorkItemIDY; 238 } 239 240 bool hasWorkItemIDZ() const { 241 return WorkItemIDZ; 242 } 243 244 unsigned getNumUserSGPRs() const { 245 return NumUserSGPRs; 246 } 247 248 unsigned getNumPreloadedSGPRs() const { 249 return NumUserSGPRs + NumSystemSGPRs; 250 } 251 252 unsigned getPrivateSegmentWaveByteOffsetSystemSGPR() const { 253 return PrivateSegmentWaveByteOffsetSystemSGPR; 254 } 255 256 /// \brief Returns the physical register reserved for use as the resource 257 /// descriptor for scratch accesses. 258 unsigned getScratchRSrcReg() const { 259 return ScratchRSrcReg; 260 } 261 262 void setScratchRSrcReg(unsigned Reg) { 263 assert(Reg != AMDGPU::NoRegister && "Should never be unset"); 264 ScratchRSrcReg = Reg; 265 } 266 267 unsigned getScratchWaveOffsetReg() const { 268 return ScratchWaveOffsetReg; 269 } 270 271 void setScratchWaveOffsetReg(unsigned Reg) { 272 assert(Reg != AMDGPU::NoRegister && "Should never be unset"); 273 ScratchWaveOffsetReg = Reg; 274 } 275 276 unsigned getQueuePtrUserSGPR() const { 277 return QueuePtrUserSGPR; 278 } 279 280 bool hasSpilledSGPRs() const { 281 return HasSpilledSGPRs; 282 } 283 284 void setHasSpilledSGPRs(bool Spill = true) { 285 HasSpilledSGPRs = Spill; 286 } 287 288 bool hasSpilledVGPRs() const { 289 return HasSpilledVGPRs; 290 } 291 292 void setHasSpilledVGPRs(bool Spill = true) { 293 HasSpilledVGPRs = Spill; 294 } 295 296 bool hasNonSpillStackObjects() const { 297 return HasNonSpillStackObjects; 298 } 299 300 void setHasNonSpillStackObjects(bool StackObject = true) { 301 HasNonSpillStackObjects = StackObject; 302 } 303 304 bool hasFlatInstructions() const { 305 return HasFlatInstructions; 306 } 307 308 void setHasFlatInstructions(bool UseFlat = true) { 309 HasFlatInstructions = UseFlat; 310 } 311 312 unsigned getPSInputAddr() const { 313 return PSInputAddr; 314 } 315 316 bool isPSInputAllocated(unsigned Index) const { 317 return PSInputAddr & (1 << Index); 318 } 319 320 void markPSInputAllocated(unsigned Index) { 321 PSInputAddr |= 1 << Index; 322 } 323 324 bool returnsVoid() const { 325 return ReturnsVoid; 326 } 327 328 void setIfReturnsVoid(bool Value) { 329 ReturnsVoid = Value; 330 } 331 332 unsigned getDebuggerReserveTrapVGPRCount() const { 333 return DebuggerReserveTrapVGPRCount; 334 } 335 336 unsigned getMaximumWorkGroupSize(const MachineFunction &MF) const; 337 }; 338 339 } // End namespace llvm 340 341 #endif 342