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