1296417Sdim//=====-- AMDGPUSubtarget.h - Define Subtarget for AMDGPU ------*- C++ -*-====// 2284677Sdim// 3284677Sdim// The LLVM Compiler Infrastructure 4284677Sdim// 5284677Sdim// This file is distributed under the University of Illinois Open Source 6284677Sdim// License. See LICENSE.TXT for details. 7284677Sdim// 8284677Sdim//==-----------------------------------------------------------------------===// 9284677Sdim// 10284677Sdim/// \file 11284677Sdim/// \brief AMDGPU specific subclass of TargetSubtarget. 12284677Sdim// 13284677Sdim//===----------------------------------------------------------------------===// 14284677Sdim 15296417Sdim#ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUSUBTARGET_H 16296417Sdim#define LLVM_LIB_TARGET_AMDGPU_AMDGPUSUBTARGET_H 17296417Sdim 18284677Sdim#include "AMDGPU.h" 19284677Sdim#include "AMDGPUFrameLowering.h" 20284677Sdim#include "AMDGPUInstrInfo.h" 21296417Sdim#include "AMDGPUISelLowering.h" 22284677Sdim#include "AMDGPUSubtarget.h" 23285181Sdim#include "Utils/AMDGPUBaseInfo.h" 24284677Sdim#include "llvm/ADT/StringRef.h" 25284677Sdim#include "llvm/Target/TargetSubtargetInfo.h" 26284677Sdim 27284677Sdim#define GET_SUBTARGETINFO_HEADER 28284677Sdim#include "AMDGPUGenSubtargetInfo.inc" 29284677Sdim 30284677Sdimnamespace llvm { 31284677Sdim 32284677Sdimclass SIMachineFunctionInfo; 33284677Sdim 34284677Sdimclass AMDGPUSubtarget : public AMDGPUGenSubtargetInfo { 35284677Sdim 36284677Sdimpublic: 37284677Sdim enum Generation { 38284677Sdim R600 = 0, 39284677Sdim R700, 40284677Sdim EVERGREEN, 41284677Sdim NORTHERN_ISLANDS, 42284677Sdim SOUTHERN_ISLANDS, 43284677Sdim SEA_ISLANDS, 44284677Sdim VOLCANIC_ISLANDS, 45284677Sdim }; 46284677Sdim 47284677Sdim enum { 48284677Sdim FIXED_SGPR_COUNT_FOR_INIT_BUG = 80 49284677Sdim }; 50284677Sdim 51285181Sdim enum { 52285181Sdim ISAVersion0_0_0, 53285181Sdim ISAVersion7_0_0, 54285181Sdim ISAVersion7_0_1, 55285181Sdim ISAVersion8_0_0, 56296417Sdim ISAVersion8_0_1, 57296417Sdim ISAVersion8_0_3 58285181Sdim }; 59285181Sdim 60284677Sdimprivate: 61284677Sdim std::string DevName; 62284677Sdim bool Is64bit; 63284677Sdim bool DumpCode; 64284677Sdim bool R600ALUInst; 65284677Sdim bool HasVertexCache; 66284677Sdim short TexVTXClauseSize; 67284677Sdim Generation Gen; 68284677Sdim bool FP64; 69284677Sdim bool FP64Denormals; 70284677Sdim bool FP32Denormals; 71284677Sdim bool FastFMAF32; 72284677Sdim bool CaymanISA; 73284677Sdim bool FlatAddressSpace; 74296417Sdim bool FlatForGlobal; 75284677Sdim bool EnableIRStructurizer; 76284677Sdim bool EnablePromoteAlloca; 77284677Sdim bool EnableIfCvt; 78284677Sdim bool EnableLoadStoreOpt; 79286684Sdim bool EnableUnsafeDSOffsetFolding; 80296417Sdim bool EnableXNACK; 81284677Sdim unsigned WavefrontSize; 82284677Sdim bool CFALUBug; 83284677Sdim int LocalMemorySize; 84284677Sdim bool EnableVGPRSpilling; 85284677Sdim bool SGPRInitBug; 86284677Sdim bool IsGCN; 87284677Sdim bool GCN1Encoding; 88284677Sdim bool GCN3Encoding; 89284677Sdim bool CIInsts; 90284677Sdim bool FeatureDisable; 91284677Sdim int LDSBankCount; 92296417Sdim unsigned IsaVersion; 93287521Sdim bool EnableHugeScratchBuffer; 94296417Sdim bool EnableSIScheduler; 95284677Sdim 96296417Sdim std::unique_ptr<AMDGPUFrameLowering> FrameLowering; 97284677Sdim std::unique_ptr<AMDGPUTargetLowering> TLInfo; 98284677Sdim std::unique_ptr<AMDGPUInstrInfo> InstrInfo; 99284677Sdim InstrItineraryData InstrItins; 100284677Sdim Triple TargetTriple; 101284677Sdim 102284677Sdimpublic: 103284677Sdim AMDGPUSubtarget(const Triple &TT, StringRef CPU, StringRef FS, 104284677Sdim TargetMachine &TM); 105284677Sdim AMDGPUSubtarget &initializeSubtargetDependencies(const Triple &TT, 106284677Sdim StringRef GPU, StringRef FS); 107284677Sdim 108284677Sdim const AMDGPUFrameLowering *getFrameLowering() const override { 109296417Sdim return FrameLowering.get(); 110284677Sdim } 111284677Sdim const AMDGPUInstrInfo *getInstrInfo() const override { 112284677Sdim return InstrInfo.get(); 113284677Sdim } 114284677Sdim const AMDGPURegisterInfo *getRegisterInfo() const override { 115284677Sdim return &InstrInfo->getRegisterInfo(); 116284677Sdim } 117284677Sdim AMDGPUTargetLowering *getTargetLowering() const override { 118284677Sdim return TLInfo.get(); 119284677Sdim } 120284677Sdim const InstrItineraryData *getInstrItineraryData() const override { 121284677Sdim return &InstrItins; 122284677Sdim } 123284677Sdim 124284677Sdim void ParseSubtargetFeatures(StringRef CPU, StringRef FS); 125284677Sdim 126284677Sdim bool is64bit() const { 127284677Sdim return Is64bit; 128284677Sdim } 129284677Sdim 130284677Sdim bool hasVertexCache() const { 131284677Sdim return HasVertexCache; 132284677Sdim } 133284677Sdim 134284677Sdim short getTexVTXClauseSize() const { 135284677Sdim return TexVTXClauseSize; 136284677Sdim } 137284677Sdim 138284677Sdim Generation getGeneration() const { 139284677Sdim return Gen; 140284677Sdim } 141284677Sdim 142284677Sdim bool hasHWFP64() const { 143284677Sdim return FP64; 144284677Sdim } 145284677Sdim 146284677Sdim bool hasCaymanISA() const { 147284677Sdim return CaymanISA; 148284677Sdim } 149284677Sdim 150284677Sdim bool hasFP32Denormals() const { 151284677Sdim return FP32Denormals; 152284677Sdim } 153284677Sdim 154284677Sdim bool hasFP64Denormals() const { 155284677Sdim return FP64Denormals; 156284677Sdim } 157284677Sdim 158284677Sdim bool hasFastFMAF32() const { 159284677Sdim return FastFMAF32; 160284677Sdim } 161284677Sdim 162284677Sdim bool hasFlatAddressSpace() const { 163284677Sdim return FlatAddressSpace; 164284677Sdim } 165284677Sdim 166296417Sdim bool useFlatForGlobal() const { 167296417Sdim return FlatForGlobal; 168296417Sdim } 169296417Sdim 170284677Sdim bool hasBFE() const { 171284677Sdim return (getGeneration() >= EVERGREEN); 172284677Sdim } 173284677Sdim 174284677Sdim bool hasBFI() const { 175284677Sdim return (getGeneration() >= EVERGREEN); 176284677Sdim } 177284677Sdim 178284677Sdim bool hasBFM() const { 179284677Sdim return hasBFE(); 180284677Sdim } 181284677Sdim 182284677Sdim bool hasBCNT(unsigned Size) const { 183284677Sdim if (Size == 32) 184284677Sdim return (getGeneration() >= EVERGREEN); 185284677Sdim 186284677Sdim if (Size == 64) 187284677Sdim return (getGeneration() >= SOUTHERN_ISLANDS); 188284677Sdim 189284677Sdim return false; 190284677Sdim } 191284677Sdim 192284677Sdim bool hasMulU24() const { 193284677Sdim return (getGeneration() >= EVERGREEN); 194284677Sdim } 195284677Sdim 196284677Sdim bool hasMulI24() const { 197284677Sdim return (getGeneration() >= SOUTHERN_ISLANDS || 198284677Sdim hasCaymanISA()); 199284677Sdim } 200284677Sdim 201284677Sdim bool hasFFBL() const { 202284677Sdim return (getGeneration() >= EVERGREEN); 203284677Sdim } 204284677Sdim 205284677Sdim bool hasFFBH() const { 206284677Sdim return (getGeneration() >= EVERGREEN); 207284677Sdim } 208284677Sdim 209284677Sdim bool hasCARRY() const { 210284677Sdim return (getGeneration() >= EVERGREEN); 211284677Sdim } 212284677Sdim 213284677Sdim bool hasBORROW() const { 214284677Sdim return (getGeneration() >= EVERGREEN); 215284677Sdim } 216284677Sdim 217284677Sdim bool IsIRStructurizerEnabled() const { 218284677Sdim return EnableIRStructurizer; 219284677Sdim } 220284677Sdim 221284677Sdim bool isPromoteAllocaEnabled() const { 222284677Sdim return EnablePromoteAlloca; 223284677Sdim } 224284677Sdim 225284677Sdim bool isIfCvtEnabled() const { 226284677Sdim return EnableIfCvt; 227284677Sdim } 228284677Sdim 229284677Sdim bool loadStoreOptEnabled() const { 230284677Sdim return EnableLoadStoreOpt; 231284677Sdim } 232284677Sdim 233286684Sdim bool unsafeDSOffsetFoldingEnabled() const { 234286684Sdim return EnableUnsafeDSOffsetFolding; 235286684Sdim } 236286684Sdim 237284677Sdim unsigned getWavefrontSize() const { 238284677Sdim return WavefrontSize; 239284677Sdim } 240284677Sdim 241284677Sdim unsigned getStackEntrySize() const; 242284677Sdim 243284677Sdim bool hasCFAluBug() const { 244284677Sdim assert(getGeneration() <= NORTHERN_ISLANDS); 245284677Sdim return CFALUBug; 246284677Sdim } 247284677Sdim 248284677Sdim int getLocalMemorySize() const { 249284677Sdim return LocalMemorySize; 250284677Sdim } 251284677Sdim 252284677Sdim bool hasSGPRInitBug() const { 253284677Sdim return SGPRInitBug; 254284677Sdim } 255284677Sdim 256284677Sdim int getLDSBankCount() const { 257284677Sdim return LDSBankCount; 258284677Sdim } 259284677Sdim 260284677Sdim unsigned getAmdKernelCodeChipID() const; 261284677Sdim 262285181Sdim AMDGPU::IsaVersion getIsaVersion() const; 263285181Sdim 264284677Sdim bool enableMachineScheduler() const override { 265284677Sdim return true; 266284677Sdim } 267284677Sdim 268284677Sdim void overrideSchedPolicy(MachineSchedPolicy &Policy, 269284677Sdim MachineInstr *begin, MachineInstr *end, 270284677Sdim unsigned NumRegionInstrs) const override; 271284677Sdim 272284677Sdim // Helper functions to simplify if statements 273284677Sdim bool isTargetELF() const { 274284677Sdim return false; 275284677Sdim } 276284677Sdim 277284677Sdim StringRef getDeviceName() const { 278284677Sdim return DevName; 279284677Sdim } 280284677Sdim 281287521Sdim bool enableHugeScratchBuffer() const { 282287521Sdim return EnableHugeScratchBuffer; 283287521Sdim } 284287521Sdim 285296417Sdim bool enableSIScheduler() const { 286296417Sdim return EnableSIScheduler; 287296417Sdim } 288296417Sdim 289284677Sdim bool dumpCode() const { 290284677Sdim return DumpCode; 291284677Sdim } 292284677Sdim bool r600ALUEncoding() const { 293284677Sdim return R600ALUInst; 294284677Sdim } 295284677Sdim bool isAmdHsaOS() const { 296284677Sdim return TargetTriple.getOS() == Triple::AMDHSA; 297284677Sdim } 298284677Sdim bool isVGPRSpillingEnabled(const SIMachineFunctionInfo *MFI) const; 299284677Sdim 300296417Sdim bool isXNACKEnabled() const { 301296417Sdim return EnableXNACK; 302296417Sdim } 303296417Sdim 304284677Sdim unsigned getMaxWavesPerCU() const { 305284677Sdim if (getGeneration() >= AMDGPUSubtarget::SOUTHERN_ISLANDS) 306284677Sdim return 10; 307284677Sdim 308284677Sdim // FIXME: Not sure what this is for other subtagets. 309284677Sdim llvm_unreachable("do not know max waves per CU for this subtarget."); 310284677Sdim } 311284677Sdim 312284677Sdim bool enableSubRegLiveness() const override { 313284677Sdim return true; 314284677Sdim } 315285181Sdim 316285181Sdim /// \brief Returns the offset in bytes from the start of the input buffer 317285181Sdim /// of the first explicit kernel argument. 318285181Sdim unsigned getExplicitKernelArgOffset() const { 319285181Sdim return isAmdHsaOS() ? 0 : 36; 320285181Sdim } 321285181Sdim 322296417Sdim unsigned getMaxNumUserSGPRs() const { 323296417Sdim return 16; 324296417Sdim } 325284677Sdim}; 326284677Sdim 327284677Sdim} // End namespace llvm 328284677Sdim 329284677Sdim#endif 330