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