LLVM 21.0.0git
AArch64Subtarget.h
Go to the documentation of this file.
1//===--- AArch64Subtarget.h - Define Subtarget for the AArch64 -*- C++ -*--===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file declares the AArch64 specific subclass of TargetSubtarget.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_LIB_TARGET_AARCH64_AARCH64SUBTARGET_H
14#define LLVM_LIB_TARGET_AARCH64_AARCH64SUBTARGET_H
15
17#include "AArch64ISelLowering.h"
18#include "AArch64InstrInfo.h"
19#include "AArch64PointerAuth.h"
20#include "AArch64RegisterInfo.h"
28#include "llvm/IR/DataLayout.h"
29
30#define GET_SUBTARGETINFO_HEADER
31#include "AArch64GenSubtargetInfo.inc"
32
33namespace llvm {
34class GlobalValue;
35class StringRef;
36class Triple;
37
39public:
42#define ARM_PROCESSOR_FAMILY(ENUM) ENUM,
43#include "llvm/TargetParser/AArch64TargetParserDef.inc"
44#undef ARM_PROCESSOR_FAMILY
45 };
46
47protected:
48 /// ARMProcFamily - ARM processor family: Cortex-A53, Cortex-A57, and others.
50
51 // Enable 64-bit vectorization in SLP.
53
54// Bool members corresponding to the SubtargetFeatures defined in tablegen
55#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
56 bool ATTRIBUTE = DEFAULT;
57#include "AArch64GenSubtargetInfo.inc"
58
63 // Default scatter/gather overhead.
64 unsigned ScatterOverhead = 10;
65 unsigned GatherOverhead = 10;
68 unsigned MaxPrefetchIterationsAhead = UINT_MAX;
73 unsigned MaxJumpTableSize = 0;
74
75 // ReserveXRegister[i] - X#i is not available as a general purpose register.
77
78 // ReserveXRegisterForRA[i] - X#i is not available for register allocator.
80
81 // CustomCallUsedXRegister[i] - X#i call saved.
83
85
88 std::optional<unsigned> StreamingHazardSize;
91 unsigned VScaleForTuning = 1;
93
95
96 /// TargetTriple - What processor and OS we're targeting.
98
103
104 /// GlobalISel related APIs.
105 std::unique_ptr<CallLowering> CallLoweringInfo;
106 std::unique_ptr<InlineAsmLowering> InlineAsmLoweringInfo;
107 std::unique_ptr<InstructionSelector> InstSelector;
108 std::unique_ptr<LegalizerInfo> Legalizer;
109 std::unique_ptr<RegisterBankInfo> RegBankInfo;
110
111private:
112 /// initializeSubtargetDependencies - Initializes using CPUString and the
113 /// passed in feature string so that we can use initializer lists for
114 /// subtarget initialization.
115 AArch64Subtarget &initializeSubtargetDependencies(StringRef FS,
116 StringRef CPUString,
117 StringRef TuneCPUString,
118 bool HasMinSize);
119
120 /// Initialize properties based on the selected processor family.
121 void initializeProperties(bool HasMinSize);
122
123public:
124 /// This constructor initializes the data members to match that
125 /// of the specified triple.
126 AArch64Subtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU,
127 StringRef FS, const TargetMachine &TM, bool LittleEndian,
128 unsigned MinSVEVectorSizeInBitsOverride = 0,
129 unsigned MaxSVEVectorSizeInBitsOverride = 0,
130 bool IsStreaming = false, bool IsStreamingCompatible = false,
131 bool HasMinSize = false);
132
133 virtual unsigned getHwModeSet() const override;
134
135// Getters for SubtargetFeatures defined in tablegen
136#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
137 bool GETTER() const { return ATTRIBUTE; }
138#include "AArch64GenSubtargetInfo.inc"
139
141 return &TSInfo;
142 }
143 const AArch64FrameLowering *getFrameLowering() const override {
144 return &FrameLowering;
145 }
146 const AArch64TargetLowering *getTargetLowering() const override {
147 return &TLInfo;
148 }
149 const AArch64InstrInfo *getInstrInfo() const override { return &InstrInfo; }
150 const AArch64RegisterInfo *getRegisterInfo() const override {
151 return &getInstrInfo()->getRegisterInfo();
152 }
153 const CallLowering *getCallLowering() const override;
154 const InlineAsmLowering *getInlineAsmLowering() const override;
156 const LegalizerInfo *getLegalizerInfo() const override;
157 const RegisterBankInfo *getRegBankInfo() const override;
158 const Triple &getTargetTriple() const { return TargetTriple; }
159 bool enableMachineScheduler() const override { return true; }
160 bool enablePostRAScheduler() const override { return usePostRAScheduler(); }
161 bool enableSubRegLiveness() const override { return EnableSubregLiveness; }
162
163 bool enableMachinePipeliner() const override;
164 bool useDFAforSMS() const override { return false; }
165
166 /// Returns ARM processor family.
167 /// Avoid this function! CPU specifics should be kept local to this class
168 /// and preferably modeled with SubtargetFeatures or properties in
169 /// initializeProperties().
171 return ARMProcFamily;
172 }
173
174 bool isXRaySupported() const override { return true; }
175
176 /// Returns true if the function has a streaming body.
177 bool isStreaming() const { return IsStreaming; }
178
179 /// Returns true if the function has a streaming-compatible body.
181
182 /// Returns the size of memory region that if accessed by both the CPU and
183 /// the SME unit could result in a hazard. 0 = disabled.
184 unsigned getStreamingHazardSize() const {
185 return StreamingHazardSize.value_or(
186 !hasSMEFA64() && hasSME() && hasSVE() ? 1024 : 0);
187 }
188
189 /// Returns true if the target has NEON and the function at runtime is known
190 /// to have NEON enabled (e.g. the function is known not to be in streaming-SVE
191 /// mode, which disables NEON instructions).
192 bool isNeonAvailable() const {
193 return hasNEON() &&
194 (hasSMEFA64() || (!isStreaming() && !isStreamingCompatible()));
195 }
196
197 /// Returns true if the target has SVE and can use the full range of SVE
198 /// instructions, for example because it knows the function is known not to be
199 /// in streaming-SVE mode or when the target has FEAT_FA64 enabled.
200 bool isSVEAvailable() const {
201 return hasSVE() &&
202 (hasSMEFA64() || (!isStreaming() && !isStreamingCompatible()));
203 }
204
205 /// Returns true if the target has access to the streaming-compatible subset
206 /// of SVE instructions.
207 bool isStreamingSVEAvailable() const { return hasSME() && isStreaming(); }
208
209 /// Returns true if the target has access to either the full range of SVE
210 /// instructions, or the streaming-compatible subset of SVE instructions.
212 return hasSVE() || isStreamingSVEAvailable();
213 }
214
216 // Don't assume any minimum vector size when PSTATE.SM may not be 0, because
217 // we don't yet support streaming-compatible codegen support that we trust
218 // is safe for functions that may be executed in streaming-SVE mode.
219 // By returning '0' here, we disable vectorization.
220 if (!isSVEAvailable() && !isNeonAvailable())
221 return 0;
223 }
224
225 bool isXRegisterReserved(size_t i) const { return ReserveXRegister[i]; }
226 bool isXRegisterReservedForRA(size_t i) const { return ReserveXRegisterForRA[i]; }
227 unsigned getNumXRegisterReserved() const {
228 BitVector AllReservedX(AArch64::GPR64commonRegClass.getNumRegs());
229 AllReservedX |= ReserveXRegister;
230 AllReservedX |= ReserveXRegisterForRA;
231 return AllReservedX.count();
232 }
233 bool isLRReservedForRA() const { return ReserveLRForRA; }
234 bool isXRegCustomCalleeSaved(size_t i) const {
235 return CustomCallSavedXRegs[i];
236 }
238
239 /// Return true if the CPU supports any kind of instruction fusion.
240 bool hasFusion() const {
241 return hasArithmeticBccFusion() || hasArithmeticCbzFusion() ||
242 hasFuseAES() || hasFuseArithmeticLogic() || hasFuseCCSelect() ||
243 hasFuseAdrpAdd() || hasFuseLiterals();
244 }
245
248 }
249 unsigned getMaxInterleaveFactor() const { return MaxInterleaveFactor; }
250 unsigned getVectorInsertExtractBaseCost() const;
251 unsigned getCacheLineSize() const override { return CacheLineSize; }
252 unsigned getScatterOverhead() const { return ScatterOverhead; }
253 unsigned getGatherOverhead() const { return GatherOverhead; }
254 unsigned getPrefetchDistance() const override { return PrefetchDistance; }
255 unsigned getMinPrefetchStride(unsigned NumMemAccesses,
256 unsigned NumStridedMemAccesses,
257 unsigned NumPrefetches,
258 bool HasCall) const override {
259 return MinPrefetchStride;
260 }
261 unsigned getMaxPrefetchIterationsAhead() const override {
263 }
266 }
268
271 }
272
273 unsigned getMaximumJumpTableSize() const { return MaxJumpTableSize; }
274 unsigned getMinimumJumpTableEntries() const {
276 }
277
278 /// CPU has TBI (top byte of addresses is ignored during HW address
279 /// translation) and OS enables it.
281
282 bool isLittleEndian() const { return IsLittle; }
283
284 bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); }
285 bool isTargetIOS() const { return TargetTriple.isiOS(); }
286 bool isTargetLinux() const { return TargetTriple.isOSLinux(); }
287 bool isTargetWindows() const { return TargetTriple.isOSWindows(); }
288 bool isTargetAndroid() const { return TargetTriple.isAndroid(); }
289 bool isTargetFuchsia() const { return TargetTriple.isOSFuchsia(); }
291
292 bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); }
293 bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
295
296 bool isTargetILP32() const {
297 return TargetTriple.isArch32Bit() ||
299 }
300
301 bool useAA() const override;
302
303 bool addrSinkUsingGEPs() const override {
304 // Keeping GEPs inbounds is important for exploiting AArch64
305 // addressing-modes in ILP32 mode.
306 return useAA() || isTargetILP32();
307 }
308
309 bool useSmallAddressing() const {
312 // Kernel is currently allowed only for Fuchsia targets,
313 // where it is the same as Small for almost all purposes.
314 case CodeModel::Small:
315 return true;
316 default:
317 return false;
318 }
319 }
320
321 /// ParseSubtargetFeatures - Parses features string setting specified
322 /// subtarget options. Definition of function is auto generated by tblgen.
324
325 /// ClassifyGlobalReference - Find the target operand flags that describe
326 /// how a global value should be referenced for the current subtarget.
327 unsigned ClassifyGlobalReference(const GlobalValue *GV,
328 const TargetMachine &TM) const;
329
331 const TargetMachine &TM) const;
332
333 /// This function is design to compatible with the function def in other
334 /// targets and escape build error about the virtual function def in base
335 /// class TargetSubtargetInfo. Updeate me if AArch64 target need to use it.
336 unsigned char
338 return 0;
339 }
340
342 unsigned NumRegionInstrs) const override;
343 void adjustSchedDependency(SUnit *Def, int DefOpIdx, SUnit *Use, int UseOpIdx,
344 SDep &Dep,
345 const TargetSchedModel *SchedModel) const override;
346
347 bool enableEarlyIfConversion() const override;
348
349 std::unique_ptr<PBQPRAConstraint> getCustomPBQPConstraints() const override;
350
351 bool isCallingConvWin64(CallingConv::ID CC, bool IsVarArg) const {
352 switch (CC) {
353 case CallingConv::C:
357 return isTargetWindows();
359 return IsVarArg && isTargetWindows();
361 return true;
362 default:
363 return false;
364 }
365 }
366
367 /// Return whether FrameLowering should always set the "extended frame
368 /// present" bit in FP, or set it based on a symbol in the runtime.
370 // Older OS versions (particularly system unwinders) are confused by the
371 // Swift extended frame, so when building code that might be run on them we
372 // must dynamically query the concurrency library to determine whether
373 // extended frames should be flagged as present.
374 const Triple &TT = getTargetTriple();
375
376 unsigned Major = TT.getOSVersion().getMajor();
377 switch(TT.getOS()) {
378 default:
379 return false;
380 case Triple::IOS:
381 case Triple::TvOS:
382 return Major < 15;
383 case Triple::WatchOS:
384 return Major < 8;
385 case Triple::MacOSX:
386 case Triple::Darwin:
387 return Major < 12;
388 }
389 }
390
391 void mirFileLoaded(MachineFunction &MF) const override;
392
393 // Return the known range for the bit length of SVE data registers. A value
394 // of 0 means nothing is known about that particular limit beyong what's
395 // implied by the architecture.
396 unsigned getMaxSVEVectorSizeInBits() const {
398 "Tried to get SVE vector length without SVE support!");
400 }
401
402 unsigned getMinSVEVectorSizeInBits() const {
404 "Tried to get SVE vector length without SVE support!");
406 }
407
410 return false;
411
412 // Prefer NEON unless larger SVE registers are available.
413 return !isNeonAvailable() || getMinSVEVectorSizeInBits() >= 256;
414 }
415
418 return false;
421 }
422
423 unsigned getVScaleForTuning() const { return VScaleForTuning; }
424
426 return DefaultSVETFOpts;
427 }
428
429 /// Returns true to use the addvl/inc/dec instructions, as opposed to separate
430 /// add + cnt instructions.
431 bool useScalarIncVL() const;
432
433 const char* getChkStkName() const {
434 if (isWindowsArm64EC())
435 return "#__chkstk_arm64ec";
436 return "__chkstk";
437 }
438
439 const char* getSecurityCheckCookieName() const {
440 if (isWindowsArm64EC())
441 return "#__security_check_cookie_arm64ec";
442 return "__security_check_cookie";
443 }
444
445 /// Choose a method of checking LR before performing a tail call.
448
449 /// Compute the integer discriminator for a given BlockAddress constant, if
450 /// blockaddress signing is enabled, or std::nullopt otherwise.
451 /// Blockaddress signing is controlled by the function attribute
452 /// "ptrauth-indirect-gotos" on the parent function.
453 /// Note that this assumes the discriminator is independent of the indirect
454 /// goto branch site itself, i.e., it's the same for all BlockAddresses in
455 /// a function.
456 std::optional<uint16_t>
458};
459} // End llvm namespace
460
461#endif
This file describes how to lower LLVM calls to machine code calls.
This file describes how to lower LLVM inline asm to machine code INLINEASM.
Interface for Targets to specify which operations they can successfully select and how the others sho...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const AArch64RegisterInfo & getRegisterInfo() const
getRegisterInfo - TargetInstrInfo is a superset of MRegister info.
const AArch64SelectionDAGInfo * getSelectionDAGInfo() const override
const CallLowering * getCallLowering() const override
const AArch64RegisterInfo * getRegisterInfo() const override
bool isNeonAvailable() const
Returns true if the target has NEON and the function at runtime is known to have NEON enabled (e....
bool isLRReservedForRA() const
TailFoldingOpts DefaultSVETFOpts
unsigned getMinPrefetchStride(unsigned NumMemAccesses, unsigned NumStridedMemAccesses, unsigned NumPrefetches, bool HasCall) const override
bool addrSinkUsingGEPs() const override
std::unique_ptr< InstructionSelector > InstSelector
ARMProcFamilyEnum ARMProcFamily
ARMProcFamily - ARM processor family: Cortex-A53, Cortex-A57, and others.
unsigned getMinimumJumpTableEntries() const
std::unique_ptr< RegisterBankInfo > RegBankInfo
bool useSVEForFixedLengthVectors(EVT VT) const
const AArch64InstrInfo * getInstrInfo() const override
bool useSmallAddressing() const
bool hasFusion() const
Return true if the CPU supports any kind of instruction fusion.
AArch64SelectionDAGInfo TSInfo
const char * getSecurityCheckCookieName() const
unsigned getMaximumJumpTableSize() const
std::optional< unsigned > StreamingHazardSize
void overrideSchedPolicy(MachineSchedPolicy &Policy, unsigned NumRegionInstrs) const override
AArch64FrameLowering FrameLowering
bool enableEarlyIfConversion() const override
const InlineAsmLowering * getInlineAsmLowering() const override
unsigned getCacheLineSize() const override
unsigned getVectorInsertExtractBaseCost() const
bool enableMachinePipeliner() const override
ARMProcFamilyEnum getProcFamily() const
Returns ARM processor family.
std::unique_ptr< CallLowering > CallLoweringInfo
GlobalISel related APIs.
std::optional< uint16_t > getPtrAuthBlockAddressDiscriminatorIfEnabled(const Function &ParentFn) const
Compute the integer discriminator for a given BlockAddress constant, if blockaddress signing is enabl...
unsigned getGatherOverhead() const
bool isXRegisterReservedForRA(size_t i) const
unsigned getNumXRegisterReserved() const
unsigned classifyGlobalFunctionReference(const GlobalValue *GV, const TargetMachine &TM) const
bool useAA() const override
bool isStreamingSVEAvailable() const
Returns true if the target has access to the streaming-compatible subset of SVE instructions.
const AArch64TargetLowering * getTargetLowering() const override
Align getPrefLoopAlignment() const
Align getPrefFunctionAlignment() const
unsigned getMaxBytesForLoopAlignment() const
bool supportsAddressTopByteIgnored() const
CPU has TBI (top byte of addresses is ignored during HW address translation) and OS enables it.
unsigned getMaxInterleaveFactor() const
unsigned char classifyGlobalFunctionReference(const GlobalValue *GV) const override
This function is design to compatible with the function def in other targets and escape build error a...
const Triple & getTargetTriple() const
unsigned getStreamingHazardSize() const
Returns the size of memory region that if accessed by both the CPU and the SME unit could result in a...
bool isStreamingCompatible() const
Returns true if the function has a streaming-compatible body.
const char * getChkStkName() const
bool isXRegCustomCalleeSaved(size_t i) const
void adjustSchedDependency(SUnit *Def, int DefOpIdx, SUnit *Use, int UseOpIdx, SDep &Dep, const TargetSchedModel *SchedModel) const override
void mirFileLoaded(MachineFunction &MF) const override
Triple TargetTriple
TargetTriple - What processor and OS we're targeting.
InstructionSelector * getInstructionSelector() const override
bool isSVEorStreamingSVEAvailable() const
Returns true if the target has access to either the full range of SVE instructions,...
bool enableSubRegLiveness() const override
TailFoldingOpts getSVETailFoldingDefaultOpts() const
bool useSVEForFixedLengthVectors() const
unsigned ClassifyGlobalReference(const GlobalValue *GV, const TargetMachine &TM) const
ClassifyGlobalReference - Find the target operand flags that describe how a global value should be re...
void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)
ParseSubtargetFeatures - Parses features string setting specified subtarget options.
unsigned getMinVectorRegisterBitWidth() const
bool isStreaming() const
Returns true if the function has a streaming body.
bool isXRegisterReserved(size_t i) const
unsigned getMaxPrefetchIterationsAhead() const override
virtual unsigned getHwModeSet() const override
bool useScalarIncVL() const
Returns true to use the addvl/inc/dec instructions, as opposed to separate add + cnt instructions.
bool useDFAforSMS() const override
const LegalizerInfo * getLegalizerInfo() const override
bool enableMachineScheduler() const override
unsigned getScatterOverhead() const
bool enablePostRAScheduler() const override
std::unique_ptr< PBQPRAConstraint > getCustomPBQPConstraints() const override
unsigned getEpilogueVectorizationMinVF() const
unsigned getMaxSVEVectorSizeInBits() const
bool isCallingConvWin64(CallingConv::ID CC, bool IsVarArg) const
unsigned getVScaleForTuning() const
unsigned getMinSVEVectorSizeInBits() const
AArch64PAuth::AuthCheckMethod getAuthenticatedLRCheckMethod(const MachineFunction &MF) const
Choose a method of checking LR before performing a tail call.
AArch64InstrInfo InstrInfo
AArch64TargetLowering TLInfo
const RegisterBankInfo * getRegBankInfo() const override
std::unique_ptr< LegalizerInfo > Legalizer
std::unique_ptr< InlineAsmLowering > InlineAsmLoweringInfo
bool isXRaySupported() const override
bool isSVEAvailable() const
Returns true if the target has SVE and can use the full range of SVE instructions,...
bool hasCustomCallingConv() const
const AArch64FrameLowering * getFrameLowering() const override
bool swiftAsyncContextIsDynamicallySet() const
Return whether FrameLowering should always set the "extended frame present" bit in FP,...
unsigned getPrefetchDistance() const override
size_type count() const
count - Returns the number of bits which are set.
Definition: BitVector.h:162
bool any() const
any - Returns true if any bit is set.
Definition: BitVector.h:170
Holds all the information related to register banks.
Scheduling dependency.
Definition: ScheduleDAG.h:49
Scheduling unit. This is a node in the scheduling DAG.
Definition: ScheduleDAG.h:242
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
const TargetMachine & getTargetMachine() const
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:80
CodeModel::Model getCodeModel() const
Returns the code model.
Provide an instruction scheduling machine model to CodeGen passes.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
bool isAndroid() const
Tests whether the target is Android.
Definition: Triple.h:803
bool isOSBinFormatMachO() const
Tests whether the environment is MachO.
Definition: Triple.h:766
bool isOSBinFormatCOFF() const
Tests whether the OS uses the COFF binary format.
Definition: Triple.h:758
EnvironmentType getEnvironment() const
Get the parsed environment type of this triple.
Definition: Triple.h:412
bool isOSWindows() const
Tests whether the OS is Windows.
Definition: Triple.h:655
bool isOSLinux() const
Tests whether the OS is Linux.
Definition: Triple.h:712
bool isOSDarwin() const
Is this a "Darwin" OS (macOS, iOS, tvOS, watchOS, XROS, or DriverKit).
Definition: Triple.h:588
bool isWindowsArm64EC() const
Definition: Triple.h:674
bool isiOS() const
Is this an iOS triple.
Definition: Triple.h:556
bool isArch32Bit() const
Test whether the architecture is 32-bit.
Definition: Triple.cpp:1738
bool isOSFuchsia() const
Definition: Triple.h:618
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
Definition: Triple.h:753
A Use represents the edge between a Value definition and its users.
Definition: Use.h:35
AuthCheckMethod
Variants of check performed on an authenticated pointer.
static constexpr unsigned SVEBitsPerBlock
@ Swift
Calling convention for Swift.
Definition: CallingConv.h:69
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition: CallingConv.h:41
@ PreserveNone
Used for runtime calls that preserves none general registers.
Definition: CallingConv.h:90
@ Win64
The C convention as implemented on Windows/x86-64 and AArch64.
Definition: CallingConv.h:159
@ SwiftTail
This follows the Swift calling convention in how arguments are passed but guarantees tail calls will ...
Definition: CallingConv.h:87
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
TailFoldingOpts
An enum to describe what types of loops we should attempt to tail-fold: Disabled: None Reductions: Lo...
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
Extended Value Type.
Definition: ValueTypes.h:35
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
Definition: ValueTypes.h:376
bool isFixedLengthVector() const
Definition: ValueTypes.h:181
Define a generic scheduling policy for targets that don't provide their own MachineSchedStrategy.