1 //=====-- AMDGPUSubtarget.h - Define 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 /// AMDGPU specific subclass of TargetSubtarget. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUSUBTARGET_H 15 #define LLVM_LIB_TARGET_AMDGPU_AMDGPUSUBTARGET_H 16 17 #include "AMDGPU.h" 18 #include "AMDGPUCallLowering.h" 19 #include "MCTargetDesc/AMDGPUMCTargetDesc.h" 20 #include "R600FrameLowering.h" 21 #include "R600ISelLowering.h" 22 #include "R600InstrInfo.h" 23 #include "SIFrameLowering.h" 24 #include "SIISelLowering.h" 25 #include "SIInstrInfo.h" 26 #include "Utils/AMDGPUBaseInfo.h" 27 #include "llvm/ADT/Triple.h" 28 #include "llvm/CodeGen/GlobalISel/InlineAsmLowering.h" 29 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" 30 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" 31 #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" 32 #include "llvm/CodeGen/MachineFunction.h" 33 #include "llvm/CodeGen/SelectionDAGTargetInfo.h" 34 #include "llvm/MC/MCInstrItineraries.h" 35 #include "llvm/Support/MathExtras.h" 36 #include <cassert> 37 #include <cstdint> 38 #include <memory> 39 #include <utility> 40 41 #define GET_SUBTARGETINFO_HEADER 42 #include "AMDGPUGenSubtargetInfo.inc" 43 #define GET_SUBTARGETINFO_HEADER 44 #include "R600GenSubtargetInfo.inc" 45 46 namespace llvm { 47 48 class StringRef; 49 50 class AMDGPUSubtarget { 51 public: 52 enum Generation { 53 R600 = 0, 54 R700 = 1, 55 EVERGREEN = 2, 56 NORTHERN_ISLANDS = 3, 57 SOUTHERN_ISLANDS = 4, 58 SEA_ISLANDS = 5, 59 VOLCANIC_ISLANDS = 6, 60 GFX9 = 7, 61 GFX10 = 8 62 }; 63 64 private: 65 Triple TargetTriple; 66 67 protected: 68 bool Has16BitInsts; 69 bool HasMadMixInsts; 70 bool HasMadMacF32Insts; 71 bool HasDsSrc2Insts; 72 bool HasSDWA; 73 bool HasVOP3PInsts; 74 bool HasMulI24; 75 bool HasMulU24; 76 bool HasInv2PiInlineImm; 77 bool HasFminFmaxLegacy; 78 bool EnablePromoteAlloca; 79 bool HasTrigReducedRange; 80 unsigned MaxWavesPerEU; 81 unsigned LocalMemorySize; 82 char WavefrontSizeLog2; 83 84 public: 85 AMDGPUSubtarget(const Triple &TT); 86 87 static const AMDGPUSubtarget &get(const MachineFunction &MF); 88 static const AMDGPUSubtarget &get(const TargetMachine &TM, 89 const Function &F); 90 91 /// \returns Default range flat work group size for a calling convention. 92 std::pair<unsigned, unsigned> getDefaultFlatWorkGroupSize(CallingConv::ID CC) const; 93 94 /// \returns Subtarget's default pair of minimum/maximum flat work group sizes 95 /// for function \p F, or minimum/maximum flat work group sizes explicitly 96 /// requested using "amdgpu-flat-work-group-size" attribute attached to 97 /// function \p F. 98 /// 99 /// \returns Subtarget's default values if explicitly requested values cannot 100 /// be converted to integer, or violate subtarget's specifications. 101 std::pair<unsigned, unsigned> getFlatWorkGroupSizes(const Function &F) const; 102 103 /// \returns Subtarget's default pair of minimum/maximum number of waves per 104 /// execution unit for function \p F, or minimum/maximum number of waves per 105 /// execution unit explicitly requested using "amdgpu-waves-per-eu" attribute 106 /// attached to function \p F. 107 /// 108 /// \returns Subtarget's default values if explicitly requested values cannot 109 /// be converted to integer, violate subtarget's specifications, or are not 110 /// compatible with minimum/maximum number of waves limited by flat work group 111 /// size, register usage, and/or lds usage. 112 std::pair<unsigned, unsigned> getWavesPerEU(const Function &F) const; 113 114 /// Return the amount of LDS that can be used that will not restrict the 115 /// occupancy lower than WaveCount. 116 unsigned getMaxLocalMemSizeWithWaveCount(unsigned WaveCount, 117 const Function &) const; 118 119 /// Inverse of getMaxLocalMemWithWaveCount. Return the maximum wavecount if 120 /// the given LDS memory size is the only constraint. 121 unsigned getOccupancyWithLocalMemSize(uint32_t Bytes, const Function &) const; 122 123 unsigned getOccupancyWithLocalMemSize(const MachineFunction &MF) const; 124 125 bool isAmdHsaOS() const { 126 return TargetTriple.getOS() == Triple::AMDHSA; 127 } 128 129 bool isAmdPalOS() const { 130 return TargetTriple.getOS() == Triple::AMDPAL; 131 } 132 133 bool isMesa3DOS() const { 134 return TargetTriple.getOS() == Triple::Mesa3D; 135 } 136 137 bool isMesaKernel(const Function &F) const { 138 return isMesa3DOS() && !AMDGPU::isShader(F.getCallingConv()); 139 } 140 141 bool isAmdHsaOrMesa(const Function &F) const { 142 return isAmdHsaOS() || isMesaKernel(F); 143 } 144 145 bool isGCN() const { 146 return TargetTriple.getArch() == Triple::amdgcn; 147 } 148 149 bool has16BitInsts() const { 150 return Has16BitInsts; 151 } 152 153 bool hasMadMixInsts() const { 154 return HasMadMixInsts; 155 } 156 157 bool hasMadMacF32Insts() const { 158 return HasMadMacF32Insts || !isGCN(); 159 } 160 161 bool hasDsSrc2Insts() const { 162 return HasDsSrc2Insts; 163 } 164 165 bool hasSDWA() const { 166 return HasSDWA; 167 } 168 169 bool hasVOP3PInsts() const { 170 return HasVOP3PInsts; 171 } 172 173 bool hasMulI24() const { 174 return HasMulI24; 175 } 176 177 bool hasMulU24() const { 178 return HasMulU24; 179 } 180 181 bool hasInv2PiInlineImm() const { 182 return HasInv2PiInlineImm; 183 } 184 185 bool hasFminFmaxLegacy() const { 186 return HasFminFmaxLegacy; 187 } 188 189 bool hasTrigReducedRange() const { 190 return HasTrigReducedRange; 191 } 192 193 bool isPromoteAllocaEnabled() const { 194 return EnablePromoteAlloca; 195 } 196 197 unsigned getWavefrontSize() const { 198 return 1 << WavefrontSizeLog2; 199 } 200 201 unsigned getWavefrontSizeLog2() const { 202 return WavefrontSizeLog2; 203 } 204 205 unsigned getLocalMemorySize() const { 206 return LocalMemorySize; 207 } 208 209 Align getAlignmentForImplicitArgPtr() const { 210 return isAmdHsaOS() ? Align(8) : Align(4); 211 } 212 213 /// Returns the offset in bytes from the start of the input buffer 214 /// of the first explicit kernel argument. 215 unsigned getExplicitKernelArgOffset(const Function &F) const { 216 return isAmdHsaOrMesa(F) ? 0 : 36; 217 } 218 219 /// \returns Maximum number of work groups per compute unit supported by the 220 /// subtarget and limited by given \p FlatWorkGroupSize. 221 virtual unsigned getMaxWorkGroupsPerCU(unsigned FlatWorkGroupSize) const = 0; 222 223 /// \returns Minimum flat work group size supported by the subtarget. 224 virtual unsigned getMinFlatWorkGroupSize() const = 0; 225 226 /// \returns Maximum flat work group size supported by the subtarget. 227 virtual unsigned getMaxFlatWorkGroupSize() const = 0; 228 229 /// \returns Number of waves per execution unit required to support the given 230 /// \p FlatWorkGroupSize. 231 virtual unsigned 232 getWavesPerEUForWorkGroup(unsigned FlatWorkGroupSize) const = 0; 233 234 /// \returns Minimum number of waves per execution unit supported by the 235 /// subtarget. 236 virtual unsigned getMinWavesPerEU() const = 0; 237 238 /// \returns Maximum number of waves per execution unit supported by the 239 /// subtarget without any kind of limitation. 240 unsigned getMaxWavesPerEU() const { return MaxWavesPerEU; } 241 242 /// Return the maximum workitem ID value in the function, for the given (0, 1, 243 /// 2) dimension. 244 unsigned getMaxWorkitemID(const Function &Kernel, unsigned Dimension) const; 245 246 /// Creates value range metadata on an workitemid.* intrinsic call or load. 247 bool makeLIDRangeMetadata(Instruction *I) const; 248 249 /// \returns Number of bytes of arguments that are passed to a shader or 250 /// kernel in addition to the explicit ones declared for the function. 251 unsigned getImplicitArgNumBytes(const Function &F) const { 252 if (isMesaKernel(F)) 253 return 16; 254 return AMDGPU::getIntegerAttribute(F, "amdgpu-implicitarg-num-bytes", 0); 255 } 256 uint64_t getExplicitKernArgSize(const Function &F, Align &MaxAlign) const; 257 unsigned getKernArgSegmentSize(const Function &F, Align &MaxAlign) const; 258 259 /// \returns Corresponsing DWARF register number mapping flavour for the 260 /// \p WavefrontSize. 261 AMDGPUDwarfFlavour getAMDGPUDwarfFlavour() const { 262 return getWavefrontSize() == 32 ? AMDGPUDwarfFlavour::Wave32 263 : AMDGPUDwarfFlavour::Wave64; 264 } 265 266 virtual ~AMDGPUSubtarget() {} 267 }; 268 269 class GCNSubtarget : public AMDGPUGenSubtargetInfo, 270 public AMDGPUSubtarget { 271 272 using AMDGPUSubtarget::getMaxWavesPerEU; 273 274 public: 275 enum TrapHandlerAbi { 276 TrapHandlerAbiNone = 0, 277 TrapHandlerAbiHsa = 1 278 }; 279 280 enum TrapID { 281 TrapIDHardwareReserved = 0, 282 TrapIDHSADebugTrap = 1, 283 TrapIDLLVMTrap = 2, 284 TrapIDLLVMDebugTrap = 3, 285 TrapIDDebugBreakpoint = 7, 286 TrapIDDebugReserved8 = 8, 287 TrapIDDebugReservedFE = 0xfe, 288 TrapIDDebugReservedFF = 0xff 289 }; 290 291 enum TrapRegValues { 292 LLVMTrapHandlerRegValue = 1 293 }; 294 295 private: 296 /// GlobalISel related APIs. 297 std::unique_ptr<AMDGPUCallLowering> CallLoweringInfo; 298 std::unique_ptr<InlineAsmLowering> InlineAsmLoweringInfo; 299 std::unique_ptr<InstructionSelector> InstSelector; 300 std::unique_ptr<LegalizerInfo> Legalizer; 301 std::unique_ptr<RegisterBankInfo> RegBankInfo; 302 303 protected: 304 // Basic subtarget description. 305 Triple TargetTriple; 306 unsigned Gen; 307 InstrItineraryData InstrItins; 308 int LDSBankCount; 309 unsigned MaxPrivateElementSize; 310 311 // Possibly statically set by tablegen, but may want to be overridden. 312 bool FastFMAF32; 313 bool FastDenormalF32; 314 bool HalfRate64Ops; 315 316 // Dynamically set bits that enable features. 317 bool FlatForGlobal; 318 bool AutoWaitcntBeforeBarrier; 319 bool UnalignedScratchAccess; 320 bool UnalignedBufferAccess; 321 bool UnalignedAccessMode; 322 bool HasApertureRegs; 323 bool EnableXNACK; 324 bool DoesNotSupportXNACK; 325 bool EnableCuMode; 326 bool TrapHandler; 327 328 // Used as options. 329 bool EnableLoadStoreOpt; 330 bool EnableUnsafeDSOffsetFolding; 331 bool EnableSIScheduler; 332 bool EnableDS128; 333 bool EnablePRTStrictNull; 334 bool DumpCode; 335 336 // Subtarget statically properties set by tablegen 337 bool FP64; 338 bool FMA; 339 bool MIMG_R128; 340 bool IsGCN; 341 bool GCN3Encoding; 342 bool CIInsts; 343 bool GFX8Insts; 344 bool GFX9Insts; 345 bool GFX10Insts; 346 bool GFX10_3Insts; 347 bool GFX7GFX8GFX9Insts; 348 bool SGPRInitBug; 349 bool HasSMemRealTime; 350 bool HasIntClamp; 351 bool HasFmaMixInsts; 352 bool HasMovrel; 353 bool HasVGPRIndexMode; 354 bool HasScalarStores; 355 bool HasScalarAtomics; 356 bool HasSDWAOmod; 357 bool HasSDWAScalar; 358 bool HasSDWASdst; 359 bool HasSDWAMac; 360 bool HasSDWAOutModsVOPC; 361 bool HasDPP; 362 bool HasDPP8; 363 bool HasR128A16; 364 bool HasGFX10A16; 365 bool HasG16; 366 bool HasNSAEncoding; 367 bool GFX10_BEncoding; 368 bool HasDLInsts; 369 bool HasDot1Insts; 370 bool HasDot2Insts; 371 bool HasDot3Insts; 372 bool HasDot4Insts; 373 bool HasDot5Insts; 374 bool HasDot6Insts; 375 bool HasMAIInsts; 376 bool HasPkFmacF16Inst; 377 bool HasAtomicFaddInsts; 378 bool EnableSRAMECC; 379 bool DoesNotSupportSRAMECC; 380 bool HasNoSdstCMPX; 381 bool HasVscnt; 382 bool HasGetWaveIdInst; 383 bool HasSMemTimeInst; 384 bool HasRegisterBanking; 385 bool HasVOP3Literal; 386 bool HasNoDataDepHazard; 387 bool FlatAddressSpace; 388 bool FlatInstOffsets; 389 bool FlatGlobalInsts; 390 bool FlatScratchInsts; 391 bool ScalarFlatScratchInsts; 392 bool AddNoCarryInsts; 393 bool HasUnpackedD16VMem; 394 bool R600ALUInst; 395 bool CaymanISA; 396 bool CFALUBug; 397 bool LDSMisalignedBug; 398 bool HasMFMAInlineLiteralBug; 399 bool HasVertexCache; 400 short TexVTXClauseSize; 401 bool UnalignedDSAccess; 402 bool ScalarizeGlobal; 403 404 bool HasVcmpxPermlaneHazard; 405 bool HasVMEMtoScalarWriteHazard; 406 bool HasSMEMtoVectorWriteHazard; 407 bool HasInstFwdPrefetchBug; 408 bool HasVcmpxExecWARHazard; 409 bool HasLdsBranchVmemWARHazard; 410 bool HasNSAtoVMEMBug; 411 bool HasOffset3fBug; 412 bool HasFlatSegmentOffsetBug; 413 bool HasImageStoreD16Bug; 414 bool HasImageGather4D16Bug; 415 416 // Dummy feature to use for assembler in tablegen. 417 bool FeatureDisable; 418 419 SelectionDAGTargetInfo TSInfo; 420 private: 421 SIInstrInfo InstrInfo; 422 SITargetLowering TLInfo; 423 SIFrameLowering FrameLowering; 424 425 // See COMPUTE_TMPRING_SIZE.WAVESIZE, 13-bit field in units of 256-dword. 426 static const unsigned MaxWaveScratchSize = (256 * 4) * ((1 << 13) - 1); 427 428 public: 429 GCNSubtarget(const Triple &TT, StringRef GPU, StringRef FS, 430 const GCNTargetMachine &TM); 431 ~GCNSubtarget() override; 432 433 GCNSubtarget &initializeSubtargetDependencies(const Triple &TT, 434 StringRef GPU, StringRef FS); 435 436 const SIInstrInfo *getInstrInfo() const override { 437 return &InstrInfo; 438 } 439 440 const SIFrameLowering *getFrameLowering() const override { 441 return &FrameLowering; 442 } 443 444 const SITargetLowering *getTargetLowering() const override { 445 return &TLInfo; 446 } 447 448 const SIRegisterInfo *getRegisterInfo() const override { 449 return &InstrInfo.getRegisterInfo(); 450 } 451 452 const CallLowering *getCallLowering() const override { 453 return CallLoweringInfo.get(); 454 } 455 456 const InlineAsmLowering *getInlineAsmLowering() const override { 457 return InlineAsmLoweringInfo.get(); 458 } 459 460 InstructionSelector *getInstructionSelector() const override { 461 return InstSelector.get(); 462 } 463 464 const LegalizerInfo *getLegalizerInfo() const override { 465 return Legalizer.get(); 466 } 467 468 const RegisterBankInfo *getRegBankInfo() const override { 469 return RegBankInfo.get(); 470 } 471 472 // Nothing implemented, just prevent crashes on use. 473 const SelectionDAGTargetInfo *getSelectionDAGInfo() const override { 474 return &TSInfo; 475 } 476 477 const InstrItineraryData *getInstrItineraryData() const override { 478 return &InstrItins; 479 } 480 481 void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS); 482 483 Generation getGeneration() const { 484 return (Generation)Gen; 485 } 486 487 /// Return the number of high bits known to be zero fror a frame index. 488 unsigned getKnownHighZeroBitsForFrameIndex() const { 489 return countLeadingZeros(MaxWaveScratchSize) + getWavefrontSizeLog2(); 490 } 491 492 int getLDSBankCount() const { 493 return LDSBankCount; 494 } 495 496 unsigned getMaxPrivateElementSize() const { 497 return MaxPrivateElementSize; 498 } 499 500 unsigned getConstantBusLimit(unsigned Opcode) const; 501 502 bool hasIntClamp() const { 503 return HasIntClamp; 504 } 505 506 bool hasFP64() const { 507 return FP64; 508 } 509 510 bool hasMIMG_R128() const { 511 return MIMG_R128; 512 } 513 514 bool hasHWFP64() const { 515 return FP64; 516 } 517 518 bool hasFastFMAF32() const { 519 return FastFMAF32; 520 } 521 522 bool hasHalfRate64Ops() const { 523 return HalfRate64Ops; 524 } 525 526 bool hasAddr64() const { 527 return (getGeneration() < AMDGPUSubtarget::VOLCANIC_ISLANDS); 528 } 529 530 // Return true if the target only has the reverse operand versions of VALU 531 // shift instructions (e.g. v_lshrrev_b32, and no v_lshr_b32). 532 bool hasOnlyRevVALUShifts() const { 533 return getGeneration() >= VOLCANIC_ISLANDS; 534 } 535 536 bool hasFractBug() const { 537 return getGeneration() == SOUTHERN_ISLANDS; 538 } 539 540 bool hasBFE() const { 541 return true; 542 } 543 544 bool hasBFI() const { 545 return true; 546 } 547 548 bool hasBFM() const { 549 return hasBFE(); 550 } 551 552 bool hasBCNT(unsigned Size) const { 553 return true; 554 } 555 556 bool hasFFBL() const { 557 return true; 558 } 559 560 bool hasFFBH() const { 561 return true; 562 } 563 564 bool hasMed3_16() const { 565 return getGeneration() >= AMDGPUSubtarget::GFX9; 566 } 567 568 bool hasMin3Max3_16() const { 569 return getGeneration() >= AMDGPUSubtarget::GFX9; 570 } 571 572 bool hasFmaMixInsts() const { 573 return HasFmaMixInsts; 574 } 575 576 bool hasCARRY() const { 577 return true; 578 } 579 580 bool hasFMA() const { 581 return FMA; 582 } 583 584 bool hasSwap() const { 585 return GFX9Insts; 586 } 587 588 bool hasScalarPackInsts() const { 589 return GFX9Insts; 590 } 591 592 bool hasScalarMulHiInsts() const { 593 return GFX9Insts; 594 } 595 596 TrapHandlerAbi getTrapHandlerAbi() const { 597 return isAmdHsaOS() ? TrapHandlerAbiHsa : TrapHandlerAbiNone; 598 } 599 600 /// True if the offset field of DS instructions works as expected. On SI, the 601 /// offset uses a 16-bit adder and does not always wrap properly. 602 bool hasUsableDSOffset() const { 603 return getGeneration() >= SEA_ISLANDS; 604 } 605 606 bool unsafeDSOffsetFoldingEnabled() const { 607 return EnableUnsafeDSOffsetFolding; 608 } 609 610 /// Condition output from div_scale is usable. 611 bool hasUsableDivScaleConditionOutput() const { 612 return getGeneration() != SOUTHERN_ISLANDS; 613 } 614 615 /// Extra wait hazard is needed in some cases before 616 /// s_cbranch_vccnz/s_cbranch_vccz. 617 bool hasReadVCCZBug() const { 618 return getGeneration() <= SEA_ISLANDS; 619 } 620 621 /// Writes to VCC_LO/VCC_HI update the VCCZ flag. 622 bool partialVCCWritesUpdateVCCZ() const { 623 return getGeneration() >= GFX10; 624 } 625 626 /// A read of an SGPR by SMRD instruction requires 4 wait states when the SGPR 627 /// was written by a VALU instruction. 628 bool hasSMRDReadVALUDefHazard() const { 629 return getGeneration() == SOUTHERN_ISLANDS; 630 } 631 632 /// A read of an SGPR by a VMEM instruction requires 5 wait states when the 633 /// SGPR was written by a VALU Instruction. 634 bool hasVMEMReadSGPRVALUDefHazard() const { 635 return getGeneration() >= VOLCANIC_ISLANDS; 636 } 637 638 bool hasRFEHazards() const { 639 return getGeneration() >= VOLCANIC_ISLANDS; 640 } 641 642 /// Number of hazard wait states for s_setreg_b32/s_setreg_imm32_b32. 643 unsigned getSetRegWaitStates() const { 644 return getGeneration() <= SEA_ISLANDS ? 1 : 2; 645 } 646 647 bool dumpCode() const { 648 return DumpCode; 649 } 650 651 /// Return the amount of LDS that can be used that will not restrict the 652 /// occupancy lower than WaveCount. 653 unsigned getMaxLocalMemSizeWithWaveCount(unsigned WaveCount, 654 const Function &) const; 655 656 bool supportsMinMaxDenormModes() const { 657 return getGeneration() >= AMDGPUSubtarget::GFX9; 658 } 659 660 /// \returns If target supports S_DENORM_MODE. 661 bool hasDenormModeInst() const { 662 return getGeneration() >= AMDGPUSubtarget::GFX10; 663 } 664 665 bool useFlatForGlobal() const { 666 return FlatForGlobal; 667 } 668 669 /// \returns If target supports ds_read/write_b128 and user enables generation 670 /// of ds_read/write_b128. 671 bool useDS128() const { 672 return CIInsts && EnableDS128; 673 } 674 675 /// \return If target supports ds_read/write_b96/128. 676 bool hasDS96AndDS128() const { 677 return CIInsts; 678 } 679 680 /// Have v_trunc_f64, v_ceil_f64, v_rndne_f64 681 bool haveRoundOpsF64() const { 682 return CIInsts; 683 } 684 685 /// \returns If MUBUF instructions always perform range checking, even for 686 /// buffer resources used for private memory access. 687 bool privateMemoryResourceIsRangeChecked() const { 688 return getGeneration() < AMDGPUSubtarget::GFX9; 689 } 690 691 /// \returns If target requires PRT Struct NULL support (zero result registers 692 /// for sparse texture support). 693 bool usePRTStrictNull() const { 694 return EnablePRTStrictNull; 695 } 696 697 bool hasAutoWaitcntBeforeBarrier() const { 698 return AutoWaitcntBeforeBarrier; 699 } 700 701 bool hasUnalignedBufferAccess() const { 702 return UnalignedBufferAccess; 703 } 704 705 bool hasUnalignedScratchAccess() const { 706 return UnalignedScratchAccess; 707 } 708 709 bool hasUnalignedAccessMode() const { 710 return UnalignedAccessMode; 711 } 712 713 bool hasUnalignedDSAccess() const { 714 return UnalignedDSAccess; 715 } 716 717 bool hasApertureRegs() const { 718 return HasApertureRegs; 719 } 720 721 bool isTrapHandlerEnabled() const { 722 return TrapHandler; 723 } 724 725 bool isXNACKEnabled() const { 726 return EnableXNACK; 727 } 728 729 bool isCuModeEnabled() const { 730 return EnableCuMode; 731 } 732 733 bool hasFlatAddressSpace() const { 734 return FlatAddressSpace; 735 } 736 737 bool hasFlatScrRegister() const { 738 return hasFlatAddressSpace(); 739 } 740 741 bool hasFlatInstOffsets() const { 742 return FlatInstOffsets; 743 } 744 745 bool hasFlatGlobalInsts() const { 746 return FlatGlobalInsts; 747 } 748 749 bool hasFlatScratchInsts() const { 750 return FlatScratchInsts; 751 } 752 753 // Check if target supports ST addressing mode with FLAT scratch instructions. 754 // The ST addressing mode means no registers are used, either VGPR or SGPR, 755 // but only immediate offset is swizzled and added to the FLAT scratch base. 756 bool hasFlatScratchSTMode() const { 757 return hasFlatScratchInsts() && hasGFX10_3Insts(); 758 } 759 760 bool hasScalarFlatScratchInsts() const { 761 return ScalarFlatScratchInsts; 762 } 763 764 bool hasGlobalAddTidInsts() const { 765 return GFX10_BEncoding; 766 } 767 768 bool hasAtomicCSub() const { 769 return GFX10_BEncoding; 770 } 771 772 bool hasMultiDwordFlatScratchAddressing() const { 773 return getGeneration() >= GFX9; 774 } 775 776 bool hasFlatSegmentOffsetBug() const { 777 return HasFlatSegmentOffsetBug; 778 } 779 780 bool hasFlatLgkmVMemCountInOrder() const { 781 return getGeneration() > GFX9; 782 } 783 784 bool hasD16LoadStore() const { 785 return getGeneration() >= GFX9; 786 } 787 788 bool d16PreservesUnusedBits() const { 789 return hasD16LoadStore() && !isSRAMECCEnabled(); 790 } 791 792 bool hasD16Images() const { 793 return getGeneration() >= VOLCANIC_ISLANDS; 794 } 795 796 /// Return if most LDS instructions have an m0 use that require m0 to be 797 /// iniitalized. 798 bool ldsRequiresM0Init() const { 799 return getGeneration() < GFX9; 800 } 801 802 // True if the hardware rewinds and replays GWS operations if a wave is 803 // preempted. 804 // 805 // If this is false, a GWS operation requires testing if a nack set the 806 // MEM_VIOL bit, and repeating if so. 807 bool hasGWSAutoReplay() const { 808 return getGeneration() >= GFX9; 809 } 810 811 /// \returns if target has ds_gws_sema_release_all instruction. 812 bool hasGWSSemaReleaseAll() const { 813 return CIInsts; 814 } 815 816 /// \returns true if the target has integer add/sub instructions that do not 817 /// produce a carry-out. This includes v_add_[iu]32, v_sub_[iu]32, 818 /// v_add_[iu]16, and v_sub_[iu]16, all of which support the clamp modifier 819 /// for saturation. 820 bool hasAddNoCarry() const { 821 return AddNoCarryInsts; 822 } 823 824 bool hasUnpackedD16VMem() const { 825 return HasUnpackedD16VMem; 826 } 827 828 // Covers VS/PS/CS graphics shaders 829 bool isMesaGfxShader(const Function &F) const { 830 return isMesa3DOS() && AMDGPU::isShader(F.getCallingConv()); 831 } 832 833 bool hasMad64_32() const { 834 return getGeneration() >= SEA_ISLANDS; 835 } 836 837 bool hasSDWAOmod() const { 838 return HasSDWAOmod; 839 } 840 841 bool hasSDWAScalar() const { 842 return HasSDWAScalar; 843 } 844 845 bool hasSDWASdst() const { 846 return HasSDWASdst; 847 } 848 849 bool hasSDWAMac() const { 850 return HasSDWAMac; 851 } 852 853 bool hasSDWAOutModsVOPC() const { 854 return HasSDWAOutModsVOPC; 855 } 856 857 bool hasDLInsts() const { 858 return HasDLInsts; 859 } 860 861 bool hasDot1Insts() const { 862 return HasDot1Insts; 863 } 864 865 bool hasDot2Insts() const { 866 return HasDot2Insts; 867 } 868 869 bool hasDot3Insts() const { 870 return HasDot3Insts; 871 } 872 873 bool hasDot4Insts() const { 874 return HasDot4Insts; 875 } 876 877 bool hasDot5Insts() const { 878 return HasDot5Insts; 879 } 880 881 bool hasDot6Insts() const { 882 return HasDot6Insts; 883 } 884 885 bool hasMAIInsts() const { 886 return HasMAIInsts; 887 } 888 889 bool hasPkFmacF16Inst() const { 890 return HasPkFmacF16Inst; 891 } 892 893 bool hasAtomicFaddInsts() const { 894 return HasAtomicFaddInsts; 895 } 896 897 bool isSRAMECCEnabled() const { 898 return EnableSRAMECC; 899 } 900 901 bool hasNoSdstCMPX() const { 902 return HasNoSdstCMPX; 903 } 904 905 bool hasVscnt() const { 906 return HasVscnt; 907 } 908 909 bool hasGetWaveIdInst() const { 910 return HasGetWaveIdInst; 911 } 912 913 bool hasSMemTimeInst() const { 914 return HasSMemTimeInst; 915 } 916 917 bool hasRegisterBanking() const { 918 return HasRegisterBanking; 919 } 920 921 bool hasVOP3Literal() const { 922 return HasVOP3Literal; 923 } 924 925 bool hasNoDataDepHazard() const { 926 return HasNoDataDepHazard; 927 } 928 929 bool vmemWriteNeedsExpWaitcnt() const { 930 return getGeneration() < SEA_ISLANDS; 931 } 932 933 // Scratch is allocated in 256 dword per wave blocks for the entire 934 // wavefront. When viewed from the perspecive of an arbitrary workitem, this 935 // is 4-byte aligned. 936 // 937 // Only 4-byte alignment is really needed to access anything. Transformations 938 // on the pointer value itself may rely on the alignment / known low bits of 939 // the pointer. Set this to something above the minimum to avoid needing 940 // dynamic realignment in common cases. 941 Align getStackAlignment() const { return Align(16); } 942 943 bool enableMachineScheduler() const override { 944 return true; 945 } 946 947 bool enableSubRegLiveness() const override { 948 return true; 949 } 950 951 void setScalarizeGlobalBehavior(bool b) { ScalarizeGlobal = b; } 952 bool getScalarizeGlobalBehavior() const { return ScalarizeGlobal; } 953 954 // static wrappers 955 static bool hasHalfRate64Ops(const TargetSubtargetInfo &STI); 956 957 // XXX - Why is this here if it isn't in the default pass set? 958 bool enableEarlyIfConversion() const override { 959 return true; 960 } 961 962 void overrideSchedPolicy(MachineSchedPolicy &Policy, 963 unsigned NumRegionInstrs) const override; 964 965 unsigned getMaxNumUserSGPRs() const { 966 return 16; 967 } 968 969 bool hasSMemRealTime() const { 970 return HasSMemRealTime; 971 } 972 973 bool hasMovrel() const { 974 return HasMovrel; 975 } 976 977 bool hasVGPRIndexMode() const { 978 return HasVGPRIndexMode; 979 } 980 981 bool useVGPRIndexMode() const; 982 983 bool hasScalarCompareEq64() const { 984 return getGeneration() >= VOLCANIC_ISLANDS; 985 } 986 987 bool hasScalarStores() const { 988 return HasScalarStores; 989 } 990 991 bool hasScalarAtomics() const { 992 return HasScalarAtomics; 993 } 994 995 bool hasLDSFPAtomics() const { 996 return GFX8Insts; 997 } 998 999 bool hasDPP() const { 1000 return HasDPP; 1001 } 1002 1003 bool hasDPPBroadcasts() const { 1004 return HasDPP && getGeneration() < GFX10; 1005 } 1006 1007 bool hasDPPWavefrontShifts() const { 1008 return HasDPP && getGeneration() < GFX10; 1009 } 1010 1011 bool hasDPP8() const { 1012 return HasDPP8; 1013 } 1014 1015 bool hasR128A16() const { 1016 return HasR128A16; 1017 } 1018 1019 bool hasGFX10A16() const { 1020 return HasGFX10A16; 1021 } 1022 1023 bool hasA16() const { return hasR128A16() || hasGFX10A16(); } 1024 1025 bool hasG16() const { return HasG16; } 1026 1027 bool hasOffset3fBug() const { 1028 return HasOffset3fBug; 1029 } 1030 1031 bool hasImageStoreD16Bug() const { return HasImageStoreD16Bug; } 1032 1033 bool hasImageGather4D16Bug() const { return HasImageGather4D16Bug; } 1034 1035 bool hasNSAEncoding() const { return HasNSAEncoding; } 1036 1037 bool hasGFX10_BEncoding() const { 1038 return GFX10_BEncoding; 1039 } 1040 1041 bool hasGFX10_3Insts() const { 1042 return GFX10_3Insts; 1043 } 1044 1045 bool hasMadF16() const; 1046 1047 bool enableSIScheduler() const { 1048 return EnableSIScheduler; 1049 } 1050 1051 bool loadStoreOptEnabled() const { 1052 return EnableLoadStoreOpt; 1053 } 1054 1055 bool hasSGPRInitBug() const { 1056 return SGPRInitBug; 1057 } 1058 1059 bool hasMFMAInlineLiteralBug() const { 1060 return HasMFMAInlineLiteralBug; 1061 } 1062 1063 bool has12DWordStoreHazard() const { 1064 return getGeneration() != AMDGPUSubtarget::SOUTHERN_ISLANDS; 1065 } 1066 1067 // \returns true if the subtarget supports DWORDX3 load/store instructions. 1068 bool hasDwordx3LoadStores() const { 1069 return CIInsts; 1070 } 1071 1072 bool hasReadM0MovRelInterpHazard() const { 1073 return getGeneration() == AMDGPUSubtarget::GFX9; 1074 } 1075 1076 bool hasReadM0SendMsgHazard() const { 1077 return getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS && 1078 getGeneration() <= AMDGPUSubtarget::GFX9; 1079 } 1080 1081 bool hasVcmpxPermlaneHazard() const { 1082 return HasVcmpxPermlaneHazard; 1083 } 1084 1085 bool hasVMEMtoScalarWriteHazard() const { 1086 return HasVMEMtoScalarWriteHazard; 1087 } 1088 1089 bool hasSMEMtoVectorWriteHazard() const { 1090 return HasSMEMtoVectorWriteHazard; 1091 } 1092 1093 bool hasLDSMisalignedBug() const { 1094 return LDSMisalignedBug && !EnableCuMode; 1095 } 1096 1097 bool hasInstFwdPrefetchBug() const { 1098 return HasInstFwdPrefetchBug; 1099 } 1100 1101 bool hasVcmpxExecWARHazard() const { 1102 return HasVcmpxExecWARHazard; 1103 } 1104 1105 bool hasLdsBranchVmemWARHazard() const { 1106 return HasLdsBranchVmemWARHazard; 1107 } 1108 1109 bool hasNSAtoVMEMBug() const { 1110 return HasNSAtoVMEMBug; 1111 } 1112 1113 bool hasHardClauses() const { return getGeneration() >= GFX10; } 1114 1115 /// Return the maximum number of waves per SIMD for kernels using \p SGPRs 1116 /// SGPRs 1117 unsigned getOccupancyWithNumSGPRs(unsigned SGPRs) const; 1118 1119 /// Return the maximum number of waves per SIMD for kernels using \p VGPRs 1120 /// VGPRs 1121 unsigned getOccupancyWithNumVGPRs(unsigned VGPRs) const; 1122 1123 /// Return occupancy for the given function. Used LDS and a number of 1124 /// registers if provided. 1125 /// Note, occupancy can be affected by the scratch allocation as well, but 1126 /// we do not have enough information to compute it. 1127 unsigned computeOccupancy(const Function &F, unsigned LDSSize = 0, 1128 unsigned NumSGPRs = 0, unsigned NumVGPRs = 0) const; 1129 1130 /// \returns true if the flat_scratch register should be initialized with the 1131 /// pointer to the wave's scratch memory rather than a size and offset. 1132 bool flatScratchIsPointer() const { 1133 return getGeneration() >= AMDGPUSubtarget::GFX9; 1134 } 1135 1136 /// \returns true if the machine has merged shaders in which s0-s7 are 1137 /// reserved by the hardware and user SGPRs start at s8 1138 bool hasMergedShaders() const { 1139 return getGeneration() >= GFX9; 1140 } 1141 1142 /// \returns SGPR allocation granularity supported by the subtarget. 1143 unsigned getSGPRAllocGranule() const { 1144 return AMDGPU::IsaInfo::getSGPRAllocGranule(this); 1145 } 1146 1147 /// \returns SGPR encoding granularity supported by the subtarget. 1148 unsigned getSGPREncodingGranule() const { 1149 return AMDGPU::IsaInfo::getSGPREncodingGranule(this); 1150 } 1151 1152 /// \returns Total number of SGPRs supported by the subtarget. 1153 unsigned getTotalNumSGPRs() const { 1154 return AMDGPU::IsaInfo::getTotalNumSGPRs(this); 1155 } 1156 1157 /// \returns Addressable number of SGPRs supported by the subtarget. 1158 unsigned getAddressableNumSGPRs() const { 1159 return AMDGPU::IsaInfo::getAddressableNumSGPRs(this); 1160 } 1161 1162 /// \returns Minimum number of SGPRs that meets the given number of waves per 1163 /// execution unit requirement supported by the subtarget. 1164 unsigned getMinNumSGPRs(unsigned WavesPerEU) const { 1165 return AMDGPU::IsaInfo::getMinNumSGPRs(this, WavesPerEU); 1166 } 1167 1168 /// \returns Maximum number of SGPRs that meets the given number of waves per 1169 /// execution unit requirement supported by the subtarget. 1170 unsigned getMaxNumSGPRs(unsigned WavesPerEU, bool Addressable) const { 1171 return AMDGPU::IsaInfo::getMaxNumSGPRs(this, WavesPerEU, Addressable); 1172 } 1173 1174 /// \returns Reserved number of SGPRs for given function \p MF. 1175 unsigned getReservedNumSGPRs(const MachineFunction &MF) const; 1176 1177 /// \returns Maximum number of SGPRs that meets number of waves per execution 1178 /// unit requirement for function \p MF, or number of SGPRs explicitly 1179 /// requested using "amdgpu-num-sgpr" attribute attached to function \p MF. 1180 /// 1181 /// \returns Value that meets number of waves per execution unit requirement 1182 /// if explicitly requested value cannot be converted to integer, violates 1183 /// subtarget's specifications, or does not meet number of waves per execution 1184 /// unit requirement. 1185 unsigned getMaxNumSGPRs(const MachineFunction &MF) const; 1186 1187 /// \returns VGPR allocation granularity supported by the subtarget. 1188 unsigned getVGPRAllocGranule() const { 1189 return AMDGPU::IsaInfo::getVGPRAllocGranule(this); 1190 } 1191 1192 /// \returns VGPR encoding granularity supported by the subtarget. 1193 unsigned getVGPREncodingGranule() const { 1194 return AMDGPU::IsaInfo::getVGPREncodingGranule(this); 1195 } 1196 1197 /// \returns Total number of VGPRs supported by the subtarget. 1198 unsigned getTotalNumVGPRs() const { 1199 return AMDGPU::IsaInfo::getTotalNumVGPRs(this); 1200 } 1201 1202 /// \returns Addressable number of VGPRs supported by the subtarget. 1203 unsigned getAddressableNumVGPRs() const { 1204 return AMDGPU::IsaInfo::getAddressableNumVGPRs(this); 1205 } 1206 1207 /// \returns Minimum number of VGPRs that meets given number of waves per 1208 /// execution unit requirement supported by the subtarget. 1209 unsigned getMinNumVGPRs(unsigned WavesPerEU) const { 1210 return AMDGPU::IsaInfo::getMinNumVGPRs(this, WavesPerEU); 1211 } 1212 1213 /// \returns Maximum number of VGPRs that meets given number of waves per 1214 /// execution unit requirement supported by the subtarget. 1215 unsigned getMaxNumVGPRs(unsigned WavesPerEU) const { 1216 return AMDGPU::IsaInfo::getMaxNumVGPRs(this, WavesPerEU); 1217 } 1218 1219 /// \returns Maximum number of VGPRs that meets number of waves per execution 1220 /// unit requirement for function \p MF, or number of VGPRs explicitly 1221 /// requested using "amdgpu-num-vgpr" attribute attached to function \p MF. 1222 /// 1223 /// \returns Value that meets number of waves per execution unit requirement 1224 /// if explicitly requested value cannot be converted to integer, violates 1225 /// subtarget's specifications, or does not meet number of waves per execution 1226 /// unit requirement. 1227 unsigned getMaxNumVGPRs(const MachineFunction &MF) const; 1228 1229 void getPostRAMutations( 1230 std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) 1231 const override; 1232 1233 bool isWave32() const { 1234 return getWavefrontSize() == 32; 1235 } 1236 1237 bool isWave64() const { 1238 return getWavefrontSize() == 64; 1239 } 1240 1241 const TargetRegisterClass *getBoolRC() const { 1242 return getRegisterInfo()->getBoolRC(); 1243 } 1244 1245 /// \returns Maximum number of work groups per compute unit supported by the 1246 /// subtarget and limited by given \p FlatWorkGroupSize. 1247 unsigned getMaxWorkGroupsPerCU(unsigned FlatWorkGroupSize) const override { 1248 return AMDGPU::IsaInfo::getMaxWorkGroupsPerCU(this, FlatWorkGroupSize); 1249 } 1250 1251 /// \returns Minimum flat work group size supported by the subtarget. 1252 unsigned getMinFlatWorkGroupSize() const override { 1253 return AMDGPU::IsaInfo::getMinFlatWorkGroupSize(this); 1254 } 1255 1256 /// \returns Maximum flat work group size supported by the subtarget. 1257 unsigned getMaxFlatWorkGroupSize() const override { 1258 return AMDGPU::IsaInfo::getMaxFlatWorkGroupSize(this); 1259 } 1260 1261 /// \returns Number of waves per execution unit required to support the given 1262 /// \p FlatWorkGroupSize. 1263 unsigned 1264 getWavesPerEUForWorkGroup(unsigned FlatWorkGroupSize) const override { 1265 return AMDGPU::IsaInfo::getWavesPerEUForWorkGroup(this, FlatWorkGroupSize); 1266 } 1267 1268 /// \returns Minimum number of waves per execution unit supported by the 1269 /// subtarget. 1270 unsigned getMinWavesPerEU() const override { 1271 return AMDGPU::IsaInfo::getMinWavesPerEU(this); 1272 } 1273 1274 void adjustSchedDependency(SUnit *Def, int DefOpIdx, SUnit *Use, int UseOpIdx, 1275 SDep &Dep) const override; 1276 }; 1277 1278 class R600Subtarget final : public R600GenSubtargetInfo, 1279 public AMDGPUSubtarget { 1280 private: 1281 R600InstrInfo InstrInfo; 1282 R600FrameLowering FrameLowering; 1283 bool FMA; 1284 bool CaymanISA; 1285 bool CFALUBug; 1286 bool HasVertexCache; 1287 bool R600ALUInst; 1288 bool FP64; 1289 short TexVTXClauseSize; 1290 Generation Gen; 1291 R600TargetLowering TLInfo; 1292 InstrItineraryData InstrItins; 1293 SelectionDAGTargetInfo TSInfo; 1294 1295 public: 1296 R600Subtarget(const Triple &TT, StringRef CPU, StringRef FS, 1297 const TargetMachine &TM); 1298 1299 const R600InstrInfo *getInstrInfo() const override { return &InstrInfo; } 1300 1301 const R600FrameLowering *getFrameLowering() const override { 1302 return &FrameLowering; 1303 } 1304 1305 const R600TargetLowering *getTargetLowering() const override { 1306 return &TLInfo; 1307 } 1308 1309 const R600RegisterInfo *getRegisterInfo() const override { 1310 return &InstrInfo.getRegisterInfo(); 1311 } 1312 1313 const InstrItineraryData *getInstrItineraryData() const override { 1314 return &InstrItins; 1315 } 1316 1317 // Nothing implemented, just prevent crashes on use. 1318 const SelectionDAGTargetInfo *getSelectionDAGInfo() const override { 1319 return &TSInfo; 1320 } 1321 1322 void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS); 1323 1324 Generation getGeneration() const { 1325 return Gen; 1326 } 1327 1328 Align getStackAlignment() const { return Align(4); } 1329 1330 R600Subtarget &initializeSubtargetDependencies(const Triple &TT, 1331 StringRef GPU, StringRef FS); 1332 1333 bool hasBFE() const { 1334 return (getGeneration() >= EVERGREEN); 1335 } 1336 1337 bool hasBFI() const { 1338 return (getGeneration() >= EVERGREEN); 1339 } 1340 1341 bool hasBCNT(unsigned Size) const { 1342 if (Size == 32) 1343 return (getGeneration() >= EVERGREEN); 1344 1345 return false; 1346 } 1347 1348 bool hasBORROW() const { 1349 return (getGeneration() >= EVERGREEN); 1350 } 1351 1352 bool hasCARRY() const { 1353 return (getGeneration() >= EVERGREEN); 1354 } 1355 1356 bool hasCaymanISA() const { 1357 return CaymanISA; 1358 } 1359 1360 bool hasFFBL() const { 1361 return (getGeneration() >= EVERGREEN); 1362 } 1363 1364 bool hasFFBH() const { 1365 return (getGeneration() >= EVERGREEN); 1366 } 1367 1368 bool hasFMA() const { return FMA; } 1369 1370 bool hasCFAluBug() const { return CFALUBug; } 1371 1372 bool hasVertexCache() const { return HasVertexCache; } 1373 1374 short getTexVTXClauseSize() const { return TexVTXClauseSize; } 1375 1376 bool enableMachineScheduler() const override { 1377 return true; 1378 } 1379 1380 bool enableSubRegLiveness() const override { 1381 return true; 1382 } 1383 1384 /// \returns Maximum number of work groups per compute unit supported by the 1385 /// subtarget and limited by given \p FlatWorkGroupSize. 1386 unsigned getMaxWorkGroupsPerCU(unsigned FlatWorkGroupSize) const override { 1387 return AMDGPU::IsaInfo::getMaxWorkGroupsPerCU(this, FlatWorkGroupSize); 1388 } 1389 1390 /// \returns Minimum flat work group size supported by the subtarget. 1391 unsigned getMinFlatWorkGroupSize() const override { 1392 return AMDGPU::IsaInfo::getMinFlatWorkGroupSize(this); 1393 } 1394 1395 /// \returns Maximum flat work group size supported by the subtarget. 1396 unsigned getMaxFlatWorkGroupSize() const override { 1397 return AMDGPU::IsaInfo::getMaxFlatWorkGroupSize(this); 1398 } 1399 1400 /// \returns Number of waves per execution unit required to support the given 1401 /// \p FlatWorkGroupSize. 1402 unsigned 1403 getWavesPerEUForWorkGroup(unsigned FlatWorkGroupSize) const override { 1404 return AMDGPU::IsaInfo::getWavesPerEUForWorkGroup(this, FlatWorkGroupSize); 1405 } 1406 1407 /// \returns Minimum number of waves per execution unit supported by the 1408 /// subtarget. 1409 unsigned getMinWavesPerEU() const override { 1410 return AMDGPU::IsaInfo::getMinWavesPerEU(this); 1411 } 1412 }; 1413 1414 } // end namespace llvm 1415 1416 #endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUSUBTARGET_H 1417