1 //=====-- AMDGPUSubtarget.h - Define Subtarget for AMDGPU ------*- 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 /// \brief AMDGPU specific subclass of TargetSubtarget. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUSUBTARGET_H 16 #define LLVM_LIB_TARGET_AMDGPU_AMDGPUSUBTARGET_H 17 18 #include "AMDGPU.h" 19 #include "R600InstrInfo.h" 20 #include "R600ISelLowering.h" 21 #include "R600FrameLowering.h" 22 #include "SIInstrInfo.h" 23 #include "SIISelLowering.h" 24 #include "SIFrameLowering.h" 25 #include "Utils/AMDGPUBaseInfo.h" 26 #include "llvm/ADT/Triple.h" 27 #include "llvm/CodeGen/GlobalISel/GISelAccessor.h" 28 #include "llvm/CodeGen/MachineFunction.h" 29 #include "llvm/CodeGen/SelectionDAGTargetInfo.h" 30 #include "llvm/MC/MCInstrItineraries.h" 31 #include "llvm/Support/MathExtras.h" 32 #include <cassert> 33 #include <cstdint> 34 #include <memory> 35 #include <utility> 36 37 #define GET_SUBTARGETINFO_HEADER 38 #include "AMDGPUGenSubtargetInfo.inc" 39 40 namespace llvm { 41 42 class StringRef; 43 44 class AMDGPUSubtarget : public AMDGPUGenSubtargetInfo { 45 public: 46 enum Generation { 47 R600 = 0, 48 R700, 49 EVERGREEN, 50 NORTHERN_ISLANDS, 51 SOUTHERN_ISLANDS, 52 SEA_ISLANDS, 53 VOLCANIC_ISLANDS, 54 GFX9, 55 }; 56 57 enum { 58 ISAVersion0_0_0, 59 ISAVersion7_0_0, 60 ISAVersion7_0_1, 61 ISAVersion7_0_2, 62 ISAVersion8_0_0, 63 ISAVersion8_0_1, 64 ISAVersion8_0_2, 65 ISAVersion8_0_3, 66 ISAVersion8_0_4, 67 ISAVersion8_1_0, 68 ISAVersion9_0_0, 69 ISAVersion9_0_1 70 }; 71 72 enum TrapHandlerAbi { 73 TrapHandlerAbiNone = 0, 74 TrapHandlerAbiHsa = 1 75 }; 76 77 enum TrapID { 78 TrapIDHardwareReserved = 0, 79 TrapIDHSADebugTrap = 1, 80 TrapIDLLVMTrap = 2, 81 TrapIDLLVMDebugTrap = 3, 82 TrapIDDebugBreakpoint = 7, 83 TrapIDDebugReserved8 = 8, 84 TrapIDDebugReservedFE = 0xfe, 85 TrapIDDebugReservedFF = 0xff 86 }; 87 88 enum TrapRegValues { 89 LLVMTrapHandlerRegValue = 1 90 }; 91 92 protected: 93 // Basic subtarget description. 94 Triple TargetTriple; 95 Generation Gen; 96 unsigned IsaVersion; 97 unsigned WavefrontSize; 98 int LocalMemorySize; 99 int LDSBankCount; 100 unsigned MaxPrivateElementSize; 101 102 // Possibly statically set by tablegen, but may want to be overridden. 103 bool FastFMAF32; 104 bool HalfRate64Ops; 105 106 // Dynamially set bits that enable features. 107 bool FP32Denormals; 108 bool FP64FP16Denormals; 109 bool FPExceptions; 110 bool DX10Clamp; 111 bool FlatForGlobal; 112 bool UnalignedScratchAccess; 113 bool UnalignedBufferAccess; 114 bool HasApertureRegs; 115 bool EnableXNACK; 116 bool TrapHandler; 117 bool DebuggerInsertNops; 118 bool DebuggerReserveRegs; 119 bool DebuggerEmitPrologue; 120 121 // Used as options. 122 bool EnableVGPRSpilling; 123 bool EnablePromoteAlloca; 124 bool EnableLoadStoreOpt; 125 bool EnableUnsafeDSOffsetFolding; 126 bool EnableSIScheduler; 127 bool DumpCode; 128 129 // Subtarget statically properties set by tablegen 130 bool FP64; 131 bool IsGCN; 132 bool GCN1Encoding; 133 bool GCN3Encoding; 134 bool CIInsts; 135 bool GFX9Insts; 136 bool SGPRInitBug; 137 bool HasSMemRealTime; 138 bool Has16BitInsts; 139 bool HasVOP3PInsts; 140 bool HasMovrel; 141 bool HasVGPRIndexMode; 142 bool HasScalarStores; 143 bool HasInv2PiInlineImm; 144 bool HasSDWA; 145 bool HasDPP; 146 bool FlatAddressSpace; 147 bool R600ALUInst; 148 bool CaymanISA; 149 bool CFALUBug; 150 bool HasVertexCache; 151 short TexVTXClauseSize; 152 bool ScalarizeGlobal; 153 154 // Dummy feature to use for assembler in tablegen. 155 bool FeatureDisable; 156 157 InstrItineraryData InstrItins; 158 SelectionDAGTargetInfo TSInfo; 159 160 public: 161 AMDGPUSubtarget(const Triple &TT, StringRef GPU, StringRef FS, 162 const TargetMachine &TM); 163 ~AMDGPUSubtarget() override; 164 165 AMDGPUSubtarget &initializeSubtargetDependencies(const Triple &TT, 166 StringRef GPU, StringRef FS); 167 168 const AMDGPUInstrInfo *getInstrInfo() const override = 0; 169 const AMDGPUFrameLowering *getFrameLowering() const override = 0; 170 const AMDGPUTargetLowering *getTargetLowering() const override = 0; 171 const AMDGPURegisterInfo *getRegisterInfo() const override = 0; 172 173 const InstrItineraryData *getInstrItineraryData() const override { 174 return &InstrItins; 175 } 176 177 // Nothing implemented, just prevent crashes on use. 178 const SelectionDAGTargetInfo *getSelectionDAGInfo() const override { 179 return &TSInfo; 180 } 181 182 void ParseSubtargetFeatures(StringRef CPU, StringRef FS); 183 184 bool isAmdHsaOS() const { 185 return TargetTriple.getOS() == Triple::AMDHSA; 186 } 187 188 bool isMesa3DOS() const { 189 return TargetTriple.getOS() == Triple::Mesa3D; 190 } 191 192 bool isOpenCLEnv() const { 193 return TargetTriple.getEnvironment() == Triple::OpenCL; 194 } 195 196 Generation getGeneration() const { 197 return Gen; 198 } 199 200 unsigned getWavefrontSize() const { 201 return WavefrontSize; 202 } 203 204 int getLocalMemorySize() const { 205 return LocalMemorySize; 206 } 207 208 int getLDSBankCount() const { 209 return LDSBankCount; 210 } 211 212 unsigned getMaxPrivateElementSize() const { 213 return MaxPrivateElementSize; 214 } 215 216 bool has16BitInsts() const { 217 return Has16BitInsts; 218 } 219 220 bool hasVOP3PInsts() const { 221 return HasVOP3PInsts; 222 } 223 224 bool hasHWFP64() const { 225 return FP64; 226 } 227 228 bool hasFastFMAF32() const { 229 return FastFMAF32; 230 } 231 232 bool hasHalfRate64Ops() const { 233 return HalfRate64Ops; 234 } 235 236 bool hasAddr64() const { 237 return (getGeneration() < VOLCANIC_ISLANDS); 238 } 239 240 bool hasBFE() const { 241 return (getGeneration() >= EVERGREEN); 242 } 243 244 bool hasBFI() const { 245 return (getGeneration() >= EVERGREEN); 246 } 247 248 bool hasBFM() const { 249 return hasBFE(); 250 } 251 252 bool hasBCNT(unsigned Size) const { 253 if (Size == 32) 254 return (getGeneration() >= EVERGREEN); 255 256 if (Size == 64) 257 return (getGeneration() >= SOUTHERN_ISLANDS); 258 259 return false; 260 } 261 262 bool hasMulU24() const { 263 return (getGeneration() >= EVERGREEN); 264 } 265 266 bool hasMulI24() const { 267 return (getGeneration() >= SOUTHERN_ISLANDS || 268 hasCaymanISA()); 269 } 270 271 bool hasFFBL() const { 272 return (getGeneration() >= EVERGREEN); 273 } 274 275 bool hasFFBH() const { 276 return (getGeneration() >= EVERGREEN); 277 } 278 279 bool hasMed3_16() const { 280 return getGeneration() >= GFX9; 281 } 282 283 bool hasCARRY() const { 284 return (getGeneration() >= EVERGREEN); 285 } 286 287 bool hasBORROW() const { 288 return (getGeneration() >= EVERGREEN); 289 } 290 291 bool hasCaymanISA() const { 292 return CaymanISA; 293 } 294 295 TrapHandlerAbi getTrapHandlerAbi() const { 296 return isAmdHsaOS() ? TrapHandlerAbiHsa : TrapHandlerAbiNone; 297 } 298 299 bool isPromoteAllocaEnabled() const { 300 return EnablePromoteAlloca; 301 } 302 303 bool unsafeDSOffsetFoldingEnabled() const { 304 return EnableUnsafeDSOffsetFolding; 305 } 306 307 bool dumpCode() const { 308 return DumpCode; 309 } 310 311 /// Return the amount of LDS that can be used that will not restrict the 312 /// occupancy lower than WaveCount. 313 unsigned getMaxLocalMemSizeWithWaveCount(unsigned WaveCount, 314 const Function &) const; 315 316 /// Inverse of getMaxLocalMemWithWaveCount. Return the maximum wavecount if 317 /// the given LDS memory size is the only constraint. 318 unsigned getOccupancyWithLocalMemSize(uint32_t Bytes, const Function &) const; 319 320 bool hasFP16Denormals() const { 321 return FP64FP16Denormals; 322 } 323 324 bool hasFP32Denormals() const { 325 return FP32Denormals; 326 } 327 328 bool hasFP64Denormals() const { 329 return FP64FP16Denormals; 330 } 331 332 bool hasFPExceptions() const { 333 return FPExceptions; 334 } 335 336 bool enableDX10Clamp() const { 337 return DX10Clamp; 338 } 339 340 bool enableIEEEBit(const MachineFunction &MF) const { 341 return AMDGPU::isCompute(MF.getFunction()->getCallingConv()); 342 } 343 344 bool useFlatForGlobal() const { 345 return FlatForGlobal; 346 } 347 348 bool hasUnalignedBufferAccess() const { 349 return UnalignedBufferAccess; 350 } 351 352 bool hasUnalignedScratchAccess() const { 353 return UnalignedScratchAccess; 354 } 355 356 bool hasApertureRegs() const { 357 return HasApertureRegs; 358 } 359 360 bool isTrapHandlerEnabled() const { 361 return TrapHandler; 362 } 363 364 bool isXNACKEnabled() const { 365 return EnableXNACK; 366 } 367 368 bool hasFlatAddressSpace() const { 369 return FlatAddressSpace; 370 } 371 372 bool isMesaKernel(const MachineFunction &MF) const { 373 return isMesa3DOS() && !AMDGPU::isShader(MF.getFunction()->getCallingConv()); 374 } 375 376 // Covers VS/PS/CS graphics shaders 377 bool isMesaGfxShader(const MachineFunction &MF) const { 378 return isMesa3DOS() && AMDGPU::isShader(MF.getFunction()->getCallingConv()); 379 } 380 381 bool isAmdCodeObjectV2(const MachineFunction &MF) const { 382 return isAmdHsaOS() || isMesaKernel(MF); 383 } 384 385 bool hasFminFmaxLegacy() const { 386 return getGeneration() < AMDGPUSubtarget::VOLCANIC_ISLANDS; 387 } 388 389 /// \brief Returns the offset in bytes from the start of the input buffer 390 /// of the first explicit kernel argument. 391 unsigned getExplicitKernelArgOffset(const MachineFunction &MF) const { 392 return isAmdCodeObjectV2(MF) ? 0 : 36; 393 } 394 395 unsigned getAlignmentForImplicitArgPtr() const { 396 return isAmdHsaOS() ? 8 : 4; 397 } 398 399 unsigned getImplicitArgNumBytes(const MachineFunction &MF) const { 400 if (isMesaKernel(MF)) 401 return 16; 402 if (isAmdHsaOS() && isOpenCLEnv()) 403 return 32; 404 return 0; 405 } 406 407 unsigned getStackAlignment() const { 408 // Scratch is allocated in 256 dword per wave blocks. 409 return 4 * 256 / getWavefrontSize(); 410 } 411 412 bool enableMachineScheduler() const override { 413 return true; 414 } 415 416 bool enableSubRegLiveness() const override { 417 return true; 418 } 419 420 void setScalarizeGlobalBehavior(bool b) { ScalarizeGlobal = b;} 421 bool getScalarizeGlobalBehavior() const { return ScalarizeGlobal;} 422 423 /// \returns Number of execution units per compute unit supported by the 424 /// subtarget. 425 unsigned getEUsPerCU() const { 426 return AMDGPU::IsaInfo::getEUsPerCU(getFeatureBits()); 427 } 428 429 /// \returns Maximum number of work groups per compute unit supported by the 430 /// subtarget and limited by given \p FlatWorkGroupSize. 431 unsigned getMaxWorkGroupsPerCU(unsigned FlatWorkGroupSize) const { 432 return AMDGPU::IsaInfo::getMaxWorkGroupsPerCU(getFeatureBits(), 433 FlatWorkGroupSize); 434 } 435 436 /// \returns Maximum number of waves per compute unit supported by the 437 /// subtarget without any kind of limitation. 438 unsigned getMaxWavesPerCU() const { 439 return AMDGPU::IsaInfo::getMaxWavesPerCU(getFeatureBits()); 440 } 441 442 /// \returns Maximum number of waves per compute unit supported by the 443 /// subtarget and limited by given \p FlatWorkGroupSize. 444 unsigned getMaxWavesPerCU(unsigned FlatWorkGroupSize) const { 445 return AMDGPU::IsaInfo::getMaxWavesPerCU(getFeatureBits(), 446 FlatWorkGroupSize); 447 } 448 449 /// \returns Minimum number of waves per execution unit supported by the 450 /// subtarget. 451 unsigned getMinWavesPerEU() const { 452 return AMDGPU::IsaInfo::getMinWavesPerEU(getFeatureBits()); 453 } 454 455 /// \returns Maximum number of waves per execution unit supported by the 456 /// subtarget without any kind of limitation. 457 unsigned getMaxWavesPerEU() const { 458 return AMDGPU::IsaInfo::getMaxWavesPerEU(getFeatureBits()); 459 } 460 461 /// \returns Maximum number of waves per execution unit supported by the 462 /// subtarget and limited by given \p FlatWorkGroupSize. 463 unsigned getMaxWavesPerEU(unsigned FlatWorkGroupSize) const { 464 return AMDGPU::IsaInfo::getMaxWavesPerEU(getFeatureBits(), 465 FlatWorkGroupSize); 466 } 467 468 /// \returns Minimum flat work group size supported by the subtarget. 469 unsigned getMinFlatWorkGroupSize() const { 470 return AMDGPU::IsaInfo::getMinFlatWorkGroupSize(getFeatureBits()); 471 } 472 473 /// \returns Maximum flat work group size supported by the subtarget. 474 unsigned getMaxFlatWorkGroupSize() const { 475 return AMDGPU::IsaInfo::getMaxFlatWorkGroupSize(getFeatureBits()); 476 } 477 478 /// \returns Number of waves per work group supported by the subtarget and 479 /// limited by given \p FlatWorkGroupSize. 480 unsigned getWavesPerWorkGroup(unsigned FlatWorkGroupSize) const { 481 return AMDGPU::IsaInfo::getWavesPerWorkGroup(getFeatureBits(), 482 FlatWorkGroupSize); 483 } 484 485 /// \returns Subtarget's default pair of minimum/maximum flat work group sizes 486 /// for function \p F, or minimum/maximum flat work group sizes explicitly 487 /// requested using "amdgpu-flat-work-group-size" attribute attached to 488 /// function \p F. 489 /// 490 /// \returns Subtarget's default values if explicitly requested values cannot 491 /// be converted to integer, or violate subtarget's specifications. 492 std::pair<unsigned, unsigned> getFlatWorkGroupSizes(const Function &F) const; 493 494 /// \returns Subtarget's default pair of minimum/maximum number of waves per 495 /// execution unit for function \p F, or minimum/maximum number of waves per 496 /// execution unit explicitly requested using "amdgpu-waves-per-eu" attribute 497 /// attached to function \p F. 498 /// 499 /// \returns Subtarget's default values if explicitly requested values cannot 500 /// be converted to integer, violate subtarget's specifications, or are not 501 /// compatible with minimum/maximum number of waves limited by flat work group 502 /// size, register usage, and/or lds usage. 503 std::pair<unsigned, unsigned> getWavesPerEU(const Function &F) const; 504 }; 505 506 class R600Subtarget final : public AMDGPUSubtarget { 507 private: 508 R600InstrInfo InstrInfo; 509 R600FrameLowering FrameLowering; 510 R600TargetLowering TLInfo; 511 512 public: 513 R600Subtarget(const Triple &TT, StringRef CPU, StringRef FS, 514 const TargetMachine &TM); 515 516 const R600InstrInfo *getInstrInfo() const override { 517 return &InstrInfo; 518 } 519 520 const R600FrameLowering *getFrameLowering() const override { 521 return &FrameLowering; 522 } 523 524 const R600TargetLowering *getTargetLowering() const override { 525 return &TLInfo; 526 } 527 528 const R600RegisterInfo *getRegisterInfo() const override { 529 return &InstrInfo.getRegisterInfo(); 530 } 531 532 bool hasCFAluBug() const { 533 return CFALUBug; 534 } 535 536 bool hasVertexCache() const { 537 return HasVertexCache; 538 } 539 540 short getTexVTXClauseSize() const { 541 return TexVTXClauseSize; 542 } 543 }; 544 545 class SISubtarget final : public AMDGPUSubtarget { 546 private: 547 SIInstrInfo InstrInfo; 548 SIFrameLowering FrameLowering; 549 SITargetLowering TLInfo; 550 std::unique_ptr<GISelAccessor> GISel; 551 552 public: 553 SISubtarget(const Triple &TT, StringRef CPU, StringRef FS, 554 const TargetMachine &TM); 555 556 const SIInstrInfo *getInstrInfo() const override { 557 return &InstrInfo; 558 } 559 560 const SIFrameLowering *getFrameLowering() const override { 561 return &FrameLowering; 562 } 563 564 const SITargetLowering *getTargetLowering() const override { 565 return &TLInfo; 566 } 567 568 const CallLowering *getCallLowering() const override { 569 assert(GISel && "Access to GlobalISel APIs not set"); 570 return GISel->getCallLowering(); 571 } 572 573 const InstructionSelector *getInstructionSelector() const override { 574 assert(GISel && "Access to GlobalISel APIs not set"); 575 return GISel->getInstructionSelector(); 576 } 577 578 const LegalizerInfo *getLegalizerInfo() const override { 579 assert(GISel && "Access to GlobalISel APIs not set"); 580 return GISel->getLegalizerInfo(); 581 } 582 583 const RegisterBankInfo *getRegBankInfo() const override { 584 assert(GISel && "Access to GlobalISel APIs not set"); 585 return GISel->getRegBankInfo(); 586 } 587 588 const SIRegisterInfo *getRegisterInfo() const override { 589 return &InstrInfo.getRegisterInfo(); 590 } 591 592 void setGISelAccessor(GISelAccessor &GISel) { 593 this->GISel.reset(&GISel); 594 } 595 596 // XXX - Why is this here if it isn't in the default pass set? 597 bool enableEarlyIfConversion() const override { 598 return true; 599 } 600 601 void overrideSchedPolicy(MachineSchedPolicy &Policy, 602 unsigned NumRegionInstrs) const override; 603 604 bool isVGPRSpillingEnabled(const Function& F) const; 605 606 unsigned getMaxNumUserSGPRs() const { 607 return 16; 608 } 609 610 bool hasSMemRealTime() const { 611 return HasSMemRealTime; 612 } 613 614 bool hasMovrel() const { 615 return HasMovrel; 616 } 617 618 bool hasVGPRIndexMode() const { 619 return HasVGPRIndexMode; 620 } 621 622 bool hasScalarCompareEq64() const { 623 return getGeneration() >= VOLCANIC_ISLANDS; 624 } 625 626 bool hasScalarStores() const { 627 return HasScalarStores; 628 } 629 630 bool hasInv2PiInlineImm() const { 631 return HasInv2PiInlineImm; 632 } 633 634 bool hasSDWA() const { 635 return HasSDWA; 636 } 637 638 bool hasDPP() const { 639 return HasDPP; 640 } 641 642 bool enableSIScheduler() const { 643 return EnableSIScheduler; 644 } 645 646 bool debuggerSupported() const { 647 return debuggerInsertNops() && debuggerReserveRegs() && 648 debuggerEmitPrologue(); 649 } 650 651 bool debuggerInsertNops() const { 652 return DebuggerInsertNops; 653 } 654 655 bool debuggerReserveRegs() const { 656 return DebuggerReserveRegs; 657 } 658 659 bool debuggerEmitPrologue() const { 660 return DebuggerEmitPrologue; 661 } 662 663 bool loadStoreOptEnabled() const { 664 return EnableLoadStoreOpt; 665 } 666 667 bool hasSGPRInitBug() const { 668 return SGPRInitBug; 669 } 670 671 bool has12DWordStoreHazard() const { 672 return getGeneration() != AMDGPUSubtarget::SOUTHERN_ISLANDS; 673 } 674 675 bool hasSMovFedHazard() const { 676 return getGeneration() >= AMDGPUSubtarget::GFX9; 677 } 678 679 bool hasReadM0Hazard() const { 680 return getGeneration() >= AMDGPUSubtarget::GFX9; 681 } 682 683 unsigned getKernArgSegmentSize(const MachineFunction &MF, unsigned ExplictArgBytes) const; 684 685 /// Return the maximum number of waves per SIMD for kernels using \p SGPRs SGPRs 686 unsigned getOccupancyWithNumSGPRs(unsigned SGPRs) const; 687 688 /// Return the maximum number of waves per SIMD for kernels using \p VGPRs VGPRs 689 unsigned getOccupancyWithNumVGPRs(unsigned VGPRs) const; 690 691 /// \returns True if waitcnt instruction is needed before barrier instruction, 692 /// false otherwise. 693 bool needWaitcntBeforeBarrier() const { 694 return getGeneration() < GFX9; 695 } 696 697 /// \returns true if the flat_scratch register should be initialized with the 698 /// pointer to the wave's scratch memory rather than a size and offset. 699 bool flatScratchIsPointer() const { 700 return getGeneration() >= GFX9; 701 } 702 703 /// \returns SGPR allocation granularity supported by the subtarget. 704 unsigned getSGPRAllocGranule() const { 705 return AMDGPU::IsaInfo::getSGPRAllocGranule(getFeatureBits()); 706 } 707 708 /// \returns SGPR encoding granularity supported by the subtarget. 709 unsigned getSGPREncodingGranule() const { 710 return AMDGPU::IsaInfo::getSGPREncodingGranule(getFeatureBits()); 711 } 712 713 /// \returns Total number of SGPRs supported by the subtarget. 714 unsigned getTotalNumSGPRs() const { 715 return AMDGPU::IsaInfo::getTotalNumSGPRs(getFeatureBits()); 716 } 717 718 /// \returns Addressable number of SGPRs supported by the subtarget. 719 unsigned getAddressableNumSGPRs() const { 720 return AMDGPU::IsaInfo::getAddressableNumSGPRs(getFeatureBits()); 721 } 722 723 /// \returns Minimum number of SGPRs that meets the given number of waves per 724 /// execution unit requirement supported by the subtarget. 725 unsigned getMinNumSGPRs(unsigned WavesPerEU) const { 726 return AMDGPU::IsaInfo::getMinNumSGPRs(getFeatureBits(), WavesPerEU); 727 } 728 729 /// \returns Maximum number of SGPRs that meets the given number of waves per 730 /// execution unit requirement supported by the subtarget. 731 unsigned getMaxNumSGPRs(unsigned WavesPerEU, bool Addressable) const { 732 return AMDGPU::IsaInfo::getMaxNumSGPRs(getFeatureBits(), WavesPerEU, 733 Addressable); 734 } 735 736 /// \returns Reserved number of SGPRs for given function \p MF. 737 unsigned getReservedNumSGPRs(const MachineFunction &MF) const; 738 739 /// \returns Maximum number of SGPRs that meets number of waves per execution 740 /// unit requirement for function \p MF, or number of SGPRs explicitly 741 /// requested using "amdgpu-num-sgpr" attribute attached to function \p MF. 742 /// 743 /// \returns Value that meets number of waves per execution unit requirement 744 /// if explicitly requested value cannot be converted to integer, violates 745 /// subtarget's specifications, or does not meet number of waves per execution 746 /// unit requirement. 747 unsigned getMaxNumSGPRs(const MachineFunction &MF) const; 748 749 /// \returns VGPR allocation granularity supported by the subtarget. 750 unsigned getVGPRAllocGranule() const { 751 return AMDGPU::IsaInfo::getVGPRAllocGranule(getFeatureBits());; 752 } 753 754 /// \returns VGPR encoding granularity supported by the subtarget. 755 unsigned getVGPREncodingGranule() const { 756 return AMDGPU::IsaInfo::getVGPREncodingGranule(getFeatureBits()); 757 } 758 759 /// \returns Total number of VGPRs supported by the subtarget. 760 unsigned getTotalNumVGPRs() const { 761 return AMDGPU::IsaInfo::getTotalNumVGPRs(getFeatureBits()); 762 } 763 764 /// \returns Addressable number of VGPRs supported by the subtarget. 765 unsigned getAddressableNumVGPRs() const { 766 return AMDGPU::IsaInfo::getAddressableNumVGPRs(getFeatureBits()); 767 } 768 769 /// \returns Minimum number of VGPRs that meets given number of waves per 770 /// execution unit requirement supported by the subtarget. 771 unsigned getMinNumVGPRs(unsigned WavesPerEU) const { 772 return AMDGPU::IsaInfo::getMinNumVGPRs(getFeatureBits(), WavesPerEU); 773 } 774 775 /// \returns Maximum number of VGPRs that meets given number of waves per 776 /// execution unit requirement supported by the subtarget. 777 unsigned getMaxNumVGPRs(unsigned WavesPerEU) const { 778 return AMDGPU::IsaInfo::getMaxNumVGPRs(getFeatureBits(), WavesPerEU); 779 } 780 781 /// \returns Reserved number of VGPRs for given function \p MF. 782 unsigned getReservedNumVGPRs(const MachineFunction &MF) const { 783 return debuggerReserveRegs() ? 4 : 0; 784 } 785 786 /// \returns Maximum number of VGPRs that meets number of waves per execution 787 /// unit requirement for function \p MF, or number of VGPRs explicitly 788 /// requested using "amdgpu-num-vgpr" attribute attached to function \p MF. 789 /// 790 /// \returns Value that meets number of waves per execution unit requirement 791 /// if explicitly requested value cannot be converted to integer, violates 792 /// subtarget's specifications, or does not meet number of waves per execution 793 /// unit requirement. 794 unsigned getMaxNumVGPRs(const MachineFunction &MF) const; 795 }; 796 797 } // end namespace llvm 798 799 #endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUSUBTARGET_H 800