Line data Source code
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 1534 : 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 : bool HasV8_5aOps = false;
71 :
72 : bool HasFPARMv8 = false;
73 : bool HasNEON = false;
74 : bool HasCrypto = false;
75 : bool HasDotProd = false;
76 : bool HasCRC = false;
77 : bool HasLSE = false;
78 : bool HasRAS = false;
79 : bool HasRDM = false;
80 : bool HasPerfMon = false;
81 : bool HasFullFP16 = false;
82 : bool HasFP16FML = false;
83 : bool HasSPE = false;
84 :
85 : // ARMv8.4 Crypto extensions
86 : bool HasSM4 = true;
87 : bool HasSHA3 = true;
88 :
89 : bool HasSHA2 = true;
90 : bool HasAES = true;
91 :
92 : bool HasLSLFast = false;
93 : bool HasSVE = false;
94 : bool HasRCPC = false;
95 : bool HasAggressiveFMA = false;
96 :
97 : // Armv8.5-A Extensions
98 : bool HasAlternativeNZCV = false;
99 : bool HasFRInt3264 = false;
100 : bool HasSpecRestrict = false;
101 : bool HasSpecCtrl = false;
102 : bool HasPredCtrl = false;
103 : bool HasCCDP = false;
104 : bool HasBTI = false;
105 : bool HasRandGen = false;
106 : bool HasMTE = false;
107 :
108 : // HasZeroCycleRegMove - Has zero-cycle register mov instructions.
109 : bool HasZeroCycleRegMove = false;
110 :
111 : // HasZeroCycleZeroing - Has zero-cycle zeroing instructions.
112 : bool HasZeroCycleZeroing = false;
113 : bool HasZeroCycleZeroingGP = false;
114 : bool HasZeroCycleZeroingFP = false;
115 : bool HasZeroCycleZeroingFPWorkaround = false;
116 :
117 : // StrictAlign - Disallow unaligned memory accesses.
118 : bool StrictAlign = false;
119 :
120 : // NegativeImmediates - transform instructions with negative immediates
121 : bool NegativeImmediates = true;
122 :
123 : // Enable 64-bit vectorization in SLP.
124 : unsigned MinVectorRegisterBitWidth = 64;
125 :
126 : bool UseAA = false;
127 : bool PredictableSelectIsExpensive = false;
128 : bool BalanceFPOps = false;
129 : bool CustomAsCheapAsMove = false;
130 : bool ExynosAsCheapAsMove = false;
131 : bool UsePostRAScheduler = false;
132 : bool Misaligned128StoreIsSlow = false;
133 : bool Paired128IsSlow = false;
134 : bool STRQroIsSlow = false;
135 : bool UseAlternateSExtLoadCVTF32Pattern = false;
136 : bool HasArithmeticBccFusion = false;
137 : bool HasArithmeticCbzFusion = false;
138 : bool HasFuseAddress = false;
139 : bool HasFuseAES = false;
140 : bool HasFuseCryptoEOR = false;
141 : bool HasFuseCCSelect = false;
142 : bool HasFuseLiterals = false;
143 : bool DisableLatencySchedHeuristic = false;
144 : bool UseRSqrt = false;
145 : uint8_t MaxInterleaveFactor = 2;
146 : uint8_t VectorInsertExtractBaseCost = 3;
147 : uint16_t CacheLineSize = 0;
148 : uint16_t PrefetchDistance = 0;
149 : uint16_t MinPrefetchStride = 1;
150 : unsigned MaxPrefetchIterationsAhead = UINT_MAX;
151 : unsigned PrefFunctionAlignment = 0;
152 : unsigned PrefLoopAlignment = 0;
153 : unsigned MaxJumpTableSize = 0;
154 : unsigned WideningBaseCost = 0;
155 :
156 : // ReserveXRegister[i] - X#i is not available as a general purpose register.
157 : BitVector ReserveXRegister;
158 :
159 : // CustomCallUsedXRegister[i] - X#i call saved.
160 : BitVector CustomCallSavedXRegs;
161 :
162 : bool IsLittle;
163 :
164 : /// TargetTriple - What processor and OS we're targeting.
165 : Triple TargetTriple;
166 :
167 : AArch64FrameLowering FrameLowering;
168 : AArch64InstrInfo InstrInfo;
169 : AArch64SelectionDAGInfo TSInfo;
170 : AArch64TargetLowering TLInfo;
171 :
172 : /// GlobalISel related APIs.
173 : std::unique_ptr<CallLowering> CallLoweringInfo;
174 : std::unique_ptr<InstructionSelector> InstSelector;
175 : std::unique_ptr<LegalizerInfo> Legalizer;
176 : std::unique_ptr<RegisterBankInfo> RegBankInfo;
177 :
178 : private:
179 : /// initializeSubtargetDependencies - Initializes using CPUString and the
180 : /// passed in feature string so that we can use initializer lists for
181 : /// subtarget initialization.
182 : AArch64Subtarget &initializeSubtargetDependencies(StringRef FS,
183 : StringRef CPUString);
184 :
185 : /// Initialize properties based on the selected processor family.
186 : void initializeProperties();
187 :
188 : public:
189 : /// This constructor initializes the data members to match that
190 : /// of the specified triple.
191 : AArch64Subtarget(const Triple &TT, const std::string &CPU,
192 : const std::string &FS, const TargetMachine &TM,
193 : bool LittleEndian);
194 :
195 15321 : const AArch64SelectionDAGInfo *getSelectionDAGInfo() const override {
196 15321 : return &TSInfo;
197 : }
198 784499 : const AArch64FrameLowering *getFrameLowering() const override {
199 784499 : return &FrameLowering;
200 : }
201 397356 : const AArch64TargetLowering *getTargetLowering() const override {
202 767121 : return &TLInfo;
203 : }
204 1512784 : const AArch64InstrInfo *getInstrInfo() const override { return &InstrInfo; }
205 3480736 : const AArch64RegisterInfo *getRegisterInfo() const override {
206 3480736 : return &getInstrInfo()->getRegisterInfo();
207 : }
208 : const CallLowering *getCallLowering() const override;
209 : const InstructionSelector *getInstructionSelector() const override;
210 : const LegalizerInfo *getLegalizerInfo() const override;
211 : const RegisterBankInfo *getRegBankInfo() const override;
212 1573 : const Triple &getTargetTriple() const { return TargetTriple; }
213 43490 : bool enableMachineScheduler() const override { return true; }
214 11181 : bool enablePostRAScheduler() const override {
215 11181 : return UsePostRAScheduler;
216 : }
217 :
218 : /// Returns ARM processor family.
219 : /// Avoid this function! CPU specifics should be kept local to this class
220 : /// and preferably modeled with SubtargetFeatures or properties in
221 : /// initializeProperties().
222 0 : ARMProcFamilyEnum getProcFamily() const {
223 0 : return ARMProcFamily;
224 : }
225 :
226 : bool hasV8_1aOps() const { return HasV8_1aOps; }
227 : bool hasV8_2aOps() const { return HasV8_2aOps; }
228 0 : bool hasV8_3aOps() const { return HasV8_3aOps; }
229 : bool hasV8_4aOps() const { return HasV8_4aOps; }
230 : bool hasV8_5aOps() const { return HasV8_5aOps; }
231 :
232 0 : bool hasZeroCycleRegMove() const { return HasZeroCycleRegMove; }
233 :
234 0 : bool hasZeroCycleZeroingGP() const { return HasZeroCycleZeroingGP; }
235 :
236 0 : bool hasZeroCycleZeroingFP() const { return HasZeroCycleZeroingFP; }
237 :
238 0 : bool hasZeroCycleZeroingFPWorkaround() const {
239 0 : return HasZeroCycleZeroingFPWorkaround;
240 : }
241 :
242 0 : bool requiresStrictAlign() const { return StrictAlign; }
243 :
244 3 : bool isXRaySupported() const override { return true; }
245 :
246 0 : unsigned getMinVectorRegisterBitWidth() const {
247 0 : return MinVectorRegisterBitWidth;
248 : }
249 :
250 7096582 : bool isXRegisterReserved(size_t i) const { return ReserveXRegister[i]; }
251 : unsigned getNumXRegisterReserved() const { return ReserveXRegister.count(); }
252 : bool isXRegCustomCalleeSaved(size_t i) const {
253 1116 : return CustomCallSavedXRegs[i];
254 : }
255 : bool hasCustomCallingConv() const { return CustomCallSavedXRegs.any(); }
256 0 : bool hasFPARMv8() const { return HasFPARMv8; }
257 0 : bool hasNEON() const { return HasNEON; }
258 : bool hasCrypto() const { return HasCrypto; }
259 0 : bool hasDotProd() const { return HasDotProd; }
260 0 : bool hasCRC() const { return HasCRC; }
261 0 : bool hasLSE() const { return HasLSE; }
262 : bool hasRAS() const { return HasRAS; }
263 0 : bool hasRDM() const { return HasRDM; }
264 : bool hasSM4() const { return HasSM4; }
265 : bool hasSHA3() const { return HasSHA3; }
266 0 : bool hasSHA2() const { return HasSHA2; }
267 0 : bool hasAES() const { return HasAES; }
268 0 : bool balanceFPOps() const { return BalanceFPOps; }
269 0 : bool predictableSelectIsExpensive() const {
270 0 : return PredictableSelectIsExpensive;
271 : }
272 0 : bool hasCustomCheapAsMoveHandling() const { return CustomAsCheapAsMove; }
273 0 : bool hasExynosCheapAsMoveHandling() const { return ExynosAsCheapAsMove; }
274 0 : bool isMisaligned128StoreSlow() const { return Misaligned128StoreIsSlow; }
275 0 : bool isPaired128Slow() const { return Paired128IsSlow; }
276 0 : bool isSTRQroSlow() const { return STRQroIsSlow; }
277 0 : bool useAlternateSExtLoadCVTF32Pattern() const {
278 0 : return UseAlternateSExtLoadCVTF32Pattern;
279 : }
280 0 : bool hasArithmeticBccFusion() const { return HasArithmeticBccFusion; }
281 0 : bool hasArithmeticCbzFusion() const { return HasArithmeticCbzFusion; }
282 0 : bool hasFuseAddress() const { return HasFuseAddress; }
283 0 : bool hasFuseAES() const { return HasFuseAES; }
284 0 : bool hasFuseCryptoEOR() const { return HasFuseCryptoEOR; }
285 0 : bool hasFuseCCSelect() const { return HasFuseCCSelect; }
286 0 : bool hasFuseLiterals() const { return HasFuseLiterals; }
287 :
288 : /// Return true if the CPU supports any kind of instruction fusion.
289 : bool hasFusion() const {
290 23957 : return hasArithmeticBccFusion() || hasArithmeticCbzFusion() ||
291 48358 : hasFuseAES() || hasFuseCCSelect() || hasFuseLiterals();
292 : }
293 :
294 0 : bool useRSqrt() const { return UseRSqrt; }
295 34 : unsigned getMaxInterleaveFactor() const { return MaxInterleaveFactor; }
296 0 : unsigned getVectorInsertExtractBaseCost() const {
297 0 : return VectorInsertExtractBaseCost;
298 : }
299 0 : unsigned getCacheLineSize() const { return CacheLineSize; }
300 14214 : unsigned getPrefetchDistance() const { return PrefetchDistance; }
301 12 : unsigned getMinPrefetchStride() const { return MinPrefetchStride; }
302 0 : unsigned getMaxPrefetchIterationsAhead() const {
303 0 : return MaxPrefetchIterationsAhead;
304 : }
305 0 : unsigned getPrefFunctionAlignment() const { return PrefFunctionAlignment; }
306 0 : unsigned getPrefLoopAlignment() const { return PrefLoopAlignment; }
307 :
308 0 : unsigned getMaximumJumpTableSize() const { return MaxJumpTableSize; }
309 :
310 0 : unsigned getWideningBaseCost() const { return WideningBaseCost; }
311 :
312 : /// CPU has TBI (top byte of addresses is ignored during HW address
313 : /// translation) and OS enables it.
314 : bool supportsAddressTopByteIgnored() const;
315 :
316 0 : bool hasPerfMon() const { return HasPerfMon; }
317 0 : bool hasFullFP16() const { return HasFullFP16; }
318 : bool hasFP16FML() const { return HasFP16FML; }
319 : bool hasSPE() const { return HasSPE; }
320 0 : bool hasLSLFast() const { return HasLSLFast; }
321 : bool hasSVE() const { return HasSVE; }
322 : bool hasRCPC() const { return HasRCPC; }
323 0 : bool hasAggressiveFMA() const { return HasAggressiveFMA; }
324 : bool hasAlternativeNZCV() const { return HasAlternativeNZCV; }
325 : bool hasFRInt3264() const { return HasFRInt3264; }
326 : bool hasSpecRestrict() const { return HasSpecRestrict; }
327 : bool hasSpecCtrl() const { return HasSpecCtrl; }
328 : bool hasPredCtrl() const { return HasPredCtrl; }
329 : bool hasCCDP() const { return HasCCDP; }
330 : bool hasBTI() const { return HasBTI; }
331 : bool hasRandGen() const { return HasRandGen; }
332 : bool hasMTE() const { return HasMTE; }
333 :
334 0 : bool isLittleEndian() const { return IsLittle; }
335 :
336 : bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); }
337 : bool isTargetIOS() const { return TargetTriple.isiOS(); }
338 : bool isTargetLinux() const { return TargetTriple.isOSLinux(); }
339 : bool isTargetWindows() const { return TargetTriple.isOSWindows(); }
340 : bool isTargetAndroid() const { return TargetTriple.isAndroid(); }
341 : bool isTargetFuchsia() const { return TargetTriple.isOSFuchsia(); }
342 :
343 : bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); }
344 : bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
345 : bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); }
346 :
347 43024 : bool useAA() const override { return UseAA; }
348 :
349 : bool useSmallAddressing() const {
350 7308 : switch (TLInfo.getTargetMachine().getCodeModel()) {
351 : case CodeModel::Kernel:
352 : // Kernel is currently allowed only for Fuchsia targets,
353 : // where it is the same as Small for almost all purposes.
354 : case CodeModel::Small:
355 : return true;
356 : default:
357 : return false;
358 : }
359 : }
360 :
361 : /// ParseSubtargetFeatures - Parses features string setting specified
362 : /// subtarget options. Definition of function is auto generated by tblgen.
363 : void ParseSubtargetFeatures(StringRef CPU, StringRef FS);
364 :
365 : /// ClassifyGlobalReference - Find the target operand flags that describe
366 : /// how a global value should be referenced for the current subtarget.
367 : unsigned char ClassifyGlobalReference(const GlobalValue *GV,
368 : const TargetMachine &TM) const;
369 :
370 : unsigned char classifyGlobalFunctionReference(const GlobalValue *GV,
371 : const TargetMachine &TM) const;
372 :
373 : void overrideSchedPolicy(MachineSchedPolicy &Policy,
374 : unsigned NumRegionInstrs) const override;
375 :
376 : bool enableEarlyIfConversion() const override;
377 :
378 : std::unique_ptr<PBQPRAConstraint> getCustomPBQPConstraints() const override;
379 :
380 : bool isCallingConvWin64(CallingConv::ID CC) const {
381 33982 : switch (CC) {
382 : case CallingConv::C:
383 : return isTargetWindows();
384 : case CallingConv::Win64:
385 : return true;
386 87 : default:
387 : return false;
388 : }
389 : }
390 :
391 : void mirFileLoaded(MachineFunction &MF) const override;
392 : };
393 : } // End llvm namespace
394 :
395 : #endif
|