LLVM 20.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:
40 enum ARMProcFamilyEnum : uint8_t {
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
62 // Default scatter/gather overhead.
63 unsigned ScatterOverhead = 10;
64 unsigned GatherOverhead = 10;
67 unsigned MaxPrefetchIterationsAhead = UINT_MAX;
72 unsigned MaxJumpTableSize = 0;
73
74 // ReserveXRegister[i] - X#i is not available as a general purpose register.
76
77 // ReserveXRegisterForRA[i] - X#i is not available for register allocator.
79
80 // CustomCallUsedXRegister[i] - X#i call saved.
82
84
89 unsigned VScaleForTuning = 2;
91
92 /// TargetTriple - What processor and OS we're targeting.
94
99
100 /// GlobalISel related APIs.
101 std::unique_ptr<CallLowering> CallLoweringInfo;
102 std::unique_ptr<InlineAsmLowering> InlineAsmLoweringInfo;
103 std::unique_ptr<InstructionSelector> InstSelector;
104 std::unique_ptr<LegalizerInfo> Legalizer;
105 std::unique_ptr<RegisterBankInfo> RegBankInfo;
106
107private:
108 /// initializeSubtargetDependencies - Initializes using CPUString and the
109 /// passed in feature string so that we can use initializer lists for
110 /// subtarget initialization.
111 AArch64Subtarget &initializeSubtargetDependencies(StringRef FS,
112 StringRef CPUString,
113 StringRef TuneCPUString,
114 bool HasMinSize);
115
116 /// Initialize properties based on the selected processor family.
117 void initializeProperties(bool HasMinSize);
118
119public:
120 /// This constructor initializes the data members to match that
121 /// of the specified triple.
122 AArch64Subtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU,
123 StringRef FS, const TargetMachine &TM, bool LittleEndian,
124 unsigned MinSVEVectorSizeInBitsOverride = 0,
125 unsigned MaxSVEVectorSizeInBitsOverride = 0,
126 bool IsStreaming = false, bool IsStreamingCompatible = false,
127 bool HasMinSize = false);
128
129// Getters for SubtargetFeatures defined in tablegen
130#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
131 bool GETTER() const { return ATTRIBUTE; }
132#include "AArch64GenSubtargetInfo.inc"
133
135 return &TSInfo;
136 }
137 const AArch64FrameLowering *getFrameLowering() const override {
138 return &FrameLowering;
139 }
140 const AArch64TargetLowering *getTargetLowering() const override {
141 return &TLInfo;
142 }
143 const AArch64InstrInfo *getInstrInfo() const override { return &InstrInfo; }
144 const AArch64RegisterInfo *getRegisterInfo() const override {
145 return &getInstrInfo()->getRegisterInfo();
146 }
147 const CallLowering *getCallLowering() const override;
148 const InlineAsmLowering *getInlineAsmLowering() const override;
150 const LegalizerInfo *getLegalizerInfo() const override;
151 const RegisterBankInfo *getRegBankInfo() const override;
152 const Triple &getTargetTriple() const { return TargetTriple; }
153 bool enableMachineScheduler() const override { return true; }
154 bool enablePostRAScheduler() const override { return usePostRAScheduler(); }
155
156 bool enableMachinePipeliner() const override;
157 bool useDFAforSMS() const override { return false; }
158
159 /// Returns ARM processor family.
160 /// Avoid this function! CPU specifics should be kept local to this class
161 /// and preferably modeled with SubtargetFeatures or properties in
162 /// initializeProperties().
164 return ARMProcFamily;
165 }
166
167 bool isXRaySupported() const override { return true; }
168
169 /// Returns true if the function has a streaming body.
170 bool isStreaming() const { return IsStreaming; }
171
172 /// Returns true if the function has a streaming-compatible body.
174
175 /// Returns true if the target has NEON and the function at runtime is known
176 /// to have NEON enabled (e.g. the function is known not to be in streaming-SVE
177 /// mode, which disables NEON instructions).
178 bool isNeonAvailable() const {
179 return hasNEON() &&
180 (hasSMEFA64() || (!isStreaming() && !isStreamingCompatible()));
181 }
182
183 /// Returns true if the target has SVE and can use the full range of SVE
184 /// instructions, for example because it knows the function is known not to be
185 /// in streaming-SVE mode or when the target has FEAT_FA64 enabled.
186 bool isSVEAvailable() const {
187 return hasSVE() &&
188 (hasSMEFA64() || (!isStreaming() && !isStreamingCompatible()));
189 }
190
191 /// Returns true if the target has access to either the full range of SVE instructions,
192 /// or the streaming-compatible subset of SVE instructions.
194 return hasSVE() || (hasSME() && isStreaming());
195 }
196
198 // Don't assume any minimum vector size when PSTATE.SM may not be 0, because
199 // we don't yet support streaming-compatible codegen support that we trust
200 // is safe for functions that may be executed in streaming-SVE mode.
201 // By returning '0' here, we disable vectorization.
202 if (!isSVEAvailable() && !isNeonAvailable())
203 return 0;
205 }
206
207 bool isXRegisterReserved(size_t i) const { return ReserveXRegister[i]; }
208 bool isXRegisterReservedForRA(size_t i) const { return ReserveXRegisterForRA[i]; }
209 unsigned getNumXRegisterReserved() const {
210 BitVector AllReservedX(AArch64::GPR64commonRegClass.getNumRegs());
211 AllReservedX |= ReserveXRegister;
212 AllReservedX |= ReserveXRegisterForRA;
213 return AllReservedX.count();
214 }
215 bool isLRReservedForRA() const { return ReserveLRForRA; }
216 bool isXRegCustomCalleeSaved(size_t i) const {
217 return CustomCallSavedXRegs[i];
218 }
220
221 /// Return true if the CPU supports any kind of instruction fusion.
222 bool hasFusion() const {
223 return hasArithmeticBccFusion() || hasArithmeticCbzFusion() ||
224 hasFuseAES() || hasFuseArithmeticLogic() || hasFuseCCSelect() ||
225 hasFuseAdrpAdd() || hasFuseLiterals();
226 }
227
228 unsigned getMaxInterleaveFactor() const { return MaxInterleaveFactor; }
229 unsigned getVectorInsertExtractBaseCost() const;
230 unsigned getCacheLineSize() const override { return CacheLineSize; }
231 unsigned getScatterOverhead() const { return ScatterOverhead; }
232 unsigned getGatherOverhead() const { return GatherOverhead; }
233 unsigned getPrefetchDistance() const override { return PrefetchDistance; }
234 unsigned getMinPrefetchStride(unsigned NumMemAccesses,
235 unsigned NumStridedMemAccesses,
236 unsigned NumPrefetches,
237 bool HasCall) const override {
238 return MinPrefetchStride;
239 }
240 unsigned getMaxPrefetchIterationsAhead() const override {
242 }
245 }
247
250 }
251
252 unsigned getMaximumJumpTableSize() const { return MaxJumpTableSize; }
253 unsigned getMinimumJumpTableEntries() const {
255 }
256
257 /// CPU has TBI (top byte of addresses is ignored during HW address
258 /// translation) and OS enables it.
260
261 bool isLittleEndian() const { return IsLittle; }
262
263 bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); }
264 bool isTargetIOS() const { return TargetTriple.isiOS(); }
265 bool isTargetLinux() const { return TargetTriple.isOSLinux(); }
266 bool isTargetWindows() const { return TargetTriple.isOSWindows(); }
267 bool isTargetAndroid() const { return TargetTriple.isAndroid(); }
268 bool isTargetFuchsia() const { return TargetTriple.isOSFuchsia(); }
270
271 bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); }
272 bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
274
275 bool isTargetILP32() const {
276 return TargetTriple.isArch32Bit() ||
278 }
279
280 bool useAA() const override;
281
282 bool addrSinkUsingGEPs() const override {
283 // Keeping GEPs inbounds is important for exploiting AArch64
284 // addressing-modes in ILP32 mode.
285 return useAA() || isTargetILP32();
286 }
287
288 bool useSmallAddressing() const {
291 // Kernel is currently allowed only for Fuchsia targets,
292 // where it is the same as Small for almost all purposes.
293 case CodeModel::Small:
294 return true;
295 default:
296 return false;
297 }
298 }
299
300 /// ParseSubtargetFeatures - Parses features string setting specified
301 /// subtarget options. Definition of function is auto generated by tblgen.
303
304 /// ClassifyGlobalReference - Find the target operand flags that describe
305 /// how a global value should be referenced for the current subtarget.
306 unsigned ClassifyGlobalReference(const GlobalValue *GV,
307 const TargetMachine &TM) const;
308
310 const TargetMachine &TM) const;
311
312 /// This function is design to compatible with the function def in other
313 /// targets and escape build error about the virtual function def in base
314 /// class TargetSubtargetInfo. Updeate me if AArch64 target need to use it.
315 unsigned char
317 return 0;
318 }
319
321 unsigned NumRegionInstrs) const override;
322 void adjustSchedDependency(SUnit *Def, int DefOpIdx, SUnit *Use, int UseOpIdx,
323 SDep &Dep,
324 const TargetSchedModel *SchedModel) const override;
325
326 bool enableEarlyIfConversion() const override;
327
328 std::unique_ptr<PBQPRAConstraint> getCustomPBQPConstraints() const override;
329
330 bool isCallingConvWin64(CallingConv::ID CC, bool IsVarArg) const {
331 switch (CC) {
332 case CallingConv::C:
336 return isTargetWindows();
338 return IsVarArg && isTargetWindows();
340 return true;
341 default:
342 return false;
343 }
344 }
345
346 /// Return whether FrameLowering should always set the "extended frame
347 /// present" bit in FP, or set it based on a symbol in the runtime.
349 // Older OS versions (particularly system unwinders) are confused by the
350 // Swift extended frame, so when building code that might be run on them we
351 // must dynamically query the concurrency library to determine whether
352 // extended frames should be flagged as present.
353 const Triple &TT = getTargetTriple();
354
355 unsigned Major = TT.getOSVersion().getMajor();
356 switch(TT.getOS()) {
357 default:
358 return false;
359 case Triple::IOS:
360 case Triple::TvOS:
361 return Major < 15;
362 case Triple::WatchOS:
363 return Major < 8;
364 case Triple::MacOSX:
365 case Triple::Darwin:
366 return Major < 12;
367 }
368 }
369
370 void mirFileLoaded(MachineFunction &MF) const override;
371
372 // Return the known range for the bit length of SVE data registers. A value
373 // of 0 means nothing is known about that particular limit beyong what's
374 // implied by the architecture.
375 unsigned getMaxSVEVectorSizeInBits() const {
377 "Tried to get SVE vector length without SVE support!");
379 }
380
381 unsigned getMinSVEVectorSizeInBits() const {
383 "Tried to get SVE vector length without SVE support!");
385 }
386
389 return false;
390
391 // Prefer NEON unless larger SVE registers are available.
392 return !isNeonAvailable() || getMinSVEVectorSizeInBits() >= 256;
393 }
394
397 return false;
400 }
401
402 unsigned getVScaleForTuning() const { return VScaleForTuning; }
403
405 return DefaultSVETFOpts;
406 }
407
408 const char* getChkStkName() const {
409 if (isWindowsArm64EC())
410 return "#__chkstk_arm64ec";
411 return "__chkstk";
412 }
413
414 const char* getSecurityCheckCookieName() const {
415 if (isWindowsArm64EC())
416 return "#__security_check_cookie_arm64ec";
417 return "__security_check_cookie";
418 }
419
420 /// Choose a method of checking LR before performing a tail call.
423
424 /// Compute the integer discriminator for a given BlockAddress constant, if
425 /// blockaddress signing is enabled, or std::nullopt otherwise.
426 /// Blockaddress signing is controlled by the function attribute
427 /// "ptrauth-indirect-gotos" on the parent function.
428 /// Note that this assumes the discriminator is independent of the indirect
429 /// goto branch site itself, i.e., it's the same for all BlockAddresses in
430 /// a function.
431 std::optional<uint16_t>
433
435 return AddressCheckPSV.get();
436 }
437
438private:
439 /// Pseudo value representing memory load performed to check an address.
440 ///
441 /// This load operation is solely used for its side-effects: if the address
442 /// is not mapped (or not readable), it triggers CPU exception, otherwise
443 /// execution proceeds and the value is not used.
444 class AddressCheckPseudoSourceValue : public PseudoSourceValue {
445 public:
446 AddressCheckPseudoSourceValue(const TargetMachine &TM)
448
449 bool isConstant(const MachineFrameInfo *) const override { return false; }
450 bool isAliased(const MachineFrameInfo *) const override { return true; }
451 bool mayAlias(const MachineFrameInfo *) const override { return true; }
452 void printCustom(raw_ostream &OS) const override { OS << "AddressCheck"; }
453 };
454
455 std::unique_ptr<AddressCheckPseudoSourceValue> AddressCheckPSV;
456};
457} // End llvm namespace
458
459#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())
raw_pwrite_stream & OS
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
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
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
const PseudoSourceValue * getAddressCheckPSV() const
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,...
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
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 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
Special value supplied for machine level alias analysis.
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:50
const TargetMachine & getTargetMachine() const
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:77
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:769
bool isOSBinFormatMachO() const
Tests whether the environment is MachO.
Definition: Triple.h:732
bool isOSBinFormatCOFF() const
Tests whether the OS uses the COFF binary format.
Definition: Triple.h:724
EnvironmentType getEnvironment() const
Get the parsed environment type of this triple.
Definition: Triple.h:390
bool isOSWindows() const
Tests whether the OS is Windows.
Definition: Triple.h:624
bool isOSLinux() const
Tests whether the OS is Linux.
Definition: Triple.h:678
bool isOSDarwin() const
Is this a "Darwin" OS (macOS, iOS, tvOS, watchOS, XROS, or DriverKit).
Definition: Triple.h:558
bool isWindowsArm64EC() const
Definition: Triple.h:640
bool isiOS() const
Is this an iOS triple.
Definition: Triple.h:531
bool isArch32Bit() const
Test whether the architecture is 32-bit.
Definition: Triple.cpp:1655
bool isOSFuchsia() const
Definition: Triple.h:588
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
Definition: Triple.h:719
A Use represents the edge between a Value definition and its users.
Definition: Use.h:43
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:367
bool isFixedLengthVector() const
Definition: ValueTypes.h:178
Define a generic scheduling policy for targets that don't provide their own MachineSchedStrategy.