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