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 {
96 TSV110
97 };
98
99protected:
100 /// ARMProcFamily - ARM processor family: Cortex-A53, Cortex-A57, and others.
102
103 // Enable 64-bit vectorization in SLP.
105
106// Bool members corresponding to the SubtargetFeatures defined in tablegen
107#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
108 bool ATTRIBUTE = DEFAULT;
109#include "AArch64GenSubtargetInfo.inc"
110
116 unsigned MaxPrefetchIterationsAhead = UINT_MAX;
121 unsigned MaxJumpTableSize = 0;
122
123 // ReserveXRegister[i] - X#i is not available as a general purpose register.
125
126 // ReserveXRegisterForRA[i] - X#i is not available for register allocator.
128
129 // CustomCallUsedXRegister[i] - X#i call saved.
131
133
138 unsigned VScaleForTuning = 2;
140
141 /// TargetTriple - What processor and OS we're targeting.
143
148
149 /// GlobalISel related APIs.
150 std::unique_ptr<CallLowering> CallLoweringInfo;
151 std::unique_ptr<InlineAsmLowering> InlineAsmLoweringInfo;
152 std::unique_ptr<InstructionSelector> InstSelector;
153 std::unique_ptr<LegalizerInfo> Legalizer;
154 std::unique_ptr<RegisterBankInfo> RegBankInfo;
155
156private:
157 /// initializeSubtargetDependencies - Initializes using CPUString and the
158 /// passed in feature string so that we can use initializer lists for
159 /// subtarget initialization.
160 AArch64Subtarget &initializeSubtargetDependencies(StringRef FS,
161 StringRef CPUString,
162 StringRef TuneCPUString,
163 bool HasMinSize);
164
165 /// Initialize properties based on the selected processor family.
166 void initializeProperties(bool HasMinSize);
167
168public:
169 /// This constructor initializes the data members to match that
170 /// of the specified triple.
171 AArch64Subtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU,
172 StringRef FS, const TargetMachine &TM, bool LittleEndian,
173 unsigned MinSVEVectorSizeInBitsOverride = 0,
174 unsigned MaxSVEVectorSizeInBitsOverride = 0,
175 bool StreamingSVEMode = false,
176 bool StreamingCompatibleSVEMode = false,
177 bool HasMinSize = false);
178
179// Getters for SubtargetFeatures defined in tablegen
180#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
181 bool GETTER() const { return ATTRIBUTE; }
182#include "AArch64GenSubtargetInfo.inc"
183
185 return &TSInfo;
186 }
187 const AArch64FrameLowering *getFrameLowering() const override {
188 return &FrameLowering;
189 }
190 const AArch64TargetLowering *getTargetLowering() const override {
191 return &TLInfo;
192 }
193 const AArch64InstrInfo *getInstrInfo() const override { return &InstrInfo; }
194 const AArch64RegisterInfo *getRegisterInfo() const override {
195 return &getInstrInfo()->getRegisterInfo();
196 }
197 const CallLowering *getCallLowering() const override;
198 const InlineAsmLowering *getInlineAsmLowering() const override;
200 const LegalizerInfo *getLegalizerInfo() const override;
201 const RegisterBankInfo *getRegBankInfo() const override;
202 const Triple &getTargetTriple() const { return TargetTriple; }
203 bool enableMachineScheduler() const override { return true; }
204 bool enablePostRAScheduler() const override { return usePostRAScheduler(); }
205
206 bool enableMachinePipeliner() const override;
207 bool useDFAforSMS() const override { return false; }
208
209 /// Returns ARM processor family.
210 /// Avoid this function! CPU specifics should be kept local to this class
211 /// and preferably modeled with SubtargetFeatures or properties in
212 /// initializeProperties().
214 return ARMProcFamily;
215 }
216
217 bool isXRaySupported() const override { return true; }
218
219 /// Returns true if the function has a streaming body.
220 bool isStreaming() const { return StreamingSVEMode; }
221
222 /// Returns true if the function has a streaming-compatible body.
223 bool isStreamingCompatible() const;
224
225 /// Returns true if the target has NEON and the function at runtime is known
226 /// to have NEON enabled (e.g. the function is known not to be in streaming-SVE
227 /// mode, which disables NEON instructions).
228 bool isNeonAvailable() const;
229
230 /// Returns true if the target has SVE and can use the full range of SVE
231 /// instructions, for example because it knows the function is known not to be
232 /// in streaming-SVE mode or when the target has FEAT_FA64 enabled.
233 bool isSVEAvailable() const;
234
236 // Don't assume any minimum vector size when PSTATE.SM may not be 0, because
237 // we don't yet support streaming-compatible codegen support that we trust
238 // is safe for functions that may be executed in streaming-SVE mode.
239 // By returning '0' here, we disable vectorization.
240 if (!isSVEAvailable() && !isNeonAvailable())
241 return 0;
243 }
244
245 bool isXRegisterReserved(size_t i) const { return ReserveXRegister[i]; }
246 bool isXRegisterReservedForRA(size_t i) const { return ReserveXRegisterForRA[i]; }
247 unsigned getNumXRegisterReserved() const {
248 BitVector AllReservedX(AArch64::GPR64commonRegClass.getNumRegs());
249 AllReservedX |= ReserveXRegister;
250 AllReservedX |= ReserveXRegisterForRA;
251 return AllReservedX.count();
252 }
253 bool isXRegCustomCalleeSaved(size_t i) const {
254 return CustomCallSavedXRegs[i];
255 }
257
258 /// Return true if the CPU supports any kind of instruction fusion.
259 bool hasFusion() const {
260 return hasArithmeticBccFusion() || hasArithmeticCbzFusion() ||
261 hasFuseAES() || hasFuseArithmeticLogic() || hasFuseCCSelect() ||
262 hasFuseAdrpAdd() || hasFuseLiterals();
263 }
264
265 unsigned getMaxInterleaveFactor() const { return MaxInterleaveFactor; }
266 unsigned getVectorInsertExtractBaseCost() const;
267 unsigned getCacheLineSize() const override { return CacheLineSize; }
268 unsigned getPrefetchDistance() const override { return PrefetchDistance; }
269 unsigned getMinPrefetchStride(unsigned NumMemAccesses,
270 unsigned NumStridedMemAccesses,
271 unsigned NumPrefetches,
272 bool HasCall) const override {
273 return MinPrefetchStride;
274 }
275 unsigned getMaxPrefetchIterationsAhead() const override {
277 }
280 }
282
285 }
286
287 unsigned getMaximumJumpTableSize() const { return MaxJumpTableSize; }
288 unsigned getMinimumJumpTableEntries() const {
290 }
291
292 /// CPU has TBI (top byte of addresses is ignored during HW address
293 /// translation) and OS enables it.
295
296 bool isLittleEndian() const { return IsLittle; }
297
298 bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); }
299 bool isTargetIOS() const { return TargetTriple.isiOS(); }
300 bool isTargetLinux() const { return TargetTriple.isOSLinux(); }
301 bool isTargetWindows() const { return TargetTriple.isOSWindows(); }
302 bool isTargetAndroid() const { return TargetTriple.isAndroid(); }
303 bool isTargetFuchsia() const { return TargetTriple.isOSFuchsia(); }
305
306 bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); }
307 bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
309
310 bool isTargetILP32() const {
311 return TargetTriple.isArch32Bit() ||
313 }
314
315 bool useAA() const override;
316
317 bool addrSinkUsingGEPs() const override {
318 // Keeping GEPs inbounds is important for exploiting AArch64
319 // addressing-modes in ILP32 mode.
320 return useAA() || isTargetILP32();
321 }
322
323 bool useSmallAddressing() const {
326 // Kernel is currently allowed only for Fuchsia targets,
327 // where it is the same as Small for almost all purposes.
328 case CodeModel::Small:
329 return true;
330 default:
331 return false;
332 }
333 }
334
335 /// ParseSubtargetFeatures - Parses features string setting specified
336 /// subtarget options. Definition of function is auto generated by tblgen.
338
339 /// ClassifyGlobalReference - Find the target operand flags that describe
340 /// how a global value should be referenced for the current subtarget.
341 unsigned ClassifyGlobalReference(const GlobalValue *GV,
342 const TargetMachine &TM) const;
343
345 const TargetMachine &TM) const;
346
347 /// This function is design to compatible with the function def in other
348 /// targets and escape build error about the virtual function def in base
349 /// class TargetSubtargetInfo. Updeate me if AArch64 target need to use it.
350 unsigned char
352 return 0;
353 }
354
356 unsigned NumRegionInstrs) const override;
357 void adjustSchedDependency(SUnit *Def, int DefOpIdx, SUnit *Use, int UseOpIdx,
358 SDep &Dep,
359 const TargetSchedModel *SchedModel) const override;
360
361 bool enableEarlyIfConversion() const override;
362
363 std::unique_ptr<PBQPRAConstraint> getCustomPBQPConstraints() const override;
364
366 switch (CC) {
367 case CallingConv::C:
371 return isTargetWindows();
373 return true;
374 default:
375 return false;
376 }
377 }
378
379 /// Return whether FrameLowering should always set the "extended frame
380 /// present" bit in FP, or set it based on a symbol in the runtime.
382 // Older OS versions (particularly system unwinders) are confused by the
383 // Swift extended frame, so when building code that might be run on them we
384 // must dynamically query the concurrency library to determine whether
385 // extended frames should be flagged as present.
386 const Triple &TT = getTargetTriple();
387
388 unsigned Major = TT.getOSVersion().getMajor();
389 switch(TT.getOS()) {
390 default:
391 return false;
392 case Triple::IOS:
393 case Triple::TvOS:
394 return Major < 15;
395 case Triple::WatchOS:
396 return Major < 8;
397 case Triple::MacOSX:
398 case Triple::Darwin:
399 return Major < 12;
400 }
401 }
402
403 void mirFileLoaded(MachineFunction &MF) const override;
404
405 bool hasSVEorSME() const { return hasSVE() || hasSME(); }
406 bool hasSVE2orSME() const { return hasSVE2() || hasSME(); }
407
408 // Return the known range for the bit length of SVE data registers. A value
409 // of 0 means nothing is known about that particular limit beyong what's
410 // implied by the architecture.
411 unsigned getMaxSVEVectorSizeInBits() const {
413 "Tried to get SVE vector length without SVE support!");
415 }
416
417 unsigned getMinSVEVectorSizeInBits() const {
419 "Tried to get SVE vector length without SVE support!");
421 }
422
424 if (!isNeonAvailable())
425 return hasSVEorSME();
426
427 // Prefer NEON unless larger SVE registers are available.
428 return hasSVEorSME() && getMinSVEVectorSizeInBits() >= 256;
429 }
430
433 return false;
436 }
437
438 unsigned getVScaleForTuning() const { return VScaleForTuning; }
439
441 return DefaultSVETFOpts;
442 }
443
444 const char* getChkStkName() const {
445 if (isWindowsArm64EC())
446 return "#__chkstk_arm64ec";
447 return "__chkstk";
448 }
449
450 const char* getSecurityCheckCookieName() const {
451 if (isWindowsArm64EC())
452 return "#__security_check_cookie_arm64ec";
453 return "__security_check_cookie";
454 }
455
456 /// Choose a method of checking LR before performing a tail call.
458
460 return AddressCheckPSV.get();
461 }
462
463private:
464 /// Pseudo value representing memory load performed to check an address.
465 ///
466 /// This load operation is solely used for its side-effects: if the address
467 /// is not mapped (or not readable), it triggers CPU exception, otherwise
468 /// execution proceeds and the value is not used.
469 class AddressCheckPseudoSourceValue : public PseudoSourceValue {
470 public:
471 AddressCheckPseudoSourceValue(const TargetMachine &TM)
473
474 bool isConstant(const MachineFrameInfo *) const override { return false; }
475 bool isAliased(const MachineFrameInfo *) const override { return true; }
476 bool mayAlias(const MachineFrameInfo *) const override { return true; }
477 void printCustom(raw_ostream &OS) const override { OS << "AddressCheck"; }
478 };
479
480 std::unique_ptr<AddressCheckPseudoSourceValue> AddressCheckPSV;
481};
482} // End llvm namespace
483
484#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:753
bool isOSBinFormatMachO() const
Tests whether the environment is MachO.
Definition: Triple.h:716
bool isOSBinFormatCOFF() const
Tests whether the OS uses the COFF binary format.
Definition: Triple.h:708
EnvironmentType getEnvironment() const
Get the parsed environment type of this triple.
Definition: Triple.h:378
bool isOSWindows() const
Tests whether the OS is Windows.
Definition: Triple.h:608
bool isOSLinux() const
Tests whether the OS is Linux.
Definition: Triple.h:662
bool isOSDarwin() const
Is this a "Darwin" OS (macOS, iOS, tvOS, watchOS, XROS, or DriverKit).
Definition: Triple.h:542
bool isWindowsArm64EC() const
Definition: Triple.h:624
bool isiOS() const
Is this an iOS triple.
Definition: Triple.h:515
bool isArch32Bit() const
Test whether the architecture is 32-bit.
Definition: Triple.cpp:1542
bool isOSFuchsia() const
Definition: Triple.h:572
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
Definition: Triple.h:703
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.