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