LLVM 19.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
64 unsigned MaxPrefetchIterationsAhead = UINT_MAX;
69 unsigned MaxJumpTableSize = 0;
70
71 // ReserveXRegister[i] - X#i is not available as a general purpose register.
73
74 // ReserveXRegisterForRA[i] - X#i is not available for register allocator.
76
77 // CustomCallUsedXRegister[i] - X#i call saved.
79
81
86 unsigned VScaleForTuning = 2;
88
89 /// TargetTriple - What processor and OS we're targeting.
91
96
97 /// GlobalISel related APIs.
98 std::unique_ptr<CallLowering> CallLoweringInfo;
99 std::unique_ptr<InlineAsmLowering> InlineAsmLoweringInfo;
100 std::unique_ptr<InstructionSelector> InstSelector;
101 std::unique_ptr<LegalizerInfo> Legalizer;
102 std::unique_ptr<RegisterBankInfo> RegBankInfo;
103
104private:
105 /// initializeSubtargetDependencies - Initializes using CPUString and the
106 /// passed in feature string so that we can use initializer lists for
107 /// subtarget initialization.
108 AArch64Subtarget &initializeSubtargetDependencies(StringRef FS,
109 StringRef CPUString,
110 StringRef TuneCPUString,
111 bool HasMinSize);
112
113 /// Initialize properties based on the selected processor family.
114 void initializeProperties(bool HasMinSize);
115
116public:
117 /// This constructor initializes the data members to match that
118 /// of the specified triple.
119 AArch64Subtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU,
120 StringRef FS, const TargetMachine &TM, bool LittleEndian,
121 unsigned MinSVEVectorSizeInBitsOverride = 0,
122 unsigned MaxSVEVectorSizeInBitsOverride = 0,
123 bool StreamingSVEMode = false,
124 bool StreamingCompatibleSVEMode = false,
125 bool HasMinSize = false);
126
127// Getters for SubtargetFeatures defined in tablegen
128#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
129 bool GETTER() const { return ATTRIBUTE; }
130#include "AArch64GenSubtargetInfo.inc"
131
133 return &TSInfo;
134 }
135 const AArch64FrameLowering *getFrameLowering() const override {
136 return &FrameLowering;
137 }
138 const AArch64TargetLowering *getTargetLowering() const override {
139 return &TLInfo;
140 }
141 const AArch64InstrInfo *getInstrInfo() const override { return &InstrInfo; }
142 const AArch64RegisterInfo *getRegisterInfo() const override {
143 return &getInstrInfo()->getRegisterInfo();
144 }
145 const CallLowering *getCallLowering() const override;
146 const InlineAsmLowering *getInlineAsmLowering() const override;
148 const LegalizerInfo *getLegalizerInfo() const override;
149 const RegisterBankInfo *getRegBankInfo() const override;
150 const Triple &getTargetTriple() const { return TargetTriple; }
151 bool enableMachineScheduler() const override { return true; }
152 bool enablePostRAScheduler() const override { return usePostRAScheduler(); }
153
154 bool enableMachinePipeliner() const override;
155 bool useDFAforSMS() const override { return false; }
156
157 /// Returns ARM processor family.
158 /// Avoid this function! CPU specifics should be kept local to this class
159 /// and preferably modeled with SubtargetFeatures or properties in
160 /// initializeProperties().
162 return ARMProcFamily;
163 }
164
165 bool isXRaySupported() const override { return true; }
166
167 /// Returns true if the function has a streaming body.
168 bool isStreaming() const { return StreamingSVEMode; }
169
170 /// Returns true if the function has a streaming-compatible body.
171 bool isStreamingCompatible() const;
172
173 /// Returns true if the target has NEON and the function at runtime is known
174 /// to have NEON enabled (e.g. the function is known not to be in streaming-SVE
175 /// mode, which disables NEON instructions).
176 bool isNeonAvailable() const;
177
178 /// Returns true if the target has SVE and can use the full range of SVE
179 /// instructions, for example because it knows the function is known not to be
180 /// in streaming-SVE mode or when the target has FEAT_FA64 enabled.
181 bool isSVEAvailable() const;
182
184 // Don't assume any minimum vector size when PSTATE.SM may not be 0, because
185 // we don't yet support streaming-compatible codegen support that we trust
186 // is safe for functions that may be executed in streaming-SVE mode.
187 // By returning '0' here, we disable vectorization.
188 if (!isSVEAvailable() && !isNeonAvailable())
189 return 0;
191 }
192
193 bool isXRegisterReserved(size_t i) const { return ReserveXRegister[i]; }
194 bool isXRegisterReservedForRA(size_t i) const { return ReserveXRegisterForRA[i]; }
195 unsigned getNumXRegisterReserved() const {
196 BitVector AllReservedX(AArch64::GPR64commonRegClass.getNumRegs());
197 AllReservedX |= ReserveXRegister;
198 AllReservedX |= ReserveXRegisterForRA;
199 return AllReservedX.count();
200 }
201 bool isXRegCustomCalleeSaved(size_t i) const {
202 return CustomCallSavedXRegs[i];
203 }
205
206 /// Return true if the CPU supports any kind of instruction fusion.
207 bool hasFusion() const {
208 return hasArithmeticBccFusion() || hasArithmeticCbzFusion() ||
209 hasFuseAES() || hasFuseArithmeticLogic() || hasFuseCCSelect() ||
210 hasFuseAdrpAdd() || hasFuseLiterals();
211 }
212
213 unsigned getMaxInterleaveFactor() const { return MaxInterleaveFactor; }
214 unsigned getVectorInsertExtractBaseCost() const;
215 unsigned getCacheLineSize() const override { return CacheLineSize; }
216 unsigned getPrefetchDistance() const override { return PrefetchDistance; }
217 unsigned getMinPrefetchStride(unsigned NumMemAccesses,
218 unsigned NumStridedMemAccesses,
219 unsigned NumPrefetches,
220 bool HasCall) const override {
221 return MinPrefetchStride;
222 }
223 unsigned getMaxPrefetchIterationsAhead() const override {
225 }
228 }
230
233 }
234
235 unsigned getMaximumJumpTableSize() const { return MaxJumpTableSize; }
236 unsigned getMinimumJumpTableEntries() const {
238 }
239
240 /// CPU has TBI (top byte of addresses is ignored during HW address
241 /// translation) and OS enables it.
243
244 bool isLittleEndian() const { return IsLittle; }
245
246 bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); }
247 bool isTargetIOS() const { return TargetTriple.isiOS(); }
248 bool isTargetLinux() const { return TargetTriple.isOSLinux(); }
249 bool isTargetWindows() const { return TargetTriple.isOSWindows(); }
250 bool isTargetAndroid() const { return TargetTriple.isAndroid(); }
251 bool isTargetFuchsia() const { return TargetTriple.isOSFuchsia(); }
253
254 bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); }
255 bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
257
258 bool isTargetILP32() const {
259 return TargetTriple.isArch32Bit() ||
261 }
262
263 bool useAA() const override;
264
265 bool addrSinkUsingGEPs() const override {
266 // Keeping GEPs inbounds is important for exploiting AArch64
267 // addressing-modes in ILP32 mode.
268 return useAA() || isTargetILP32();
269 }
270
271 bool useSmallAddressing() const {
274 // Kernel is currently allowed only for Fuchsia targets,
275 // where it is the same as Small for almost all purposes.
276 case CodeModel::Small:
277 return true;
278 default:
279 return false;
280 }
281 }
282
283 /// ParseSubtargetFeatures - Parses features string setting specified
284 /// subtarget options. Definition of function is auto generated by tblgen.
286
287 /// ClassifyGlobalReference - Find the target operand flags that describe
288 /// how a global value should be referenced for the current subtarget.
289 unsigned ClassifyGlobalReference(const GlobalValue *GV,
290 const TargetMachine &TM) const;
291
293 const TargetMachine &TM) const;
294
295 /// This function is design to compatible with the function def in other
296 /// targets and escape build error about the virtual function def in base
297 /// class TargetSubtargetInfo. Updeate me if AArch64 target need to use it.
298 unsigned char
300 return 0;
301 }
302
304 unsigned NumRegionInstrs) const override;
305 void adjustSchedDependency(SUnit *Def, int DefOpIdx, SUnit *Use, int UseOpIdx,
306 SDep &Dep,
307 const TargetSchedModel *SchedModel) const override;
308
309 bool enableEarlyIfConversion() const override;
310
311 std::unique_ptr<PBQPRAConstraint> getCustomPBQPConstraints() const override;
312
314 switch (CC) {
315 case CallingConv::C:
319 return isTargetWindows();
321 return true;
322 default:
323 return false;
324 }
325 }
326
327 /// Return whether FrameLowering should always set the "extended frame
328 /// present" bit in FP, or set it based on a symbol in the runtime.
330 // Older OS versions (particularly system unwinders) are confused by the
331 // Swift extended frame, so when building code that might be run on them we
332 // must dynamically query the concurrency library to determine whether
333 // extended frames should be flagged as present.
334 const Triple &TT = getTargetTriple();
335
336 unsigned Major = TT.getOSVersion().getMajor();
337 switch(TT.getOS()) {
338 default:
339 return false;
340 case Triple::IOS:
341 case Triple::TvOS:
342 return Major < 15;
343 case Triple::WatchOS:
344 return Major < 8;
345 case Triple::MacOSX:
346 case Triple::Darwin:
347 return Major < 12;
348 }
349 }
350
351 void mirFileLoaded(MachineFunction &MF) const override;
352
353 bool hasSVEorSME() const { return hasSVE() || hasSME(); }
354 bool hasSVE2orSME() const { return hasSVE2() || hasSME(); }
355
356 // Return the known range for the bit length of SVE data registers. A value
357 // of 0 means nothing is known about that particular limit beyong what's
358 // implied by the architecture.
359 unsigned getMaxSVEVectorSizeInBits() const {
361 "Tried to get SVE vector length without SVE support!");
363 }
364
365 unsigned getMinSVEVectorSizeInBits() const {
367 "Tried to get SVE vector length without SVE support!");
369 }
370
372 if (!isNeonAvailable())
373 return hasSVEorSME();
374
375 // Prefer NEON unless larger SVE registers are available.
376 return hasSVEorSME() && getMinSVEVectorSizeInBits() >= 256;
377 }
378
381 return false;
384 }
385
386 unsigned getVScaleForTuning() const { return VScaleForTuning; }
387
389 return DefaultSVETFOpts;
390 }
391
392 const char* getChkStkName() const {
393 if (isWindowsArm64EC())
394 return "#__chkstk_arm64ec";
395 return "__chkstk";
396 }
397
398 const char* getSecurityCheckCookieName() const {
399 if (isWindowsArm64EC())
400 return "#__security_check_cookie_arm64ec";
401 return "__security_check_cookie";
402 }
403
404 /// Choose a method of checking LR before performing a tail call.
406
408 return AddressCheckPSV.get();
409 }
410
411private:
412 /// Pseudo value representing memory load performed to check an address.
413 ///
414 /// This load operation is solely used for its side-effects: if the address
415 /// is not mapped (or not readable), it triggers CPU exception, otherwise
416 /// execution proceeds and the value is not used.
417 class AddressCheckPseudoSourceValue : public PseudoSourceValue {
418 public:
419 AddressCheckPseudoSourceValue(const TargetMachine &TM)
421
422 bool isConstant(const MachineFrameInfo *) const override { return false; }
423 bool isAliased(const MachineFrameInfo *) const override { return true; }
424 bool mayAlias(const MachineFrameInfo *) const override { return true; }
425 void printCustom(raw_ostream &OS) const override { OS << "AddressCheck"; }
426 };
427
428 std::unique_ptr<AddressCheckPseudoSourceValue> AddressCheckPSV;
429};
430} // End llvm namespace
431
432#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...
const char LLVMTargetMachineRef TM
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
bool isNeonAvailable() const
Returns true if the target has NEON and the function at runtime is known to have NEON enabled (e....
const AArch64RegisterInfo * getRegisterInfo() const override
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
bool isStreamingCompatible() const
Returns true if the function has a streaming-compatible body.
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.
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 isCallingConvWin64(CallingConv::ID CC) const
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
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.
AArch64PAuth::AuthCheckMethod getAuthenticatedLRCheckMethod() const
Choose a method of checking LR before performing a tail call.
bool isSVEAvailable() const
Returns true if the target has SVE and can use the full range of SVE instructions,...
bool isXRegisterReserved(size_t i) const
unsigned getMaxPrefetchIterationsAhead() const override
bool useDFAforSMS() const override
const LegalizerInfo * getLegalizerInfo() const override
bool enableMachineScheduler() const override
bool enablePostRAScheduler() const override
std::unique_ptr< PBQPRAConstraint > getCustomPBQPConstraints() const override
unsigned getMaxSVEVectorSizeInBits() const
unsigned getVScaleForTuning() const
unsigned getMinSVEVectorSizeInBits() const
AArch64InstrInfo InstrInfo
AArch64TargetLowering TLInfo
const RegisterBankInfo * getRegBankInfo() const override
std::unique_ptr< LegalizerInfo > Legalizer
std::unique_ptr< InlineAsmLowering > InlineAsmLoweringInfo
bool isXRaySupported() const override
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:76
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:764
bool isOSBinFormatMachO() const
Tests whether the environment is MachO.
Definition: Triple.h:727
bool isOSBinFormatCOFF() const
Tests whether the OS uses the COFF binary format.
Definition: Triple.h:719
EnvironmentType getEnvironment() const
Get the parsed environment type of this triple.
Definition: Triple.h:389
bool isOSWindows() const
Tests whether the OS is Windows.
Definition: Triple.h:619
bool isOSLinux() const
Tests whether the OS is Linux.
Definition: Triple.h:673
bool isOSDarwin() const
Is this a "Darwin" OS (macOS, iOS, tvOS, watchOS, XROS, or DriverKit).
Definition: Triple.h:553
bool isWindowsArm64EC() const
Definition: Triple.h:635
bool isiOS() const
Is this an iOS triple.
Definition: Triple.h:526
bool isArch32Bit() const
Test whether the architecture is 32-bit.
Definition: Triple.cpp:1560
bool isOSFuchsia() const
Definition: Triple.h:583
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
Definition: Triple.h:714
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
@ 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:34
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
Definition: ValueTypes.h:366
bool isFixedLengthVector() const
Definition: ValueTypes.h:177
Define a generic scheduling policy for targets that don't provide their own MachineSchedStrategy.