1 //=====-- AMDGPUSubtarget.h - Define Subtarget for AMDGPU ------*- C++ -*-====// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //==-----------------------------------------------------------------------===// 9 // 10 /// \file 11 /// AMDGPU specific subclass of TargetSubtarget. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUSUBTARGET_H 16 #define LLVM_LIB_TARGET_AMDGPU_AMDGPUSUBTARGET_H 17 18 #include "AMDGPU.h" 19 #include "AMDGPUCallLowering.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/InstructionSelector.h" 29 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" 30 #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" 31 #include "llvm/CodeGen/MachineFunction.h" 32 #include "llvm/CodeGen/SelectionDAGTargetInfo.h" 33 #include "llvm/MC/MCInstrItineraries.h" 34 #include "llvm/Support/MathExtras.h" 35 #include <cassert> 36 #include <cstdint> 37 #include <memory> 38 #include <utility> 39 40 #define GET_SUBTARGETINFO_HEADER 41 #include "AMDGPUGenSubtargetInfo.inc" 42 #define GET_SUBTARGETINFO_HEADER 43 #include "R600GenSubtargetInfo.inc" 44 45 namespace llvm { 46 47 class StringRef; 48 49 class AMDGPUSubtarget { 50 public: 51 enum Generation { 52 R600 = 0, 53 R700 = 1, 54 EVERGREEN = 2, 55 NORTHERN_ISLANDS = 3, 56 SOUTHERN_ISLANDS = 4, 57 SEA_ISLANDS = 5, 58 VOLCANIC_ISLANDS = 6, 59 GFX9 = 7 60 }; 61 62 private: 63 Triple TargetTriple; 64 65 protected: 66 bool Has16BitInsts; 67 bool HasMadMixInsts; 68 bool FP32Denormals; 69 bool FPExceptions; 70 bool HasSDWA; 71 bool HasVOP3PInsts; 72 bool HasMulI24; 73 bool HasMulU24; 74 bool HasInv2PiInlineImm; 75 bool HasFminFmaxLegacy; 76 bool EnablePromoteAlloca; 77 bool HasTrigReducedRange; 78 int LocalMemorySize; 79 unsigned WavefrontSize; 80 81 public: 82 AMDGPUSubtarget(const Triple &TT); 83 84 static const AMDGPUSubtarget &get(const MachineFunction &MF); 85 static const AMDGPUSubtarget &get(const TargetMachine &TM, 86 const Function &F); 87 88 /// \returns Default range flat work group size for a calling convention. 89 std::pair<unsigned, unsigned> getDefaultFlatWorkGroupSize(CallingConv::ID CC) const; 90 91 /// \returns Subtarget's default pair of minimum/maximum flat work group sizes 92 /// for function \p F, or minimum/maximum flat work group sizes explicitly 93 /// requested using "amdgpu-flat-work-group-size" attribute attached to 94 /// function \p F. 95 /// 96 /// \returns Subtarget's default values if explicitly requested values cannot 97 /// be converted to integer, or violate subtarget's specifications. 98 std::pair<unsigned, unsigned> getFlatWorkGroupSizes(const Function &F) const; 99 100 /// \returns Subtarget's default pair of minimum/maximum number of waves per 101 /// execution unit for function \p F, or minimum/maximum number of waves per 102 /// execution unit explicitly requested using "amdgpu-waves-per-eu" attribute 103 /// attached to function \p F. 104 /// 105 /// \returns Subtarget's default values if explicitly requested values cannot 106 /// be converted to integer, violate subtarget's specifications, or are not 107 /// compatible with minimum/maximum number of waves limited by flat work group 108 /// size, register usage, and/or lds usage. 109 std::pair<unsigned, unsigned> getWavesPerEU(const Function &F) const; 110 111 /// Return the amount of LDS that can be used that will not restrict the 112 /// occupancy lower than WaveCount. 113 unsigned getMaxLocalMemSizeWithWaveCount(unsigned WaveCount, 114 const Function &) const; 115 116 /// Inverse of getMaxLocalMemWithWaveCount. Return the maximum wavecount if 117 /// the given LDS memory size is the only constraint. 118 unsigned getOccupancyWithLocalMemSize(uint32_t Bytes, const Function &) const; 119 120 unsigned getOccupancyWithLocalMemSize(const MachineFunction &MF) const; 121 122 bool isAmdHsaOS() const { 123 return TargetTriple.getOS() == Triple::AMDHSA; 124 } 125 126 bool isAmdPalOS() const { 127 return TargetTriple.getOS() == Triple::AMDPAL; 128 } 129 130 bool isMesa3DOS() const { 131 return TargetTriple.getOS() == Triple::Mesa3D; 132 } 133 134 bool isMesaKernel(const Function &F) const { 135 return isMesa3DOS() && !AMDGPU::isShader(F.getCallingConv()); 136 } 137 138 bool isAmdHsaOrMesa(const Function &F) const { 139 return isAmdHsaOS() || isMesaKernel(F); 140 } 141 142 bool has16BitInsts() const { 143 return Has16BitInsts; 144 } 145 146 bool hasMadMixInsts() const { 147 return HasMadMixInsts; 148 } 149 150 bool hasFP32Denormals() const { 151 return FP32Denormals; 152 } 153 154 bool hasFPExceptions() const { 155 return FPExceptions; 156 } 157 158 bool hasSDWA() const { 159 return HasSDWA; 160 } 161 162 bool hasVOP3PInsts() const { 163 return HasVOP3PInsts; 164 } 165 166 bool hasMulI24() const { 167 return HasMulI24; 168 } 169 170 bool hasMulU24() const { 171 return HasMulU24; 172 } 173 174 bool hasInv2PiInlineImm() const { 175 return HasInv2PiInlineImm; 176 } 177 178 bool hasFminFmaxLegacy() const { 179 return HasFminFmaxLegacy; 180 } 181 182 bool hasTrigReducedRange() const { 183 return HasTrigReducedRange; 184 } 185 186 bool isPromoteAllocaEnabled() const { 187 return EnablePromoteAlloca; 188 } 189 190 unsigned getWavefrontSize() const { 191 return WavefrontSize; 192 } 193 194 int getLocalMemorySize() const { 195 return LocalMemorySize; 196 } 197 198 unsigned getAlignmentForImplicitArgPtr() const { 199 return isAmdHsaOS() ? 8 : 4; 200 } 201 202 /// Returns the offset in bytes from the start of the input buffer 203 /// of the first explicit kernel argument. 204 unsigned getExplicitKernelArgOffset(const Function &F) const { 205 return isAmdHsaOrMesa(F) ? 0 : 36; 206 } 207 208 /// \returns Maximum number of work groups per compute unit supported by the 209 /// subtarget and limited by given \p FlatWorkGroupSize. 210 virtual unsigned getMaxWorkGroupsPerCU(unsigned FlatWorkGroupSize) const = 0; 211 212 /// \returns Minimum flat work group size supported by the subtarget. 213 virtual unsigned getMinFlatWorkGroupSize() const = 0; 214 215 /// \returns Maximum flat work group size supported by the subtarget. 216 virtual unsigned getMaxFlatWorkGroupSize() const = 0; 217 218 /// \returns Maximum number of waves per execution unit supported by the 219 /// subtarget and limited by given \p FlatWorkGroupSize. 220 virtual unsigned getMaxWavesPerEU(unsigned FlatWorkGroupSize) const = 0; 221 222 /// \returns Minimum number of waves per execution unit supported by the 223 /// subtarget. 224 virtual unsigned getMinWavesPerEU() const = 0; 225 226 unsigned getMaxWavesPerEU() const { return 10; } 227 228 /// Creates value range metadata on an workitemid.* inrinsic call or load. 229 bool makeLIDRangeMetadata(Instruction *I) const; 230 231 /// \returns Number of bytes of arguments that are passed to a shader or 232 /// kernel in addition to the explicit ones declared for the function. 233 unsigned getImplicitArgNumBytes(const Function &F) const { 234 if (isMesaKernel(F)) 235 return 16; 236 return AMDGPU::getIntegerAttribute(F, "amdgpu-implicitarg-num-bytes", 0); 237 } 238 uint64_t getExplicitKernArgSize(const Function &F, 239 unsigned &MaxAlign) const; 240 unsigned getKernArgSegmentSize(const Function &F, 241 unsigned &MaxAlign) const; 242 243 virtual ~AMDGPUSubtarget() {} 244 }; 245 246 class GCNSubtarget : public AMDGPUGenSubtargetInfo, 247 public AMDGPUSubtarget { 248 public: 249 enum { 250 ISAVersion0_0_0, 251 ISAVersion6_0_0, 252 ISAVersion6_0_1, 253 ISAVersion7_0_0, 254 ISAVersion7_0_1, 255 ISAVersion7_0_2, 256 ISAVersion7_0_3, 257 ISAVersion7_0_4, 258 ISAVersion8_0_1, 259 ISAVersion8_0_2, 260 ISAVersion8_0_3, 261 ISAVersion8_1_0, 262 ISAVersion9_0_0, 263 ISAVersion9_0_2, 264 ISAVersion9_0_4, 265 ISAVersion9_0_6, 266 ISAVersion9_0_9, 267 }; 268 269 enum TrapHandlerAbi { 270 TrapHandlerAbiNone = 0, 271 TrapHandlerAbiHsa = 1 272 }; 273 274 enum TrapID { 275 TrapIDHardwareReserved = 0, 276 TrapIDHSADebugTrap = 1, 277 TrapIDLLVMTrap = 2, 278 TrapIDLLVMDebugTrap = 3, 279 TrapIDDebugBreakpoint = 7, 280 TrapIDDebugReserved8 = 8, 281 TrapIDDebugReservedFE = 0xfe, 282 TrapIDDebugReservedFF = 0xff 283 }; 284 285 enum TrapRegValues { 286 LLVMTrapHandlerRegValue = 1 287 }; 288 289 private: 290 /// GlobalISel related APIs. 291 std::unique_ptr<AMDGPUCallLowering> CallLoweringInfo; 292 std::unique_ptr<InstructionSelector> InstSelector; 293 std::unique_ptr<LegalizerInfo> Legalizer; 294 std::unique_ptr<RegisterBankInfo> RegBankInfo; 295 296 protected: 297 // Basic subtarget description. 298 Triple TargetTriple; 299 unsigned Gen; 300 unsigned IsaVersion; 301 InstrItineraryData InstrItins; 302 int LDSBankCount; 303 unsigned MaxPrivateElementSize; 304 305 // Possibly statically set by tablegen, but may want to be overridden. 306 bool FastFMAF32; 307 bool HalfRate64Ops; 308 309 // Dynamially set bits that enable features. 310 bool FP64FP16Denormals; 311 bool DX10Clamp; 312 bool FlatForGlobal; 313 bool AutoWaitcntBeforeBarrier; 314 bool CodeObjectV3; 315 bool UnalignedScratchAccess; 316 bool UnalignedBufferAccess; 317 bool HasApertureRegs; 318 bool EnableXNACK; 319 bool TrapHandler; 320 bool DebuggerInsertNops; 321 bool DebuggerEmitPrologue; 322 323 // Used as options. 324 bool EnableHugePrivateBuffer; 325 bool EnableVGPRSpilling; 326 bool EnableLoadStoreOpt; 327 bool EnableUnsafeDSOffsetFolding; 328 bool EnableSIScheduler; 329 bool EnableDS128; 330 bool DumpCode; 331 332 // Subtarget statically properties set by tablegen 333 bool FP64; 334 bool FMA; 335 bool MIMG_R128; 336 bool IsGCN; 337 bool GCN3Encoding; 338 bool CIInsts; 339 bool VIInsts; 340 bool GFX9Insts; 341 bool SGPRInitBug; 342 bool HasSMemRealTime; 343 bool HasIntClamp; 344 bool HasFmaMixInsts; 345 bool HasMovrel; 346 bool HasVGPRIndexMode; 347 bool HasScalarStores; 348 bool HasScalarAtomics; 349 bool HasSDWAOmod; 350 bool HasSDWAScalar; 351 bool HasSDWASdst; 352 bool HasSDWAMac; 353 bool HasSDWAOutModsVOPC; 354 bool HasDPP; 355 bool HasR128A16; 356 bool HasDLInsts; 357 bool D16PreservesUnusedBits; 358 bool FlatAddressSpace; 359 bool FlatInstOffsets; 360 bool FlatGlobalInsts; 361 bool FlatScratchInsts; 362 bool AddNoCarryInsts; 363 bool HasUnpackedD16VMem; 364 bool R600ALUInst; 365 bool CaymanISA; 366 bool CFALUBug; 367 bool HasVertexCache; 368 short TexVTXClauseSize; 369 bool ScalarizeGlobal; 370 371 // Dummy feature to use for assembler in tablegen. 372 bool FeatureDisable; 373 374 SelectionDAGTargetInfo TSInfo; 375 private: 376 SIInstrInfo InstrInfo; 377 SITargetLowering TLInfo; 378 SIFrameLowering FrameLowering; 379 380 public: 381 GCNSubtarget(const Triple &TT, StringRef GPU, StringRef FS, 382 const GCNTargetMachine &TM); 383 ~GCNSubtarget() override; 384 385 GCNSubtarget &initializeSubtargetDependencies(const Triple &TT, 386 StringRef GPU, StringRef FS); 387 388 const SIInstrInfo *getInstrInfo() const override { 389 return &InstrInfo; 390 } 391 392 const SIFrameLowering *getFrameLowering() const override { 393 return &FrameLowering; 394 } 395 396 const SITargetLowering *getTargetLowering() const override { 397 return &TLInfo; 398 } 399 400 const SIRegisterInfo *getRegisterInfo() const override { 401 return &InstrInfo.getRegisterInfo(); 402 } 403 404 const CallLowering *getCallLowering() const override { 405 return CallLoweringInfo.get(); 406 } 407 408 const InstructionSelector *getInstructionSelector() const override { 409 return InstSelector.get(); 410 } 411 412 const LegalizerInfo *getLegalizerInfo() const override { 413 return Legalizer.get(); 414 } 415 416 const RegisterBankInfo *getRegBankInfo() const override { 417 return RegBankInfo.get(); 418 } 419 420 // Nothing implemented, just prevent crashes on use. 421 const SelectionDAGTargetInfo *getSelectionDAGInfo() const override { 422 return &TSInfo; 423 } 424 425 const InstrItineraryData *getInstrItineraryData() const override { 426 return &InstrItins; 427 } 428 429 void ParseSubtargetFeatures(StringRef CPU, StringRef FS); 430 431 Generation getGeneration() const { 432 return (Generation)Gen; 433 } 434 435 unsigned getWavefrontSizeLog2() const { 436 return Log2_32(WavefrontSize); 437 } 438 439 int getLDSBankCount() const { 440 return LDSBankCount; 441 } 442 443 unsigned getMaxPrivateElementSize() const { 444 return MaxPrivateElementSize; 445 } 446 447 bool hasIntClamp() const { 448 return HasIntClamp; 449 } 450 451 bool hasFP64() const { 452 return FP64; 453 } 454 455 bool hasMIMG_R128() const { 456 return MIMG_R128; 457 } 458 459 bool hasHWFP64() const { 460 return FP64; 461 } 462 463 bool hasFastFMAF32() const { 464 return FastFMAF32; 465 } 466 467 bool hasHalfRate64Ops() const { 468 return HalfRate64Ops; 469 } 470 471 bool hasAddr64() const { 472 return (getGeneration() < AMDGPUSubtarget::VOLCANIC_ISLANDS); 473 } 474 475 bool hasBFE() const { 476 return true; 477 } 478 479 bool hasBFI() const { 480 return true; 481 } 482 483 bool hasBFM() const { 484 return hasBFE(); 485 } 486 487 bool hasBCNT(unsigned Size) const { 488 return true; 489 } 490 491 bool hasFFBL() const { 492 return true; 493 } 494 495 bool hasFFBH() const { 496 return true; 497 } 498 499 bool hasMed3_16() const { 500 return getGeneration() >= AMDGPUSubtarget::GFX9; 501 } 502 503 bool hasMin3Max3_16() const { 504 return getGeneration() >= AMDGPUSubtarget::GFX9; 505 } 506 507 bool hasFmaMixInsts() const { 508 return HasFmaMixInsts; 509 } 510 511 bool hasCARRY() const { 512 return true; 513 } 514 515 bool hasFMA() const { 516 return FMA; 517 } 518 519 bool hasSwap() const { 520 return GFX9Insts; 521 } 522 523 TrapHandlerAbi getTrapHandlerAbi() const { 524 return isAmdHsaOS() ? TrapHandlerAbiHsa : TrapHandlerAbiNone; 525 } 526 527 bool enableHugePrivateBuffer() const { 528 return EnableHugePrivateBuffer; 529 } 530 531 bool unsafeDSOffsetFoldingEnabled() const { 532 return EnableUnsafeDSOffsetFolding; 533 } 534 535 bool dumpCode() const { 536 return DumpCode; 537 } 538 539 /// Return the amount of LDS that can be used that will not restrict the 540 /// occupancy lower than WaveCount. 541 unsigned getMaxLocalMemSizeWithWaveCount(unsigned WaveCount, 542 const Function &) const; 543 544 bool hasFP16Denormals() const { 545 return FP64FP16Denormals; 546 } 547 548 bool hasFP64Denormals() const { 549 return FP64FP16Denormals; 550 } 551 552 bool supportsMinMaxDenormModes() const { 553 return getGeneration() >= AMDGPUSubtarget::GFX9; 554 } 555 556 bool enableDX10Clamp() const { 557 return DX10Clamp; 558 } 559 560 bool enableIEEEBit(const MachineFunction &MF) const { 561 return AMDGPU::isCompute(MF.getFunction().getCallingConv()); 562 } 563 564 bool useFlatForGlobal() const { 565 return FlatForGlobal; 566 } 567 568 /// \returns If target supports ds_read/write_b128 and user enables generation 569 /// of ds_read/write_b128. 570 bool useDS128() const { 571 return CIInsts && EnableDS128; 572 } 573 574 /// \returns If MUBUF instructions always perform range checking, even for 575 /// buffer resources used for private memory access. 576 bool privateMemoryResourceIsRangeChecked() const { 577 return getGeneration() < AMDGPUSubtarget::GFX9; 578 } 579 580 bool hasAutoWaitcntBeforeBarrier() const { 581 return AutoWaitcntBeforeBarrier; 582 } 583 584 bool hasCodeObjectV3() const { 585 return CodeObjectV3; 586 } 587 588 bool hasUnalignedBufferAccess() const { 589 return UnalignedBufferAccess; 590 } 591 592 bool hasUnalignedScratchAccess() const { 593 return UnalignedScratchAccess; 594 } 595 596 bool hasApertureRegs() const { 597 return HasApertureRegs; 598 } 599 600 bool isTrapHandlerEnabled() const { 601 return TrapHandler; 602 } 603 604 bool isXNACKEnabled() const { 605 return EnableXNACK; 606 } 607 608 bool hasFlatAddressSpace() const { 609 return FlatAddressSpace; 610 } 611 612 bool hasFlatInstOffsets() const { 613 return FlatInstOffsets; 614 } 615 616 bool hasFlatGlobalInsts() const { 617 return FlatGlobalInsts; 618 } 619 620 bool hasFlatScratchInsts() const { 621 return FlatScratchInsts; 622 } 623 624 bool hasFlatLgkmVMemCountInOrder() const { 625 return getGeneration() > GFX9; 626 } 627 628 bool hasD16LoadStore() const { 629 return getGeneration() >= GFX9; 630 } 631 632 /// Return if most LDS instructions have an m0 use that require m0 to be 633 /// iniitalized. 634 bool ldsRequiresM0Init() const { 635 return getGeneration() < GFX9; 636 } 637 638 bool hasAddNoCarry() const { 639 return AddNoCarryInsts; 640 } 641 642 bool hasUnpackedD16VMem() const { 643 return HasUnpackedD16VMem; 644 } 645 646 // Covers VS/PS/CS graphics shaders 647 bool isMesaGfxShader(const Function &F) const { 648 return isMesa3DOS() && AMDGPU::isShader(F.getCallingConv()); 649 } 650 651 bool hasMad64_32() const { 652 return getGeneration() >= SEA_ISLANDS; 653 } 654 655 bool hasSDWAOmod() const { 656 return HasSDWAOmod; 657 } 658 659 bool hasSDWAScalar() const { 660 return HasSDWAScalar; 661 } 662 663 bool hasSDWASdst() const { 664 return HasSDWASdst; 665 } 666 667 bool hasSDWAMac() const { 668 return HasSDWAMac; 669 } 670 671 bool hasSDWAOutModsVOPC() const { 672 return HasSDWAOutModsVOPC; 673 } 674 675 bool vmemWriteNeedsExpWaitcnt() const { 676 return getGeneration() < SEA_ISLANDS; 677 } 678 679 bool hasDLInsts() const { 680 return HasDLInsts; 681 } 682 683 bool d16PreservesUnusedBits() const { 684 return D16PreservesUnusedBits; 685 } 686 687 // Scratch is allocated in 256 dword per wave blocks for the entire 688 // wavefront. When viewed from the perspecive of an arbitrary workitem, this 689 // is 4-byte aligned. 690 // 691 // Only 4-byte alignment is really needed to access anything. Transformations 692 // on the pointer value itself may rely on the alignment / known low bits of 693 // the pointer. Set this to something above the minimum to avoid needing 694 // dynamic realignment in common cases. 695 unsigned getStackAlignment() const { 696 return 16; 697 } 698 699 bool enableMachineScheduler() const override { 700 return true; 701 } 702 703 bool enableSubRegLiveness() const override { 704 return true; 705 } 706 707 void setScalarizeGlobalBehavior(bool b) { ScalarizeGlobal = b; } 708 bool getScalarizeGlobalBehavior() const { return ScalarizeGlobal; } 709 710 /// \returns Number of execution units per compute unit supported by the 711 /// subtarget. 712 unsigned getEUsPerCU() const { 713 return AMDGPU::IsaInfo::getEUsPerCU(this); 714 } 715 716 /// \returns Maximum number of waves per compute unit supported by the 717 /// subtarget without any kind of limitation. 718 unsigned getMaxWavesPerCU() const { 719 return AMDGPU::IsaInfo::getMaxWavesPerCU(this); 720 } 721 722 /// \returns Maximum number of waves per compute unit supported by the 723 /// subtarget and limited by given \p FlatWorkGroupSize. 724 unsigned getMaxWavesPerCU(unsigned FlatWorkGroupSize) const { 725 return AMDGPU::IsaInfo::getMaxWavesPerCU(this, FlatWorkGroupSize); 726 } 727 728 /// \returns Maximum number of waves per execution unit supported by the 729 /// subtarget without any kind of limitation. 730 unsigned getMaxWavesPerEU() const { 731 return AMDGPU::IsaInfo::getMaxWavesPerEU(); 732 } 733 734 /// \returns Number of waves per work group supported by the subtarget and 735 /// limited by given \p FlatWorkGroupSize. 736 unsigned getWavesPerWorkGroup(unsigned FlatWorkGroupSize) const { 737 return AMDGPU::IsaInfo::getWavesPerWorkGroup(this, FlatWorkGroupSize); 738 } 739 740 // static wrappers 741 static bool hasHalfRate64Ops(const TargetSubtargetInfo &STI); 742 743 // XXX - Why is this here if it isn't in the default pass set? 744 bool enableEarlyIfConversion() const override { 745 return true; 746 } 747 748 void overrideSchedPolicy(MachineSchedPolicy &Policy, 749 unsigned NumRegionInstrs) const override; 750 751 bool isVGPRSpillingEnabled(const Function &F) const; 752 753 unsigned getMaxNumUserSGPRs() const { 754 return 16; 755 } 756 757 bool hasSMemRealTime() const { 758 return HasSMemRealTime; 759 } 760 761 bool hasMovrel() const { 762 return HasMovrel; 763 } 764 765 bool hasVGPRIndexMode() const { 766 return HasVGPRIndexMode; 767 } 768 769 bool useVGPRIndexMode(bool UserEnable) const { 770 return !hasMovrel() || (UserEnable && hasVGPRIndexMode()); 771 } 772 773 bool hasScalarCompareEq64() const { 774 return getGeneration() >= VOLCANIC_ISLANDS; 775 } 776 777 bool hasScalarStores() const { 778 return HasScalarStores; 779 } 780 781 bool hasScalarAtomics() const { 782 return HasScalarAtomics; 783 } 784 785 786 bool hasDPP() const { 787 return HasDPP; 788 } 789 790 bool hasR128A16() const { 791 return HasR128A16; 792 } 793 794 bool enableSIScheduler() const { 795 return EnableSIScheduler; 796 } 797 798 bool debuggerSupported() const { 799 return debuggerInsertNops() && debuggerEmitPrologue(); 800 } 801 802 bool debuggerInsertNops() const { 803 return DebuggerInsertNops; 804 } 805 806 bool debuggerEmitPrologue() const { 807 return DebuggerEmitPrologue; 808 } 809 810 bool loadStoreOptEnabled() const { 811 return EnableLoadStoreOpt; 812 } 813 814 bool hasSGPRInitBug() const { 815 return SGPRInitBug; 816 } 817 818 bool has12DWordStoreHazard() const { 819 return getGeneration() != AMDGPUSubtarget::SOUTHERN_ISLANDS; 820 } 821 822 bool hasSMovFedHazard() const { 823 return getGeneration() >= AMDGPUSubtarget::GFX9; 824 } 825 826 bool hasReadM0MovRelInterpHazard() const { 827 return getGeneration() >= AMDGPUSubtarget::GFX9; 828 } 829 830 bool hasReadM0SendMsgHazard() const { 831 return getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS; 832 } 833 834 /// Return the maximum number of waves per SIMD for kernels using \p SGPRs 835 /// SGPRs 836 unsigned getOccupancyWithNumSGPRs(unsigned SGPRs) const; 837 838 /// Return the maximum number of waves per SIMD for kernels using \p VGPRs 839 /// VGPRs 840 unsigned getOccupancyWithNumVGPRs(unsigned VGPRs) const; 841 842 /// \returns true if the flat_scratch register should be initialized with the 843 /// pointer to the wave's scratch memory rather than a size and offset. 844 bool flatScratchIsPointer() const { 845 return getGeneration() >= AMDGPUSubtarget::GFX9; 846 } 847 848 /// \returns true if the machine has merged shaders in which s0-s7 are 849 /// reserved by the hardware and user SGPRs start at s8 850 bool hasMergedShaders() const { 851 return getGeneration() >= GFX9; 852 } 853 854 /// \returns SGPR allocation granularity supported by the subtarget. 855 unsigned getSGPRAllocGranule() const { 856 return AMDGPU::IsaInfo::getSGPRAllocGranule(this); 857 } 858 859 /// \returns SGPR encoding granularity supported by the subtarget. 860 unsigned getSGPREncodingGranule() const { 861 return AMDGPU::IsaInfo::getSGPREncodingGranule(this); 862 } 863 864 /// \returns Total number of SGPRs supported by the subtarget. 865 unsigned getTotalNumSGPRs() const { 866 return AMDGPU::IsaInfo::getTotalNumSGPRs(this); 867 } 868 869 /// \returns Addressable number of SGPRs supported by the subtarget. 870 unsigned getAddressableNumSGPRs() const { 871 return AMDGPU::IsaInfo::getAddressableNumSGPRs(this); 872 } 873 874 /// \returns Minimum number of SGPRs that meets the given number of waves per 875 /// execution unit requirement supported by the subtarget. 876 unsigned getMinNumSGPRs(unsigned WavesPerEU) const { 877 return AMDGPU::IsaInfo::getMinNumSGPRs(this, WavesPerEU); 878 } 879 880 /// \returns Maximum number of SGPRs that meets the given number of waves per 881 /// execution unit requirement supported by the subtarget. 882 unsigned getMaxNumSGPRs(unsigned WavesPerEU, bool Addressable) const { 883 return AMDGPU::IsaInfo::getMaxNumSGPRs(this, WavesPerEU, Addressable); 884 } 885 886 /// \returns Reserved number of SGPRs for given function \p MF. 887 unsigned getReservedNumSGPRs(const MachineFunction &MF) const; 888 889 /// \returns Maximum number of SGPRs that meets number of waves per execution 890 /// unit requirement for function \p MF, or number of SGPRs explicitly 891 /// requested using "amdgpu-num-sgpr" attribute attached to function \p MF. 892 /// 893 /// \returns Value that meets number of waves per execution unit requirement 894 /// if explicitly requested value cannot be converted to integer, violates 895 /// subtarget's specifications, or does not meet number of waves per execution 896 /// unit requirement. 897 unsigned getMaxNumSGPRs(const MachineFunction &MF) const; 898 899 /// \returns VGPR allocation granularity supported by the subtarget. 900 unsigned getVGPRAllocGranule() const { 901 return AMDGPU::IsaInfo::getVGPRAllocGranule(this); 902 } 903 904 /// \returns VGPR encoding granularity supported by the subtarget. 905 unsigned getVGPREncodingGranule() const { 906 return AMDGPU::IsaInfo::getVGPREncodingGranule(this); 907 } 908 909 /// \returns Total number of VGPRs supported by the subtarget. 910 unsigned getTotalNumVGPRs() const { 911 return AMDGPU::IsaInfo::getTotalNumVGPRs(this); 912 } 913 914 /// \returns Addressable number of VGPRs supported by the subtarget. 915 unsigned getAddressableNumVGPRs() const { 916 return AMDGPU::IsaInfo::getAddressableNumVGPRs(this); 917 } 918 919 /// \returns Minimum number of VGPRs that meets given number of waves per 920 /// execution unit requirement supported by the subtarget. 921 unsigned getMinNumVGPRs(unsigned WavesPerEU) const { 922 return AMDGPU::IsaInfo::getMinNumVGPRs(this, WavesPerEU); 923 } 924 925 /// \returns Maximum number of VGPRs that meets given number of waves per 926 /// execution unit requirement supported by the subtarget. 927 unsigned getMaxNumVGPRs(unsigned WavesPerEU) const { 928 return AMDGPU::IsaInfo::getMaxNumVGPRs(this, WavesPerEU); 929 } 930 931 /// \returns Maximum number of VGPRs that meets number of waves per execution 932 /// unit requirement for function \p MF, or number of VGPRs explicitly 933 /// requested using "amdgpu-num-vgpr" attribute attached to function \p MF. 934 /// 935 /// \returns Value that meets number of waves per execution unit requirement 936 /// if explicitly requested value cannot be converted to integer, violates 937 /// subtarget's specifications, or does not meet number of waves per execution 938 /// unit requirement. 939 unsigned getMaxNumVGPRs(const MachineFunction &MF) const; 940 941 void getPostRAMutations( 942 std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) 943 const override; 944 945 /// \returns Maximum number of work groups per compute unit supported by the 946 /// subtarget and limited by given \p FlatWorkGroupSize. 947 unsigned getMaxWorkGroupsPerCU(unsigned FlatWorkGroupSize) const override { 948 return AMDGPU::IsaInfo::getMaxWorkGroupsPerCU(this, FlatWorkGroupSize); 949 } 950 951 /// \returns Minimum flat work group size supported by the subtarget. 952 unsigned getMinFlatWorkGroupSize() const override { 953 return AMDGPU::IsaInfo::getMinFlatWorkGroupSize(this); 954 } 955 956 /// \returns Maximum flat work group size supported by the subtarget. 957 unsigned getMaxFlatWorkGroupSize() const override { 958 return AMDGPU::IsaInfo::getMaxFlatWorkGroupSize(this); 959 } 960 961 /// \returns Maximum number of waves per execution unit supported by the 962 /// subtarget and limited by given \p FlatWorkGroupSize. 963 unsigned getMaxWavesPerEU(unsigned FlatWorkGroupSize) const override { 964 return AMDGPU::IsaInfo::getMaxWavesPerEU(this, FlatWorkGroupSize); 965 } 966 967 /// \returns Minimum number of waves per execution unit supported by the 968 /// subtarget. 969 unsigned getMinWavesPerEU() const override { 970 return AMDGPU::IsaInfo::getMinWavesPerEU(this); 971 } 972 }; 973 974 class R600Subtarget final : public R600GenSubtargetInfo, 975 public AMDGPUSubtarget { 976 private: 977 R600InstrInfo InstrInfo; 978 R600FrameLowering FrameLowering; 979 bool FMA; 980 bool CaymanISA; 981 bool CFALUBug; 982 bool DX10Clamp; 983 bool HasVertexCache; 984 bool R600ALUInst; 985 bool FP64; 986 short TexVTXClauseSize; 987 Generation Gen; 988 R600TargetLowering TLInfo; 989 InstrItineraryData InstrItins; 990 SelectionDAGTargetInfo TSInfo; 991 992 public: 993 R600Subtarget(const Triple &TT, StringRef CPU, StringRef FS, 994 const TargetMachine &TM); 995 996 const R600InstrInfo *getInstrInfo() const override { return &InstrInfo; } 997 998 const R600FrameLowering *getFrameLowering() const override { 999 return &FrameLowering; 1000 } 1001 1002 const R600TargetLowering *getTargetLowering() const override { 1003 return &TLInfo; 1004 } 1005 1006 const R600RegisterInfo *getRegisterInfo() const override { 1007 return &InstrInfo.getRegisterInfo(); 1008 } 1009 1010 const InstrItineraryData *getInstrItineraryData() const override { 1011 return &InstrItins; 1012 } 1013 1014 // Nothing implemented, just prevent crashes on use. 1015 const SelectionDAGTargetInfo *getSelectionDAGInfo() const override { 1016 return &TSInfo; 1017 } 1018 1019 void ParseSubtargetFeatures(StringRef CPU, StringRef FS); 1020 1021 Generation getGeneration() const { 1022 return Gen; 1023 } 1024 1025 unsigned getStackAlignment() const { 1026 return 4; 1027 } 1028 1029 R600Subtarget &initializeSubtargetDependencies(const Triple &TT, 1030 StringRef GPU, StringRef FS); 1031 1032 bool hasBFE() const { 1033 return (getGeneration() >= EVERGREEN); 1034 } 1035 1036 bool hasBFI() const { 1037 return (getGeneration() >= EVERGREEN); 1038 } 1039 1040 bool hasBCNT(unsigned Size) const { 1041 if (Size == 32) 1042 return (getGeneration() >= EVERGREEN); 1043 1044 return false; 1045 } 1046 1047 bool hasBORROW() const { 1048 return (getGeneration() >= EVERGREEN); 1049 } 1050 1051 bool hasCARRY() const { 1052 return (getGeneration() >= EVERGREEN); 1053 } 1054 1055 bool hasCaymanISA() const { 1056 return CaymanISA; 1057 } 1058 1059 bool hasFFBL() const { 1060 return (getGeneration() >= EVERGREEN); 1061 } 1062 1063 bool hasFFBH() const { 1064 return (getGeneration() >= EVERGREEN); 1065 } 1066 1067 bool hasFMA() const { return FMA; } 1068 1069 bool hasCFAluBug() const { return CFALUBug; } 1070 1071 bool hasVertexCache() const { return HasVertexCache; } 1072 1073 short getTexVTXClauseSize() const { return TexVTXClauseSize; } 1074 1075 bool enableMachineScheduler() const override { 1076 return true; 1077 } 1078 1079 bool enableSubRegLiveness() const override { 1080 return true; 1081 } 1082 1083 /// \returns Maximum number of work groups per compute unit supported by the 1084 /// subtarget and limited by given \p FlatWorkGroupSize. 1085 unsigned getMaxWorkGroupsPerCU(unsigned FlatWorkGroupSize) const override { 1086 return AMDGPU::IsaInfo::getMaxWorkGroupsPerCU(this, FlatWorkGroupSize); 1087 } 1088 1089 /// \returns Minimum flat work group size supported by the subtarget. 1090 unsigned getMinFlatWorkGroupSize() const override { 1091 return AMDGPU::IsaInfo::getMinFlatWorkGroupSize(this); 1092 } 1093 1094 /// \returns Maximum flat work group size supported by the subtarget. 1095 unsigned getMaxFlatWorkGroupSize() const override { 1096 return AMDGPU::IsaInfo::getMaxFlatWorkGroupSize(this); 1097 } 1098 1099 /// \returns Maximum number of waves per execution unit supported by the 1100 /// subtarget and limited by given \p FlatWorkGroupSize. 1101 unsigned getMaxWavesPerEU(unsigned FlatWorkGroupSize) const override { 1102 return AMDGPU::IsaInfo::getMaxWavesPerEU(this, FlatWorkGroupSize); 1103 } 1104 1105 /// \returns Minimum number of waves per execution unit supported by the 1106 /// subtarget. 1107 unsigned getMinWavesPerEU() const override { 1108 return AMDGPU::IsaInfo::getMinWavesPerEU(this); 1109 } 1110 }; 1111 1112 } // end namespace llvm 1113 1114 #endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUSUBTARGET_H 1115