LCOV - code coverage report
Current view: top level - lib/Target/AMDGPU - AMDGPUSubtarget.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 101 101 100.0 %
Date: 2018-02-23 15:42:53 Functions: 24 27 88.9 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : /// \brief 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 "SIMachineFunctionInfo.h"
      27             : #include "Utils/AMDGPUBaseInfo.h"
      28             : #include "llvm/ADT/Triple.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             : 
      44             : namespace llvm {
      45             : 
      46             : class StringRef;
      47             : 
      48        4634 : class AMDGPUSubtarget : public AMDGPUGenSubtargetInfo {
      49             : public:
      50             :   enum Generation {
      51             :     R600 = 0,
      52             :     R700,
      53             :     EVERGREEN,
      54             :     NORTHERN_ISLANDS,
      55             :     SOUTHERN_ISLANDS,
      56             :     SEA_ISLANDS,
      57             :     VOLCANIC_ISLANDS,
      58             :     GFX9,
      59             :   };
      60             : 
      61             :   enum {
      62             :     ISAVersion0_0_0,
      63             :     ISAVersion6_0_0,
      64             :     ISAVersion6_0_1,
      65             :     ISAVersion7_0_0,
      66             :     ISAVersion7_0_1,
      67             :     ISAVersion7_0_2,
      68             :     ISAVersion7_0_3,
      69             :     ISAVersion7_0_4,
      70             :     ISAVersion8_0_1,
      71             :     ISAVersion8_0_2,
      72             :     ISAVersion8_0_3,
      73             :     ISAVersion8_1_0,
      74             :     ISAVersion9_0_0,
      75             :     ISAVersion9_0_2
      76             :   };
      77             : 
      78             :   enum TrapHandlerAbi {
      79             :     TrapHandlerAbiNone = 0,
      80             :     TrapHandlerAbiHsa = 1
      81             :   };
      82             : 
      83             :   enum TrapID {
      84             :     TrapIDHardwareReserved = 0,
      85             :     TrapIDHSADebugTrap = 1,
      86             :     TrapIDLLVMTrap = 2,
      87             :     TrapIDLLVMDebugTrap = 3,
      88             :     TrapIDDebugBreakpoint = 7,
      89             :     TrapIDDebugReserved8 = 8,
      90             :     TrapIDDebugReservedFE = 0xfe,
      91             :     TrapIDDebugReservedFF = 0xff
      92             :   };
      93             : 
      94             :   enum TrapRegValues {
      95             :     LLVMTrapHandlerRegValue = 1
      96             :   };
      97             : 
      98             : protected:
      99             :   // Basic subtarget description.
     100             :   Triple TargetTriple;
     101             :   Generation Gen;
     102             :   unsigned IsaVersion;
     103             :   unsigned WavefrontSize;
     104             :   int LocalMemorySize;
     105             :   int LDSBankCount;
     106             :   unsigned MaxPrivateElementSize;
     107             : 
     108             :   // Possibly statically set by tablegen, but may want to be overridden.
     109             :   bool FastFMAF32;
     110             :   bool HalfRate64Ops;
     111             : 
     112             :   // Dynamially set bits that enable features.
     113             :   bool FP32Denormals;
     114             :   bool FP64FP16Denormals;
     115             :   bool FPExceptions;
     116             :   bool DX10Clamp;
     117             :   bool FlatForGlobal;
     118             :   bool AutoWaitcntBeforeBarrier;
     119             :   bool CodeObjectV3;
     120             :   bool UnalignedScratchAccess;
     121             :   bool UnalignedBufferAccess;
     122             :   bool HasApertureRegs;
     123             :   bool EnableXNACK;
     124             :   bool TrapHandler;
     125             :   bool DebuggerInsertNops;
     126             :   bool DebuggerReserveRegs;
     127             :   bool DebuggerEmitPrologue;
     128             : 
     129             :   // Used as options.
     130             :   bool EnableHugePrivateBuffer;
     131             :   bool EnableVGPRSpilling;
     132             :   bool EnablePromoteAlloca;
     133             :   bool EnableLoadStoreOpt;
     134             :   bool EnableUnsafeDSOffsetFolding;
     135             :   bool EnableSIScheduler;
     136             :   bool DumpCode;
     137             : 
     138             :   // Subtarget statically properties set by tablegen
     139             :   bool FP64;
     140             :   bool FMA;
     141             :   bool MIMG_R128;
     142             :   bool IsGCN;
     143             :   bool GCN3Encoding;
     144             :   bool CIInsts;
     145             :   bool GFX9Insts;
     146             :   bool SGPRInitBug;
     147             :   bool HasSMemRealTime;
     148             :   bool Has16BitInsts;
     149             :   bool HasIntClamp;
     150             :   bool HasVOP3PInsts;
     151             :   bool HasMadMixInsts;
     152             :   bool HasMovrel;
     153             :   bool HasVGPRIndexMode;
     154             :   bool HasScalarStores;
     155             :   bool HasInv2PiInlineImm;
     156             :   bool HasSDWA;
     157             :   bool HasSDWAOmod;
     158             :   bool HasSDWAScalar;
     159             :   bool HasSDWASdst;
     160             :   bool HasSDWAMac;
     161             :   bool HasSDWAOutModsVOPC;
     162             :   bool HasDPP;
     163             :   bool FlatAddressSpace;
     164             :   bool FlatInstOffsets;
     165             :   bool FlatGlobalInsts;
     166             :   bool FlatScratchInsts;
     167             :   bool AddNoCarryInsts;
     168             :   bool HasUnpackedD16VMem;
     169             :   bool R600ALUInst;
     170             :   bool CaymanISA;
     171             :   bool CFALUBug;
     172             :   bool HasVertexCache;
     173             :   short TexVTXClauseSize;
     174             :   bool ScalarizeGlobal;
     175             : 
     176             :   // Dummy feature to use for assembler in tablegen.
     177             :   bool FeatureDisable;
     178             : 
     179             :   InstrItineraryData InstrItins;
     180             :   SelectionDAGTargetInfo TSInfo;
     181             :   AMDGPUAS AS;
     182             : 
     183             : public:
     184             :   AMDGPUSubtarget(const Triple &TT, StringRef GPU, StringRef FS,
     185             :                   const TargetMachine &TM);
     186             :   ~AMDGPUSubtarget() override;
     187             : 
     188             :   AMDGPUSubtarget &initializeSubtargetDependencies(const Triple &TT,
     189             :                                                    StringRef GPU, StringRef FS);
     190             : 
     191             :   const AMDGPUInstrInfo *getInstrInfo() const override = 0;
     192             :   const AMDGPUFrameLowering *getFrameLowering() const override = 0;
     193             :   const AMDGPUTargetLowering *getTargetLowering() const override = 0;
     194             :   const AMDGPURegisterInfo *getRegisterInfo() const override = 0;
     195             : 
     196       54896 :   const InstrItineraryData *getInstrItineraryData() const override {
     197       54896 :     return &InstrItins;
     198             :   }
     199             : 
     200             :   // Nothing implemented, just prevent crashes on use.
     201       24918 :   const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
     202       24918 :     return &TSInfo;
     203             :   }
     204             : 
     205             :   void ParseSubtargetFeatures(StringRef CPU, StringRef FS);
     206             : 
     207             :   bool isAmdHsaOS() const {
     208      224514 :     return TargetTriple.getOS() == Triple::AMDHSA;
     209             :   }
     210             : 
     211             :   bool isMesa3DOS() const {
     212       18475 :     return TargetTriple.getOS() == Triple::Mesa3D;
     213             :   }
     214             : 
     215        3574 :   bool isOpenCLEnv() const {
     216        3574 :     return TargetTriple.getEnvironment() == Triple::OpenCL ||
     217        7130 :            TargetTriple.getEnvironmentName() == "amdgizcl";
     218             :   }
     219             : 
     220             :   bool isAmdPalOS() const {
     221       17986 :     return TargetTriple.getOS() == Triple::AMDPAL;
     222             :   }
     223             : 
     224             :   Generation getGeneration() const {
     225             :     return Gen;
     226             :   }
     227             : 
     228             :   unsigned getWavefrontSize() const {
     229             :     return WavefrontSize;
     230             :   }
     231             : 
     232             :   unsigned getWavefrontSizeLog2() const {
     233             :     return Log2_32(WavefrontSize);
     234             :   }
     235             : 
     236             :   int getLocalMemorySize() const {
     237             :     return LocalMemorySize;
     238             :   }
     239             : 
     240             :   int getLDSBankCount() const {
     241             :     return LDSBankCount;
     242             :   }
     243             : 
     244             :   unsigned getMaxPrivateElementSize() const {
     245             :     return MaxPrivateElementSize;
     246             :   }
     247             : 
     248             :   AMDGPUAS getAMDGPUAS() const {
     249      110266 :     return AS;
     250             :   }
     251             : 
     252             :   bool has16BitInsts() const {
     253             :     return Has16BitInsts;
     254             :   }
     255             : 
     256             :   bool hasIntClamp() const {
     257             :     return HasIntClamp;
     258             :   }
     259             : 
     260             :   bool hasVOP3PInsts() const {
     261             :     return HasVOP3PInsts;
     262             :   }
     263             : 
     264             :   bool hasFP64() const {
     265             :     return FP64;
     266             :   }
     267             : 
     268             :   bool hasMIMG_R128() const {
     269             :     return MIMG_R128;
     270             :   }
     271             : 
     272             :   bool hasFastFMAF32() const {
     273             :     return FastFMAF32;
     274             :   }
     275             : 
     276             :   bool hasHalfRate64Ops() const {
     277             :     return HalfRate64Ops;
     278             :   }
     279             : 
     280             :   bool hasAddr64() const {
     281       57940 :     return (getGeneration() < VOLCANIC_ISLANDS);
     282             :   }
     283             : 
     284             :   bool hasBFE() const {
     285        3172 :     return (getGeneration() >= EVERGREEN);
     286             :   }
     287             : 
     288             :   bool hasBFI() const {
     289        2326 :     return (getGeneration() >= EVERGREEN);
     290             :   }
     291             : 
     292             :   bool hasBFM() const {
     293             :     return hasBFE();
     294             :   }
     295             : 
     296             :   bool hasBCNT(unsigned Size) const {
     297             :     if (Size == 32)
     298        2326 :       return (getGeneration() >= EVERGREEN);
     299             : 
     300             :     if (Size == 64)
     301        2326 :       return (getGeneration() >= SOUTHERN_ISLANDS);
     302             : 
     303             :     return false;
     304             :   }
     305             : 
     306             :   bool hasMulU24() const {
     307        8156 :     return (getGeneration() >= EVERGREEN);
     308             :   }
     309             : 
     310             :   bool hasMulI24() const {
     311        4969 :     return (getGeneration() >= SOUTHERN_ISLANDS ||
     312         415 :             hasCaymanISA());
     313             :   }
     314             : 
     315             :   bool hasFFBL() const {
     316        2326 :     return (getGeneration() >= EVERGREEN);
     317             :   }
     318             : 
     319             :   bool hasFFBH() const {
     320        2326 :     return (getGeneration() >= EVERGREEN);
     321             :   }
     322             : 
     323             :   bool hasMed3_16() const {
     324           9 :     return getGeneration() >= GFX9;
     325             :   }
     326             : 
     327             :   bool hasMin3Max3_16() const {
     328         218 :     return getGeneration() >= GFX9;
     329             :   }
     330             : 
     331             :   bool hasMadMixInsts() const {
     332             :     return HasMadMixInsts;
     333             :   }
     334             : 
     335             :   bool hasCARRY() const {
     336         282 :     return (getGeneration() >= EVERGREEN);
     337             :   }
     338             : 
     339             :   bool hasBORROW() const {
     340         282 :     return (getGeneration() >= EVERGREEN);
     341             :   }
     342             : 
     343             :   bool hasCaymanISA() const {
     344             :     return CaymanISA;
     345             :   }
     346             : 
     347             :   bool hasFMA() const {
     348             :     return FMA;
     349             :   }
     350             : 
     351             :   TrapHandlerAbi getTrapHandlerAbi() const {
     352          36 :     return isAmdHsaOS() ? TrapHandlerAbiHsa : TrapHandlerAbiNone;
     353             :   }
     354             : 
     355             :   bool enableHugePrivateBuffer() const {
     356             :     return EnableHugePrivateBuffer;
     357             :   }
     358             : 
     359             :   bool isPromoteAllocaEnabled() const {
     360             :     return EnablePromoteAlloca;
     361             :   }
     362             : 
     363             :   bool unsafeDSOffsetFoldingEnabled() const {
     364             :     return EnableUnsafeDSOffsetFolding;
     365             :   }
     366             : 
     367             :   bool dumpCode() const {
     368             :     return DumpCode;
     369             :   }
     370             : 
     371             :   /// Return the amount of LDS that can be used that will not restrict the
     372             :   /// occupancy lower than WaveCount.
     373             :   unsigned getMaxLocalMemSizeWithWaveCount(unsigned WaveCount,
     374             :                                            const Function &) const;
     375             : 
     376             :   /// Inverse of getMaxLocalMemWithWaveCount. Return the maximum wavecount if
     377             :   /// the given LDS memory size is the only constraint.
     378             :   unsigned getOccupancyWithLocalMemSize(uint32_t Bytes, const Function &) const;
     379             : 
     380           7 :   unsigned getOccupancyWithLocalMemSize(const MachineFunction &MF) const {
     381             :     const auto *MFI = MF.getInfo<SIMachineFunctionInfo>();
     382           7 :     return getOccupancyWithLocalMemSize(MFI->getLDSSize(), MF.getFunction());
     383             :   }
     384             : 
     385             :   bool hasFP16Denormals() const {
     386             :     return FP64FP16Denormals;
     387             :   }
     388             : 
     389             :   bool hasFP32Denormals() const {
     390             :     return FP32Denormals;
     391             :   }
     392             : 
     393             :   bool hasFP64Denormals() const {
     394             :     return FP64FP16Denormals;
     395             :   }
     396             : 
     397             :   bool supportsMinMaxDenormModes() const {
     398          44 :     return getGeneration() >= AMDGPUSubtarget::GFX9;
     399             :   }
     400             : 
     401             :   bool hasFPExceptions() const {
     402             :     return FPExceptions;
     403             :   }
     404             : 
     405             :   bool enableDX10Clamp() const {
     406             :     return DX10Clamp;
     407             :   }
     408             : 
     409             :   bool enableIEEEBit(const MachineFunction &MF) const {
     410       96848 :     return AMDGPU::isCompute(MF.getFunction().getCallingConv());
     411             :   }
     412             : 
     413             :   bool useFlatForGlobal() const {
     414             :     return FlatForGlobal;
     415             :   }
     416             : 
     417             :   /// \returns If MUBUF instructions always perform range checking, even for
     418             :   /// buffer resources used for private memory access.
     419             :   bool privateMemoryResourceIsRangeChecked() const {
     420        5123 :     return getGeneration() < AMDGPUSubtarget::GFX9;
     421             :   }
     422             : 
     423             :   bool hasAutoWaitcntBeforeBarrier() const {
     424             :     return AutoWaitcntBeforeBarrier;
     425             :   }
     426             : 
     427             :   bool hasCodeObjectV3() const {
     428             :     return CodeObjectV3;
     429             :   }
     430             : 
     431             :   bool hasUnalignedBufferAccess() const {
     432             :     return UnalignedBufferAccess;
     433             :   }
     434             : 
     435             :   bool hasUnalignedScratchAccess() const {
     436             :     return UnalignedScratchAccess;
     437             :   }
     438             : 
     439             :   bool hasApertureRegs() const {
     440             :    return HasApertureRegs;
     441             :   }
     442             : 
     443             :   bool isTrapHandlerEnabled() const {
     444             :     return TrapHandler;
     445             :   }
     446             : 
     447             :   bool isXNACKEnabled() const {
     448             :     return EnableXNACK;
     449             :   }
     450             : 
     451             :   bool hasFlatAddressSpace() const {
     452             :     return FlatAddressSpace;
     453             :   }
     454             : 
     455             :   bool hasFlatInstOffsets() const {
     456             :     return FlatInstOffsets;
     457             :   }
     458             : 
     459             :   bool hasFlatGlobalInsts() const {
     460             :     return FlatGlobalInsts;
     461             :   }
     462             : 
     463             :   bool hasFlatScratchInsts() const {
     464             :     return FlatScratchInsts;
     465             :   }
     466             : 
     467             :   bool hasD16LoadStore() const {
     468         381 :     return getGeneration() >= GFX9;
     469             :   }
     470             : 
     471             :   /// Return if most LDS instructions have an m0 use that require m0 to be
     472             :   /// iniitalized.
     473             :   bool ldsRequiresM0Init() const {
     474       30248 :     return getGeneration() < GFX9;
     475             :   }
     476             : 
     477             :   bool hasAddNoCarry() const {
     478             :     return AddNoCarryInsts;
     479             :   }
     480             : 
     481             :   bool hasUnpackedD16VMem() const {
     482             :     return HasUnpackedD16VMem;
     483             :   }
     484             : 
     485             :   bool isMesaKernel(const MachineFunction &MF) const {
     486      101172 :     return isMesa3DOS() && !AMDGPU::isShader(MF.getFunction().getCallingConv());
     487             :   }
     488             : 
     489             :   // Covers VS/PS/CS graphics shaders
     490             :   bool isMesaGfxShader(const MachineFunction &MF) const {
     491       15682 :     return isMesa3DOS() && AMDGPU::isShader(MF.getFunction().getCallingConv());
     492             :   }
     493             : 
     494      108571 :   bool isAmdCodeObjectV2(const MachineFunction &MF) const {
     495      217142 :     return isAmdHsaOS() || isMesaKernel(MF);
     496             :   }
     497             : 
     498             :   bool hasMad64_32() const {
     499         732 :     return getGeneration() >= SEA_ISLANDS;
     500             :   }
     501             : 
     502             :   bool hasFminFmaxLegacy() const {
     503         624 :     return getGeneration() < AMDGPUSubtarget::VOLCANIC_ISLANDS;
     504             :   }
     505             : 
     506             :   bool hasSDWA() const {
     507             :     return HasSDWA;
     508             :   }
     509             : 
     510             :   bool hasSDWAOmod() const {
     511             :     return HasSDWAOmod;
     512             :   }
     513             : 
     514             :   bool hasSDWAScalar() const {
     515             :     return HasSDWAScalar;
     516             :   }
     517             : 
     518             :   bool hasSDWASdst() const {
     519             :     return HasSDWASdst;
     520             :   }
     521             : 
     522             :   bool hasSDWAMac() const {
     523             :     return HasSDWAMac;
     524             :   }
     525             : 
     526             :   bool hasSDWAOutModsVOPC() const {
     527             :     return HasSDWAOutModsVOPC;
     528             :   }
     529             : 
     530             :   /// \brief Returns the offset in bytes from the start of the input buffer
     531             :   ///        of the first explicit kernel argument.
     532             :   unsigned getExplicitKernelArgOffset(const MachineFunction &MF) const {
     533       39715 :     return isAmdCodeObjectV2(MF) ? 0 : 36;
     534             :   }
     535             : 
     536             :   unsigned getAlignmentForImplicitArgPtr() const {
     537         150 :     return isAmdHsaOS() ? 8 : 4;
     538             :   }
     539             : 
     540        3658 :   unsigned getImplicitArgNumBytes(const MachineFunction &MF) const {
     541             :     if (isMesaKernel(MF))
     542             :       return 16;
     543        3574 :     if (isAmdHsaOS() && isOpenCLEnv())
     544             :       return 32;
     545             :     return 0;
     546             :   }
     547             : 
     548             :   // Scratch is allocated in 256 dword per wave blocks for the entire
     549             :   // wavefront. When viewed from the perspecive of an arbitrary workitem, this
     550             :   // is 4-byte aligned.
     551             :   unsigned getStackAlignment() const {
     552             :     return 4;
     553             :   }
     554             : 
     555       57823 :   bool enableMachineScheduler() const override {
     556       57823 :     return true;
     557             :   }
     558             : 
     559       19185 :   bool enableSubRegLiveness() const override {
     560       19185 :     return true;
     561             :   }
     562             : 
     563      454621 :   void setScalarizeGlobalBehavior(bool b) { ScalarizeGlobal = b;}
     564             :   bool getScalarizeGlobalBehavior() const { return ScalarizeGlobal;}
     565             : 
     566             :   /// \returns Number of execution units per compute unit supported by the
     567             :   /// subtarget.
     568             :   unsigned getEUsPerCU() const {
     569             :     return AMDGPU::IsaInfo::getEUsPerCU(getFeatureBits());
     570             :   }
     571             : 
     572             :   /// \returns Maximum number of work groups per compute unit supported by the
     573             :   /// subtarget and limited by given \p FlatWorkGroupSize.
     574             :   unsigned getMaxWorkGroupsPerCU(unsigned FlatWorkGroupSize) const {
     575             :     return AMDGPU::IsaInfo::getMaxWorkGroupsPerCU(getFeatureBits(),
     576      154164 :                                                   FlatWorkGroupSize);
     577             :   }
     578             : 
     579             :   /// \returns Maximum number of waves per compute unit supported by the
     580             :   /// subtarget without any kind of limitation.
     581             :   unsigned getMaxWavesPerCU() const {
     582             :     return AMDGPU::IsaInfo::getMaxWavesPerCU(getFeatureBits());
     583             :   }
     584             : 
     585             :   /// \returns Maximum number of waves per compute unit supported by the
     586             :   /// subtarget and limited by given \p FlatWorkGroupSize.
     587             :   unsigned getMaxWavesPerCU(unsigned FlatWorkGroupSize) const {
     588             :     return AMDGPU::IsaInfo::getMaxWavesPerCU(getFeatureBits(),
     589             :                                              FlatWorkGroupSize);
     590             :   }
     591             : 
     592             :   /// \returns Minimum number of waves per execution unit supported by the
     593             :   /// subtarget.
     594             :   unsigned getMinWavesPerEU() const {
     595       33340 :     return AMDGPU::IsaInfo::getMinWavesPerEU(getFeatureBits());
     596             :   }
     597             : 
     598             :   /// \returns Maximum number of waves per execution unit supported by the
     599             :   /// subtarget without any kind of limitation.
     600             :   unsigned getMaxWavesPerEU() const {
     601      270529 :     return AMDGPU::IsaInfo::getMaxWavesPerEU(getFeatureBits());
     602             :   }
     603             : 
     604             :   /// \returns Maximum number of waves per execution unit supported by the
     605             :   /// subtarget and limited by given \p FlatWorkGroupSize.
     606             :   unsigned getMaxWavesPerEU(unsigned FlatWorkGroupSize) const {
     607             :     return AMDGPU::IsaInfo::getMaxWavesPerEU(getFeatureBits(),
     608       33340 :                                              FlatWorkGroupSize);
     609             :   }
     610             : 
     611             :   /// \returns Minimum flat work group size supported by the subtarget.
     612             :   unsigned getMinFlatWorkGroupSize() const {
     613      208709 :     return AMDGPU::IsaInfo::getMinFlatWorkGroupSize(getFeatureBits());
     614             :   }
     615             : 
     616             :   /// \returns Maximum flat work group size supported by the subtarget.
     617             :   unsigned getMaxFlatWorkGroupSize() const {
     618      208616 :     return AMDGPU::IsaInfo::getMaxFlatWorkGroupSize(getFeatureBits());
     619             :   }
     620             : 
     621             :   /// \returns Number of waves per work group supported by the subtarget and
     622             :   /// limited by given \p FlatWorkGroupSize.
     623             :   unsigned getWavesPerWorkGroup(unsigned FlatWorkGroupSize) const {
     624             :     return AMDGPU::IsaInfo::getWavesPerWorkGroup(getFeatureBits(),
     625             :                                                  FlatWorkGroupSize);
     626             :   }
     627             : 
     628             :   /// \returns Default range flat work group size for a calling convention.
     629             :   std::pair<unsigned, unsigned> getDefaultFlatWorkGroupSize(CallingConv::ID CC) const;
     630             : 
     631             :   /// \returns Subtarget's default pair of minimum/maximum flat work group sizes
     632             :   /// for function \p F, or minimum/maximum flat work group sizes explicitly
     633             :   /// requested using "amdgpu-flat-work-group-size" attribute attached to
     634             :   /// function \p F.
     635             :   ///
     636             :   /// \returns Subtarget's default values if explicitly requested values cannot
     637             :   /// be converted to integer, or violate subtarget's specifications.
     638             :   std::pair<unsigned, unsigned> getFlatWorkGroupSizes(const Function &F) const;
     639             : 
     640             :   /// \returns Subtarget's default pair of minimum/maximum number of waves per
     641             :   /// execution unit for function \p F, or minimum/maximum number of waves per
     642             :   /// execution unit explicitly requested using "amdgpu-waves-per-eu" attribute
     643             :   /// attached to function \p F.
     644             :   ///
     645             :   /// \returns Subtarget's default values if explicitly requested values cannot
     646             :   /// be converted to integer, violate subtarget's specifications, or are not
     647             :   /// compatible with minimum/maximum number of waves limited by flat work group
     648             :   /// size, register usage, and/or lds usage.
     649             :   std::pair<unsigned, unsigned> getWavesPerEU(const Function &F) const;
     650             : 
     651             :   /// Creates value range metadata on an workitemid.* inrinsic call or load.
     652             :   bool makeLIDRangeMetadata(Instruction *I) const;
     653             : };
     654             : 
     655        1124 : class R600Subtarget final : public AMDGPUSubtarget {
     656             : private:
     657             :   R600InstrInfo InstrInfo;
     658             :   R600FrameLowering FrameLowering;
     659             :   R600TargetLowering TLInfo;
     660             : 
     661             : public:
     662             :   R600Subtarget(const Triple &TT, StringRef CPU, StringRef FS,
     663             :                 const TargetMachine &TM);
     664             : 
     665      528002 :   const R600InstrInfo *getInstrInfo() const override {
     666      954982 :     return &InstrInfo;
     667             :   }
     668             : 
     669       26667 :   const R600FrameLowering *getFrameLowering() const override {
     670       29059 :     return &FrameLowering;
     671             :   }
     672             : 
     673      116655 :   const R600TargetLowering *getTargetLowering() const override {
     674      116655 :     return &TLInfo;
     675             :   }
     676             : 
     677     1542397 :   const R600RegisterInfo *getRegisterInfo() const override {
     678     1542397 :     return &InstrInfo.getRegisterInfo();
     679             :   }
     680             : 
     681             :   bool hasCFAluBug() const {
     682             :     return CFALUBug;
     683             :   }
     684             : 
     685             :   bool hasVertexCache() const {
     686             :     return HasVertexCache;
     687             :   }
     688             : 
     689             :   short getTexVTXClauseSize() const {
     690             :     return TexVTXClauseSize;
     691             :   }
     692             : };
     693             : 
     694        6108 : class SISubtarget final : public AMDGPUSubtarget {
     695             : private:
     696             :   SIInstrInfo InstrInfo;
     697             :   SIFrameLowering FrameLowering;
     698             :   SITargetLowering TLInfo;
     699             : 
     700             :   /// GlobalISel related APIs.
     701             :   std::unique_ptr<AMDGPUCallLowering> CallLoweringInfo;
     702             :   std::unique_ptr<InstructionSelector> InstSelector;
     703             :   std::unique_ptr<LegalizerInfo> Legalizer;
     704             :   std::unique_ptr<RegisterBankInfo> RegBankInfo;
     705             : 
     706             : public:
     707             :   SISubtarget(const Triple &TT, StringRef CPU, StringRef FS,
     708             :               const TargetMachine &TM);
     709             : 
     710     3543280 :   const SIInstrInfo *getInstrInfo() const override {
     711     3955655 :     return &InstrInfo;
     712             :   }
     713             : 
     714      201970 :   const SIFrameLowering *getFrameLowering() const override {
     715      201970 :     return &FrameLowering;
     716             :   }
     717             : 
     718     1046044 :   const SITargetLowering *getTargetLowering() const override {
     719     1046044 :     return &TLInfo;
     720             :   }
     721             : 
     722          20 :   const CallLowering *getCallLowering() const override {
     723          20 :     return CallLoweringInfo.get();
     724             :   }
     725             : 
     726          20 :   const InstructionSelector *getInstructionSelector() const override {
     727          20 :     return InstSelector.get();
     728             :   }
     729             : 
     730          25 :   const LegalizerInfo *getLegalizerInfo() const override {
     731          25 :     return Legalizer.get();
     732             :   }
     733             : 
     734         147 :   const RegisterBankInfo *getRegBankInfo() const override {
     735         147 :     return RegBankInfo.get();
     736             :   }
     737             : 
     738    25728080 :   const SIRegisterInfo *getRegisterInfo() const override {
     739    25728080 :     return &InstrInfo.getRegisterInfo();
     740             :   }
     741             : 
     742             :   // XXX - Why is this here if it isn't in the default pass set?
     743          22 :   bool enableEarlyIfConversion() const override {
     744          22 :     return true;
     745             :   }
     746             : 
     747             :   void overrideSchedPolicy(MachineSchedPolicy &Policy,
     748             :                            unsigned NumRegionInstrs) const override;
     749             : 
     750             :   bool isVGPRSpillingEnabled(const Function& F) const;
     751             : 
     752             :   unsigned getMaxNumUserSGPRs() const {
     753             :     return 16;
     754             :   }
     755             : 
     756             :   bool hasSMemRealTime() const {
     757             :     return HasSMemRealTime;
     758             :   }
     759             : 
     760             :   bool hasMovrel() const {
     761             :     return HasMovrel;
     762             :   }
     763             : 
     764             :   bool hasVGPRIndexMode() const {
     765             :     return HasVGPRIndexMode;
     766             :   }
     767             : 
     768             :   bool useVGPRIndexMode(bool UserEnable) const {
     769         161 :     return !hasMovrel() || (UserEnable && hasVGPRIndexMode());
     770             :   }
     771             : 
     772             :   bool hasScalarCompareEq64() const {
     773          27 :     return getGeneration() >= VOLCANIC_ISLANDS;
     774             :   }
     775             : 
     776             :   bool hasScalarStores() const {
     777             :     return HasScalarStores;
     778             :   }
     779             : 
     780             :   bool hasInv2PiInlineImm() const {
     781             :     return HasInv2PiInlineImm;
     782             :   }
     783             : 
     784             :   bool hasDPP() const {
     785             :     return HasDPP;
     786             :   }
     787             : 
     788             :   bool enableSIScheduler() const {
     789             :     return EnableSIScheduler;
     790             :   }
     791             : 
     792             :   bool debuggerSupported() const {
     793        3664 :     return debuggerInsertNops() && debuggerReserveRegs() &&
     794           6 :       debuggerEmitPrologue();
     795             :   }
     796             : 
     797             :   bool debuggerInsertNops() const {
     798             :     return DebuggerInsertNops;
     799             :   }
     800             : 
     801             :   bool debuggerReserveRegs() const {
     802             :     return DebuggerReserveRegs;
     803             :   }
     804             : 
     805             :   bool debuggerEmitPrologue() const {
     806             :     return DebuggerEmitPrologue;
     807             :   }
     808             : 
     809             :   bool loadStoreOptEnabled() const {
     810             :     return EnableLoadStoreOpt;
     811             :   }
     812             : 
     813             :   bool hasSGPRInitBug() const {
     814             :     return SGPRInitBug;
     815             :   }
     816             : 
     817             :   bool has12DWordStoreHazard() const {
     818      291659 :     return getGeneration() != AMDGPUSubtarget::SOUTHERN_ISLANDS;
     819             :   }
     820             : 
     821             :   bool hasSMovFedHazard() const {
     822      653678 :     return getGeneration() >= AMDGPUSubtarget::GFX9;
     823             :   }
     824             : 
     825             :   bool hasReadM0MovRelInterpHazard() const {
     826      596230 :     return getGeneration() >= AMDGPUSubtarget::GFX9;
     827             :   }
     828             : 
     829             :   bool hasReadM0SendMsgHazard() const {
     830      186502 :     return getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS;
     831             :   }
     832             : 
     833             :   unsigned getKernArgSegmentSize(const MachineFunction &MF,
     834             :                                  unsigned ExplictArgBytes) const;
     835             : 
     836             :   /// Return the maximum number of waves per SIMD for kernels using \p SGPRs SGPRs
     837             :   unsigned getOccupancyWithNumSGPRs(unsigned SGPRs) const;
     838             : 
     839             :   /// Return the maximum number of waves per SIMD for kernels using \p VGPRs 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         349 :     return getGeneration() >= GFX9;
     846             :   }
     847             : 
     848             :   /// \returns SGPR allocation granularity supported by the subtarget.
     849             :   unsigned getSGPRAllocGranule() const {
     850             :     return AMDGPU::IsaInfo::getSGPRAllocGranule(getFeatureBits());
     851             :   }
     852             : 
     853             :   /// \returns SGPR encoding granularity supported by the subtarget.
     854             :   unsigned getSGPREncodingGranule() const {
     855       30808 :     return AMDGPU::IsaInfo::getSGPREncodingGranule(getFeatureBits());
     856             :   }
     857             : 
     858             :   /// \returns Total number of SGPRs supported by the subtarget.
     859             :   unsigned getTotalNumSGPRs() const {
     860             :     return AMDGPU::IsaInfo::getTotalNumSGPRs(getFeatureBits());
     861             :   }
     862             : 
     863             :   /// \returns Addressable number of SGPRs supported by the subtarget.
     864             :   unsigned getAddressableNumSGPRs() const {
     865       31983 :     return AMDGPU::IsaInfo::getAddressableNumSGPRs(getFeatureBits());
     866             :   }
     867             : 
     868             :   /// \returns Minimum number of SGPRs that meets the given number of waves per
     869             :   /// execution unit requirement supported by the subtarget.
     870             :   unsigned getMinNumSGPRs(unsigned WavesPerEU) const {
     871       15470 :     return AMDGPU::IsaInfo::getMinNumSGPRs(getFeatureBits(), WavesPerEU);
     872             :   }
     873             : 
     874             :   /// \returns Maximum number of SGPRs that meets the given number of waves per
     875             :   /// execution unit requirement supported by the subtarget.
     876             :   unsigned getMaxNumSGPRs(unsigned WavesPerEU, bool Addressable) const {
     877             :     return AMDGPU::IsaInfo::getMaxNumSGPRs(getFeatureBits(), WavesPerEU,
     878      170482 :                                            Addressable);
     879             :   }
     880             : 
     881             :   /// \returns Reserved number of SGPRs for given function \p MF.
     882             :   unsigned getReservedNumSGPRs(const MachineFunction &MF) const;
     883             : 
     884             :   /// \returns Maximum number of SGPRs that meets number of waves per execution
     885             :   /// unit requirement for function \p MF, or number of SGPRs explicitly
     886             :   /// requested using "amdgpu-num-sgpr" attribute attached to function \p MF.
     887             :   ///
     888             :   /// \returns Value that meets number of waves per execution unit requirement
     889             :   /// if explicitly requested value cannot be converted to integer, violates
     890             :   /// subtarget's specifications, or does not meet number of waves per execution
     891             :   /// unit requirement.
     892             :   unsigned getMaxNumSGPRs(const MachineFunction &MF) const;
     893             : 
     894             :   /// \returns VGPR allocation granularity supported by the subtarget.
     895             :   unsigned getVGPRAllocGranule() const {
     896             :     return AMDGPU::IsaInfo::getVGPRAllocGranule(getFeatureBits());
     897             :   }
     898             : 
     899             :   /// \returns VGPR encoding granularity supported by the subtarget.
     900             :   unsigned getVGPREncodingGranule() const {
     901       30808 :     return AMDGPU::IsaInfo::getVGPREncodingGranule(getFeatureBits());
     902             :   }
     903             : 
     904             :   /// \returns Total number of VGPRs supported by the subtarget.
     905             :   unsigned getTotalNumVGPRs() const {
     906             :     return AMDGPU::IsaInfo::getTotalNumVGPRs(getFeatureBits());
     907             :   }
     908             : 
     909             :   /// \returns Addressable number of VGPRs supported by the subtarget.
     910             :   unsigned getAddressableNumVGPRs() const {
     911       16579 :     return AMDGPU::IsaInfo::getAddressableNumVGPRs(getFeatureBits());
     912             :   }
     913             : 
     914             :   /// \returns Minimum number of VGPRs that meets given number of waves per
     915             :   /// execution unit requirement supported by the subtarget.
     916             :   unsigned getMinNumVGPRs(unsigned WavesPerEU) const {
     917       15428 :     return AMDGPU::IsaInfo::getMinNumVGPRs(getFeatureBits(), WavesPerEU);
     918             :   }
     919             : 
     920             :   /// \returns Maximum number of VGPRs that meets given number of waves per
     921             :   /// execution unit requirement supported by the subtarget.
     922             :   unsigned getMaxNumVGPRs(unsigned WavesPerEU) const {
     923      137996 :     return AMDGPU::IsaInfo::getMaxNumVGPRs(getFeatureBits(), WavesPerEU);
     924             :   }
     925             : 
     926             :   /// \returns Reserved number of VGPRs for given function \p MF.
     927             :   unsigned getReservedNumVGPRs(const MachineFunction &MF) const {
     928      116479 :     return debuggerReserveRegs() ? 4 : 0;
     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             : 
     946             : } // end namespace llvm
     947             : 
     948             : #endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUSUBTARGET_H

Generated by: LCOV version 1.13