1 //==- SIMachineFunctionInfo.h - SIMachineFunctionInfo interface --*- C++ -*-==// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 /// \file 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_LIB_TARGET_AMDGPU_SIMACHINEFUNCTIONINFO_H 14 #define LLVM_LIB_TARGET_AMDGPU_SIMACHINEFUNCTIONINFO_H 15 16 #include "AMDGPUArgumentUsageInfo.h" 17 #include "AMDGPUMachineFunction.h" 18 #include "MCTargetDesc/AMDGPUMCTargetDesc.h" 19 #include "SIInstrInfo.h" 20 #include "SIRegisterInfo.h" 21 #include "llvm/ADT/ArrayRef.h" 22 #include "llvm/ADT/DenseMap.h" 23 #include "llvm/ADT/Optional.h" 24 #include "llvm/ADT/SmallVector.h" 25 #include "llvm/ADT/SparseBitVector.h" 26 #include "llvm/CodeGen/MIRYamlMapping.h" 27 #include "llvm/CodeGen/PseudoSourceValue.h" 28 #include "llvm/CodeGen/TargetInstrInfo.h" 29 #include "llvm/MC/MCRegisterInfo.h" 30 #include "llvm/Support/ErrorHandling.h" 31 #include <array> 32 #include <cassert> 33 #include <utility> 34 #include <vector> 35 36 namespace llvm { 37 38 class MachineFrameInfo; 39 class MachineFunction; 40 class TargetRegisterClass; 41 42 class AMDGPUPseudoSourceValue : public PseudoSourceValue { 43 public: 44 enum AMDGPUPSVKind : unsigned { 45 PSVBuffer = PseudoSourceValue::TargetCustom, 46 PSVImage, 47 GWSResource 48 }; 49 50 protected: 51 AMDGPUPseudoSourceValue(unsigned Kind, const TargetInstrInfo &TII) 52 : PseudoSourceValue(Kind, TII) {} 53 54 public: 55 bool isConstant(const MachineFrameInfo *) const override { 56 // This should probably be true for most images, but we will start by being 57 // conservative. 58 return false; 59 } 60 61 bool isAliased(const MachineFrameInfo *) const override { 62 return true; 63 } 64 65 bool mayAlias(const MachineFrameInfo *) const override { 66 return true; 67 } 68 }; 69 70 class AMDGPUBufferPseudoSourceValue final : public AMDGPUPseudoSourceValue { 71 public: 72 explicit AMDGPUBufferPseudoSourceValue(const TargetInstrInfo &TII) 73 : AMDGPUPseudoSourceValue(PSVBuffer, TII) {} 74 75 static bool classof(const PseudoSourceValue *V) { 76 return V->kind() == PSVBuffer; 77 } 78 }; 79 80 class AMDGPUImagePseudoSourceValue final : public AMDGPUPseudoSourceValue { 81 public: 82 // TODO: Is the img rsrc useful? 83 explicit AMDGPUImagePseudoSourceValue(const TargetInstrInfo &TII) 84 : AMDGPUPseudoSourceValue(PSVImage, TII) {} 85 86 static bool classof(const PseudoSourceValue *V) { 87 return V->kind() == PSVImage; 88 } 89 }; 90 91 class AMDGPUGWSResourcePseudoSourceValue final : public AMDGPUPseudoSourceValue { 92 public: 93 explicit AMDGPUGWSResourcePseudoSourceValue(const TargetInstrInfo &TII) 94 : AMDGPUPseudoSourceValue(GWSResource, TII) {} 95 96 static bool classof(const PseudoSourceValue *V) { 97 return V->kind() == GWSResource; 98 } 99 100 // These are inaccessible memory from IR. 101 bool isAliased(const MachineFrameInfo *) const override { 102 return false; 103 } 104 105 // These are inaccessible memory from IR. 106 bool mayAlias(const MachineFrameInfo *) const override { 107 return false; 108 } 109 110 void printCustom(raw_ostream &OS) const override { 111 OS << "GWSResource"; 112 } 113 }; 114 115 namespace yaml { 116 117 struct SIMachineFunctionInfo final : public yaml::MachineFunctionInfo { 118 uint64_t ExplicitKernArgSize = 0; 119 unsigned MaxKernArgAlign = 0; 120 unsigned LDSSize = 0; 121 bool IsEntryFunction = false; 122 bool NoSignedZerosFPMath = false; 123 bool MemoryBound = false; 124 bool WaveLimiter = false; 125 126 StringValue ScratchRSrcReg = "$private_rsrc_reg"; 127 StringValue ScratchWaveOffsetReg = "$scratch_wave_offset_reg"; 128 StringValue FrameOffsetReg = "$fp_reg"; 129 StringValue StackPtrOffsetReg = "$sp_reg"; 130 131 SIMachineFunctionInfo() = default; 132 SIMachineFunctionInfo(const llvm::SIMachineFunctionInfo &, 133 const TargetRegisterInfo &TRI); 134 135 void mappingImpl(yaml::IO &YamlIO) override; 136 ~SIMachineFunctionInfo() = default; 137 }; 138 139 template <> struct MappingTraits<SIMachineFunctionInfo> { 140 static void mapping(IO &YamlIO, SIMachineFunctionInfo &MFI) { 141 YamlIO.mapOptional("explicitKernArgSize", MFI.ExplicitKernArgSize, 142 UINT64_C(0)); 143 YamlIO.mapOptional("maxKernArgAlign", MFI.MaxKernArgAlign, 0u); 144 YamlIO.mapOptional("ldsSize", MFI.LDSSize, 0u); 145 YamlIO.mapOptional("isEntryFunction", MFI.IsEntryFunction, false); 146 YamlIO.mapOptional("noSignedZerosFPMath", MFI.NoSignedZerosFPMath, false); 147 YamlIO.mapOptional("memoryBound", MFI.MemoryBound, false); 148 YamlIO.mapOptional("waveLimiter", MFI.WaveLimiter, false); 149 YamlIO.mapOptional("scratchRSrcReg", MFI.ScratchRSrcReg, 150 StringValue("$private_rsrc_reg")); 151 YamlIO.mapOptional("scratchWaveOffsetReg", MFI.ScratchWaveOffsetReg, 152 StringValue("$scratch_wave_offset_reg")); 153 YamlIO.mapOptional("frameOffsetReg", MFI.FrameOffsetReg, 154 StringValue("$fp_reg")); 155 YamlIO.mapOptional("stackPtrOffsetReg", MFI.StackPtrOffsetReg, 156 StringValue("$sp_reg")); 157 } 158 }; 159 160 } // end namespace yaml 161 162 /// This class keeps track of the SPI_SP_INPUT_ADDR config register, which 163 /// tells the hardware which interpolation parameters to load. 164 class SIMachineFunctionInfo final : public AMDGPUMachineFunction { 165 friend class GCNTargetMachine; 166 167 unsigned TIDReg = AMDGPU::NoRegister; 168 169 // Registers that may be reserved for spilling purposes. These may be the same 170 // as the input registers. 171 unsigned ScratchRSrcReg = AMDGPU::PRIVATE_RSRC_REG; 172 unsigned ScratchWaveOffsetReg = AMDGPU::SCRATCH_WAVE_OFFSET_REG; 173 174 // This is the current function's incremented size from the kernel's scratch 175 // wave offset register. For an entry function, this is exactly the same as 176 // the ScratchWaveOffsetReg. 177 unsigned FrameOffsetReg = AMDGPU::FP_REG; 178 179 // Top of the stack SGPR offset derived from the ScratchWaveOffsetReg. 180 unsigned StackPtrOffsetReg = AMDGPU::SP_REG; 181 182 AMDGPUFunctionArgInfo ArgInfo; 183 184 // State of MODE register, assumed FP mode. 185 AMDGPU::SIModeRegisterDefaults Mode; 186 187 // Graphics info. 188 unsigned PSInputAddr = 0; 189 unsigned PSInputEnable = 0; 190 191 /// Number of bytes of arguments this function has on the stack. If the callee 192 /// is expected to restore the argument stack this should be a multiple of 16, 193 /// all usable during a tail call. 194 /// 195 /// The alternative would forbid tail call optimisation in some cases: if we 196 /// want to transfer control from a function with 8-bytes of stack-argument 197 /// space to a function with 16-bytes then misalignment of this value would 198 /// make a stack adjustment necessary, which could not be undone by the 199 /// callee. 200 unsigned BytesInStackArgArea = 0; 201 202 bool ReturnsVoid = true; 203 204 // A pair of default/requested minimum/maximum flat work group sizes. 205 // Minimum - first, maximum - second. 206 std::pair<unsigned, unsigned> FlatWorkGroupSizes = {0, 0}; 207 208 // A pair of default/requested minimum/maximum number of waves per execution 209 // unit. Minimum - first, maximum - second. 210 std::pair<unsigned, unsigned> WavesPerEU = {0, 0}; 211 212 DenseMap<const Value *, 213 std::unique_ptr<const AMDGPUBufferPseudoSourceValue>> BufferPSVs; 214 DenseMap<const Value *, 215 std::unique_ptr<const AMDGPUImagePseudoSourceValue>> ImagePSVs; 216 std::unique_ptr<const AMDGPUGWSResourcePseudoSourceValue> GWSResourcePSV; 217 218 private: 219 unsigned LDSWaveSpillSize = 0; 220 unsigned NumUserSGPRs = 0; 221 unsigned NumSystemSGPRs = 0; 222 223 bool HasSpilledSGPRs = false; 224 bool HasSpilledVGPRs = false; 225 bool HasNonSpillStackObjects = false; 226 bool IsStackRealigned = false; 227 228 unsigned NumSpilledSGPRs = 0; 229 unsigned NumSpilledVGPRs = 0; 230 231 // Feature bits required for inputs passed in user SGPRs. 232 bool PrivateSegmentBuffer : 1; 233 bool DispatchPtr : 1; 234 bool QueuePtr : 1; 235 bool KernargSegmentPtr : 1; 236 bool DispatchID : 1; 237 bool FlatScratchInit : 1; 238 239 // Feature bits required for inputs passed in system SGPRs. 240 bool WorkGroupIDX : 1; // Always initialized. 241 bool WorkGroupIDY : 1; 242 bool WorkGroupIDZ : 1; 243 bool WorkGroupInfo : 1; 244 bool PrivateSegmentWaveByteOffset : 1; 245 246 bool WorkItemIDX : 1; // Always initialized. 247 bool WorkItemIDY : 1; 248 bool WorkItemIDZ : 1; 249 250 // Private memory buffer 251 // Compute directly in sgpr[0:1] 252 // Other shaders indirect 64-bits at sgpr[0:1] 253 bool ImplicitBufferPtr : 1; 254 255 // Pointer to where the ABI inserts special kernel arguments separate from the 256 // user arguments. This is an offset from the KernargSegmentPtr. 257 bool ImplicitArgPtr : 1; 258 259 // The hard-wired high half of the address of the global information table 260 // for AMDPAL OS type. 0xffffffff represents no hard-wired high half, since 261 // current hardware only allows a 16 bit value. 262 unsigned GITPtrHigh; 263 264 unsigned HighBitsOf32BitAddress; 265 266 // Current recorded maximum possible occupancy. 267 unsigned Occupancy; 268 269 MCPhysReg getNextUserSGPR() const; 270 271 MCPhysReg getNextSystemSGPR() const; 272 273 public: 274 struct SpilledReg { 275 unsigned VGPR = 0; 276 int Lane = -1; 277 278 SpilledReg() = default; 279 SpilledReg(unsigned R, int L) : VGPR (R), Lane (L) {} 280 281 bool hasLane() { return Lane != -1;} 282 bool hasReg() { return VGPR != 0;} 283 }; 284 285 struct SGPRSpillVGPRCSR { 286 // VGPR used for SGPR spills 287 unsigned VGPR; 288 289 // If the VGPR is a CSR, the stack slot used to save/restore it in the 290 // prolog/epilog. 291 Optional<int> FI; 292 293 SGPRSpillVGPRCSR(unsigned V, Optional<int> F) : VGPR(V), FI(F) {} 294 }; 295 296 SparseBitVector<> WWMReservedRegs; 297 298 void ReserveWWMRegister(unsigned reg) { WWMReservedRegs.set(reg); } 299 300 private: 301 // SGPR->VGPR spilling support. 302 using SpillRegMask = std::pair<unsigned, unsigned>; 303 304 // Track VGPR + wave index for each subregister of the SGPR spilled to 305 // frameindex key. 306 DenseMap<int, std::vector<SpilledReg>> SGPRToVGPRSpills; 307 unsigned NumVGPRSpillLanes = 0; 308 SmallVector<SGPRSpillVGPRCSR, 2> SpillVGPRs; 309 310 public: 311 SIMachineFunctionInfo(const MachineFunction &MF); 312 313 bool initializeBaseYamlFields(const yaml::SIMachineFunctionInfo &YamlMFI); 314 315 ArrayRef<SpilledReg> getSGPRToVGPRSpills(int FrameIndex) const { 316 auto I = SGPRToVGPRSpills.find(FrameIndex); 317 return (I == SGPRToVGPRSpills.end()) ? 318 ArrayRef<SpilledReg>() : makeArrayRef(I->second); 319 } 320 321 ArrayRef<SGPRSpillVGPRCSR> getSGPRSpillVGPRs() const { 322 return SpillVGPRs; 323 } 324 325 AMDGPU::SIModeRegisterDefaults getMode() const { 326 return Mode; 327 } 328 329 bool allocateSGPRSpillToVGPR(MachineFunction &MF, int FI); 330 void removeSGPRToVGPRFrameIndices(MachineFrameInfo &MFI); 331 332 bool hasCalculatedTID() const { return TIDReg != 0; }; 333 unsigned getTIDReg() const { return TIDReg; }; 334 void setTIDReg(unsigned Reg) { TIDReg = Reg; } 335 336 unsigned getBytesInStackArgArea() const { 337 return BytesInStackArgArea; 338 } 339 340 void setBytesInStackArgArea(unsigned Bytes) { 341 BytesInStackArgArea = Bytes; 342 } 343 344 // Add user SGPRs. 345 unsigned addPrivateSegmentBuffer(const SIRegisterInfo &TRI); 346 unsigned addDispatchPtr(const SIRegisterInfo &TRI); 347 unsigned addQueuePtr(const SIRegisterInfo &TRI); 348 unsigned addKernargSegmentPtr(const SIRegisterInfo &TRI); 349 unsigned addDispatchID(const SIRegisterInfo &TRI); 350 unsigned addFlatScratchInit(const SIRegisterInfo &TRI); 351 unsigned addImplicitBufferPtr(const SIRegisterInfo &TRI); 352 353 // Add system SGPRs. 354 unsigned addWorkGroupIDX() { 355 ArgInfo.WorkGroupIDX = ArgDescriptor::createRegister(getNextSystemSGPR()); 356 NumSystemSGPRs += 1; 357 return ArgInfo.WorkGroupIDX.getRegister(); 358 } 359 360 unsigned addWorkGroupIDY() { 361 ArgInfo.WorkGroupIDY = ArgDescriptor::createRegister(getNextSystemSGPR()); 362 NumSystemSGPRs += 1; 363 return ArgInfo.WorkGroupIDY.getRegister(); 364 } 365 366 unsigned addWorkGroupIDZ() { 367 ArgInfo.WorkGroupIDZ = ArgDescriptor::createRegister(getNextSystemSGPR()); 368 NumSystemSGPRs += 1; 369 return ArgInfo.WorkGroupIDZ.getRegister(); 370 } 371 372 unsigned addWorkGroupInfo() { 373 ArgInfo.WorkGroupInfo = ArgDescriptor::createRegister(getNextSystemSGPR()); 374 NumSystemSGPRs += 1; 375 return ArgInfo.WorkGroupInfo.getRegister(); 376 } 377 378 // Add special VGPR inputs 379 void setWorkItemIDX(ArgDescriptor Arg) { 380 ArgInfo.WorkItemIDX = Arg; 381 } 382 383 void setWorkItemIDY(ArgDescriptor Arg) { 384 ArgInfo.WorkItemIDY = Arg; 385 } 386 387 void setWorkItemIDZ(ArgDescriptor Arg) { 388 ArgInfo.WorkItemIDZ = Arg; 389 } 390 391 unsigned addPrivateSegmentWaveByteOffset() { 392 ArgInfo.PrivateSegmentWaveByteOffset 393 = ArgDescriptor::createRegister(getNextSystemSGPR()); 394 NumSystemSGPRs += 1; 395 return ArgInfo.PrivateSegmentWaveByteOffset.getRegister(); 396 } 397 398 void setPrivateSegmentWaveByteOffset(unsigned Reg) { 399 ArgInfo.PrivateSegmentWaveByteOffset = ArgDescriptor::createRegister(Reg); 400 } 401 402 bool hasPrivateSegmentBuffer() const { 403 return PrivateSegmentBuffer; 404 } 405 406 bool hasDispatchPtr() const { 407 return DispatchPtr; 408 } 409 410 bool hasQueuePtr() const { 411 return QueuePtr; 412 } 413 414 bool hasKernargSegmentPtr() const { 415 return KernargSegmentPtr; 416 } 417 418 bool hasDispatchID() const { 419 return DispatchID; 420 } 421 422 bool hasFlatScratchInit() const { 423 return FlatScratchInit; 424 } 425 426 bool hasWorkGroupIDX() const { 427 return WorkGroupIDX; 428 } 429 430 bool hasWorkGroupIDY() const { 431 return WorkGroupIDY; 432 } 433 434 bool hasWorkGroupIDZ() const { 435 return WorkGroupIDZ; 436 } 437 438 bool hasWorkGroupInfo() const { 439 return WorkGroupInfo; 440 } 441 442 bool hasPrivateSegmentWaveByteOffset() const { 443 return PrivateSegmentWaveByteOffset; 444 } 445 446 bool hasWorkItemIDX() const { 447 return WorkItemIDX; 448 } 449 450 bool hasWorkItemIDY() const { 451 return WorkItemIDY; 452 } 453 454 bool hasWorkItemIDZ() const { 455 return WorkItemIDZ; 456 } 457 458 bool hasImplicitArgPtr() const { 459 return ImplicitArgPtr; 460 } 461 462 bool hasImplicitBufferPtr() const { 463 return ImplicitBufferPtr; 464 } 465 466 AMDGPUFunctionArgInfo &getArgInfo() { 467 return ArgInfo; 468 } 469 470 const AMDGPUFunctionArgInfo &getArgInfo() const { 471 return ArgInfo; 472 } 473 474 std::pair<const ArgDescriptor *, const TargetRegisterClass *> 475 getPreloadedValue(AMDGPUFunctionArgInfo::PreloadedValue Value) const { 476 return ArgInfo.getPreloadedValue(Value); 477 } 478 479 Register getPreloadedReg(AMDGPUFunctionArgInfo::PreloadedValue Value) const { 480 auto Arg = ArgInfo.getPreloadedValue(Value).first; 481 return Arg ? Arg->getRegister() : Register(); 482 } 483 484 unsigned getGITPtrHigh() const { 485 return GITPtrHigh; 486 } 487 488 unsigned get32BitAddressHighBits() const { 489 return HighBitsOf32BitAddress; 490 } 491 492 unsigned getNumUserSGPRs() const { 493 return NumUserSGPRs; 494 } 495 496 unsigned getNumPreloadedSGPRs() const { 497 return NumUserSGPRs + NumSystemSGPRs; 498 } 499 500 unsigned getPrivateSegmentWaveByteOffsetSystemSGPR() const { 501 return ArgInfo.PrivateSegmentWaveByteOffset.getRegister(); 502 } 503 504 /// Returns the physical register reserved for use as the resource 505 /// descriptor for scratch accesses. 506 unsigned getScratchRSrcReg() const { 507 return ScratchRSrcReg; 508 } 509 510 void setScratchRSrcReg(unsigned Reg) { 511 assert(Reg != 0 && "Should never be unset"); 512 ScratchRSrcReg = Reg; 513 } 514 515 unsigned getScratchWaveOffsetReg() const { 516 return ScratchWaveOffsetReg; 517 } 518 519 unsigned getFrameOffsetReg() const { 520 return FrameOffsetReg; 521 } 522 523 void setFrameOffsetReg(unsigned Reg) { 524 assert(Reg != 0 && "Should never be unset"); 525 FrameOffsetReg = Reg; 526 } 527 528 void setStackPtrOffsetReg(unsigned Reg) { 529 assert(Reg != 0 && "Should never be unset"); 530 StackPtrOffsetReg = Reg; 531 } 532 533 // Note the unset value for this is AMDGPU::SP_REG rather than 534 // NoRegister. This is mostly a workaround for MIR tests where state that 535 // can't be directly computed from the function is not preserved in serialized 536 // MIR. 537 unsigned getStackPtrOffsetReg() const { 538 return StackPtrOffsetReg; 539 } 540 541 void setScratchWaveOffsetReg(unsigned Reg) { 542 assert(Reg != 0 && "Should never be unset"); 543 ScratchWaveOffsetReg = Reg; 544 } 545 546 unsigned getQueuePtrUserSGPR() const { 547 return ArgInfo.QueuePtr.getRegister(); 548 } 549 550 unsigned getImplicitBufferPtrUserSGPR() const { 551 return ArgInfo.ImplicitBufferPtr.getRegister(); 552 } 553 554 bool hasSpilledSGPRs() const { 555 return HasSpilledSGPRs; 556 } 557 558 void setHasSpilledSGPRs(bool Spill = true) { 559 HasSpilledSGPRs = Spill; 560 } 561 562 bool hasSpilledVGPRs() const { 563 return HasSpilledVGPRs; 564 } 565 566 void setHasSpilledVGPRs(bool Spill = true) { 567 HasSpilledVGPRs = Spill; 568 } 569 570 bool hasNonSpillStackObjects() const { 571 return HasNonSpillStackObjects; 572 } 573 574 void setHasNonSpillStackObjects(bool StackObject = true) { 575 HasNonSpillStackObjects = StackObject; 576 } 577 578 bool isStackRealigned() const { 579 return IsStackRealigned; 580 } 581 582 void setIsStackRealigned(bool Realigned = true) { 583 IsStackRealigned = Realigned; 584 } 585 586 unsigned getNumSpilledSGPRs() const { 587 return NumSpilledSGPRs; 588 } 589 590 unsigned getNumSpilledVGPRs() const { 591 return NumSpilledVGPRs; 592 } 593 594 void addToSpilledSGPRs(unsigned num) { 595 NumSpilledSGPRs += num; 596 } 597 598 void addToSpilledVGPRs(unsigned num) { 599 NumSpilledVGPRs += num; 600 } 601 602 unsigned getPSInputAddr() const { 603 return PSInputAddr; 604 } 605 606 unsigned getPSInputEnable() const { 607 return PSInputEnable; 608 } 609 610 bool isPSInputAllocated(unsigned Index) const { 611 return PSInputAddr & (1 << Index); 612 } 613 614 void markPSInputAllocated(unsigned Index) { 615 PSInputAddr |= 1 << Index; 616 } 617 618 void markPSInputEnabled(unsigned Index) { 619 PSInputEnable |= 1 << Index; 620 } 621 622 bool returnsVoid() const { 623 return ReturnsVoid; 624 } 625 626 void setIfReturnsVoid(bool Value) { 627 ReturnsVoid = Value; 628 } 629 630 /// \returns A pair of default/requested minimum/maximum flat work group sizes 631 /// for this function. 632 std::pair<unsigned, unsigned> getFlatWorkGroupSizes() const { 633 return FlatWorkGroupSizes; 634 } 635 636 /// \returns Default/requested minimum flat work group size for this function. 637 unsigned getMinFlatWorkGroupSize() const { 638 return FlatWorkGroupSizes.first; 639 } 640 641 /// \returns Default/requested maximum flat work group size for this function. 642 unsigned getMaxFlatWorkGroupSize() const { 643 return FlatWorkGroupSizes.second; 644 } 645 646 /// \returns A pair of default/requested minimum/maximum number of waves per 647 /// execution unit. 648 std::pair<unsigned, unsigned> getWavesPerEU() const { 649 return WavesPerEU; 650 } 651 652 /// \returns Default/requested minimum number of waves per execution unit. 653 unsigned getMinWavesPerEU() const { 654 return WavesPerEU.first; 655 } 656 657 /// \returns Default/requested maximum number of waves per execution unit. 658 unsigned getMaxWavesPerEU() const { 659 return WavesPerEU.second; 660 } 661 662 /// \returns SGPR used for \p Dim's work group ID. 663 unsigned getWorkGroupIDSGPR(unsigned Dim) const { 664 switch (Dim) { 665 case 0: 666 assert(hasWorkGroupIDX()); 667 return ArgInfo.WorkGroupIDX.getRegister(); 668 case 1: 669 assert(hasWorkGroupIDY()); 670 return ArgInfo.WorkGroupIDY.getRegister(); 671 case 2: 672 assert(hasWorkGroupIDZ()); 673 return ArgInfo.WorkGroupIDZ.getRegister(); 674 } 675 llvm_unreachable("unexpected dimension"); 676 } 677 678 unsigned getLDSWaveSpillSize() const { 679 return LDSWaveSpillSize; 680 } 681 682 const AMDGPUBufferPseudoSourceValue *getBufferPSV(const SIInstrInfo &TII, 683 const Value *BufferRsrc) { 684 assert(BufferRsrc); 685 auto PSV = BufferPSVs.try_emplace( 686 BufferRsrc, 687 llvm::make_unique<AMDGPUBufferPseudoSourceValue>(TII)); 688 return PSV.first->second.get(); 689 } 690 691 const AMDGPUImagePseudoSourceValue *getImagePSV(const SIInstrInfo &TII, 692 const Value *ImgRsrc) { 693 assert(ImgRsrc); 694 auto PSV = ImagePSVs.try_emplace( 695 ImgRsrc, 696 llvm::make_unique<AMDGPUImagePseudoSourceValue>(TII)); 697 return PSV.first->second.get(); 698 } 699 700 const AMDGPUGWSResourcePseudoSourceValue *getGWSPSV(const SIInstrInfo &TII) { 701 if (!GWSResourcePSV) { 702 GWSResourcePSV = 703 llvm::make_unique<AMDGPUGWSResourcePseudoSourceValue>(TII); 704 } 705 706 return GWSResourcePSV.get(); 707 } 708 709 unsigned getOccupancy() const { 710 return Occupancy; 711 } 712 713 unsigned getMinAllowedOccupancy() const { 714 if (!isMemoryBound() && !needsWaveLimiter()) 715 return Occupancy; 716 return (Occupancy < 4) ? Occupancy : 4; 717 } 718 719 void limitOccupancy(const MachineFunction &MF); 720 721 void limitOccupancy(unsigned Limit) { 722 if (Occupancy > Limit) 723 Occupancy = Limit; 724 } 725 726 void increaseOccupancy(const MachineFunction &MF, unsigned Limit) { 727 if (Occupancy < Limit) 728 Occupancy = Limit; 729 limitOccupancy(MF); 730 } 731 }; 732 733 } // end namespace llvm 734 735 #endif // LLVM_LIB_TARGET_AMDGPU_SIMACHINEFUNCTIONINFO_H 736