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