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