]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/AArch64/AArch64Subtarget.h
Merge ^/head r337619 through r337645.
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / AArch64 / AArch64Subtarget.h
1 //===--- AArch64Subtarget.h - Define Subtarget for the AArch64 -*- 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 // This file declares the AArch64 specific subclass of TargetSubtarget.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_LIB_TARGET_AARCH64_AARCH64SUBTARGET_H
15 #define LLVM_LIB_TARGET_AARCH64_AARCH64SUBTARGET_H
16
17 #include "AArch64FrameLowering.h"
18 #include "AArch64ISelLowering.h"
19 #include "AArch64InstrInfo.h"
20 #include "AArch64RegisterInfo.h"
21 #include "AArch64SelectionDAGInfo.h"
22 #include "llvm/CodeGen/GlobalISel/CallLowering.h"
23 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
24 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
25 #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
26 #include "llvm/CodeGen/TargetSubtargetInfo.h"
27 #include "llvm/IR/DataLayout.h"
28 #include <string>
29
30 #define GET_SUBTARGETINFO_HEADER
31 #include "AArch64GenSubtargetInfo.inc"
32
33 namespace llvm {
34 class GlobalValue;
35 class StringRef;
36 class Triple;
37
38 class AArch64Subtarget final : public AArch64GenSubtargetInfo {
39 public:
40   enum ARMProcFamilyEnum : uint8_t {
41     Others,
42     CortexA35,
43     CortexA53,
44     CortexA55,
45     CortexA57,
46     CortexA72,
47     CortexA73,
48     CortexA75,
49     Cyclone,
50     ExynosM1,
51     ExynosM3,
52     Falkor,
53     Kryo,
54     Saphira,
55     ThunderX2T99,
56     ThunderX,
57     ThunderXT81,
58     ThunderXT83,
59     ThunderXT88
60   };
61
62 protected:
63   /// ARMProcFamily - ARM processor family: Cortex-A53, Cortex-A57, and others.
64   ARMProcFamilyEnum ARMProcFamily = Others;
65
66   bool HasV8_1aOps = false;
67   bool HasV8_2aOps = false;
68   bool HasV8_3aOps = false;
69   bool HasV8_4aOps = false;
70
71   bool HasFPARMv8 = false;
72   bool HasNEON = false;
73   bool HasCrypto = false;
74   bool HasDotProd = false;
75   bool HasCRC = false;
76   bool HasLSE = false;
77   bool HasRAS = false;
78   bool HasRDM = false;
79   bool HasPerfMon = false;
80   bool HasFullFP16 = false;
81   bool HasSPE = false;
82
83   // ARMv8.4 Crypto extensions
84   bool HasSM4 = true;
85   bool HasSHA3 = true;
86
87   bool HasSHA2 = true;
88   bool HasAES = true;
89
90   bool HasLSLFast = false;
91   bool HasSVE = false;
92   bool HasRCPC = false;
93   bool HasAggressiveFMA = false;
94
95   // HasZeroCycleRegMove - Has zero-cycle register mov instructions.
96   bool HasZeroCycleRegMove = false;
97
98   // HasZeroCycleZeroing - Has zero-cycle zeroing instructions.
99   bool HasZeroCycleZeroing = false;
100   bool HasZeroCycleZeroingFPWorkaround = false;
101
102   // StrictAlign - Disallow unaligned memory accesses.
103   bool StrictAlign = false;
104
105   // NegativeImmediates - transform instructions with negative immediates
106   bool NegativeImmediates = true;
107
108   // Enable 64-bit vectorization in SLP.
109   unsigned MinVectorRegisterBitWidth = 64;
110
111   bool UseAA = false;
112   bool PredictableSelectIsExpensive = false;
113   bool BalanceFPOps = false;
114   bool CustomAsCheapAsMove = false;
115   bool ExynosAsCheapAsMove = false;
116   bool UsePostRAScheduler = false;
117   bool Misaligned128StoreIsSlow = false;
118   bool Paired128IsSlow = false;
119   bool STRQroIsSlow = false;
120   bool UseAlternateSExtLoadCVTF32Pattern = false;
121   bool HasArithmeticBccFusion = false;
122   bool HasArithmeticCbzFusion = false;
123   bool HasFuseAddress = false;
124   bool HasFuseAES = false;
125   bool HasFuseCCSelect = false;
126   bool HasFuseLiterals = false;
127   bool DisableLatencySchedHeuristic = false;
128   bool UseRSqrt = false;
129   uint8_t MaxInterleaveFactor = 2;
130   uint8_t VectorInsertExtractBaseCost = 3;
131   uint16_t CacheLineSize = 0;
132   uint16_t PrefetchDistance = 0;
133   uint16_t MinPrefetchStride = 1;
134   unsigned MaxPrefetchIterationsAhead = UINT_MAX;
135   unsigned PrefFunctionAlignment = 0;
136   unsigned PrefLoopAlignment = 0;
137   unsigned MaxJumpTableSize = 0;
138   unsigned WideningBaseCost = 0;
139
140   // ReserveX18 - X18 is not available as a general purpose register.
141   bool ReserveX18;
142
143   // ReserveX20 - X20 is not available as a general purpose register.
144   bool ReserveX20 = false;
145
146   bool IsLittle;
147
148   /// TargetTriple - What processor and OS we're targeting.
149   Triple TargetTriple;
150
151   AArch64FrameLowering FrameLowering;
152   AArch64InstrInfo InstrInfo;
153   AArch64SelectionDAGInfo TSInfo;
154   AArch64TargetLowering TLInfo;
155
156   /// GlobalISel related APIs.
157   std::unique_ptr<CallLowering> CallLoweringInfo;
158   std::unique_ptr<InstructionSelector> InstSelector;
159   std::unique_ptr<LegalizerInfo> Legalizer;
160   std::unique_ptr<RegisterBankInfo> RegBankInfo;
161
162 private:
163   /// initializeSubtargetDependencies - Initializes using CPUString and the
164   /// passed in feature string so that we can use initializer lists for
165   /// subtarget initialization.
166   AArch64Subtarget &initializeSubtargetDependencies(StringRef FS,
167                                                     StringRef CPUString);
168
169   /// Initialize properties based on the selected processor family.
170   void initializeProperties();
171
172 public:
173   /// This constructor initializes the data members to match that
174   /// of the specified triple.
175   AArch64Subtarget(const Triple &TT, const std::string &CPU,
176                    const std::string &FS, const TargetMachine &TM,
177                    bool LittleEndian);
178
179   const AArch64SelectionDAGInfo *getSelectionDAGInfo() const override {
180     return &TSInfo;
181   }
182   const AArch64FrameLowering *getFrameLowering() const override {
183     return &FrameLowering;
184   }
185   const AArch64TargetLowering *getTargetLowering() const override {
186     return &TLInfo;
187   }
188   const AArch64InstrInfo *getInstrInfo() const override { return &InstrInfo; }
189   const AArch64RegisterInfo *getRegisterInfo() const override {
190     return &getInstrInfo()->getRegisterInfo();
191   }
192   const CallLowering *getCallLowering() const override;
193   const InstructionSelector *getInstructionSelector() const override;
194   const LegalizerInfo *getLegalizerInfo() const override;
195   const RegisterBankInfo *getRegBankInfo() const override;
196   const Triple &getTargetTriple() const { return TargetTriple; }
197   bool enableMachineScheduler() const override { return true; }
198   bool enablePostRAScheduler() const override {
199     return UsePostRAScheduler;
200   }
201
202   /// Returns ARM processor family.
203   /// Avoid this function! CPU specifics should be kept local to this class
204   /// and preferably modeled with SubtargetFeatures or properties in
205   /// initializeProperties().
206   ARMProcFamilyEnum getProcFamily() const {
207     return ARMProcFamily;
208   }
209
210   bool hasV8_1aOps() const { return HasV8_1aOps; }
211   bool hasV8_2aOps() const { return HasV8_2aOps; }
212   bool hasV8_3aOps() const { return HasV8_3aOps; }
213   bool hasV8_4aOps() const { return HasV8_4aOps; }
214
215   bool hasZeroCycleRegMove() const { return HasZeroCycleRegMove; }
216
217   bool hasZeroCycleZeroing() const { return HasZeroCycleZeroing; }
218
219   bool hasZeroCycleZeroingFPWorkaround() const {
220     return HasZeroCycleZeroingFPWorkaround;
221   }
222
223   bool requiresStrictAlign() const { return StrictAlign; }
224
225   bool isXRaySupported() const override { return true; }
226
227   unsigned getMinVectorRegisterBitWidth() const {
228     return MinVectorRegisterBitWidth;
229   }
230
231   bool isX18Reserved() const { return ReserveX18; }
232   bool isX20Reserved() const { return ReserveX20; }
233   bool hasFPARMv8() const { return HasFPARMv8; }
234   bool hasNEON() const { return HasNEON; }
235   bool hasCrypto() const { return HasCrypto; }
236   bool hasDotProd() const { return HasDotProd; }
237   bool hasCRC() const { return HasCRC; }
238   bool hasLSE() const { return HasLSE; }
239   bool hasRAS() const { return HasRAS; }
240   bool hasRDM() const { return HasRDM; }
241   bool hasSM4() const { return HasSM4; }
242   bool hasSHA3() const { return HasSHA3; }
243   bool hasSHA2() const { return HasSHA2; }
244   bool hasAES() const { return HasAES; }
245   bool balanceFPOps() const { return BalanceFPOps; }
246   bool predictableSelectIsExpensive() const {
247     return PredictableSelectIsExpensive;
248   }
249   bool hasCustomCheapAsMoveHandling() const { return CustomAsCheapAsMove; }
250   bool hasExynosCheapAsMoveHandling() const { return ExynosAsCheapAsMove; }
251   bool isMisaligned128StoreSlow() const { return Misaligned128StoreIsSlow; }
252   bool isPaired128Slow() const { return Paired128IsSlow; }
253   bool isSTRQroSlow() const { return STRQroIsSlow; }
254   bool useAlternateSExtLoadCVTF32Pattern() const {
255     return UseAlternateSExtLoadCVTF32Pattern;
256   }
257   bool hasArithmeticBccFusion() const { return HasArithmeticBccFusion; }
258   bool hasArithmeticCbzFusion() const { return HasArithmeticCbzFusion; }
259   bool hasFuseAddress() const { return HasFuseAddress; }
260   bool hasFuseAES() const { return HasFuseAES; }
261   bool hasFuseCCSelect() const { return HasFuseCCSelect; }
262   bool hasFuseLiterals() const { return HasFuseLiterals; }
263
264   /// Return true if the CPU supports any kind of instruction fusion.
265   bool hasFusion() const {
266     return hasArithmeticBccFusion() || hasArithmeticCbzFusion() ||
267            hasFuseAES() || hasFuseCCSelect() || hasFuseLiterals();
268   }
269
270   bool useRSqrt() const { return UseRSqrt; }
271   unsigned getMaxInterleaveFactor() const { return MaxInterleaveFactor; }
272   unsigned getVectorInsertExtractBaseCost() const {
273     return VectorInsertExtractBaseCost;
274   }
275   unsigned getCacheLineSize() const { return CacheLineSize; }
276   unsigned getPrefetchDistance() const { return PrefetchDistance; }
277   unsigned getMinPrefetchStride() const { return MinPrefetchStride; }
278   unsigned getMaxPrefetchIterationsAhead() const {
279     return MaxPrefetchIterationsAhead;
280   }
281   unsigned getPrefFunctionAlignment() const { return PrefFunctionAlignment; }
282   unsigned getPrefLoopAlignment() const { return PrefLoopAlignment; }
283
284   unsigned getMaximumJumpTableSize() const { return MaxJumpTableSize; }
285
286   unsigned getWideningBaseCost() const { return WideningBaseCost; }
287
288   /// CPU has TBI (top byte of addresses is ignored during HW address
289   /// translation) and OS enables it.
290   bool supportsAddressTopByteIgnored() const;
291
292   bool hasPerfMon() const { return HasPerfMon; }
293   bool hasFullFP16() const { return HasFullFP16; }
294   bool hasSPE() const { return HasSPE; }
295   bool hasLSLFast() const { return HasLSLFast; }
296   bool hasSVE() const { return HasSVE; }
297   bool hasRCPC() const { return HasRCPC; }
298   bool hasAggressiveFMA() const { return HasAggressiveFMA; }
299
300   bool isLittleEndian() const { return IsLittle; }
301
302   bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); }
303   bool isTargetIOS() const { return TargetTriple.isiOS(); }
304   bool isTargetLinux() const { return TargetTriple.isOSLinux(); }
305   bool isTargetWindows() const { return TargetTriple.isOSWindows(); }
306   bool isTargetAndroid() const { return TargetTriple.isAndroid(); }
307   bool isTargetFuchsia() const { return TargetTriple.isOSFuchsia(); }
308
309   bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); }
310   bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
311   bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); }
312
313   bool useAA() const override { return UseAA; }
314
315   bool useSmallAddressing() const {
316     switch (TLInfo.getTargetMachine().getCodeModel()) {
317       case CodeModel::Kernel:
318         // Kernel is currently allowed only for Fuchsia targets,
319         // where it is the same as Small for almost all purposes.
320       case CodeModel::Small:
321         return true;
322       default:
323         return false;
324     }
325   }
326
327   /// ParseSubtargetFeatures - Parses features string setting specified
328   /// subtarget options.  Definition of function is auto generated by tblgen.
329   void ParseSubtargetFeatures(StringRef CPU, StringRef FS);
330
331   /// ClassifyGlobalReference - Find the target operand flags that describe
332   /// how a global value should be referenced for the current subtarget.
333   unsigned char ClassifyGlobalReference(const GlobalValue *GV,
334                                         const TargetMachine &TM) const;
335
336   unsigned char classifyGlobalFunctionReference(const GlobalValue *GV,
337                                                 const TargetMachine &TM) const;
338
339   void overrideSchedPolicy(MachineSchedPolicy &Policy,
340                            unsigned NumRegionInstrs) const override;
341
342   bool enableEarlyIfConversion() const override;
343
344   std::unique_ptr<PBQPRAConstraint> getCustomPBQPConstraints() const override;
345
346   bool isCallingConvWin64(CallingConv::ID CC) const {
347     switch (CC) {
348     case CallingConv::C:
349       return isTargetWindows();
350     case CallingConv::Win64:
351       return true;
352     default:
353       return false;
354     }
355   }
356
357   void mirFileLoaded(MachineFunction &MF) const override;
358 };
359 } // End llvm namespace
360
361 #endif