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 GFX10_3Insts = false; 107 bool GFX7GFX8GFX9Insts = false; 108 bool SGPRInitBug = false; 109 bool NegativeScratchOffsetBug = false; 110 bool NegativeUnalignedScratchOffsetBug = false; 111 bool HasSMemRealTime = false; 112 bool HasIntClamp = false; 113 bool HasFmaMixInsts = false; 114 bool HasMovrel = false; 115 bool HasVGPRIndexMode = false; 116 bool HasScalarStores = false; 117 bool HasScalarAtomics = false; 118 bool HasSDWAOmod = false; 119 bool HasSDWAScalar = false; 120 bool HasSDWASdst = false; 121 bool HasSDWAMac = false; 122 bool HasSDWAOutModsVOPC = false; 123 bool HasDPP = false; 124 bool HasDPP8 = false; 125 bool Has64BitDPP = false; 126 bool HasPackedFP32Ops = false; 127 bool HasImageInsts = false; 128 bool HasExtendedImageInsts = false; 129 bool HasR128A16 = false; 130 bool HasGFX10A16 = false; 131 bool HasG16 = false; 132 bool HasNSAEncoding = false; 133 unsigned NSAMaxSize = 0; 134 bool GFX10_AEncoding = false; 135 bool GFX10_BEncoding = false; 136 bool HasDLInsts = false; 137 bool HasDot1Insts = false; 138 bool HasDot2Insts = false; 139 bool HasDot3Insts = false; 140 bool HasDot4Insts = false; 141 bool HasDot5Insts = false; 142 bool HasDot6Insts = false; 143 bool HasDot7Insts = false; 144 bool HasMAIInsts = false; 145 bool HasPkFmacF16Inst = false; 146 bool HasAtomicFaddRtnInsts = false; 147 bool HasAtomicFaddNoRtnInsts = false; 148 bool HasAtomicPkFaddNoRtnInsts = false; 149 bool SupportsSRAMECC = false; 150 151 // This should not be used directly. 'TargetID' tracks the dynamic settings 152 // for SRAMECC. 153 bool EnableSRAMECC = false; 154 155 bool HasNoSdstCMPX = false; 156 bool HasVscnt = false; 157 bool HasGetWaveIdInst = false; 158 bool HasSMemTimeInst = false; 159 bool HasShaderCyclesRegister = false; 160 bool HasVOP3Literal = false; 161 bool HasNoDataDepHazard = false; 162 bool FlatAddressSpace = false; 163 bool FlatInstOffsets = false; 164 bool FlatGlobalInsts = false; 165 bool FlatScratchInsts = false; 166 bool ScalarFlatScratchInsts = false; 167 bool HasArchitectedFlatScratch = false; 168 bool EnableFlatScratch = false; 169 bool AddNoCarryInsts = false; 170 bool HasUnpackedD16VMem = false; 171 bool LDSMisalignedBug = false; 172 bool HasMFMAInlineLiteralBug = false; 173 bool UnalignedBufferAccess = false; 174 bool UnalignedDSAccess = false; 175 bool HasPackedTID = false; 176 bool ScalarizeGlobal = false; 177 178 bool HasVcmpxPermlaneHazard = false; 179 bool HasVMEMtoScalarWriteHazard = false; 180 bool HasSMEMtoVectorWriteHazard = false; 181 bool HasInstFwdPrefetchBug = false; 182 bool HasVcmpxExecWARHazard = false; 183 bool HasLdsBranchVmemWARHazard = false; 184 bool HasNSAtoVMEMBug = false; 185 bool HasNSAClauseBug = false; 186 bool HasOffset3fBug = false; 187 bool HasFlatSegmentOffsetBug = false; 188 bool HasImageStoreD16Bug = false; 189 bool HasImageGather4D16Bug = false; 190 191 // Dummy feature to use for assembler in tablegen. 192 bool FeatureDisable = false; 193 194 SelectionDAGTargetInfo TSInfo; 195 private: 196 SIInstrInfo InstrInfo; 197 SITargetLowering TLInfo; 198 SIFrameLowering FrameLowering; 199 200 public: 201 // See COMPUTE_TMPRING_SIZE.WAVESIZE, 13-bit field in units of 256-dword. 202 static const unsigned MaxWaveScratchSize = (256 * 4) * ((1 << 13) - 1); 203 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 /// Return the number of high bits known to be zero for a frame index. 267 unsigned getKnownHighZeroBitsForFrameIndex() const { 268 return countLeadingZeros(MaxWaveScratchSize) + getWavefrontSizeLog2(); 269 } 270 271 int getLDSBankCount() const { 272 return LDSBankCount; 273 } 274 275 unsigned getMaxPrivateElementSize(bool ForBufferRSrc = false) const { 276 return (ForBufferRSrc || !enableFlatScratch()) ? MaxPrivateElementSize : 16; 277 } 278 279 unsigned getConstantBusLimit(unsigned Opcode) const; 280 281 /// Returns if the result of this instruction with a 16-bit result returned in 282 /// a 32-bit register implicitly zeroes the high 16-bits, rather than preserve 283 /// the original value. 284 bool zeroesHigh16BitsOfDest(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() ? TrapHandlerAbi::AMDHSA : TrapHandlerAbi::NONE; 390 } 391 392 bool supportsGetDoorbellID() const { 393 // The S_GETREG DOORBELL_ID is supported by all GFX9 onward targets. 394 return getGeneration() >= GFX9; 395 } 396 397 /// True if the offset field of DS instructions works as expected. On SI, the 398 /// offset uses a 16-bit adder and does not always wrap properly. 399 bool hasUsableDSOffset() const { 400 return getGeneration() >= SEA_ISLANDS; 401 } 402 403 bool unsafeDSOffsetFoldingEnabled() const { 404 return EnableUnsafeDSOffsetFolding; 405 } 406 407 /// Condition output from div_scale is usable. 408 bool hasUsableDivScaleConditionOutput() const { 409 return getGeneration() != SOUTHERN_ISLANDS; 410 } 411 412 /// Extra wait hazard is needed in some cases before 413 /// s_cbranch_vccnz/s_cbranch_vccz. 414 bool hasReadVCCZBug() const { 415 return getGeneration() <= SEA_ISLANDS; 416 } 417 418 /// Writes to VCC_LO/VCC_HI update the VCCZ flag. 419 bool partialVCCWritesUpdateVCCZ() const { 420 return getGeneration() >= GFX10; 421 } 422 423 /// A read of an SGPR by SMRD instruction requires 4 wait states when the SGPR 424 /// was written by a VALU instruction. 425 bool hasSMRDReadVALUDefHazard() const { 426 return getGeneration() == SOUTHERN_ISLANDS; 427 } 428 429 /// A read of an SGPR by a VMEM instruction requires 5 wait states when the 430 /// SGPR was written by a VALU Instruction. 431 bool hasVMEMReadSGPRVALUDefHazard() const { 432 return getGeneration() >= VOLCANIC_ISLANDS; 433 } 434 435 bool hasRFEHazards() const { 436 return getGeneration() >= VOLCANIC_ISLANDS; 437 } 438 439 /// Number of hazard wait states for s_setreg_b32/s_setreg_imm32_b32. 440 unsigned getSetRegWaitStates() const { 441 return getGeneration() <= SEA_ISLANDS ? 1 : 2; 442 } 443 444 bool dumpCode() const { 445 return DumpCode; 446 } 447 448 /// Return the amount of LDS that can be used that will not restrict the 449 /// occupancy lower than WaveCount. 450 unsigned getMaxLocalMemSizeWithWaveCount(unsigned WaveCount, 451 const Function &) const; 452 453 bool supportsMinMaxDenormModes() const { 454 return getGeneration() >= AMDGPUSubtarget::GFX9; 455 } 456 457 /// \returns If target supports S_DENORM_MODE. 458 bool hasDenormModeInst() const { 459 return getGeneration() >= AMDGPUSubtarget::GFX10; 460 } 461 462 bool useFlatForGlobal() const { 463 return FlatForGlobal; 464 } 465 466 /// \returns If target supports ds_read/write_b128 and user enables generation 467 /// of ds_read/write_b128. 468 bool useDS128() const { 469 return CIInsts && EnableDS128; 470 } 471 472 /// \return If target supports ds_read/write_b96/128. 473 bool hasDS96AndDS128() const { 474 return CIInsts; 475 } 476 477 /// Have v_trunc_f64, v_ceil_f64, v_rndne_f64 478 bool haveRoundOpsF64() const { 479 return CIInsts; 480 } 481 482 /// \returns If MUBUF instructions always perform range checking, even for 483 /// buffer resources used for private memory access. 484 bool privateMemoryResourceIsRangeChecked() const { 485 return getGeneration() < AMDGPUSubtarget::GFX9; 486 } 487 488 /// \returns If target requires PRT Struct NULL support (zero result registers 489 /// for sparse texture support). 490 bool usePRTStrictNull() const { 491 return EnablePRTStrictNull; 492 } 493 494 bool hasAutoWaitcntBeforeBarrier() const { 495 return AutoWaitcntBeforeBarrier; 496 } 497 498 bool hasUnalignedBufferAccess() const { 499 return UnalignedBufferAccess; 500 } 501 502 bool hasUnalignedBufferAccessEnabled() const { 503 return UnalignedBufferAccess && UnalignedAccessMode; 504 } 505 506 bool hasUnalignedDSAccess() const { 507 return UnalignedDSAccess; 508 } 509 510 bool hasUnalignedDSAccessEnabled() const { 511 return UnalignedDSAccess && UnalignedAccessMode; 512 } 513 514 bool hasUnalignedScratchAccess() const { 515 return UnalignedScratchAccess; 516 } 517 518 bool hasUnalignedAccessMode() const { 519 return UnalignedAccessMode; 520 } 521 522 bool hasApertureRegs() const { 523 return HasApertureRegs; 524 } 525 526 bool isTrapHandlerEnabled() const { 527 return TrapHandler; 528 } 529 530 bool isXNACKEnabled() const { 531 return TargetID.isXnackOnOrAny(); 532 } 533 534 bool isTgSplitEnabled() const { 535 return EnableTgSplit; 536 } 537 538 bool isCuModeEnabled() const { 539 return EnableCuMode; 540 } 541 542 bool hasFlatAddressSpace() const { 543 return FlatAddressSpace; 544 } 545 546 bool hasFlatScrRegister() const { 547 return hasFlatAddressSpace(); 548 } 549 550 bool hasFlatInstOffsets() const { 551 return FlatInstOffsets; 552 } 553 554 bool hasFlatGlobalInsts() const { 555 return FlatGlobalInsts; 556 } 557 558 bool hasFlatScratchInsts() const { 559 return FlatScratchInsts; 560 } 561 562 // Check if target supports ST addressing mode with FLAT scratch instructions. 563 // The ST addressing mode means no registers are used, either VGPR or SGPR, 564 // but only immediate offset is swizzled and added to the FLAT scratch base. 565 bool hasFlatScratchSTMode() const { 566 return hasFlatScratchInsts() && (hasGFX10_3Insts() || hasGFX940Insts()); 567 } 568 569 bool hasFlatScratchSVSMode() const { return GFX940Insts; } 570 571 bool hasScalarFlatScratchInsts() const { 572 return ScalarFlatScratchInsts; 573 } 574 575 bool enableFlatScratch() const { 576 return flatScratchIsArchitected() || 577 (EnableFlatScratch && hasFlatScratchInsts()); 578 } 579 580 bool hasGlobalAddTidInsts() const { 581 return GFX10_BEncoding; 582 } 583 584 bool hasAtomicCSub() const { 585 return GFX10_BEncoding; 586 } 587 588 bool hasMultiDwordFlatScratchAddressing() const { 589 return getGeneration() >= GFX9; 590 } 591 592 bool hasFlatSegmentOffsetBug() const { 593 return HasFlatSegmentOffsetBug; 594 } 595 596 bool hasFlatLgkmVMemCountInOrder() const { 597 return getGeneration() > GFX9; 598 } 599 600 bool hasD16LoadStore() const { 601 return getGeneration() >= GFX9; 602 } 603 604 bool d16PreservesUnusedBits() const { 605 return hasD16LoadStore() && !TargetID.isSramEccOnOrAny(); 606 } 607 608 bool hasD16Images() const { 609 return getGeneration() >= VOLCANIC_ISLANDS; 610 } 611 612 /// Return if most LDS instructions have an m0 use that require m0 to be 613 /// initialized. 614 bool ldsRequiresM0Init() const { 615 return getGeneration() < GFX9; 616 } 617 618 // True if the hardware rewinds and replays GWS operations if a wave is 619 // preempted. 620 // 621 // If this is false, a GWS operation requires testing if a nack set the 622 // MEM_VIOL bit, and repeating if so. 623 bool hasGWSAutoReplay() const { 624 return getGeneration() >= GFX9; 625 } 626 627 /// \returns if target has ds_gws_sema_release_all instruction. 628 bool hasGWSSemaReleaseAll() const { 629 return CIInsts; 630 } 631 632 /// \returns true if the target has integer add/sub instructions that do not 633 /// produce a carry-out. This includes v_add_[iu]32, v_sub_[iu]32, 634 /// v_add_[iu]16, and v_sub_[iu]16, all of which support the clamp modifier 635 /// for saturation. 636 bool hasAddNoCarry() const { 637 return AddNoCarryInsts; 638 } 639 640 bool hasUnpackedD16VMem() const { 641 return HasUnpackedD16VMem; 642 } 643 644 // Covers VS/PS/CS graphics shaders 645 bool isMesaGfxShader(const Function &F) const { 646 return isMesa3DOS() && AMDGPU::isShader(F.getCallingConv()); 647 } 648 649 bool hasMad64_32() const { 650 return getGeneration() >= SEA_ISLANDS; 651 } 652 653 bool hasSDWAOmod() const { 654 return HasSDWAOmod; 655 } 656 657 bool hasSDWAScalar() const { 658 return HasSDWAScalar; 659 } 660 661 bool hasSDWASdst() const { 662 return HasSDWASdst; 663 } 664 665 bool hasSDWAMac() const { 666 return HasSDWAMac; 667 } 668 669 bool hasSDWAOutModsVOPC() const { 670 return HasSDWAOutModsVOPC; 671 } 672 673 bool hasDLInsts() const { 674 return HasDLInsts; 675 } 676 677 bool hasDot1Insts() const { 678 return HasDot1Insts; 679 } 680 681 bool hasDot2Insts() const { 682 return HasDot2Insts; 683 } 684 685 bool hasDot3Insts() const { 686 return HasDot3Insts; 687 } 688 689 bool hasDot4Insts() const { 690 return HasDot4Insts; 691 } 692 693 bool hasDot5Insts() const { 694 return HasDot5Insts; 695 } 696 697 bool hasDot6Insts() const { 698 return HasDot6Insts; 699 } 700 701 bool hasDot7Insts() const { 702 return HasDot7Insts; 703 } 704 705 bool hasMAIInsts() const { 706 return HasMAIInsts; 707 } 708 709 bool hasPkFmacF16Inst() const { 710 return HasPkFmacF16Inst; 711 } 712 713 bool hasAtomicFaddInsts() const { 714 return HasAtomicFaddRtnInsts || HasAtomicFaddNoRtnInsts; 715 } 716 717 bool hasAtomicFaddRtnInsts() const { return HasAtomicFaddRtnInsts; } 718 719 bool hasAtomicFaddNoRtnInsts() const { return HasAtomicFaddNoRtnInsts; } 720 721 bool hasAtomicPkFaddNoRtnInsts() const { return HasAtomicPkFaddNoRtnInsts; } 722 723 bool hasNoSdstCMPX() const { 724 return HasNoSdstCMPX; 725 } 726 727 bool hasVscnt() const { 728 return HasVscnt; 729 } 730 731 bool hasGetWaveIdInst() const { 732 return HasGetWaveIdInst; 733 } 734 735 bool hasSMemTimeInst() const { 736 return HasSMemTimeInst; 737 } 738 739 bool hasShaderCyclesRegister() const { 740 return HasShaderCyclesRegister; 741 } 742 743 bool hasVOP3Literal() const { 744 return HasVOP3Literal; 745 } 746 747 bool hasNoDataDepHazard() const { 748 return HasNoDataDepHazard; 749 } 750 751 bool vmemWriteNeedsExpWaitcnt() const { 752 return getGeneration() < SEA_ISLANDS; 753 } 754 755 // Scratch is allocated in 256 dword per wave blocks for the entire 756 // wavefront. When viewed from the perspective of an arbitrary workitem, this 757 // is 4-byte aligned. 758 // 759 // Only 4-byte alignment is really needed to access anything. Transformations 760 // on the pointer value itself may rely on the alignment / known low bits of 761 // the pointer. Set this to something above the minimum to avoid needing 762 // dynamic realignment in common cases. 763 Align getStackAlignment() const { return Align(16); } 764 765 bool enableMachineScheduler() const override { 766 return true; 767 } 768 769 bool useAA() const override; 770 771 bool enableSubRegLiveness() const override { 772 return true; 773 } 774 775 void setScalarizeGlobalBehavior(bool b) { ScalarizeGlobal = b; } 776 bool getScalarizeGlobalBehavior() const { return ScalarizeGlobal; } 777 778 // static wrappers 779 static bool hasHalfRate64Ops(const TargetSubtargetInfo &STI); 780 781 // XXX - Why is this here if it isn't in the default pass set? 782 bool enableEarlyIfConversion() const override { 783 return true; 784 } 785 786 void overrideSchedPolicy(MachineSchedPolicy &Policy, 787 unsigned NumRegionInstrs) const override; 788 789 unsigned getMaxNumUserSGPRs() const { 790 return 16; 791 } 792 793 bool hasSMemRealTime() const { 794 return HasSMemRealTime; 795 } 796 797 bool hasMovrel() const { 798 return HasMovrel; 799 } 800 801 bool hasVGPRIndexMode() const { 802 return HasVGPRIndexMode; 803 } 804 805 bool useVGPRIndexMode() const; 806 807 bool hasScalarCompareEq64() const { 808 return getGeneration() >= VOLCANIC_ISLANDS; 809 } 810 811 bool hasScalarStores() const { 812 return HasScalarStores; 813 } 814 815 bool hasScalarAtomics() const { 816 return HasScalarAtomics; 817 } 818 819 bool hasLDSFPAtomicAdd() const { return GFX8Insts; } 820 821 /// \returns true if the subtarget has the v_permlanex16_b32 instruction. 822 bool hasPermLaneX16() const { return getGeneration() >= GFX10; } 823 824 bool hasDPP() const { 825 return HasDPP; 826 } 827 828 bool hasDPPBroadcasts() const { 829 return HasDPP && getGeneration() < GFX10; 830 } 831 832 bool hasDPPWavefrontShifts() const { 833 return HasDPP && getGeneration() < GFX10; 834 } 835 836 bool hasDPP8() const { 837 return HasDPP8; 838 } 839 840 bool has64BitDPP() const { 841 return Has64BitDPP; 842 } 843 844 bool hasPackedFP32Ops() const { 845 return HasPackedFP32Ops; 846 } 847 848 bool hasFmaakFmamkF32Insts() const { 849 return getGeneration() >= GFX10 || hasGFX940Insts(); 850 } 851 852 bool hasImageInsts() const { 853 return HasImageInsts; 854 } 855 856 bool hasExtendedImageInsts() const { 857 return HasExtendedImageInsts; 858 } 859 860 bool hasR128A16() const { 861 return HasR128A16; 862 } 863 864 bool hasGFX10A16() const { 865 return HasGFX10A16; 866 } 867 868 bool hasA16() const { return hasR128A16() || hasGFX10A16(); } 869 870 bool hasG16() const { return HasG16; } 871 872 bool hasOffset3fBug() const { 873 return HasOffset3fBug; 874 } 875 876 bool hasImageStoreD16Bug() const { return HasImageStoreD16Bug; } 877 878 bool hasImageGather4D16Bug() const { return HasImageGather4D16Bug; } 879 880 bool hasNSAEncoding() const { return HasNSAEncoding; } 881 882 unsigned getNSAMaxSize() const { return NSAMaxSize; } 883 884 bool hasGFX10_AEncoding() const { 885 return GFX10_AEncoding; 886 } 887 888 bool hasGFX10_BEncoding() const { 889 return GFX10_BEncoding; 890 } 891 892 bool hasGFX10_3Insts() const { 893 return GFX10_3Insts; 894 } 895 896 bool hasMadF16() const; 897 898 bool hasMovB64() const { return GFX940Insts; } 899 900 bool hasLshlAddB64() const { return GFX940Insts; } 901 902 bool enableSIScheduler() const { 903 return EnableSIScheduler; 904 } 905 906 bool loadStoreOptEnabled() const { 907 return EnableLoadStoreOpt; 908 } 909 910 bool hasSGPRInitBug() const { 911 return SGPRInitBug; 912 } 913 914 bool hasNegativeScratchOffsetBug() const { return NegativeScratchOffsetBug; } 915 916 bool hasNegativeUnalignedScratchOffsetBug() const { 917 return NegativeUnalignedScratchOffsetBug; 918 } 919 920 bool hasMFMAInlineLiteralBug() const { 921 return HasMFMAInlineLiteralBug; 922 } 923 924 bool has12DWordStoreHazard() const { 925 return getGeneration() != AMDGPUSubtarget::SOUTHERN_ISLANDS; 926 } 927 928 // \returns true if the subtarget supports DWORDX3 load/store instructions. 929 bool hasDwordx3LoadStores() const { 930 return CIInsts; 931 } 932 933 bool hasReadM0MovRelInterpHazard() const { 934 return getGeneration() == AMDGPUSubtarget::GFX9; 935 } 936 937 bool hasReadM0SendMsgHazard() const { 938 return getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS && 939 getGeneration() <= AMDGPUSubtarget::GFX9; 940 } 941 942 bool hasReadM0LdsDmaHazard() const { 943 return getGeneration() == AMDGPUSubtarget::GFX9; 944 } 945 946 bool hasReadM0LdsDirectHazard() const { 947 return getGeneration() == AMDGPUSubtarget::GFX9; 948 } 949 950 bool hasVcmpxPermlaneHazard() const { 951 return HasVcmpxPermlaneHazard; 952 } 953 954 bool hasVMEMtoScalarWriteHazard() const { 955 return HasVMEMtoScalarWriteHazard; 956 } 957 958 bool hasSMEMtoVectorWriteHazard() const { 959 return HasSMEMtoVectorWriteHazard; 960 } 961 962 bool hasLDSMisalignedBug() const { 963 return LDSMisalignedBug && !EnableCuMode; 964 } 965 966 bool hasInstFwdPrefetchBug() const { 967 return HasInstFwdPrefetchBug; 968 } 969 970 bool hasVcmpxExecWARHazard() const { 971 return HasVcmpxExecWARHazard; 972 } 973 974 bool hasLdsBranchVmemWARHazard() const { 975 return HasLdsBranchVmemWARHazard; 976 } 977 978 // Has one cycle hazard on transcendental instruction feeding a 979 // non transcendental VALU. 980 bool hasTransForwardingHazard() const { return GFX940Insts; } 981 982 // Has one cycle hazard on a VALU instruction partially writing dst with 983 // a shift of result bits feeding another VALU instruction. 984 bool hasDstSelForwardingHazard() const { return GFX940Insts; } 985 986 // Cannot use op_sel with v_dot instructions. 987 bool hasDOTOpSelHazard() const { return GFX940Insts; } 988 989 // Does not have HW interlocs for VALU writing and then reading SGPRs. 990 bool hasVDecCoExecHazard() const { 991 return GFX940Insts; 992 } 993 994 bool hasNSAtoVMEMBug() const { 995 return HasNSAtoVMEMBug; 996 } 997 998 bool hasNSAClauseBug() const { return HasNSAClauseBug; } 999 1000 bool hasHardClauses() const { return getGeneration() >= GFX10; } 1001 1002 bool hasGFX90AInsts() const { return GFX90AInsts; } 1003 1004 /// Return if operations acting on VGPR tuples require even alignment. 1005 bool needsAlignedVGPRs() const { return GFX90AInsts; } 1006 1007 bool hasPackedTID() const { return HasPackedTID; } 1008 1009 // GFX940 is a derivation to GFX90A. hasGFX940Insts() being true implies that 1010 // hasGFX90AInsts is also true. 1011 bool hasGFX940Insts() const { return GFX940Insts; } 1012 1013 /// Return the maximum number of waves per SIMD for kernels using \p SGPRs 1014 /// SGPRs 1015 unsigned getOccupancyWithNumSGPRs(unsigned SGPRs) const; 1016 1017 /// Return the maximum number of waves per SIMD for kernels using \p VGPRs 1018 /// VGPRs 1019 unsigned getOccupancyWithNumVGPRs(unsigned VGPRs) const; 1020 1021 /// Return occupancy for the given function. Used LDS and a number of 1022 /// registers if provided. 1023 /// Note, occupancy can be affected by the scratch allocation as well, but 1024 /// we do not have enough information to compute it. 1025 unsigned computeOccupancy(const Function &F, unsigned LDSSize = 0, 1026 unsigned NumSGPRs = 0, unsigned NumVGPRs = 0) const; 1027 1028 /// \returns true if the flat_scratch register should be initialized with the 1029 /// pointer to the wave's scratch memory rather than a size and offset. 1030 bool flatScratchIsPointer() const { 1031 return getGeneration() >= AMDGPUSubtarget::GFX9; 1032 } 1033 1034 /// \returns true if the flat_scratch register is initialized by the HW. 1035 /// In this case it is readonly. 1036 bool flatScratchIsArchitected() const { return HasArchitectedFlatScratch; } 1037 1038 /// \returns true if the machine has merged shaders in which s0-s7 are 1039 /// reserved by the hardware and user SGPRs start at s8 1040 bool hasMergedShaders() const { 1041 return getGeneration() >= GFX9; 1042 } 1043 1044 /// \returns SGPR allocation granularity supported by the subtarget. 1045 unsigned getSGPRAllocGranule() const { 1046 return AMDGPU::IsaInfo::getSGPRAllocGranule(this); 1047 } 1048 1049 /// \returns SGPR encoding granularity supported by the subtarget. 1050 unsigned getSGPREncodingGranule() const { 1051 return AMDGPU::IsaInfo::getSGPREncodingGranule(this); 1052 } 1053 1054 /// \returns Total number of SGPRs supported by the subtarget. 1055 unsigned getTotalNumSGPRs() const { 1056 return AMDGPU::IsaInfo::getTotalNumSGPRs(this); 1057 } 1058 1059 /// \returns Addressable number of SGPRs supported by the subtarget. 1060 unsigned getAddressableNumSGPRs() const { 1061 return AMDGPU::IsaInfo::getAddressableNumSGPRs(this); 1062 } 1063 1064 /// \returns Minimum number of SGPRs that meets the given number of waves per 1065 /// execution unit requirement supported by the subtarget. 1066 unsigned getMinNumSGPRs(unsigned WavesPerEU) const { 1067 return AMDGPU::IsaInfo::getMinNumSGPRs(this, WavesPerEU); 1068 } 1069 1070 /// \returns Maximum number of SGPRs that meets the given number of waves per 1071 /// execution unit requirement supported by the subtarget. 1072 unsigned getMaxNumSGPRs(unsigned WavesPerEU, bool Addressable) const { 1073 return AMDGPU::IsaInfo::getMaxNumSGPRs(this, WavesPerEU, Addressable); 1074 } 1075 1076 /// \returns Reserved number of SGPRs. This is common 1077 /// utility function called by MachineFunction and 1078 /// Function variants of getReservedNumSGPRs. 1079 unsigned getBaseReservedNumSGPRs(const bool HasFlatScratch) const; 1080 /// \returns Reserved number of SGPRs for given machine function \p MF. 1081 unsigned getReservedNumSGPRs(const MachineFunction &MF) const; 1082 1083 /// \returns Reserved number of SGPRs for given function \p F. 1084 unsigned getReservedNumSGPRs(const Function &F) const; 1085 1086 /// \returns max num SGPRs. This is the common utility 1087 /// function called by MachineFunction and Function 1088 /// variants of getMaxNumSGPRs. 1089 unsigned getBaseMaxNumSGPRs(const Function &F, 1090 std::pair<unsigned, unsigned> WavesPerEU, 1091 unsigned PreloadedSGPRs, 1092 unsigned ReservedNumSGPRs) const; 1093 1094 /// \returns Maximum number of SGPRs that meets number of waves per execution 1095 /// unit requirement for function \p MF, or number of SGPRs explicitly 1096 /// requested using "amdgpu-num-sgpr" attribute attached to function \p MF. 1097 /// 1098 /// \returns Value that meets number of waves per execution unit requirement 1099 /// if explicitly requested value cannot be converted to integer, violates 1100 /// subtarget's specifications, or does not meet number of waves per execution 1101 /// unit requirement. 1102 unsigned getMaxNumSGPRs(const MachineFunction &MF) const; 1103 1104 /// \returns Maximum number of SGPRs that meets number of waves per execution 1105 /// unit requirement for function \p F, or number of SGPRs explicitly 1106 /// requested using "amdgpu-num-sgpr" attribute attached to function \p F. 1107 /// 1108 /// \returns Value that meets number of waves per execution unit requirement 1109 /// if explicitly requested value cannot be converted to integer, violates 1110 /// subtarget's specifications, or does not meet number of waves per execution 1111 /// unit requirement. 1112 unsigned getMaxNumSGPRs(const Function &F) const; 1113 1114 /// \returns VGPR allocation granularity supported by the subtarget. 1115 unsigned getVGPRAllocGranule() const { 1116 return AMDGPU::IsaInfo::getVGPRAllocGranule(this); 1117 } 1118 1119 /// \returns VGPR encoding granularity supported by the subtarget. 1120 unsigned getVGPREncodingGranule() const { 1121 return AMDGPU::IsaInfo::getVGPREncodingGranule(this); 1122 } 1123 1124 /// \returns Total number of VGPRs supported by the subtarget. 1125 unsigned getTotalNumVGPRs() const { 1126 return AMDGPU::IsaInfo::getTotalNumVGPRs(this); 1127 } 1128 1129 /// \returns Addressable number of VGPRs supported by the subtarget. 1130 unsigned getAddressableNumVGPRs() const { 1131 return AMDGPU::IsaInfo::getAddressableNumVGPRs(this); 1132 } 1133 1134 /// \returns Minimum number of VGPRs that meets given number of waves per 1135 /// execution unit requirement supported by the subtarget. 1136 unsigned getMinNumVGPRs(unsigned WavesPerEU) const { 1137 return AMDGPU::IsaInfo::getMinNumVGPRs(this, WavesPerEU); 1138 } 1139 1140 /// \returns Maximum number of VGPRs that meets given number of waves per 1141 /// execution unit requirement supported by the subtarget. 1142 unsigned getMaxNumVGPRs(unsigned WavesPerEU) const { 1143 return AMDGPU::IsaInfo::getMaxNumVGPRs(this, WavesPerEU); 1144 } 1145 1146 /// \returns max num VGPRs. This is the common utility function 1147 /// called by MachineFunction and Function variants of getMaxNumVGPRs. 1148 unsigned getBaseMaxNumVGPRs(const Function &F, 1149 std::pair<unsigned, unsigned> WavesPerEU) const; 1150 /// \returns Maximum number of VGPRs that meets number of waves per execution 1151 /// unit requirement for function \p F, or number of VGPRs explicitly 1152 /// requested using "amdgpu-num-vgpr" attribute attached to function \p F. 1153 /// 1154 /// \returns Value that meets number of waves per execution unit requirement 1155 /// if explicitly requested value cannot be converted to integer, violates 1156 /// subtarget's specifications, or does not meet number of waves per execution 1157 /// unit requirement. 1158 unsigned getMaxNumVGPRs(const Function &F) const; 1159 1160 unsigned getMaxNumAGPRs(const Function &F) const { 1161 return getMaxNumVGPRs(F); 1162 } 1163 1164 /// \returns Maximum number of VGPRs that meets number of waves per execution 1165 /// unit requirement for function \p MF, or number of VGPRs explicitly 1166 /// requested using "amdgpu-num-vgpr" attribute attached to function \p MF. 1167 /// 1168 /// \returns Value that meets number of waves per execution unit requirement 1169 /// if explicitly requested value cannot be converted to integer, violates 1170 /// subtarget's specifications, or does not meet number of waves per execution 1171 /// unit requirement. 1172 unsigned getMaxNumVGPRs(const MachineFunction &MF) const; 1173 1174 void getPostRAMutations( 1175 std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) 1176 const override; 1177 1178 std::unique_ptr<ScheduleDAGMutation> 1179 createFillMFMAShadowMutation(const TargetInstrInfo *TII) const; 1180 1181 bool isWave32() const { 1182 return getWavefrontSize() == 32; 1183 } 1184 1185 bool isWave64() const { 1186 return getWavefrontSize() == 64; 1187 } 1188 1189 const TargetRegisterClass *getBoolRC() const { 1190 return getRegisterInfo()->getBoolRC(); 1191 } 1192 1193 /// \returns Maximum number of work groups per compute unit supported by the 1194 /// subtarget and limited by given \p FlatWorkGroupSize. 1195 unsigned getMaxWorkGroupsPerCU(unsigned FlatWorkGroupSize) const override { 1196 return AMDGPU::IsaInfo::getMaxWorkGroupsPerCU(this, FlatWorkGroupSize); 1197 } 1198 1199 /// \returns Minimum flat work group size supported by the subtarget. 1200 unsigned getMinFlatWorkGroupSize() const override { 1201 return AMDGPU::IsaInfo::getMinFlatWorkGroupSize(this); 1202 } 1203 1204 /// \returns Maximum flat work group size supported by the subtarget. 1205 unsigned getMaxFlatWorkGroupSize() const override { 1206 return AMDGPU::IsaInfo::getMaxFlatWorkGroupSize(this); 1207 } 1208 1209 /// \returns Number of waves per execution unit required to support the given 1210 /// \p FlatWorkGroupSize. 1211 unsigned 1212 getWavesPerEUForWorkGroup(unsigned FlatWorkGroupSize) const override { 1213 return AMDGPU::IsaInfo::getWavesPerEUForWorkGroup(this, FlatWorkGroupSize); 1214 } 1215 1216 /// \returns Minimum number of waves per execution unit supported by the 1217 /// subtarget. 1218 unsigned getMinWavesPerEU() const override { 1219 return AMDGPU::IsaInfo::getMinWavesPerEU(this); 1220 } 1221 1222 void adjustSchedDependency(SUnit *Def, int DefOpIdx, SUnit *Use, int UseOpIdx, 1223 SDep &Dep) const override; 1224 }; 1225 1226 } // end namespace llvm 1227 1228 #endif // LLVM_LIB_TARGET_AMDGPU_GCNSUBTARGET_H 1229