1 //=====-- GCNSubtarget.h - Define GCN Subtarget for AMDGPU ------*- 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 /// AMD GCN specific subclass of TargetSubtarget. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_LIB_TARGET_AMDGPU_GCNSUBTARGET_H 15 #define LLVM_LIB_TARGET_AMDGPU_GCNSUBTARGET_H 16 17 #include "AMDGPUCallLowering.h" 18 #include "AMDGPUSubtarget.h" 19 #include "SIFrameLowering.h" 20 #include "SIISelLowering.h" 21 #include "SIInstrInfo.h" 22 #include "llvm/CodeGen/SelectionDAGTargetInfo.h" 23 24 namespace llvm { 25 26 class MCInst; 27 class MCInstrInfo; 28 29 } // namespace llvm 30 31 #define GET_SUBTARGETINFO_HEADER 32 #include "AMDGPUGenSubtargetInfo.inc" 33 34 namespace llvm { 35 36 class GCNTargetMachine; 37 38 class GCNSubtarget final : public AMDGPUGenSubtargetInfo, 39 public AMDGPUSubtarget { 40 41 using AMDGPUSubtarget::getMaxWavesPerEU; 42 43 public: 44 // Following 2 enums are documented at: 45 // - https://llvm.org/docs/AMDGPUUsage.html#trap-handler-abi 46 enum class TrapHandlerAbi { 47 NONE = 0x00, 48 AMDHSA = 0x01, 49 }; 50 51 enum class TrapID { 52 LLVMAMDHSATrap = 0x02, 53 LLVMAMDHSADebugTrap = 0x03, 54 }; 55 56 private: 57 /// GlobalISel related APIs. 58 std::unique_ptr<AMDGPUCallLowering> CallLoweringInfo; 59 std::unique_ptr<InlineAsmLowering> InlineAsmLoweringInfo; 60 std::unique_ptr<InstructionSelector> InstSelector; 61 std::unique_ptr<LegalizerInfo> Legalizer; 62 std::unique_ptr<RegisterBankInfo> RegBankInfo; 63 64 protected: 65 // Basic subtarget description. 66 Triple TargetTriple; 67 AMDGPU::IsaInfo::AMDGPUTargetID TargetID; 68 unsigned Gen; 69 InstrItineraryData InstrItins; 70 int LDSBankCount; 71 unsigned MaxPrivateElementSize; 72 73 // Possibly statically set by tablegen, but may want to be overridden. 74 bool FastFMAF32; 75 bool FastDenormalF32; 76 bool HalfRate64Ops; 77 bool FullRate64Ops; 78 79 // Dynamically set bits that enable features. 80 bool FlatForGlobal; 81 bool AutoWaitcntBeforeBarrier; 82 bool UnalignedScratchAccess; 83 bool UnalignedAccessMode; 84 bool HasApertureRegs; 85 bool SupportsXNACK; 86 87 // This should not be used directly. 'TargetID' tracks the dynamic settings 88 // for XNACK. 89 bool EnableXNACK; 90 91 bool EnableTgSplit; 92 bool EnableCuMode; 93 bool TrapHandler; 94 95 // Used as options. 96 bool EnableLoadStoreOpt; 97 bool EnableUnsafeDSOffsetFolding; 98 bool EnableSIScheduler; 99 bool EnableDS128; 100 bool EnablePRTStrictNull; 101 bool DumpCode; 102 103 // Subtarget statically properties set by tablegen 104 bool FP64; 105 bool FMA; 106 bool MIMG_R128; 107 bool IsGCN; 108 bool CIInsts; 109 bool GFX8Insts; 110 bool GFX9Insts; 111 bool GFX90AInsts; 112 bool GFX10Insts; 113 bool GFX10_3Insts; 114 bool GFX7GFX8GFX9Insts; 115 bool SGPRInitBug; 116 bool NegativeScratchOffsetBug; 117 bool NegativeUnalignedScratchOffsetBug; 118 bool HasSMemRealTime; 119 bool HasIntClamp; 120 bool HasFmaMixInsts; 121 bool HasMovrel; 122 bool HasVGPRIndexMode; 123 bool HasScalarStores; 124 bool HasScalarAtomics; 125 bool HasSDWAOmod; 126 bool HasSDWAScalar; 127 bool HasSDWASdst; 128 bool HasSDWAMac; 129 bool HasSDWAOutModsVOPC; 130 bool HasDPP; 131 bool HasDPP8; 132 bool Has64BitDPP; 133 bool HasPackedFP32Ops; 134 bool HasExtendedImageInsts; 135 bool HasR128A16; 136 bool HasGFX10A16; 137 bool HasG16; 138 bool HasNSAEncoding; 139 bool GFX10_AEncoding; 140 bool GFX10_BEncoding; 141 bool HasDLInsts; 142 bool HasDot1Insts; 143 bool HasDot2Insts; 144 bool HasDot3Insts; 145 bool HasDot4Insts; 146 bool HasDot5Insts; 147 bool HasDot6Insts; 148 bool HasDot7Insts; 149 bool HasMAIInsts; 150 bool HasPkFmacF16Inst; 151 bool HasAtomicFaddInsts; 152 bool SupportsSRAMECC; 153 154 // This should not be used directly. 'TargetID' tracks the dynamic settings 155 // for SRAMECC. 156 bool EnableSRAMECC; 157 158 bool HasNoSdstCMPX; 159 bool HasVscnt; 160 bool HasGetWaveIdInst; 161 bool HasSMemTimeInst; 162 bool HasShaderCyclesRegister; 163 bool HasRegisterBanking; 164 bool HasVOP3Literal; 165 bool HasNoDataDepHazard; 166 bool FlatAddressSpace; 167 bool FlatInstOffsets; 168 bool FlatGlobalInsts; 169 bool FlatScratchInsts; 170 bool ScalarFlatScratchInsts; 171 bool HasArchitectedFlatScratch; 172 bool AddNoCarryInsts; 173 bool HasUnpackedD16VMem; 174 bool R600ALUInst; 175 bool CaymanISA; 176 bool CFALUBug; 177 bool LDSMisalignedBug; 178 bool HasMFMAInlineLiteralBug; 179 bool HasVertexCache; 180 short TexVTXClauseSize; 181 bool UnalignedBufferAccess; 182 bool UnalignedDSAccess; 183 bool HasPackedTID; 184 bool ScalarizeGlobal; 185 186 bool HasVcmpxPermlaneHazard; 187 bool HasVMEMtoScalarWriteHazard; 188 bool HasSMEMtoVectorWriteHazard; 189 bool HasInstFwdPrefetchBug; 190 bool HasVcmpxExecWARHazard; 191 bool HasLdsBranchVmemWARHazard; 192 bool HasNSAtoVMEMBug; 193 bool HasNSAClauseBug; 194 bool HasOffset3fBug; 195 bool HasFlatSegmentOffsetBug; 196 bool HasImageStoreD16Bug; 197 bool HasImageGather4D16Bug; 198 199 // Dummy feature to use for assembler in tablegen. 200 bool FeatureDisable; 201 202 SelectionDAGTargetInfo TSInfo; 203 private: 204 SIInstrInfo InstrInfo; 205 SITargetLowering TLInfo; 206 SIFrameLowering FrameLowering; 207 208 public: 209 // See COMPUTE_TMPRING_SIZE.WAVESIZE, 13-bit field in units of 256-dword. 210 static const unsigned MaxWaveScratchSize = (256 * 4) * ((1 << 13) - 1); 211 212 GCNSubtarget(const Triple &TT, StringRef GPU, StringRef FS, 213 const GCNTargetMachine &TM); 214 ~GCNSubtarget() override; 215 216 GCNSubtarget &initializeSubtargetDependencies(const Triple &TT, 217 StringRef GPU, StringRef FS); 218 219 const SIInstrInfo *getInstrInfo() const override { 220 return &InstrInfo; 221 } 222 223 const SIFrameLowering *getFrameLowering() const override { 224 return &FrameLowering; 225 } 226 227 const SITargetLowering *getTargetLowering() const override { 228 return &TLInfo; 229 } 230 231 const SIRegisterInfo *getRegisterInfo() const override { 232 return &InstrInfo.getRegisterInfo(); 233 } 234 235 const CallLowering *getCallLowering() const override { 236 return CallLoweringInfo.get(); 237 } 238 239 const InlineAsmLowering *getInlineAsmLowering() const override { 240 return InlineAsmLoweringInfo.get(); 241 } 242 243 InstructionSelector *getInstructionSelector() const override { 244 return InstSelector.get(); 245 } 246 247 const LegalizerInfo *getLegalizerInfo() const override { 248 return Legalizer.get(); 249 } 250 251 const RegisterBankInfo *getRegBankInfo() const override { 252 return RegBankInfo.get(); 253 } 254 255 const AMDGPU::IsaInfo::AMDGPUTargetID &getTargetID() const { 256 return TargetID; 257 } 258 259 // Nothing implemented, just prevent crashes on use. 260 const SelectionDAGTargetInfo *getSelectionDAGInfo() const override { 261 return &TSInfo; 262 } 263 264 const InstrItineraryData *getInstrItineraryData() const override { 265 return &InstrItins; 266 } 267 268 void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS); 269 270 Generation getGeneration() const { 271 return (Generation)Gen; 272 } 273 274 /// Return the number of high bits known to be zero fror a frame index. 275 unsigned getKnownHighZeroBitsForFrameIndex() const { 276 return countLeadingZeros(MaxWaveScratchSize) + getWavefrontSizeLog2(); 277 } 278 279 int getLDSBankCount() const { 280 return LDSBankCount; 281 } 282 283 unsigned getMaxPrivateElementSize(bool ForBufferRSrc = false) const { 284 return (ForBufferRSrc || !enableFlatScratch()) ? MaxPrivateElementSize : 16; 285 } 286 287 unsigned getConstantBusLimit(unsigned Opcode) const; 288 289 bool hasIntClamp() const { 290 return HasIntClamp; 291 } 292 293 bool hasFP64() const { 294 return FP64; 295 } 296 297 bool hasMIMG_R128() const { 298 return MIMG_R128; 299 } 300 301 bool hasHWFP64() const { 302 return FP64; 303 } 304 305 bool hasFastFMAF32() const { 306 return FastFMAF32; 307 } 308 309 bool hasHalfRate64Ops() const { 310 return HalfRate64Ops; 311 } 312 313 bool hasFullRate64Ops() const { 314 return FullRate64Ops; 315 } 316 317 bool hasAddr64() const { 318 return (getGeneration() < AMDGPUSubtarget::VOLCANIC_ISLANDS); 319 } 320 321 bool hasFlat() const { 322 return (getGeneration() > AMDGPUSubtarget::SOUTHERN_ISLANDS); 323 } 324 325 // Return true if the target only has the reverse operand versions of VALU 326 // shift instructions (e.g. v_lshrrev_b32, and no v_lshr_b32). 327 bool hasOnlyRevVALUShifts() const { 328 return getGeneration() >= VOLCANIC_ISLANDS; 329 } 330 331 bool hasFractBug() const { 332 return getGeneration() == SOUTHERN_ISLANDS; 333 } 334 335 bool hasBFE() const { 336 return true; 337 } 338 339 bool hasBFI() const { 340 return true; 341 } 342 343 bool hasBFM() const { 344 return hasBFE(); 345 } 346 347 bool hasBCNT(unsigned Size) const { 348 return true; 349 } 350 351 bool hasFFBL() const { 352 return true; 353 } 354 355 bool hasFFBH() const { 356 return true; 357 } 358 359 bool hasMed3_16() const { 360 return getGeneration() >= AMDGPUSubtarget::GFX9; 361 } 362 363 bool hasMin3Max3_16() const { 364 return getGeneration() >= AMDGPUSubtarget::GFX9; 365 } 366 367 bool hasFmaMixInsts() const { 368 return HasFmaMixInsts; 369 } 370 371 bool hasCARRY() const { 372 return true; 373 } 374 375 bool hasFMA() const { 376 return FMA; 377 } 378 379 bool hasSwap() const { 380 return GFX9Insts; 381 } 382 383 bool hasScalarPackInsts() const { 384 return GFX9Insts; 385 } 386 387 bool hasScalarMulHiInsts() const { 388 return GFX9Insts; 389 } 390 391 TrapHandlerAbi getTrapHandlerAbi() const { 392 return isAmdHsaOS() ? TrapHandlerAbi::AMDHSA : TrapHandlerAbi::NONE; 393 } 394 395 bool supportsGetDoorbellID() const { 396 // The S_GETREG DOORBELL_ID is supported by all GFX9 onward targets. 397 return getGeneration() >= GFX9; 398 } 399 400 /// True if the offset field of DS instructions works as expected. On SI, the 401 /// offset uses a 16-bit adder and does not always wrap properly. 402 bool hasUsableDSOffset() const { 403 return getGeneration() >= SEA_ISLANDS; 404 } 405 406 bool unsafeDSOffsetFoldingEnabled() const { 407 return EnableUnsafeDSOffsetFolding; 408 } 409 410 /// Condition output from div_scale is usable. 411 bool hasUsableDivScaleConditionOutput() const { 412 return getGeneration() != SOUTHERN_ISLANDS; 413 } 414 415 /// Extra wait hazard is needed in some cases before 416 /// s_cbranch_vccnz/s_cbranch_vccz. 417 bool hasReadVCCZBug() const { 418 return getGeneration() <= SEA_ISLANDS; 419 } 420 421 /// Writes to VCC_LO/VCC_HI update the VCCZ flag. 422 bool partialVCCWritesUpdateVCCZ() const { 423 return getGeneration() >= GFX10; 424 } 425 426 /// A read of an SGPR by SMRD instruction requires 4 wait states when the SGPR 427 /// was written by a VALU instruction. 428 bool hasSMRDReadVALUDefHazard() const { 429 return getGeneration() == SOUTHERN_ISLANDS; 430 } 431 432 /// A read of an SGPR by a VMEM instruction requires 5 wait states when the 433 /// SGPR was written by a VALU Instruction. 434 bool hasVMEMReadSGPRVALUDefHazard() const { 435 return getGeneration() >= VOLCANIC_ISLANDS; 436 } 437 438 bool hasRFEHazards() const { 439 return getGeneration() >= VOLCANIC_ISLANDS; 440 } 441 442 /// Number of hazard wait states for s_setreg_b32/s_setreg_imm32_b32. 443 unsigned getSetRegWaitStates() const { 444 return getGeneration() <= SEA_ISLANDS ? 1 : 2; 445 } 446 447 bool dumpCode() const { 448 return DumpCode; 449 } 450 451 /// Return the amount of LDS that can be used that will not restrict the 452 /// occupancy lower than WaveCount. 453 unsigned getMaxLocalMemSizeWithWaveCount(unsigned WaveCount, 454 const Function &) const; 455 456 bool supportsMinMaxDenormModes() const { 457 return getGeneration() >= AMDGPUSubtarget::GFX9; 458 } 459 460 /// \returns If target supports S_DENORM_MODE. 461 bool hasDenormModeInst() const { 462 return getGeneration() >= AMDGPUSubtarget::GFX10; 463 } 464 465 bool useFlatForGlobal() const { 466 return FlatForGlobal; 467 } 468 469 /// \returns If target supports ds_read/write_b128 and user enables generation 470 /// of ds_read/write_b128. 471 bool useDS128() const { 472 return CIInsts && EnableDS128; 473 } 474 475 /// \return If target supports ds_read/write_b96/128. 476 bool hasDS96AndDS128() const { 477 return CIInsts; 478 } 479 480 /// Have v_trunc_f64, v_ceil_f64, v_rndne_f64 481 bool haveRoundOpsF64() const { 482 return CIInsts; 483 } 484 485 /// \returns If MUBUF instructions always perform range checking, even for 486 /// buffer resources used for private memory access. 487 bool privateMemoryResourceIsRangeChecked() const { 488 return getGeneration() < AMDGPUSubtarget::GFX9; 489 } 490 491 /// \returns If target requires PRT Struct NULL support (zero result registers 492 /// for sparse texture support). 493 bool usePRTStrictNull() const { 494 return EnablePRTStrictNull; 495 } 496 497 bool hasAutoWaitcntBeforeBarrier() const { 498 return AutoWaitcntBeforeBarrier; 499 } 500 501 bool hasUnalignedBufferAccess() const { 502 return UnalignedBufferAccess; 503 } 504 505 bool hasUnalignedBufferAccessEnabled() const { 506 return UnalignedBufferAccess && UnalignedAccessMode; 507 } 508 509 bool hasUnalignedDSAccess() const { 510 return UnalignedDSAccess; 511 } 512 513 bool hasUnalignedDSAccessEnabled() const { 514 return UnalignedDSAccess && UnalignedAccessMode; 515 } 516 517 bool hasUnalignedScratchAccess() const { 518 return UnalignedScratchAccess; 519 } 520 521 bool hasUnalignedAccessMode() const { 522 return UnalignedAccessMode; 523 } 524 525 bool hasApertureRegs() const { 526 return HasApertureRegs; 527 } 528 529 bool isTrapHandlerEnabled() const { 530 return TrapHandler; 531 } 532 533 bool isXNACKEnabled() const { 534 return TargetID.isXnackOnOrAny(); 535 } 536 537 bool isTgSplitEnabled() const { 538 return EnableTgSplit; 539 } 540 541 bool isCuModeEnabled() const { 542 return EnableCuMode; 543 } 544 545 bool hasFlatAddressSpace() const { 546 return FlatAddressSpace; 547 } 548 549 bool hasFlatScrRegister() const { 550 return hasFlatAddressSpace(); 551 } 552 553 bool hasFlatInstOffsets() const { 554 return FlatInstOffsets; 555 } 556 557 bool hasFlatGlobalInsts() const { 558 return FlatGlobalInsts; 559 } 560 561 bool hasFlatScratchInsts() const { 562 return FlatScratchInsts; 563 } 564 565 // Check if target supports ST addressing mode with FLAT scratch instructions. 566 // The ST addressing mode means no registers are used, either VGPR or SGPR, 567 // but only immediate offset is swizzled and added to the FLAT scratch base. 568 bool hasFlatScratchSTMode() const { 569 return hasFlatScratchInsts() && hasGFX10_3Insts(); 570 } 571 572 bool hasScalarFlatScratchInsts() const { 573 return ScalarFlatScratchInsts; 574 } 575 576 bool hasGlobalAddTidInsts() const { 577 return GFX10_BEncoding; 578 } 579 580 bool hasAtomicCSub() const { 581 return GFX10_BEncoding; 582 } 583 584 bool hasMultiDwordFlatScratchAddressing() const { 585 return getGeneration() >= GFX9; 586 } 587 588 bool hasFlatSegmentOffsetBug() const { 589 return HasFlatSegmentOffsetBug; 590 } 591 592 bool hasFlatLgkmVMemCountInOrder() const { 593 return getGeneration() > GFX9; 594 } 595 596 bool hasD16LoadStore() const { 597 return getGeneration() >= GFX9; 598 } 599 600 bool d16PreservesUnusedBits() const { 601 return hasD16LoadStore() && !TargetID.isSramEccOnOrAny(); 602 } 603 604 bool hasD16Images() const { 605 return getGeneration() >= VOLCANIC_ISLANDS; 606 } 607 608 /// Return if most LDS instructions have an m0 use that require m0 to be 609 /// iniitalized. 610 bool ldsRequiresM0Init() const { 611 return getGeneration() < GFX9; 612 } 613 614 // True if the hardware rewinds and replays GWS operations if a wave is 615 // preempted. 616 // 617 // If this is false, a GWS operation requires testing if a nack set the 618 // MEM_VIOL bit, and repeating if so. 619 bool hasGWSAutoReplay() const { 620 return getGeneration() >= GFX9; 621 } 622 623 /// \returns if target has ds_gws_sema_release_all instruction. 624 bool hasGWSSemaReleaseAll() const { 625 return CIInsts; 626 } 627 628 /// \returns true if the target has integer add/sub instructions that do not 629 /// produce a carry-out. This includes v_add_[iu]32, v_sub_[iu]32, 630 /// v_add_[iu]16, and v_sub_[iu]16, all of which support the clamp modifier 631 /// for saturation. 632 bool hasAddNoCarry() const { 633 return AddNoCarryInsts; 634 } 635 636 bool hasUnpackedD16VMem() const { 637 return HasUnpackedD16VMem; 638 } 639 640 // Covers VS/PS/CS graphics shaders 641 bool isMesaGfxShader(const Function &F) const { 642 return isMesa3DOS() && AMDGPU::isShader(F.getCallingConv()); 643 } 644 645 bool hasMad64_32() const { 646 return getGeneration() >= SEA_ISLANDS; 647 } 648 649 bool hasSDWAOmod() const { 650 return HasSDWAOmod; 651 } 652 653 bool hasSDWAScalar() const { 654 return HasSDWAScalar; 655 } 656 657 bool hasSDWASdst() const { 658 return HasSDWASdst; 659 } 660 661 bool hasSDWAMac() const { 662 return HasSDWAMac; 663 } 664 665 bool hasSDWAOutModsVOPC() const { 666 return HasSDWAOutModsVOPC; 667 } 668 669 bool hasDLInsts() const { 670 return HasDLInsts; 671 } 672 673 bool hasDot1Insts() const { 674 return HasDot1Insts; 675 } 676 677 bool hasDot2Insts() const { 678 return HasDot2Insts; 679 } 680 681 bool hasDot3Insts() const { 682 return HasDot3Insts; 683 } 684 685 bool hasDot4Insts() const { 686 return HasDot4Insts; 687 } 688 689 bool hasDot5Insts() const { 690 return HasDot5Insts; 691 } 692 693 bool hasDot6Insts() const { 694 return HasDot6Insts; 695 } 696 697 bool hasDot7Insts() const { 698 return HasDot7Insts; 699 } 700 701 bool hasMAIInsts() const { 702 return HasMAIInsts; 703 } 704 705 bool hasPkFmacF16Inst() const { 706 return HasPkFmacF16Inst; 707 } 708 709 bool hasAtomicFaddInsts() const { 710 return HasAtomicFaddInsts; 711 } 712 713 bool hasNoSdstCMPX() const { 714 return HasNoSdstCMPX; 715 } 716 717 bool hasVscnt() const { 718 return HasVscnt; 719 } 720 721 bool hasGetWaveIdInst() const { 722 return HasGetWaveIdInst; 723 } 724 725 bool hasSMemTimeInst() const { 726 return HasSMemTimeInst; 727 } 728 729 bool hasShaderCyclesRegister() const { 730 return HasShaderCyclesRegister; 731 } 732 733 bool hasRegisterBanking() const { 734 return HasRegisterBanking; 735 } 736 737 bool hasVOP3Literal() const { 738 return HasVOP3Literal; 739 } 740 741 bool hasNoDataDepHazard() const { 742 return HasNoDataDepHazard; 743 } 744 745 bool vmemWriteNeedsExpWaitcnt() const { 746 return getGeneration() < SEA_ISLANDS; 747 } 748 749 // Scratch is allocated in 256 dword per wave blocks for the entire 750 // wavefront. When viewed from the perspecive of an arbitrary workitem, this 751 // is 4-byte aligned. 752 // 753 // Only 4-byte alignment is really needed to access anything. Transformations 754 // on the pointer value itself may rely on the alignment / known low bits of 755 // the pointer. Set this to something above the minimum to avoid needing 756 // dynamic realignment in common cases. 757 Align getStackAlignment() const { return Align(16); } 758 759 bool enableMachineScheduler() const override { 760 return true; 761 } 762 763 bool useAA() const override; 764 765 bool enableSubRegLiveness() const override { 766 return true; 767 } 768 769 void setScalarizeGlobalBehavior(bool b) { ScalarizeGlobal = b; } 770 bool getScalarizeGlobalBehavior() const { return ScalarizeGlobal; } 771 772 // static wrappers 773 static bool hasHalfRate64Ops(const TargetSubtargetInfo &STI); 774 775 // XXX - Why is this here if it isn't in the default pass set? 776 bool enableEarlyIfConversion() const override { 777 return true; 778 } 779 780 bool enableFlatScratch() const; 781 782 void overrideSchedPolicy(MachineSchedPolicy &Policy, 783 unsigned NumRegionInstrs) const override; 784 785 unsigned getMaxNumUserSGPRs() const { 786 return 16; 787 } 788 789 bool hasSMemRealTime() const { 790 return HasSMemRealTime; 791 } 792 793 bool hasMovrel() const { 794 return HasMovrel; 795 } 796 797 bool hasVGPRIndexMode() const { 798 return HasVGPRIndexMode; 799 } 800 801 bool useVGPRIndexMode() const; 802 803 bool hasScalarCompareEq64() const { 804 return getGeneration() >= VOLCANIC_ISLANDS; 805 } 806 807 bool hasScalarStores() const { 808 return HasScalarStores; 809 } 810 811 bool hasScalarAtomics() const { 812 return HasScalarAtomics; 813 } 814 815 bool hasLDSFPAtomics() const { 816 return GFX8Insts; 817 } 818 819 /// \returns true if the subtarget has the v_permlanex16_b32 instruction. 820 bool hasPermLaneX16() const { return getGeneration() >= GFX10; } 821 822 bool hasDPP() const { 823 return HasDPP; 824 } 825 826 bool hasDPPBroadcasts() const { 827 return HasDPP && getGeneration() < GFX10; 828 } 829 830 bool hasDPPWavefrontShifts() const { 831 return HasDPP && getGeneration() < GFX10; 832 } 833 834 bool hasDPP8() const { 835 return HasDPP8; 836 } 837 838 bool has64BitDPP() const { 839 return Has64BitDPP; 840 } 841 842 bool hasPackedFP32Ops() const { 843 return HasPackedFP32Ops; 844 } 845 846 bool hasFmaakFmamkF32Insts() const { 847 return getGeneration() >= GFX10; 848 } 849 850 bool hasExtendedImageInsts() const { 851 return HasExtendedImageInsts; 852 } 853 854 bool hasR128A16() const { 855 return HasR128A16; 856 } 857 858 bool hasGFX10A16() const { 859 return HasGFX10A16; 860 } 861 862 bool hasA16() const { return hasR128A16() || hasGFX10A16(); } 863 864 bool hasG16() const { return HasG16; } 865 866 bool hasOffset3fBug() const { 867 return HasOffset3fBug; 868 } 869 870 bool hasImageStoreD16Bug() const { return HasImageStoreD16Bug; } 871 872 bool hasImageGather4D16Bug() const { return HasImageGather4D16Bug; } 873 874 bool hasNSAEncoding() const { return HasNSAEncoding; } 875 876 bool hasGFX10_AEncoding() const { 877 return GFX10_AEncoding; 878 } 879 880 bool hasGFX10_BEncoding() const { 881 return GFX10_BEncoding; 882 } 883 884 bool hasGFX10_3Insts() const { 885 return GFX10_3Insts; 886 } 887 888 bool hasMadF16() const; 889 890 bool enableSIScheduler() const { 891 return EnableSIScheduler; 892 } 893 894 bool loadStoreOptEnabled() const { 895 return EnableLoadStoreOpt; 896 } 897 898 bool hasSGPRInitBug() const { 899 return SGPRInitBug; 900 } 901 902 bool hasNegativeScratchOffsetBug() const { return NegativeScratchOffsetBug; } 903 904 bool hasNegativeUnalignedScratchOffsetBug() const { 905 return NegativeUnalignedScratchOffsetBug; 906 } 907 908 bool hasMFMAInlineLiteralBug() const { 909 return HasMFMAInlineLiteralBug; 910 } 911 912 bool has12DWordStoreHazard() const { 913 return getGeneration() != AMDGPUSubtarget::SOUTHERN_ISLANDS; 914 } 915 916 // \returns true if the subtarget supports DWORDX3 load/store instructions. 917 bool hasDwordx3LoadStores() const { 918 return CIInsts; 919 } 920 921 bool hasReadM0MovRelInterpHazard() const { 922 return getGeneration() == AMDGPUSubtarget::GFX9; 923 } 924 925 bool hasReadM0SendMsgHazard() const { 926 return getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS && 927 getGeneration() <= AMDGPUSubtarget::GFX9; 928 } 929 930 bool hasVcmpxPermlaneHazard() const { 931 return HasVcmpxPermlaneHazard; 932 } 933 934 bool hasVMEMtoScalarWriteHazard() const { 935 return HasVMEMtoScalarWriteHazard; 936 } 937 938 bool hasSMEMtoVectorWriteHazard() const { 939 return HasSMEMtoVectorWriteHazard; 940 } 941 942 bool hasLDSMisalignedBug() const { 943 return LDSMisalignedBug && !EnableCuMode; 944 } 945 946 bool hasInstFwdPrefetchBug() const { 947 return HasInstFwdPrefetchBug; 948 } 949 950 bool hasVcmpxExecWARHazard() const { 951 return HasVcmpxExecWARHazard; 952 } 953 954 bool hasLdsBranchVmemWARHazard() const { 955 return HasLdsBranchVmemWARHazard; 956 } 957 958 bool hasNSAtoVMEMBug() const { 959 return HasNSAtoVMEMBug; 960 } 961 962 bool hasNSAClauseBug() const { return HasNSAClauseBug; } 963 964 bool hasHardClauses() const { return getGeneration() >= GFX10; } 965 966 bool hasGFX90AInsts() const { return GFX90AInsts; } 967 968 /// Return if operations acting on VGPR tuples require even alignment. 969 bool needsAlignedVGPRs() const { return GFX90AInsts; } 970 971 bool hasPackedTID() const { return HasPackedTID; } 972 973 /// Return the maximum number of waves per SIMD for kernels using \p SGPRs 974 /// SGPRs 975 unsigned getOccupancyWithNumSGPRs(unsigned SGPRs) const; 976 977 /// Return the maximum number of waves per SIMD for kernels using \p VGPRs 978 /// VGPRs 979 unsigned getOccupancyWithNumVGPRs(unsigned VGPRs) const; 980 981 /// Return occupancy for the given function. Used LDS and a number of 982 /// registers if provided. 983 /// Note, occupancy can be affected by the scratch allocation as well, but 984 /// we do not have enough information to compute it. 985 unsigned computeOccupancy(const Function &F, unsigned LDSSize = 0, 986 unsigned NumSGPRs = 0, unsigned NumVGPRs = 0) const; 987 988 /// \returns true if the flat_scratch register should be initialized with the 989 /// pointer to the wave's scratch memory rather than a size and offset. 990 bool flatScratchIsPointer() const { 991 return getGeneration() >= AMDGPUSubtarget::GFX9; 992 } 993 994 /// \returns true if the flat_scratch register is initialized by the HW. 995 /// In this case it is readonly. 996 bool flatScratchIsArchitected() const { return HasArchitectedFlatScratch; } 997 998 /// \returns true if the machine has merged shaders in which s0-s7 are 999 /// reserved by the hardware and user SGPRs start at s8 1000 bool hasMergedShaders() const { 1001 return getGeneration() >= GFX9; 1002 } 1003 1004 /// \returns SGPR allocation granularity supported by the subtarget. 1005 unsigned getSGPRAllocGranule() const { 1006 return AMDGPU::IsaInfo::getSGPRAllocGranule(this); 1007 } 1008 1009 /// \returns SGPR encoding granularity supported by the subtarget. 1010 unsigned getSGPREncodingGranule() const { 1011 return AMDGPU::IsaInfo::getSGPREncodingGranule(this); 1012 } 1013 1014 /// \returns Total number of SGPRs supported by the subtarget. 1015 unsigned getTotalNumSGPRs() const { 1016 return AMDGPU::IsaInfo::getTotalNumSGPRs(this); 1017 } 1018 1019 /// \returns Addressable number of SGPRs supported by the subtarget. 1020 unsigned getAddressableNumSGPRs() const { 1021 return AMDGPU::IsaInfo::getAddressableNumSGPRs(this); 1022 } 1023 1024 /// \returns Minimum number of SGPRs that meets the given number of waves per 1025 /// execution unit requirement supported by the subtarget. 1026 unsigned getMinNumSGPRs(unsigned WavesPerEU) const { 1027 return AMDGPU::IsaInfo::getMinNumSGPRs(this, WavesPerEU); 1028 } 1029 1030 /// \returns Maximum number of SGPRs that meets the given number of waves per 1031 /// execution unit requirement supported by the subtarget. 1032 unsigned getMaxNumSGPRs(unsigned WavesPerEU, bool Addressable) const { 1033 return AMDGPU::IsaInfo::getMaxNumSGPRs(this, WavesPerEU, Addressable); 1034 } 1035 1036 /// \returns Reserved number of SGPRs. This is common 1037 /// utility function called by MachineFunction and 1038 /// Function variants of getReservedNumSGPRs. 1039 unsigned getBaseReservedNumSGPRs(const bool HasFlatScratchInit) const; 1040 /// \returns Reserved number of SGPRs for given machine function \p MF. 1041 unsigned getReservedNumSGPRs(const MachineFunction &MF) const; 1042 1043 /// \returns Reserved number of SGPRs for given function \p F. 1044 unsigned getReservedNumSGPRs(const Function &F) const; 1045 1046 /// \returns max num SGPRs. This is the common utility 1047 /// function called by MachineFunction and Function 1048 /// variants of getMaxNumSGPRs. 1049 unsigned getBaseMaxNumSGPRs(const Function &F, 1050 std::pair<unsigned, unsigned> WavesPerEU, 1051 unsigned PreloadedSGPRs, 1052 unsigned ReservedNumSGPRs) const; 1053 1054 /// \returns Maximum number of SGPRs that meets number of waves per execution 1055 /// unit requirement for function \p MF, or number of SGPRs explicitly 1056 /// requested using "amdgpu-num-sgpr" attribute attached to function \p MF. 1057 /// 1058 /// \returns Value that meets number of waves per execution unit requirement 1059 /// if explicitly requested value cannot be converted to integer, violates 1060 /// subtarget's specifications, or does not meet number of waves per execution 1061 /// unit requirement. 1062 unsigned getMaxNumSGPRs(const MachineFunction &MF) const; 1063 1064 /// \returns Maximum number of SGPRs that meets number of waves per execution 1065 /// unit requirement for function \p F, or number of SGPRs explicitly 1066 /// requested using "amdgpu-num-sgpr" attribute attached to function \p F. 1067 /// 1068 /// \returns Value that meets number of waves per execution unit requirement 1069 /// if explicitly requested value cannot be converted to integer, violates 1070 /// subtarget's specifications, or does not meet number of waves per execution 1071 /// unit requirement. 1072 unsigned getMaxNumSGPRs(const Function &F) const; 1073 1074 /// \returns VGPR allocation granularity supported by the subtarget. 1075 unsigned getVGPRAllocGranule() const { 1076 return AMDGPU::IsaInfo::getVGPRAllocGranule(this); 1077 } 1078 1079 /// \returns VGPR encoding granularity supported by the subtarget. 1080 unsigned getVGPREncodingGranule() const { 1081 return AMDGPU::IsaInfo::getVGPREncodingGranule(this); 1082 } 1083 1084 /// \returns Total number of VGPRs supported by the subtarget. 1085 unsigned getTotalNumVGPRs() const { 1086 return AMDGPU::IsaInfo::getTotalNumVGPRs(this); 1087 } 1088 1089 /// \returns Addressable number of VGPRs supported by the subtarget. 1090 unsigned getAddressableNumVGPRs() const { 1091 return AMDGPU::IsaInfo::getAddressableNumVGPRs(this); 1092 } 1093 1094 /// \returns Minimum number of VGPRs that meets given number of waves per 1095 /// execution unit requirement supported by the subtarget. 1096 unsigned getMinNumVGPRs(unsigned WavesPerEU) const { 1097 return AMDGPU::IsaInfo::getMinNumVGPRs(this, WavesPerEU); 1098 } 1099 1100 /// \returns Maximum number of VGPRs that meets given number of waves per 1101 /// execution unit requirement supported by the subtarget. 1102 unsigned getMaxNumVGPRs(unsigned WavesPerEU) const { 1103 return AMDGPU::IsaInfo::getMaxNumVGPRs(this, WavesPerEU); 1104 } 1105 1106 /// \returns max num VGPRs. This is the common utility function 1107 /// called by MachineFunction and Function variants of getMaxNumVGPRs. 1108 unsigned getBaseMaxNumVGPRs(const Function &F, 1109 std::pair<unsigned, unsigned> WavesPerEU) const; 1110 /// \returns Maximum number of VGPRs that meets number of waves per execution 1111 /// unit requirement for function \p F, or number of VGPRs explicitly 1112 /// requested using "amdgpu-num-vgpr" attribute attached to function \p F. 1113 /// 1114 /// \returns Value that meets number of waves per execution unit requirement 1115 /// if explicitly requested value cannot be converted to integer, violates 1116 /// subtarget's specifications, or does not meet number of waves per execution 1117 /// unit requirement. 1118 unsigned getMaxNumVGPRs(const Function &F) const; 1119 1120 /// \returns Maximum number of VGPRs that meets number of waves per execution 1121 /// unit requirement for function \p MF, or number of VGPRs explicitly 1122 /// requested using "amdgpu-num-vgpr" attribute attached to function \p MF. 1123 /// 1124 /// \returns Value that meets number of waves per execution unit requirement 1125 /// if explicitly requested value cannot be converted to integer, violates 1126 /// subtarget's specifications, or does not meet number of waves per execution 1127 /// unit requirement. 1128 unsigned getMaxNumVGPRs(const MachineFunction &MF) const; 1129 1130 void getPostRAMutations( 1131 std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) 1132 const override; 1133 1134 bool isWave32() const { 1135 return getWavefrontSize() == 32; 1136 } 1137 1138 bool isWave64() const { 1139 return getWavefrontSize() == 64; 1140 } 1141 1142 const TargetRegisterClass *getBoolRC() const { 1143 return getRegisterInfo()->getBoolRC(); 1144 } 1145 1146 /// \returns Maximum number of work groups per compute unit supported by the 1147 /// subtarget and limited by given \p FlatWorkGroupSize. 1148 unsigned getMaxWorkGroupsPerCU(unsigned FlatWorkGroupSize) const override { 1149 return AMDGPU::IsaInfo::getMaxWorkGroupsPerCU(this, FlatWorkGroupSize); 1150 } 1151 1152 /// \returns Minimum flat work group size supported by the subtarget. 1153 unsigned getMinFlatWorkGroupSize() const override { 1154 return AMDGPU::IsaInfo::getMinFlatWorkGroupSize(this); 1155 } 1156 1157 /// \returns Maximum flat work group size supported by the subtarget. 1158 unsigned getMaxFlatWorkGroupSize() const override { 1159 return AMDGPU::IsaInfo::getMaxFlatWorkGroupSize(this); 1160 } 1161 1162 /// \returns Number of waves per execution unit required to support the given 1163 /// \p FlatWorkGroupSize. 1164 unsigned 1165 getWavesPerEUForWorkGroup(unsigned FlatWorkGroupSize) const override { 1166 return AMDGPU::IsaInfo::getWavesPerEUForWorkGroup(this, FlatWorkGroupSize); 1167 } 1168 1169 /// \returns Minimum number of waves per execution unit supported by the 1170 /// subtarget. 1171 unsigned getMinWavesPerEU() const override { 1172 return AMDGPU::IsaInfo::getMinWavesPerEU(this); 1173 } 1174 1175 void adjustSchedDependency(SUnit *Def, int DefOpIdx, SUnit *Use, int UseOpIdx, 1176 SDep &Dep) const override; 1177 }; 1178 1179 } // end namespace llvm 1180 1181 #endif // LLVM_LIB_TARGET_AMDGPU_GCNSUBTARGET_H 1182