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