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