LLVM 23.0.0git
AArch64FrameLowering.cpp
Go to the documentation of this file.
1//===- AArch64FrameLowering.cpp - AArch64 Frame Lowering -------*- 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 contains the AArch64 implementation of TargetFrameLowering class.
10//
11// On AArch64, stack frames are structured as follows:
12//
13// The stack grows downward.
14//
15// All of the individual frame areas on the frame below are optional, i.e. it's
16// possible to create a function so that the particular area isn't present
17// in the frame.
18//
19// At function entry, the "frame" looks as follows:
20//
21// | | Higher address
22// |-----------------------------------|
23// | |
24// | arguments passed on the stack |
25// | |
26// |-----------------------------------| <- sp
27// | | Lower address
28//
29//
30// After the prologue has run, the frame has the following general structure.
31// Note that this doesn't depict the case where a red-zone is used. Also,
32// technically the last frame area (VLAs) doesn't get created until in the
33// main function body, after the prologue is run. However, it's depicted here
34// for completeness.
35//
36// | | Higher address
37// |-----------------------------------|
38// | |
39// | arguments passed on the stack |
40// | |
41// |-----------------------------------|
42// | |
43// | (Win64 only) varargs from reg |
44// | |
45// |-----------------------------------|
46// | |
47// | (Win64 only) callee-saved SVE reg |
48// | |
49// |-----------------------------------|
50// | |
51// | callee-saved gpr registers | <--.
52// | | | On Darwin platforms these
53// |- - - - - - - - - - - - - - - - - -| | callee saves are swapped,
54// | prev_lr | | (frame record first)
55// | prev_fp | <--'
56// | async context if needed |
57// | (a.k.a. "frame record") |
58// |-----------------------------------| <- fp(=x29)
59// Default SVE stack layout Split SVE objects
60// (aarch64-split-sve-objects=false) (aarch64-split-sve-objects=true)
61// |-----------------------------------| |-----------------------------------|
62// | <hazard padding> | | callee-saved PPR registers |
63// |-----------------------------------| |-----------------------------------|
64// | | | PPR stack objects |
65// | callee-saved fp/simd/SVE regs | |-----------------------------------|
66// | | | <hazard padding> |
67// |-----------------------------------| |-----------------------------------|
68// | | | callee-saved ZPR/FPR registers |
69// | SVE stack objects | |-----------------------------------|
70// | | | ZPR stack objects |
71// |-----------------------------------| |-----------------------------------|
72// ^ NB: FPR CSRs are promoted to ZPRs
73// |-----------------------------------|
74// |.empty.space.to.make.part.below....|
75// |.aligned.in.case.it.needs.more.than| (size of this area is unknown at
76// |.the.standard.16-byte.alignment....| compile time; if present)
77// |-----------------------------------|
78// | local variables of fixed size |
79// | including spill slots |
80// | <FPR> |
81// | <hazard padding> |
82// | <GPR> |
83// |-----------------------------------| <- bp(not defined by ABI,
84// |.variable-sized.local.variables....| LLVM chooses X19)
85// |.(VLAs)............................| (size of this area is unknown at
86// |...................................| compile time)
87// |-----------------------------------| <- sp
88// | | Lower address
89//
90//
91// To access the data in a frame, at-compile time, a constant offset must be
92// computable from one of the pointers (fp, bp, sp) to access it. The size
93// of the areas with a dotted background cannot be computed at compile-time
94// if they are present, making it required to have all three of fp, bp and
95// sp to be set up to be able to access all contents in the frame areas,
96// assuming all of the frame areas are non-empty.
97//
98// For most functions, some of the frame areas are empty. For those functions,
99// it may not be necessary to set up fp or bp:
100// * A base pointer is definitely needed when there are both VLAs and local
101// variables with more-than-default alignment requirements.
102// * A frame pointer is definitely needed when there are local variables with
103// more-than-default alignment requirements.
104//
105// For Darwin platforms the frame-record (fp, lr) is stored at the top of the
106// callee-saved area, since the unwind encoding does not allow for encoding
107// this dynamically and existing tools depend on this layout. For other
108// platforms, the frame-record is stored at the bottom of the (gpr) callee-saved
109// area to allow SVE stack objects (allocated directly below the callee-saves,
110// if available) to be accessed directly from the framepointer.
111// The SVE spill/fill instructions have VL-scaled addressing modes such
112// as:
113// ldr z8, [fp, #-7 mul vl]
114// For SVE the size of the vector length (VL) is not known at compile-time, so
115// '#-7 mul vl' is an offset that can only be evaluated at runtime. With this
116// layout, we don't need to add an unscaled offset to the framepointer before
117// accessing the SVE object in the frame.
118//
119// In some cases when a base pointer is not strictly needed, it is generated
120// anyway when offsets from the frame pointer to access local variables become
121// so large that the offset can't be encoded in the immediate fields of loads
122// or stores.
123//
124// Outgoing function arguments must be at the bottom of the stack frame when
125// calling another function. If we do not have variable-sized stack objects, we
126// can allocate a "reserved call frame" area at the bottom of the local
127// variable area, large enough for all outgoing calls. If we do have VLAs, then
128// the stack pointer must be decremented and incremented around each call to
129// make space for the arguments below the VLAs.
130//
131// FIXME: also explain the redzone concept.
132//
133// About stack hazards: Under some SME contexts, a coprocessor with its own
134// separate cache can used for FP operations. This can create hazards if the CPU
135// and the SME unit try to access the same area of memory, including if the
136// access is to an area of the stack. To try to alleviate this we attempt to
137// introduce extra padding into the stack frame between FP and GPR accesses,
138// controlled by the aarch64-stack-hazard-size option. Without changing the
139// layout of the stack frame in the diagram above, a stack object of size
140// aarch64-stack-hazard-size is added between GPR and FPR CSRs. Another is added
141// to the stack objects section, and stack objects are sorted so that FPR >
142// Hazard padding slot > GPRs (where possible). Unfortunately some things are
143// not handled well (VLA area, arguments on the stack, objects with both GPR and
144// FPR accesses), but if those are controlled by the user then the entire stack
145// frame becomes GPR at the start/end with FPR in the middle, surrounded by
146// Hazard padding.
147//
148// An example of the prologue:
149//
150// .globl __foo
151// .align 2
152// __foo:
153// Ltmp0:
154// .cfi_startproc
155// .cfi_personality 155, ___gxx_personality_v0
156// Leh_func_begin:
157// .cfi_lsda 16, Lexception33
158//
159// stp xa,bx, [sp, -#offset]!
160// ...
161// stp x28, x27, [sp, #offset-32]
162// stp fp, lr, [sp, #offset-16]
163// add fp, sp, #offset - 16
164// sub sp, sp, #1360
165//
166// The Stack:
167// +-------------------------------------------+
168// 10000 | ........ | ........ | ........ | ........ |
169// 10004 | ........ | ........ | ........ | ........ |
170// +-------------------------------------------+
171// 10008 | ........ | ........ | ........ | ........ |
172// 1000c | ........ | ........ | ........ | ........ |
173// +===========================================+
174// 10010 | X28 Register |
175// 10014 | X28 Register |
176// +-------------------------------------------+
177// 10018 | X27 Register |
178// 1001c | X27 Register |
179// +===========================================+
180// 10020 | Frame Pointer |
181// 10024 | Frame Pointer |
182// +-------------------------------------------+
183// 10028 | Link Register |
184// 1002c | Link Register |
185// +===========================================+
186// 10030 | ........ | ........ | ........ | ........ |
187// 10034 | ........ | ........ | ........ | ........ |
188// +-------------------------------------------+
189// 10038 | ........ | ........ | ........ | ........ |
190// 1003c | ........ | ........ | ........ | ........ |
191// +-------------------------------------------+
192//
193// [sp] = 10030 :: >>initial value<<
194// sp = 10020 :: stp fp, lr, [sp, #-16]!
195// fp = sp == 10020 :: mov fp, sp
196// [sp] == 10020 :: stp x28, x27, [sp, #-16]!
197// sp == 10010 :: >>final value<<
198//
199// The frame pointer (w29) points to address 10020. If we use an offset of
200// '16' from 'w29', we get the CFI offsets of -8 for w30, -16 for w29, -24
201// for w27, and -32 for w28:
202//
203// Ltmp1:
204// .cfi_def_cfa w29, 16
205// Ltmp2:
206// .cfi_offset w30, -8
207// Ltmp3:
208// .cfi_offset w29, -16
209// Ltmp4:
210// .cfi_offset w27, -24
211// Ltmp5:
212// .cfi_offset w28, -32
213//
214//===----------------------------------------------------------------------===//
215
216#include "AArch64FrameLowering.h"
217#include "AArch64InstrInfo.h"
220#include "AArch64RegisterInfo.h"
221#include "AArch64SMEAttributes.h"
222#include "AArch64Subtarget.h"
225#include "llvm/ADT/ScopeExit.h"
226#include "llvm/ADT/SmallVector.h"
244#include "llvm/IR/Attributes.h"
245#include "llvm/IR/CallingConv.h"
246#include "llvm/IR/DataLayout.h"
247#include "llvm/IR/DebugLoc.h"
248#include "llvm/IR/Function.h"
249#include "llvm/MC/MCAsmInfo.h"
250#include "llvm/MC/MCDwarf.h"
252#include "llvm/Support/Debug.h"
259#include <cassert>
260#include <cstdint>
261#include <iterator>
262#include <optional>
263#include <vector>
264
265using namespace llvm;
266
267#define DEBUG_TYPE "frame-info"
268
269static cl::opt<bool> EnableRedZone("aarch64-redzone",
270 cl::desc("enable use of redzone on AArch64"),
271 cl::init(false), cl::Hidden);
272
274 "stack-tagging-merge-settag",
275 cl::desc("merge settag instruction in function epilog"), cl::init(true),
276 cl::Hidden);
277
278static cl::opt<bool> OrderFrameObjects("aarch64-order-frame-objects",
279 cl::desc("sort stack allocations"),
280 cl::init(true), cl::Hidden);
281
282static cl::opt<bool>
283 SplitSVEObjects("aarch64-split-sve-objects",
284 cl::desc("Split allocation of ZPR & PPR objects"),
285 cl::init(true), cl::Hidden);
286
288 "homogeneous-prolog-epilog", cl::Hidden,
289 cl::desc("Emit homogeneous prologue and epilogue for the size "
290 "optimization (default = off)"));
291
292// Stack hazard size for analysis remarks. StackHazardSize takes precedence.
294 StackHazardRemarkSize("aarch64-stack-hazard-remark-size", cl::init(0),
295 cl::Hidden);
296// Whether to insert padding into non-streaming functions (for testing).
297static cl::opt<bool>
298 StackHazardInNonStreaming("aarch64-stack-hazard-in-non-streaming",
299 cl::init(false), cl::Hidden);
300
302 "aarch64-disable-multivector-spill-fill",
303 cl::desc("Disable use of LD/ST pairs for SME2 or SVE2p1"), cl::init(false),
304 cl::Hidden);
305
306int64_t
308 MachineBasicBlock &MBB) const {
309 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
311 bool IsTailCallReturn = (MBB.end() != MBBI)
313 : false;
314
315 int64_t ArgumentPopSize = 0;
316 if (IsTailCallReturn) {
317 MachineOperand &StackAdjust = MBBI->getOperand(1);
318
319 // For a tail-call in a callee-pops-arguments environment, some or all of
320 // the stack may actually be in use for the call's arguments, this is
321 // calculated during LowerCall and consumed here...
322 ArgumentPopSize = StackAdjust.getImm();
323 } else {
324 // ... otherwise the amount to pop is *all* of the argument space,
325 // conveniently stored in the MachineFunctionInfo by
326 // LowerFormalArguments. This will, of course, be zero for the C calling
327 // convention.
328 ArgumentPopSize = AFI->getArgumentStackToRestore();
329 }
330
331 return ArgumentPopSize;
332}
333
335 MachineFunction &MF);
336
337enum class AssignObjectOffsets { No, Yes };
338/// Process all the SVE stack objects and the SVE stack size and offsets for
339/// each object. If AssignOffsets is "Yes", the offsets get assigned (and SVE
340/// stack sizes set). Returns the size of the SVE stack.
342 AssignObjectOffsets AssignOffsets);
343
344static unsigned getStackHazardSize(const MachineFunction &MF) {
345 return MF.getSubtarget<AArch64Subtarget>().getStreamingHazardSize();
346}
347
353
356 // With split SVE objects, the hazard padding is added to the PPR region,
357 // which places it between the [GPR, PPR] area and the [ZPR, FPR] area. This
358 // avoids hazards between both GPRs and FPRs and ZPRs and PPRs.
361 : 0,
362 AFI->getStackSizePPR());
363}
364
365// Conservatively, returns true if the function is likely to have SVE vectors
366// on the stack. This function is safe to be called before callee-saves or
367// object offsets have been determined.
369 const MachineFunction &MF) {
370 auto *AFI = MF.getInfo<AArch64FunctionInfo>();
371 if (AFI->isSVECC())
372 return true;
373
374 if (AFI->hasCalculatedStackSizeSVE())
375 return bool(AFL.getSVEStackSize(MF));
376
377 const MachineFrameInfo &MFI = MF.getFrameInfo();
378 for (int FI = MFI.getObjectIndexBegin(); FI < MFI.getObjectIndexEnd(); FI++) {
379 if (MFI.hasScalableStackID(FI))
380 return true;
381 }
382
383 return false;
384}
385
386static bool isTargetWindows(const MachineFunction &MF) {
387 // TODO: Should this include targets like UEFI (which use Windows CFI)?
388 // Note: Currently, there is not AArch64 support for UEFI. The value returned
389 // here must align with the predicate used for returning the list of callee
390 // saved regs in AArch64RegisterInfo::getCalleeSavedRegs(), so that we use
391 // invalidateWindowsRegisterPairing() where appropriate.
393}
394
396 const MachineFunction &MF) const {
397 auto *AFI = MF.getInfo<AArch64FunctionInfo>();
398 return isTargetWindows(MF) && AFI->getSVECalleeSavedStackSize();
399}
400
401/// Returns true if a homogeneous prolog or epilog code can be emitted
402/// for the size optimization. If possible, a frame helper call is injected.
403/// When Exit block is given, this check is for epilog.
404bool AArch64FrameLowering::homogeneousPrologEpilog(
405 MachineFunction &MF, MachineBasicBlock *Exit) const {
406 if (!MF.getFunction().hasMinSize())
407 return false;
409 return false;
410 if (EnableRedZone)
411 return false;
412
413 // TODO: Window is supported yet.
414 if (isTargetWindows(MF))
415 return false;
416
417 // TODO: SVE is not supported yet.
418 if (isLikelyToHaveSVEStack(*this, MF))
419 return false;
420
421 // Bail on stack adjustment needed on return for simplicity.
422 const MachineFrameInfo &MFI = MF.getFrameInfo();
423 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
424 if (MFI.hasVarSizedObjects() || RegInfo->hasStackRealignment(MF))
425 return false;
426 if (Exit && getArgumentStackToRestore(MF, *Exit))
427 return false;
428
429 auto *AFI = MF.getInfo<AArch64FunctionInfo>();
430 if (AFI->hasSwiftAsyncContext() || AFI->hasStreamingModeChanges())
431 return false;
432
433 // If there are an odd number of GPRs before LR and FP in the CSRs list,
434 // they will not be paired into one RegPairInfo, which is incompatible with
435 // the assumption made by the homogeneous prolog epilog pass.
436 const MCPhysReg *CSRegs = MF.getRegInfo().getCalleeSavedRegs();
437 unsigned NumGPRs = 0;
438 for (unsigned I = 0; CSRegs[I]; ++I) {
439 Register Reg = CSRegs[I];
440 if (Reg == AArch64::LR) {
441 assert(CSRegs[I + 1] == AArch64::FP);
442 if (NumGPRs % 2 != 0)
443 return false;
444 break;
445 }
446 if (AArch64::GPR64RegClass.contains(Reg))
447 ++NumGPRs;
448 }
449
450 return true;
451}
452
453/// Returns true if CSRs should be paired.
454bool AArch64FrameLowering::producePairRegisters(MachineFunction &MF) const {
455 return produceCompactUnwindFrame(*this, MF) || homogeneousPrologEpilog(MF);
456}
457
458/// This is the biggest offset to the stack pointer we can encode in aarch64
459/// instructions (without using a separate calculation and a temp register).
460/// Note that the exception here are vector stores/loads which cannot encode any
461/// displacements (see estimateRSStackSizeLimit(), isAArch64FrameOffsetLegal()).
462static const unsigned DefaultSafeSPDisplacement = 255;
463
464/// Look at each instruction that references stack frames and return the stack
465/// size limit beyond which some of these instructions will require a scratch
466/// register during their expansion later.
468 // FIXME: For now, just conservatively guesstimate based on unscaled indexing
469 // range. We'll end up allocating an unnecessary spill slot a lot, but
470 // realistically that's not a big deal at this stage of the game.
471 for (MachineBasicBlock &MBB : MF) {
472 for (MachineInstr &MI : MBB) {
473 if (MI.isDebugInstr() || MI.isPseudo() ||
474 MI.getOpcode() == AArch64::ADDXri ||
475 MI.getOpcode() == AArch64::ADDSXri)
476 continue;
477
478 for (const MachineOperand &MO : MI.operands()) {
479 if (!MO.isFI())
480 continue;
481
483 if (isAArch64FrameOffsetLegal(MI, Offset, nullptr, nullptr, nullptr) ==
485 return 0;
486 }
487 }
488 }
490}
491
496
497unsigned
498AArch64FrameLowering::getFixedObjectSize(const MachineFunction &MF,
499 const AArch64FunctionInfo *AFI,
500 bool IsWin64, bool IsFunclet) const {
501 assert(AFI->getTailCallReservedStack() % 16 == 0 &&
502 "Tail call reserved stack must be aligned to 16 bytes");
503 if (!IsWin64 || IsFunclet) {
504 return AFI->getTailCallReservedStack();
505 } else {
506 if (AFI->getTailCallReservedStack() != 0 &&
507 !MF.getFunction().getAttributes().hasAttrSomewhere(
508 Attribute::SwiftAsync))
509 report_fatal_error("cannot generate ABI-changing tail call for Win64");
510 unsigned FixedObjectSize = AFI->getTailCallReservedStack();
511
512 // Var args are stored here in the primary function.
513 FixedObjectSize += AFI->getVarArgsGPRSize();
514
515 if (MF.hasEHFunclets()) {
516 // Catch objects are stored here in the primary function.
517 const MachineFrameInfo &MFI = MF.getFrameInfo();
518 const WinEHFuncInfo &EHInfo = *MF.getWinEHFuncInfo();
519 SmallSetVector<int, 8> CatchObjFrameIndices;
520 for (const WinEHTryBlockMapEntry &TBME : EHInfo.TryBlockMap) {
521 for (const WinEHHandlerType &H : TBME.HandlerArray) {
522 int FrameIndex = H.CatchObj.FrameIndex;
523 if ((FrameIndex != INT_MAX) &&
524 CatchObjFrameIndices.insert(FrameIndex)) {
525 FixedObjectSize = alignTo(FixedObjectSize,
526 MFI.getObjectAlign(FrameIndex).value()) +
527 MFI.getObjectSize(FrameIndex);
528 }
529 }
530 }
531 // To support EH funclets we allocate an UnwindHelp object
532 FixedObjectSize += 8;
533 }
534 return alignTo(FixedObjectSize, 16);
535 }
536}
537
539 if (!EnableRedZone)
540 return false;
541
542 // Don't use the red zone if the function explicitly asks us not to.
543 // This is typically used for kernel code.
544 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
545 const unsigned RedZoneSize =
547 if (!RedZoneSize)
548 return false;
549
550 const MachineFrameInfo &MFI = MF.getFrameInfo();
552 uint64_t NumBytes = AFI->getLocalStackSize();
553
554 // If neither NEON or SVE are available, a COPY from one Q-reg to
555 // another requires a spill -> reload sequence. We can do that
556 // using a pre-decrementing store/post-decrementing load, but
557 // if we do so, we can't use the Red Zone.
558 bool LowerQRegCopyThroughMem = Subtarget.hasFPARMv8() &&
559 !Subtarget.isNeonAvailable() &&
560 !Subtarget.hasSVE();
561
562 return !(MFI.hasCalls() || hasFP(MF) || NumBytes > RedZoneSize ||
563 AFI->hasSVEStackSize() || LowerQRegCopyThroughMem);
564}
565
566/// hasFPImpl - Return true if the specified function should have a dedicated
567/// frame pointer register.
569 const MachineFrameInfo &MFI = MF.getFrameInfo();
570 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
572
573 // Win64 EH requires a frame pointer if funclets are present, as the locals
574 // are accessed off the frame pointer in both the parent function and the
575 // funclets.
576 if (MF.hasEHFunclets())
577 return true;
578
579 // When the stack guard is mixed with the frame pointer, a dedicated FP is
580 // required so the guard value remains stable in the presence of dynamic
581 // stack allocations (e.g. _alloca on MSVCRT).
582 if (MFI.hasStackProtectorIndex()) {
583 const auto &Subtarget = MF.getSubtarget<AArch64Subtarget>();
584 if (Subtarget.getTargetLowering()->useStackGuardMixFP())
585 return true;
586 }
587
588 // Retain behavior of always omitting the FP for leaf functions when possible.
590 return true;
591 if (MFI.hasVarSizedObjects() || MFI.isFrameAddressTaken() ||
592 MFI.hasStackMap() || MFI.hasPatchPoint() ||
593 RegInfo->hasStackRealignment(MF))
594 return true;
595
596 // If we:
597 //
598 // 1. Have streaming mode changes
599 // OR:
600 // 2. Have a streaming body with SVE stack objects
601 //
602 // Then the value of VG restored when unwinding to this function may not match
603 // the value of VG used to set up the stack.
604 //
605 // This is a problem as the CFA can be described with an expression of the
606 // form: CFA = SP + NumBytes + VG * NumScalableBytes.
607 //
608 // If the value of VG used in that expression does not match the value used to
609 // set up the stack, an incorrect address for the CFA will be computed, and
610 // unwinding will fail.
611 //
612 // We work around this issue by ensuring the frame-pointer can describe the
613 // CFA in either of these cases.
614 if (AFI.needsDwarfUnwindInfo(MF) &&
617 return true;
618 // With large callframes around we may need to use FP to access the scavenging
619 // emergency spillslot.
620 //
621 // Unfortunately some calls to hasFP() like machine verifier ->
622 // getReservedReg() -> hasFP in the middle of global isel are too early
623 // to know the max call frame size. Hopefully conservatively returning "true"
624 // in those cases is fine.
625 // DefaultSafeSPDisplacement is fine as we only emergency spill GP regs.
626 if (!MFI.isMaxCallFrameSizeComputed() ||
628 return true;
629
630 return false;
631}
632
633/// Should the Frame Pointer be reserved for the current function?
635 const TargetMachine &TM = MF.getTarget();
636 const Triple &TT = TM.getTargetTriple();
637
638 // These OSes require the frame chain is valid, even if the current frame does
639 // not use a frame pointer.
640 if (TT.isOSDarwin() || TT.isOSWindows())
641 return true;
642
643 // If the function has a frame pointer, it is reserved.
644 if (hasFP(MF))
645 return true;
646
647 // Frontend has requested to preserve the frame pointer.
649 return true;
650
651 return false;
652}
653
654/// hasReservedCallFrame - Under normal circumstances, when a frame pointer is
655/// not required, we reserve argument space for call sites in the function
656/// immediately on entry to the current function. This eliminates the need for
657/// add/sub sp brackets around call sites. Returns true if the call frame is
658/// included as part of the stack frame.
660 const MachineFunction &MF) const {
661 // The stack probing code for the dynamically allocated outgoing arguments
662 // area assumes that the stack is probed at the top - either by the prologue
663 // code, which issues a probe if `hasVarSizedObjects` return true, or by the
664 // most recent variable-sized object allocation. Changing the condition here
665 // may need to be followed up by changes to the probe issuing logic.
666 return !MF.getFrameInfo().hasVarSizedObjects();
667}
668
672
673 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
674 const AArch64InstrInfo *TII = Subtarget.getInstrInfo();
675 const AArch64TargetLowering *TLI = Subtarget.getTargetLowering();
676 [[maybe_unused]] MachineFrameInfo &MFI = MF.getFrameInfo();
677 DebugLoc DL = I->getDebugLoc();
678 unsigned Opc = I->getOpcode();
679 bool IsDestroy = Opc == TII->getCallFrameDestroyOpcode();
680 uint64_t CalleePopAmount = IsDestroy ? I->getOperand(1).getImm() : 0;
681
682 if (!hasReservedCallFrame(MF)) {
683 int64_t Amount = I->getOperand(0).getImm();
684 Amount = alignTo(Amount, getStackAlign());
685 if (!IsDestroy)
686 Amount = -Amount;
687
688 // N.b. if CalleePopAmount is valid but zero (i.e. callee would pop, but it
689 // doesn't have to pop anything), then the first operand will be zero too so
690 // this adjustment is a no-op.
691 if (CalleePopAmount == 0) {
692 // FIXME: in-function stack adjustment for calls is limited to 24-bits
693 // because there's no guaranteed temporary register available.
694 //
695 // ADD/SUB (immediate) has only LSL #0 and LSL #12 available.
696 // 1) For offset <= 12-bit, we use LSL #0
697 // 2) For 12-bit <= offset <= 24-bit, we use two instructions. One uses
698 // LSL #0, and the other uses LSL #12.
699 //
700 // Most call frames will be allocated at the start of a function so
701 // this is OK, but it is a limitation that needs dealing with.
702 assert(Amount > -0xffffff && Amount < 0xffffff && "call frame too large");
703
704 if (TLI->hasInlineStackProbe(MF) &&
706 // When stack probing is enabled, the decrement of SP may need to be
707 // probed. We only need to do this if the call site needs 1024 bytes of
708 // space or more, because a region smaller than that is allowed to be
709 // unprobed at an ABI boundary. We rely on the fact that SP has been
710 // probed exactly at this point, either by the prologue or most recent
711 // dynamic allocation.
713 "non-reserved call frame without var sized objects?");
714 Register ScratchReg =
715 MF.getRegInfo().createVirtualRegister(&AArch64::GPR64RegClass);
716 inlineStackProbeFixed(I, ScratchReg, -Amount, StackOffset::get(0, 0));
717 } else {
718 emitFrameOffset(MBB, I, DL, AArch64::SP, AArch64::SP,
719 StackOffset::getFixed(Amount), TII);
720 }
721 }
722 } else if (CalleePopAmount != 0) {
723 // If the calling convention demands that the callee pops arguments from the
724 // stack, we want to add it back if we have a reserved call frame.
725 assert(CalleePopAmount < 0xffffff && "call frame too large");
726 emitFrameOffset(MBB, I, DL, AArch64::SP, AArch64::SP,
727 StackOffset::getFixed(-(int64_t)CalleePopAmount), TII);
728 }
729 return MBB.erase(I);
730}
731
733 MachineBasicBlock &MBB) const {
734
735 MachineFunction &MF = *MBB.getParent();
736 const auto &Subtarget = MF.getSubtarget<AArch64Subtarget>();
737 const auto &TRI = *Subtarget.getRegisterInfo();
738 const auto &MFI = *MF.getInfo<AArch64FunctionInfo>();
739
740 CFIInstBuilder CFIBuilder(MBB, MBB.begin(), MachineInstr::NoFlags);
741
742 // Reset the CFA to `SP + 0`.
743 CFIBuilder.buildDefCFA(AArch64::SP, 0);
744
745 // Flip the RA sign state.
746 if (MFI.shouldSignReturnAddress(MF)) {
747 if (MFI.branchProtectionPAuthLR()) {
748 CFIBuilder.buildNegateRAStateWithPC();
749 } else if (!MF.getTarget().getTargetTriple().isOSBinFormatMachO()) {
750 CFIBuilder.buildNegateRAState();
751 }
752 }
753
754 // Shadow call stack uses X18, reset it.
755 if (MFI.needsShadowCallStackPrologueEpilogue(MF))
756 CFIBuilder.buildSameValue(AArch64::X18);
757
758 // Emit .cfi_same_value for callee-saved registers.
759 const std::vector<CalleeSavedInfo> &CSI =
761 for (const auto &Info : CSI) {
762 MCRegister Reg = Info.getReg();
763 if (!TRI.regNeedsCFI(Reg, Reg))
764 continue;
765 CFIBuilder.buildSameValue(Reg);
766 }
767}
768
770 switch (Reg.id()) {
771 default:
772 // The called routine is expected to preserve r19-r28
773 // r29 and r30 are used as frame pointer and link register resp.
774 return 0;
775
776 // GPRs
777#define CASE(n) \
778 case AArch64::W##n: \
779 case AArch64::X##n: \
780 return AArch64::X##n
781 CASE(0);
782 CASE(1);
783 CASE(2);
784 CASE(3);
785 CASE(4);
786 CASE(5);
787 CASE(6);
788 CASE(7);
789 CASE(8);
790 CASE(9);
791 CASE(10);
792 CASE(11);
793 CASE(12);
794 CASE(13);
795 CASE(14);
796 CASE(15);
797 CASE(16);
798 CASE(17);
799 CASE(18);
800#undef CASE
801
802 // FPRs
803#define CASE(n) \
804 case AArch64::B##n: \
805 case AArch64::H##n: \
806 case AArch64::S##n: \
807 case AArch64::D##n: \
808 case AArch64::Q##n: \
809 return HasSVE ? AArch64::Z##n : AArch64::Q##n
810 CASE(0);
811 CASE(1);
812 CASE(2);
813 CASE(3);
814 CASE(4);
815 CASE(5);
816 CASE(6);
817 CASE(7);
818 CASE(8);
819 CASE(9);
820 CASE(10);
821 CASE(11);
822 CASE(12);
823 CASE(13);
824 CASE(14);
825 CASE(15);
826 CASE(16);
827 CASE(17);
828 CASE(18);
829 CASE(19);
830 CASE(20);
831 CASE(21);
832 CASE(22);
833 CASE(23);
834 CASE(24);
835 CASE(25);
836 CASE(26);
837 CASE(27);
838 CASE(28);
839 CASE(29);
840 CASE(30);
841 CASE(31);
842#undef CASE
843 }
844}
845
846void AArch64FrameLowering::emitZeroCallUsedRegs(BitVector RegsToZero,
847 MachineBasicBlock &MBB) const {
848 // Insertion point.
850
851 // Fake a debug loc.
852 DebugLoc DL;
853 if (MBBI != MBB.end())
854 DL = MBBI->getDebugLoc();
855
856 const MachineFunction &MF = *MBB.getParent();
857 const AArch64Subtarget &STI = MF.getSubtarget<AArch64Subtarget>();
858 const AArch64RegisterInfo &TRI = *STI.getRegisterInfo();
859
860 BitVector GPRsToZero(TRI.getNumRegs());
861 BitVector FPRsToZero(TRI.getNumRegs());
862 bool HasSVE = STI.isSVEorStreamingSVEAvailable();
863 for (MCRegister Reg : RegsToZero.set_bits()) {
864 if (TRI.isGeneralPurposeRegister(MF, Reg)) {
865 // For GPRs, we only care to clear out the 64-bit register.
866 if (MCRegister XReg = getRegisterOrZero(Reg, HasSVE))
867 GPRsToZero.set(XReg);
868 } else if (AArch64InstrInfo::isFpOrNEON(Reg)) {
869 // For FPRs,
870 if (MCRegister XReg = getRegisterOrZero(Reg, HasSVE))
871 FPRsToZero.set(XReg);
872 }
873 }
874
875 const AArch64InstrInfo &TII = *STI.getInstrInfo();
876
877 // Zero out GPRs.
878 for (MCRegister Reg : GPRsToZero.set_bits())
879 TII.buildClearRegister(Reg, MBB, MBBI, DL);
880
881 // Zero out FP/vector registers.
882 for (MCRegister Reg : FPRsToZero.set_bits())
883 TII.buildClearRegister(Reg, MBB, MBBI, DL);
884
885 if (HasSVE) {
886 for (MCRegister PReg :
887 {AArch64::P0, AArch64::P1, AArch64::P2, AArch64::P3, AArch64::P4,
888 AArch64::P5, AArch64::P6, AArch64::P7, AArch64::P8, AArch64::P9,
889 AArch64::P10, AArch64::P11, AArch64::P12, AArch64::P13, AArch64::P14,
890 AArch64::P15}) {
891 if (RegsToZero[PReg])
892 BuildMI(MBB, MBBI, DL, TII.get(AArch64::PFALSE), PReg);
893 }
894 }
895}
896
897bool AArch64FrameLowering::windowsRequiresStackProbe(
898 const MachineFunction &MF, uint64_t StackSizeInBytes) const {
899 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
900 const AArch64FunctionInfo &MFI = *MF.getInfo<AArch64FunctionInfo>();
901 // TODO: When implementing stack protectors, take that into account
902 // for the probe threshold.
903 return Subtarget.isTargetWindows() && MFI.hasStackProbing() &&
904 StackSizeInBytes >= uint64_t(MFI.getStackProbeSize());
905}
906
908 const MachineBasicBlock &MBB) {
909 const MachineFunction *MF = MBB.getParent();
910 LiveRegs.addLiveIns(MBB);
911 // Mark callee saved registers as used so we will not choose them.
912 const MCPhysReg *CSRegs = MF->getRegInfo().getCalleeSavedRegs();
913 for (unsigned i = 0; CSRegs[i]; ++i)
914 LiveRegs.addReg(CSRegs[i]);
915}
916
918AArch64FrameLowering::findScratchNonCalleeSaveRegister(MachineBasicBlock *MBB,
919 bool HasCall) const {
920 MachineFunction *MF = MBB->getParent();
921
922 // If MBB is an entry block, use X9 as the scratch register
923 // preserve_none functions may be using X9 to pass arguments,
924 // so prefer to pick an available register below.
925 if (&MF->front() == MBB &&
927 return AArch64::X9;
928
929 const AArch64Subtarget &Subtarget = MF->getSubtarget<AArch64Subtarget>();
930 const AArch64RegisterInfo &TRI = *Subtarget.getRegisterInfo();
931 LivePhysRegs LiveRegs(TRI);
932 getLiveRegsForEntryMBB(LiveRegs, *MBB);
933 if (HasCall) {
934 LiveRegs.addReg(AArch64::X16);
935 LiveRegs.addReg(AArch64::X17);
936 LiveRegs.addReg(AArch64::X18);
937 }
938
939 // Prefer X9 since it was historically used for the prologue scratch reg.
940 const MachineRegisterInfo &MRI = MF->getRegInfo();
941 if (LiveRegs.available(MRI, AArch64::X9))
942 return AArch64::X9;
943
944 for (unsigned Reg : AArch64::GPR64RegClass) {
945 if (LiveRegs.available(MRI, Reg))
946 return Reg;
947 }
948 return AArch64::NoRegister;
949}
950
952 const MachineBasicBlock &MBB) const {
953 const MachineFunction *MF = MBB.getParent();
954 MachineBasicBlock *TmpMBB = const_cast<MachineBasicBlock *>(&MBB);
955 const AArch64Subtarget &Subtarget = MF->getSubtarget<AArch64Subtarget>();
956 const AArch64RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
957 const AArch64TargetLowering *TLI = Subtarget.getTargetLowering();
959
960 if (AFI->hasSwiftAsyncContext()) {
961 const AArch64RegisterInfo &TRI = *Subtarget.getRegisterInfo();
962 const MachineRegisterInfo &MRI = MF->getRegInfo();
965 // The StoreSwiftAsyncContext clobbers X16 and X17. Make sure they are
966 // available.
967 if (!LiveRegs.available(MRI, AArch64::X16) ||
968 !LiveRegs.available(MRI, AArch64::X17))
969 return false;
970 }
971
972 // Certain stack probing sequences might clobber flags, then we can't use
973 // the block as a prologue if the flags register is a live-in.
975 MBB.isLiveIn(AArch64::NZCV))
976 return false;
977
978 if (RegInfo->hasStackRealignment(*MF) || TLI->hasInlineStackProbe(*MF))
979 if (findScratchNonCalleeSaveRegister(TmpMBB) == AArch64::NoRegister)
980 return false;
981
982 // May need a scratch register (for return value) if require making a special
983 // call
984 if (requiresSaveVG(*MF) ||
985 windowsRequiresStackProbe(*MF, std::numeric_limits<uint64_t>::max()))
986 if (findScratchNonCalleeSaveRegister(TmpMBB, true) == AArch64::NoRegister)
987 return false;
988
989 return true;
990}
991
993 const Function &F = MF.getFunction();
994 return MF.getTarget().getMCAsmInfo().usesWindowsCFI() &&
995 F.needsUnwindTableEntry();
996}
997
998bool AArch64FrameLowering::shouldSignReturnAddressEverywhere(
999 const MachineFunction &MF) const {
1000 // FIXME: With WinCFI, extra care should be taken to place SEH_PACSignLR
1001 // and SEH_EpilogEnd instructions in the correct order.
1003 return false;
1006}
1007
1008// Given a load or a store instruction, generate an appropriate unwinding SEH
1009// code on Windows.
1011AArch64FrameLowering::insertSEH(MachineBasicBlock::iterator MBBI,
1012 const AArch64InstrInfo &TII,
1013 MachineInstr::MIFlag Flag) const {
1014 unsigned Opc = MBBI->getOpcode();
1015 MachineBasicBlock *MBB = MBBI->getParent();
1016 MachineFunction &MF = *MBB->getParent();
1017 DebugLoc DL = MBBI->getDebugLoc();
1018 unsigned ImmIdx = MBBI->getNumOperands() - 1;
1019 int Imm = MBBI->getOperand(ImmIdx).getImm();
1021 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
1022 const AArch64RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
1023
1024 switch (Opc) {
1025 default:
1026 report_fatal_error("No SEH Opcode for this instruction");
1027 case AArch64::STR_ZXI:
1028 case AArch64::LDR_ZXI: {
1029 unsigned Reg0 = RegInfo->getSEHRegNum(MBBI->getOperand(0).getReg());
1030 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveZReg))
1031 .addImm(Reg0)
1032 .addImm(Imm)
1033 .setMIFlag(Flag);
1034 break;
1035 }
1036 case AArch64::STR_PXI:
1037 case AArch64::LDR_PXI: {
1038 unsigned Reg0 = RegInfo->getSEHRegNum(MBBI->getOperand(0).getReg());
1039 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SavePReg))
1040 .addImm(Reg0)
1041 .addImm(Imm)
1042 .setMIFlag(Flag);
1043 break;
1044 }
1045 case AArch64::LDPDpost:
1046 Imm = -Imm;
1047 [[fallthrough]];
1048 case AArch64::STPDpre: {
1049 unsigned Reg0 = RegInfo->getSEHRegNum(MBBI->getOperand(1).getReg());
1050 unsigned Reg1 = RegInfo->getSEHRegNum(MBBI->getOperand(2).getReg());
1051 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveFRegP_X))
1052 .addImm(Reg0)
1053 .addImm(Reg1)
1054 .addImm(Imm * 8)
1055 .setMIFlag(Flag);
1056 break;
1057 }
1058 case AArch64::LDPXpost:
1059 Imm = -Imm;
1060 [[fallthrough]];
1061 case AArch64::STPXpre: {
1062 Register Reg0 = MBBI->getOperand(1).getReg();
1063 Register Reg1 = MBBI->getOperand(2).getReg();
1064 if (Reg0 == AArch64::FP && Reg1 == AArch64::LR)
1065 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveFPLR_X))
1066 .addImm(Imm * 8)
1067 .setMIFlag(Flag);
1068 else
1069 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveRegP_X))
1070 .addImm(RegInfo->getSEHRegNum(Reg0))
1071 .addImm(RegInfo->getSEHRegNum(Reg1))
1072 .addImm(Imm * 8)
1073 .setMIFlag(Flag);
1074 break;
1075 }
1076 case AArch64::LDRDpost:
1077 Imm = -Imm;
1078 [[fallthrough]];
1079 case AArch64::STRDpre: {
1080 unsigned Reg = RegInfo->getSEHRegNum(MBBI->getOperand(1).getReg());
1081 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveFReg_X))
1082 .addImm(Reg)
1083 .addImm(Imm)
1084 .setMIFlag(Flag);
1085 break;
1086 }
1087 case AArch64::LDRXpost:
1088 Imm = -Imm;
1089 [[fallthrough]];
1090 case AArch64::STRXpre: {
1091 unsigned Reg = RegInfo->getSEHRegNum(MBBI->getOperand(1).getReg());
1092 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveReg_X))
1093 .addImm(Reg)
1094 .addImm(Imm)
1095 .setMIFlag(Flag);
1096 break;
1097 }
1098 case AArch64::STPDi:
1099 case AArch64::LDPDi: {
1100 unsigned Reg0 = RegInfo->getSEHRegNum(MBBI->getOperand(0).getReg());
1101 unsigned Reg1 = RegInfo->getSEHRegNum(MBBI->getOperand(1).getReg());
1102 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveFRegP))
1103 .addImm(Reg0)
1104 .addImm(Reg1)
1105 .addImm(Imm * 8)
1106 .setMIFlag(Flag);
1107 break;
1108 }
1109 case AArch64::STPXi:
1110 case AArch64::LDPXi: {
1111 Register Reg0 = MBBI->getOperand(0).getReg();
1112 Register Reg1 = MBBI->getOperand(1).getReg();
1113
1114 int SEHReg0 = RegInfo->getSEHRegNum(Reg0);
1115 int SEHReg1 = RegInfo->getSEHRegNum(Reg1);
1116
1117 if (Reg0 == AArch64::FP && Reg1 == AArch64::LR)
1118 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveFPLR))
1119 .addImm(Imm * 8)
1120 .setMIFlag(Flag);
1121 else if (SEHReg0 >= 19 && SEHReg1 >= 19)
1122 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveRegP))
1123 .addImm(SEHReg0)
1124 .addImm(SEHReg1)
1125 .addImm(Imm * 8)
1126 .setMIFlag(Flag);
1127 else
1128 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveAnyRegIP))
1129 .addImm(SEHReg0)
1130 .addImm(SEHReg1)
1131 .addImm(Imm * 8)
1132 .setMIFlag(Flag);
1133 break;
1134 }
1135 case AArch64::STRXui:
1136 case AArch64::LDRXui: {
1137 int Reg = RegInfo->getSEHRegNum(MBBI->getOperand(0).getReg());
1138 if (Reg >= 19)
1139 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveReg))
1140 .addImm(Reg)
1141 .addImm(Imm * 8)
1142 .setMIFlag(Flag);
1143 else
1144 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveAnyRegI))
1145 .addImm(Reg)
1146 .addImm(Imm * 8)
1147 .setMIFlag(Flag);
1148 break;
1149 }
1150 case AArch64::STRDui:
1151 case AArch64::LDRDui: {
1152 unsigned Reg = RegInfo->getSEHRegNum(MBBI->getOperand(0).getReg());
1153 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveFReg))
1154 .addImm(Reg)
1155 .addImm(Imm * 8)
1156 .setMIFlag(Flag);
1157 break;
1158 }
1159 case AArch64::STPQi:
1160 case AArch64::LDPQi: {
1161 unsigned Reg0 = RegInfo->getSEHRegNum(MBBI->getOperand(0).getReg());
1162 unsigned Reg1 = RegInfo->getSEHRegNum(MBBI->getOperand(1).getReg());
1163 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveAnyRegQP))
1164 .addImm(Reg0)
1165 .addImm(Reg1)
1166 .addImm(Imm * 16)
1167 .setMIFlag(Flag);
1168 break;
1169 }
1170 case AArch64::LDPQpost:
1171 Imm = -Imm;
1172 [[fallthrough]];
1173 case AArch64::STPQpre: {
1174 unsigned Reg0 = RegInfo->getSEHRegNum(MBBI->getOperand(1).getReg());
1175 unsigned Reg1 = RegInfo->getSEHRegNum(MBBI->getOperand(2).getReg());
1176 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveAnyRegQPX))
1177 .addImm(Reg0)
1178 .addImm(Reg1)
1179 .addImm(Imm * 16)
1180 .setMIFlag(Flag);
1181 break;
1182 }
1183 }
1184 auto I = MBB->insertAfter(MBBI, MIB);
1185 return I;
1186}
1187
1190 if (!AFI->needsDwarfUnwindInfo(MF) || !AFI->hasStreamingModeChanges())
1191 return false;
1192 // For Darwin platforms we don't save VG for non-SVE functions, even if SME
1193 // is enabled with streaming mode changes.
1194 auto &ST = MF.getSubtarget<AArch64Subtarget>();
1195 if (ST.isTargetDarwin())
1196 return ST.hasSVE();
1197 return true;
1198}
1199
1201 MachineFunction &MF) const {
1202 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
1203 const AArch64InstrInfo *TII = Subtarget.getInstrInfo();
1204
1205 auto EmitSignRA = [&](MachineBasicBlock &MBB) {
1206 DebugLoc DL; // Set debug location to unknown.
1208
1209 BuildMI(MBB, MBBI, DL, TII->get(AArch64::PAUTH_PROLOGUE))
1211 };
1212
1213 auto EmitAuthRA = [&](MachineBasicBlock &MBB) {
1214 DebugLoc DL;
1215 MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator();
1216 if (MBBI != MBB.end())
1217 DL = MBBI->getDebugLoc();
1218
1219 TII->createPauthEpilogueInstr(MBB, DL);
1220 };
1221
1222 // This should be in sync with PEIImpl::calculateSaveRestoreBlocks.
1223 EmitSignRA(MF.front());
1224 for (MachineBasicBlock &MBB : MF) {
1225 if (MBB.isEHFuncletEntry())
1226 EmitSignRA(MBB);
1227 if (MBB.isReturnBlock())
1228 EmitAuthRA(MBB);
1229 }
1230}
1231
1233 MachineBasicBlock &MBB) const {
1234 AArch64PrologueEmitter PrologueEmitter(MF, MBB, *this);
1235 PrologueEmitter.emitPrologue();
1236}
1237
1239 MachineBasicBlock &MBB) const {
1240 AArch64EpilogueEmitter EpilogueEmitter(MF, MBB, *this);
1241 EpilogueEmitter.emitEpilogue();
1242}
1243
1246 MF.getInfo<AArch64FunctionInfo>()->needsDwarfUnwindInfo(MF);
1247}
1248
1250 return enableCFIFixup(MF) &&
1251 MF.getInfo<AArch64FunctionInfo>()->needsAsyncDwarfUnwindInfo(MF);
1252}
1253
1254/// getFrameIndexReference - Provide a base+offset reference to an FI slot for
1255/// debug info. It's the same as what we use for resolving the code-gen
1256/// references for now. FIXME: This can go wrong when references are
1257/// SP-relative and simple call frames aren't used.
1260 Register &FrameReg) const {
1262 MF, FI, FrameReg,
1263 /*PreferFP=*/
1264 MF.getFunction().hasFnAttribute(Attribute::SanitizeHWAddress) ||
1265 MF.getFunction().hasFnAttribute(Attribute::SanitizeMemTag),
1266 /*ForSimm=*/false);
1267}
1268
1271 int FI) const {
1272 // This function serves to provide a comparable offset from a single reference
1273 // point (the value of SP at function entry) that can be used for analysis,
1274 // e.g. the stack-frame-layout analysis pass. It is not guaranteed to be
1275 // correct for all objects in the presence of VLA-area objects or dynamic
1276 // stack re-alignment.
1277
1278 const auto &MFI = MF.getFrameInfo();
1279
1280 int64_t ObjectOffset = MFI.getObjectOffset(FI);
1281 StackOffset ZPRStackSize = getZPRStackSize(MF);
1282 StackOffset PPRStackSize = getPPRStackSize(MF);
1283 StackOffset SVEStackSize = ZPRStackSize + PPRStackSize;
1284
1285 // For VLA-area objects, just emit an offset at the end of the stack frame.
1286 // Whilst not quite correct, these objects do live at the end of the frame and
1287 // so it is more useful for analysis for the offset to reflect this.
1288 if (MFI.isVariableSizedObjectIndex(FI)) {
1289 return StackOffset::getFixed(-((int64_t)MFI.getStackSize())) - SVEStackSize;
1290 }
1291
1292 // This is correct in the absence of any SVE stack objects.
1293 if (!SVEStackSize)
1294 return StackOffset::getFixed(ObjectOffset - getOffsetOfLocalArea());
1295
1296 const auto *AFI = MF.getInfo<AArch64FunctionInfo>();
1297 bool FPAfterSVECalleeSaves = hasSVECalleeSavesAboveFrameRecord(MF);
1298 if (MFI.hasScalableStackID(FI)) {
1299 if (FPAfterSVECalleeSaves &&
1300 -ObjectOffset <= (int64_t)AFI->getSVECalleeSavedStackSize()) {
1301 assert(!AFI->hasSplitSVEObjects() &&
1302 "split-sve-objects not supported with FPAfterSVECalleeSaves");
1303 return StackOffset::getScalable(ObjectOffset);
1304 }
1305 StackOffset AccessOffset{};
1306 // The scalable vectors are below (lower address) the scalable predicates
1307 // with split SVE objects, so we must subtract the size of the predicates.
1308 if (AFI->hasSplitSVEObjects() &&
1309 MFI.getStackID(FI) == TargetStackID::ScalableVector)
1310 AccessOffset = -PPRStackSize;
1311 return AccessOffset +
1312 StackOffset::get(-((int64_t)AFI->getCalleeSavedStackSize()),
1313 ObjectOffset);
1314 }
1315
1316 bool IsFixed = MFI.isFixedObjectIndex(FI);
1317 bool IsCSR =
1318 !IsFixed && ObjectOffset >= -((int)AFI->getCalleeSavedStackSize(MFI));
1319
1320 StackOffset ScalableOffset = {};
1321 if (!IsFixed && !IsCSR) {
1322 ScalableOffset = -SVEStackSize;
1323 } else if (FPAfterSVECalleeSaves && IsCSR) {
1324 ScalableOffset =
1326 }
1327
1328 return StackOffset::getFixed(ObjectOffset) + ScalableOffset;
1329}
1330
1336
1337StackOffset AArch64FrameLowering::getFPOffset(const MachineFunction &MF,
1338 int64_t ObjectOffset) const {
1339 const auto *AFI = MF.getInfo<AArch64FunctionInfo>();
1340 const auto &Subtarget = MF.getSubtarget<AArch64Subtarget>();
1341 const Function &F = MF.getFunction();
1342 bool IsWin64 = Subtarget.isCallingConvWin64(F.getCallingConv(), F.isVarArg());
1343 unsigned FixedObject =
1344 getFixedObjectSize(MF, AFI, IsWin64, /*IsFunclet=*/false);
1345 int64_t CalleeSaveSize = AFI->getCalleeSavedStackSize(MF.getFrameInfo());
1346 int64_t FPAdjust =
1347 CalleeSaveSize - AFI->getCalleeSaveBaseToFrameRecordOffset();
1348 return StackOffset::getFixed(ObjectOffset + FixedObject + FPAdjust);
1349}
1350
1351StackOffset AArch64FrameLowering::getStackOffset(const MachineFunction &MF,
1352 int64_t ObjectOffset) const {
1353 const auto &MFI = MF.getFrameInfo();
1354 return StackOffset::getFixed(ObjectOffset + (int64_t)MFI.getStackSize());
1355}
1356
1357// TODO: This function currently does not work for scalable vectors.
1359 int FI) const {
1360 const AArch64RegisterInfo *RegInfo =
1361 MF.getSubtarget<AArch64Subtarget>().getRegisterInfo();
1362 int ObjectOffset = MF.getFrameInfo().getObjectOffset(FI);
1363 return RegInfo->getLocalAddressRegister(MF) == AArch64::FP
1364 ? getFPOffset(MF, ObjectOffset).getFixed()
1365 : getStackOffset(MF, ObjectOffset).getFixed();
1366}
1367
1369 const MachineFunction &MF, int FI, Register &FrameReg, bool PreferFP,
1370 bool ForSimm) const {
1371 const auto &MFI = MF.getFrameInfo();
1372 int64_t ObjectOffset = MFI.getObjectOffset(FI);
1373 bool isFixed = MFI.isFixedObjectIndex(FI);
1374 auto StackID = static_cast<TargetStackID::Value>(MFI.getStackID(FI));
1375 return resolveFrameOffsetReference(MF, ObjectOffset, isFixed, StackID,
1376 FrameReg, PreferFP, ForSimm);
1377}
1378
1380 const MachineFunction &MF, int64_t ObjectOffset, bool isFixed,
1381 TargetStackID::Value StackID, Register &FrameReg, bool PreferFP,
1382 bool ForSimm) const {
1383 const auto &MFI = MF.getFrameInfo();
1384 const auto &Subtarget = MF.getSubtarget<AArch64Subtarget>();
1385 const AArch64RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
1386 const auto *AFI = MF.getInfo<AArch64FunctionInfo>();
1387
1388 int64_t FPOffset = getFPOffset(MF, ObjectOffset).getFixed();
1389 int64_t Offset = getStackOffset(MF, ObjectOffset).getFixed();
1390 bool isCSR =
1391 !isFixed && ObjectOffset >= -((int)AFI->getCalleeSavedStackSize(MFI));
1392 bool isSVE = MFI.isScalableStackID(StackID);
1393
1394 StackOffset ZPRStackSize = getZPRStackSize(MF);
1395 StackOffset PPRStackSize = getPPRStackSize(MF);
1396 StackOffset SVEStackSize = ZPRStackSize + PPRStackSize;
1397
1398 // Use frame pointer to reference fixed objects. Use it for locals if
1399 // there are VLAs or a dynamically realigned SP (and thus the SP isn't
1400 // reliable as a base). Make sure useFPForScavengingIndex() does the
1401 // right thing for the emergency spill slot.
1402 bool UseFP = false;
1403 if (AFI->hasStackFrame() && !isSVE) {
1404 // We shouldn't prefer using the FP to access fixed-sized stack objects when
1405 // there are scalable (SVE) objects in between the FP and the fixed-sized
1406 // objects.
1407 PreferFP &= !SVEStackSize;
1408
1409 // Note: Keeping the following as multiple 'if' statements rather than
1410 // merging to a single expression for readability.
1411 //
1412 // Argument access should always use the FP.
1413 if (isFixed) {
1414 UseFP = hasFP(MF);
1415 } else if (isCSR && RegInfo->hasStackRealignment(MF)) {
1416 // References to the CSR area must use FP if we're re-aligning the stack
1417 // since the dynamically-sized alignment padding is between the SP/BP and
1418 // the CSR area.
1419 assert(hasFP(MF) && "Re-aligned stack must have frame pointer");
1420 UseFP = true;
1421 } else if (hasFP(MF) && !RegInfo->hasStackRealignment(MF)) {
1422 // If the FPOffset is negative and we're producing a signed immediate, we
1423 // have to keep in mind that the available offset range for negative
1424 // offsets is smaller than for positive ones. If an offset is available
1425 // via the FP and the SP, use whichever is closest.
1426 bool FPOffsetFits = !ForSimm || FPOffset >= -256;
1427 PreferFP |= Offset > -FPOffset && !SVEStackSize;
1428
1429 if (FPOffset >= 0) {
1430 // If the FPOffset is positive, that'll always be best, as the SP/BP
1431 // will be even further away.
1432 UseFP = true;
1433 } else if (MFI.hasVarSizedObjects()) {
1434 // If we have variable sized objects, we can use either FP or BP, as the
1435 // SP offset is unknown. We can use the base pointer if we have one and
1436 // FP is not preferred. If not, we're stuck with using FP.
1437 bool CanUseBP = RegInfo->hasBasePointer(MF);
1438 if (FPOffsetFits && CanUseBP) // Both are ok. Pick the best.
1439 UseFP = PreferFP;
1440 else if (!CanUseBP) // Can't use BP. Forced to use FP.
1441 UseFP = true;
1442 // else we can use BP and FP, but the offset from FP won't fit.
1443 // That will make us scavenge registers which we can probably avoid by
1444 // using BP. If it won't fit for BP either, we'll scavenge anyway.
1445 } else if (MF.hasEHFunclets() && !RegInfo->hasBasePointer(MF)) {
1446 // Funclets access the locals contained in the parent's stack frame
1447 // via the frame pointer, so we have to use the FP in the parent
1448 // function.
1449 (void) Subtarget;
1450 assert(Subtarget.isCallingConvWin64(MF.getFunction().getCallingConv(),
1451 MF.getFunction().isVarArg()) &&
1452 "Funclets should only be present on Win64");
1453 UseFP = true;
1454 } else {
1455 // We have the choice between FP and (SP or BP).
1456 if (FPOffsetFits && PreferFP) // If FP is the best fit, use it.
1457 UseFP = true;
1458 }
1459 }
1460 }
1461
1462 assert(
1463 ((isFixed || isCSR) || !RegInfo->hasStackRealignment(MF) || !UseFP) &&
1464 "In the presence of dynamic stack pointer realignment, "
1465 "non-argument/CSR objects cannot be accessed through the frame pointer");
1466
1467 bool FPAfterSVECalleeSaves = hasSVECalleeSavesAboveFrameRecord(MF);
1468
1469 if (isSVE) {
1470 StackOffset FPOffset = StackOffset::get(
1471 -AFI->getCalleeSaveBaseToFrameRecordOffset(), ObjectOffset);
1472 StackOffset SPOffset =
1473 SVEStackSize +
1474 StackOffset::get(MFI.getStackSize() - AFI->getCalleeSavedStackSize(),
1475 ObjectOffset);
1476
1477 // With split SVE objects the ObjectOffset is relative to the split area
1478 // (i.e. the PPR area or ZPR area respectively).
1479 if (AFI->hasSplitSVEObjects() && StackID == TargetStackID::ScalableVector) {
1480 // If we're accessing an SVE vector with split SVE objects...
1481 // - From the FP we need to move down past the PPR area:
1482 FPOffset -= PPRStackSize;
1483 // - From the SP we only need to move up to the ZPR area:
1484 SPOffset -= PPRStackSize;
1485 // Note: `SPOffset = SVEStackSize + ...`, so `-= PPRStackSize` results in
1486 // `SPOffset = ZPRStackSize + ...`.
1487 }
1488
1489 if (FPAfterSVECalleeSaves) {
1491 if (-ObjectOffset <= (int64_t)AFI->getSVECalleeSavedStackSize()) {
1494 }
1495 }
1496
1497 // Always use the FP for SVE spills if available and beneficial.
1498 if (hasFP(MF) && (SPOffset.getFixed() ||
1499 FPOffset.getScalable() < SPOffset.getScalable() ||
1500 RegInfo->hasStackRealignment(MF))) {
1501 FrameReg = RegInfo->getFrameRegister(MF);
1502 return FPOffset;
1503 }
1504 FrameReg = RegInfo->hasBasePointer(MF) ? RegInfo->getBaseRegister()
1505 : MCRegister(AArch64::SP);
1506
1507 return SPOffset;
1508 }
1509
1510 StackOffset SVEAreaOffset = {};
1511 if (FPAfterSVECalleeSaves) {
1512 // In this stack layout, the FP is in between the callee saves and other
1513 // SVE allocations.
1514 StackOffset SVECalleeSavedStack =
1516 if (UseFP) {
1517 if (isFixed)
1518 SVEAreaOffset = SVECalleeSavedStack;
1519 else if (!isCSR)
1520 SVEAreaOffset = SVECalleeSavedStack - SVEStackSize;
1521 } else {
1522 if (isFixed)
1523 SVEAreaOffset = SVEStackSize;
1524 else if (isCSR)
1525 SVEAreaOffset = SVEStackSize - SVECalleeSavedStack;
1526 }
1527 } else {
1528 if (UseFP && !(isFixed || isCSR))
1529 SVEAreaOffset = -SVEStackSize;
1530 if (!UseFP && (isFixed || isCSR))
1531 SVEAreaOffset = SVEStackSize;
1532 }
1533
1534 if (UseFP) {
1535 FrameReg = RegInfo->getFrameRegister(MF);
1536 return StackOffset::getFixed(FPOffset) + SVEAreaOffset;
1537 }
1538
1539 // Use the base pointer if we have one.
1540 if (RegInfo->hasBasePointer(MF))
1541 FrameReg = RegInfo->getBaseRegister();
1542 else {
1543 assert(!MFI.hasVarSizedObjects() &&
1544 "Can't use SP when we have var sized objects.");
1545 FrameReg = AArch64::SP;
1546 // If we're using the red zone for this function, the SP won't actually
1547 // be adjusted, so the offsets will be negative. They're also all
1548 // within range of the signed 9-bit immediate instructions.
1549 if (canUseRedZone(MF))
1550 Offset -= AFI->getLocalStackSize();
1551 }
1552
1553 return StackOffset::getFixed(Offset) + SVEAreaOffset;
1554}
1555
1557 // Do not set a kill flag on values that are also marked as live-in. This
1558 // happens with the @llvm-returnaddress intrinsic and with arguments passed in
1559 // callee saved registers.
1560 // Omitting the kill flags is conservatively correct even if the live-in
1561 // is not used after all.
1562 bool IsLiveIn = MF.getRegInfo().isLiveIn(Reg);
1563 return getKillRegState(!IsLiveIn);
1564}
1565
1567 MachineFunction &MF) {
1568 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
1569 AttributeList Attrs = MF.getFunction().getAttributes();
1571 return Subtarget.isTargetMachO() &&
1572 !(Subtarget.getTargetLowering()->supportSwiftError() &&
1573 Attrs.hasAttrSomewhere(Attribute::SwiftError)) &&
1575 !AFL.requiresSaveVG(MF) && !AFI->isSVECC();
1576}
1577
1578static bool invalidateWindowsRegisterPairing(bool SpillExtendedVolatile,
1579 unsigned SpillCount, unsigned Reg1,
1580 unsigned Reg2, bool NeedsWinCFI,
1581 const TargetRegisterInfo *TRI) {
1582 // If we are generating register pairs for a Windows function that requires
1583 // EH support, then pair consecutive registers only. There are no unwind
1584 // opcodes for saves/restores of non-consecutive register pairs.
1585 // The unwind opcodes are save_regp, save_regp_x, save_fregp, save_frepg_x,
1586 // save_lrpair.
1587 // https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling
1588
1589 if (Reg2 == AArch64::FP)
1590 return true;
1591 if (!NeedsWinCFI)
1592 return false;
1593
1594 // ARM64EC introduced `save_any_regp`, which expects 16-byte alignment.
1595 // This is handled by only allowing paired spills for registers spilled at
1596 // even positions (which should be 16-byte aligned, as other GPRs/FPRs are
1597 // 8-bytes). We carve out an exception for {FP,LR}, which does not require
1598 // 16-byte alignment in the uop representation.
1599 if (TRI->getEncodingValue(Reg2) == TRI->getEncodingValue(Reg1) + 1)
1600 return SpillExtendedVolatile
1601 ? !((Reg1 == AArch64::FP && Reg2 == AArch64::LR) ||
1602 (SpillCount % 2) == 0)
1603 : false;
1604
1605 // If pairing a GPR with LR, the pair can be described by the save_lrpair
1606 // opcode. The save_lrpair opcode requires the first register to be odd.
1607 if (Reg1 >= AArch64::X19 && Reg1 <= AArch64::X27 &&
1608 (Reg1 - AArch64::X19) % 2 == 0 && Reg2 == AArch64::LR)
1609 return false;
1610 return true;
1611}
1612
1613/// Returns true if Reg1 and Reg2 cannot be paired using a ldp/stp instruction.
1614/// WindowsCFI requires that only consecutive registers can be paired.
1615/// LR and FP need to be allocated together when the frame needs to save
1616/// the frame-record. This means any other register pairing with LR is invalid.
1617static bool invalidateRegisterPairing(bool SpillExtendedVolatile,
1618 unsigned SpillCount, unsigned Reg1,
1619 unsigned Reg2, bool UsesWinAAPCS,
1620 bool NeedsWinCFI, bool NeedsFrameRecord,
1621 const TargetRegisterInfo *TRI) {
1622 if (UsesWinAAPCS)
1623 return invalidateWindowsRegisterPairing(SpillExtendedVolatile, SpillCount,
1624 Reg1, Reg2, NeedsWinCFI, TRI);
1625
1626 // If we need to store the frame record, don't pair any register
1627 // with LR other than FP.
1628 if (NeedsFrameRecord)
1629 return Reg2 == AArch64::LR;
1630
1631 return false;
1632}
1633
1634namespace {
1635
1636struct RegPairInfo {
1637 Register Reg1;
1638 Register Reg2;
1639 int FrameIdx;
1640 int Offset;
1641 enum RegType { GPR, FPR64, FPR128, PPR, ZPR, VG } Type;
1642 const TargetRegisterClass *RC;
1643
1644 RegPairInfo() = default;
1645
1646 bool isPaired() const { return Reg2.isValid(); }
1647
1648 bool isScalable() const { return Type == PPR || Type == ZPR; }
1649};
1650
1651} // end anonymous namespace
1652
1654 for (unsigned PReg = AArch64::P8; PReg <= AArch64::P15; ++PReg) {
1655 if (SavedRegs.test(PReg)) {
1656 unsigned PNReg = PReg - AArch64::P0 + AArch64::PN0;
1657 return MCRegister(PNReg);
1658 }
1659 }
1660 return MCRegister();
1661}
1662
1663// The multivector LD/ST are available only for SME or SVE2p1 targets
1665 MachineFunction &MF) {
1667 return false;
1668
1669 SMEAttrs FuncAttrs = MF.getInfo<AArch64FunctionInfo>()->getSMEFnAttrs();
1670 bool IsLocallyStreaming =
1671 FuncAttrs.hasStreamingBody() && !FuncAttrs.hasStreamingInterface();
1672
1673 // Only when in streaming mode SME2 instructions can be safely used.
1674 // It is not safe to use SME2 instructions when in streaming compatible or
1675 // locally streaming mode.
1676 return Subtarget.hasSVE2p1() ||
1677 (Subtarget.hasSME2() &&
1678 (!IsLocallyStreaming && Subtarget.isStreaming()));
1679}
1680
1682 MachineFunction &MF,
1684 const TargetRegisterInfo *TRI,
1686 bool NeedsFrameRecord) {
1687
1688 if (CSI.empty())
1689 return;
1690
1691 bool IsWindows = isTargetWindows(MF);
1693 unsigned StackHazardSize = getStackHazardSize(MF);
1694 MachineFrameInfo &MFI = MF.getFrameInfo();
1696 unsigned Count = CSI.size();
1697 (void)CC;
1698 // MachO's compact unwind format relies on all registers being stored in
1699 // pairs.
1700 assert((!produceCompactUnwindFrame(AFL, MF) ||
1703 (Count & 1) == 0) &&
1704 "Odd number of callee-saved regs to spill!");
1705 int ByteOffset = AFI->getCalleeSavedStackSize();
1706 int StackFillDir = -1;
1707 int RegInc = 1;
1708 unsigned FirstReg = 0;
1709 if (IsWindows) {
1710 // For WinCFI, fill the stack from the bottom up.
1711 ByteOffset = 0;
1712 StackFillDir = 1;
1713 // As the CSI array is reversed to match PrologEpilogInserter, iterate
1714 // backwards, to pair up registers starting from lower numbered registers.
1715 RegInc = -1;
1716 FirstReg = Count - 1;
1717 }
1718
1719 bool FPAfterSVECalleeSaves = AFL.hasSVECalleeSavesAboveFrameRecord(MF);
1720 // Windows AAPCS has x9-x15 as volatile registers, x16-x17 as intra-procedural
1721 // scratch, x18 as platform reserved. However, clang has extended calling
1722 // convensions such as preserve_most and preserve_all which treat these as
1723 // CSR. As such, the ARM64 unwind uOPs bias registers by 19. We use ARM64EC
1724 // uOPs which have separate restrictions. We need to check for that.
1725 //
1726 // NOTE: we currently do not account for the D registers as LLVM does not
1727 // support non-ABI compliant D register spills.
1728 bool SpillExtendedVolatile =
1729 IsWindows && llvm::any_of(CSI, [](const CalleeSavedInfo &CSI) {
1730 const auto &Reg = CSI.getReg();
1731 return Reg >= AArch64::X0 && Reg <= AArch64::X18;
1732 });
1733
1734 int ZPRByteOffset = 0;
1735 int PPRByteOffset = 0;
1736 bool SplitPPRs = AFI->hasSplitSVEObjects();
1737 if (SplitPPRs) {
1738 ZPRByteOffset = AFI->getZPRCalleeSavedStackSize();
1739 PPRByteOffset = AFI->getPPRCalleeSavedStackSize();
1740 } else if (!FPAfterSVECalleeSaves) {
1741 ZPRByteOffset =
1743 // Unused: Everything goes in ZPR space.
1744 PPRByteOffset = 0;
1745 }
1746
1747 bool NeedGapToAlignStack = AFI->hasCalleeSaveStackFreeSpace();
1748 Register LastReg = 0;
1749 bool HasCSHazardPadding = AFI->hasStackHazardSlotIndex() && !SplitPPRs;
1750
1751 auto AlignOffset = [StackFillDir](int Offset, int Align) {
1752 if (StackFillDir < 0)
1753 return alignDown(Offset, Align);
1754 return alignTo(Offset, Align);
1755 };
1756
1757 // When iterating backwards, the loop condition relies on unsigned wraparound.
1758 for (unsigned i = FirstReg; i < Count; i += RegInc) {
1759 RegPairInfo RPI;
1760 RPI.Reg1 = CSI[i].getReg();
1761
1762 if (AArch64::GPR64RegClass.contains(RPI.Reg1)) {
1763 RPI.Type = RegPairInfo::GPR;
1764 RPI.RC = &AArch64::GPR64RegClass;
1765 } else if (AArch64::FPR64RegClass.contains(RPI.Reg1)) {
1766 RPI.Type = RegPairInfo::FPR64;
1767 RPI.RC = &AArch64::FPR64RegClass;
1768 } else if (AArch64::FPR128RegClass.contains(RPI.Reg1)) {
1769 RPI.Type = RegPairInfo::FPR128;
1770 RPI.RC = &AArch64::FPR128RegClass;
1771 } else if (AArch64::ZPRRegClass.contains(RPI.Reg1)) {
1772 RPI.Type = RegPairInfo::ZPR;
1773 RPI.RC = &AArch64::ZPRRegClass;
1774 } else if (AArch64::PPRRegClass.contains(RPI.Reg1)) {
1775 RPI.Type = RegPairInfo::PPR;
1776 RPI.RC = &AArch64::PPRRegClass;
1777 } else if (RPI.Reg1 == AArch64::VG) {
1778 RPI.Type = RegPairInfo::VG;
1779 RPI.RC = &AArch64::FIXED_REGSRegClass;
1780 } else {
1781 llvm_unreachable("Unsupported register class.");
1782 }
1783
1784 int &ScalableByteOffset = RPI.Type == RegPairInfo::PPR && SplitPPRs
1785 ? PPRByteOffset
1786 : ZPRByteOffset;
1787
1788 // Add the stack hazard size as we transition from GPR->FPR CSRs.
1789 if (HasCSHazardPadding &&
1790 (!LastReg || !AArch64InstrInfo::isFpOrNEON(LastReg)) &&
1792 ByteOffset += StackFillDir * StackHazardSize;
1793 LastReg = RPI.Reg1;
1794
1795 bool NeedsWinCFI = AFL.needsWinCFI(MF);
1796 int Scale = TRI->getSpillSize(*RPI.RC);
1797 // Add the next reg to the pair if it is in the same register class.
1798 if (unsigned(i + RegInc) < Count && !HasCSHazardPadding) {
1799 MCRegister NextReg = CSI[i + RegInc].getReg();
1800 unsigned SpillCount = NeedsWinCFI ? FirstReg - i : i;
1801 int Aligned = AlignOffset(ByteOffset, Scale);
1802 int PairOffset = IsWindows ? Aligned : Aligned + StackFillDir * 2 * Scale;
1803 bool PairFitsImmRange =
1804 PairOffset / Scale >= -64 && PairOffset / Scale <= 63;
1805 switch (RPI.Type) {
1806 case RegPairInfo::GPR:
1807 if (AArch64::GPR64RegClass.contains(NextReg) && PairFitsImmRange &&
1808 !invalidateRegisterPairing(SpillExtendedVolatile, SpillCount,
1809 RPI.Reg1, NextReg, IsWindows,
1810 NeedsWinCFI, NeedsFrameRecord, TRI))
1811 RPI.Reg2 = NextReg;
1812 break;
1813 case RegPairInfo::FPR64:
1814 if (AArch64::FPR64RegClass.contains(NextReg) && PairFitsImmRange &&
1815 !invalidateRegisterPairing(SpillExtendedVolatile, SpillCount,
1816 RPI.Reg1, NextReg, IsWindows,
1817 NeedsWinCFI, NeedsFrameRecord, TRI))
1818 RPI.Reg2 = NextReg;
1819 break;
1820 case RegPairInfo::FPR128:
1821 if (AArch64::FPR128RegClass.contains(NextReg) && PairFitsImmRange)
1822 RPI.Reg2 = NextReg;
1823 break;
1824 case RegPairInfo::PPR:
1825 break;
1826 case RegPairInfo::ZPR:
1827 if (AFI->getPredicateRegForFillSpill() != 0 &&
1828 ((RPI.Reg1 - AArch64::Z0) & 1) == 0 && (NextReg == RPI.Reg1 + 1)) {
1829 // Calculate offset of register pair to see if pair instruction can be
1830 // used.
1831 int Offset = (ScalableByteOffset + StackFillDir * 2 * Scale) / Scale;
1832 if ((-16 <= Offset && Offset <= 14) && (Offset % 2 == 0))
1833 RPI.Reg2 = NextReg;
1834 }
1835 break;
1836 case RegPairInfo::VG:
1837 break;
1838 }
1839 }
1840
1841 // GPRs and FPRs are saved in pairs of 64-bit regs. We expect the CSI
1842 // list to come in sorted by frame index so that we can issue the store
1843 // pair instructions directly. Assert if we see anything otherwise.
1844 //
1845 // The order of the registers in the list is controlled by
1846 // getCalleeSavedRegs(), so they will always be in-order, as well.
1847 assert((!RPI.isPaired() ||
1848 (CSI[i].getFrameIdx() + RegInc == CSI[i + RegInc].getFrameIdx())) &&
1849 "Out of order callee saved regs!");
1850
1851 assert((!RPI.isPaired() || !NeedsFrameRecord || RPI.Reg2 != AArch64::FP ||
1852 RPI.Reg1 == AArch64::LR) &&
1853 "FrameRecord must be allocated together with LR");
1854
1855 // Windows AAPCS has FP and LR reversed.
1856 assert((!RPI.isPaired() || !NeedsFrameRecord || RPI.Reg1 != AArch64::FP ||
1857 RPI.Reg2 == AArch64::LR) &&
1858 "FrameRecord must be allocated together with LR");
1859
1860 // MachO's compact unwind format relies on all registers being stored in
1861 // adjacent register pairs.
1862 assert((!produceCompactUnwindFrame(AFL, MF) ||
1865 (RPI.isPaired() &&
1866 ((RPI.Reg1 == AArch64::LR && RPI.Reg2 == AArch64::FP) ||
1867 RPI.Reg1 + 1 == RPI.Reg2))) &&
1868 "Callee-save registers not saved as adjacent register pair!");
1869
1870 RPI.FrameIdx = CSI[i].getFrameIdx();
1871 if (IsWindows &&
1872 RPI.isPaired()) // RPI.FrameIdx must be the lower index of the pair
1873 RPI.FrameIdx = CSI[i + RegInc].getFrameIdx();
1874
1875 // Realign the scalable offset if necessary. This is relevant when spilling
1876 // predicates on Windows.
1877 if (RPI.isScalable() && ScalableByteOffset % Scale != 0)
1878 ScalableByteOffset = AlignOffset(ScalableByteOffset, Scale);
1879
1880 // Realign the fixed offset if necessary. This is relevant when spilling Q
1881 // registers after spilling an odd amount of X registers.
1882 if (!RPI.isScalable() && ByteOffset % Scale != 0)
1883 ByteOffset = AlignOffset(ByteOffset, Scale);
1884
1885 int OffsetPre = RPI.isScalable() ? ScalableByteOffset : ByteOffset;
1886 assert(OffsetPre % Scale == 0);
1887
1888 if (RPI.isScalable())
1889 ScalableByteOffset += StackFillDir * (RPI.isPaired() ? 2 * Scale : Scale);
1890 else
1891 ByteOffset += StackFillDir * (RPI.isPaired() ? 2 * Scale : Scale);
1892
1893 // Swift's async context is directly before FP, so allocate an extra
1894 // 8 bytes for it.
1895 if (NeedsFrameRecord && AFI->hasSwiftAsyncContext() &&
1896 ((!IsWindows && RPI.Reg2 == AArch64::FP) ||
1897 (IsWindows && RPI.Reg2 == AArch64::LR)))
1898 ByteOffset += StackFillDir * 8;
1899
1900 // Round up size of non-pair to pair size if we need to pad the
1901 // callee-save area to ensure 16-byte alignment.
1902 if (NeedGapToAlignStack && !IsWindows && !RPI.isScalable() &&
1903 RPI.Type != RegPairInfo::FPR128 && !RPI.isPaired() &&
1904 ByteOffset % 16 != 0) {
1905 ByteOffset += 8 * StackFillDir;
1906 assert(MFI.getObjectAlign(RPI.FrameIdx) <= Align(16));
1907 // A stack frame with a gap looks like this, bottom up:
1908 // d9, d8. x21, gap, x20, x19.
1909 // Set extra alignment on the x21 object to create the gap above it.
1910 MFI.setObjectAlignment(RPI.FrameIdx, Align(16));
1911 NeedGapToAlignStack = false;
1912 }
1913
1914 int OffsetPost = RPI.isScalable() ? ScalableByteOffset : ByteOffset;
1915 assert(OffsetPost % Scale == 0);
1916 // If filling top down (default), we want the offset after incrementing it.
1917 // If filling bottom up (WinCFI) we need the original offset.
1918 int Offset = IsWindows ? OffsetPre : OffsetPost;
1919
1920 // The FP, LR pair goes 8 bytes into our expanded 24-byte slot so that the
1921 // Swift context can directly precede FP.
1922 if (NeedsFrameRecord && AFI->hasSwiftAsyncContext() &&
1923 ((!IsWindows && RPI.Reg2 == AArch64::FP) ||
1924 (IsWindows && RPI.Reg2 == AArch64::LR)))
1925 Offset += 8;
1926 RPI.Offset = Offset / Scale;
1927
1928 assert((!RPI.isPaired() ||
1929 (!RPI.isScalable() && RPI.Offset >= -64 && RPI.Offset <= 63) ||
1930 (RPI.isScalable() && RPI.Offset >= -256 && RPI.Offset <= 255)) &&
1931 "Offset out of bounds for LDP/STP immediate");
1932
1933 auto isFrameRecord = [&] {
1934 if (RPI.isPaired())
1935 return IsWindows ? RPI.Reg1 == AArch64::FP && RPI.Reg2 == AArch64::LR
1936 : RPI.Reg1 == AArch64::LR && RPI.Reg2 == AArch64::FP;
1937 // Otherwise, look for the frame record as two unpaired registers. This is
1938 // needed for -aarch64-stack-hazard-size=<val>, which disables register
1939 // pairing (as the padding may be too large for the LDP/STP offset). Note:
1940 // On Windows, this check works out as current reg == FP, next reg == LR,
1941 // and on other platforms current reg == FP, previous reg == LR. This
1942 // works out as the correct pre-increment or post-increment offsets
1943 // respectively.
1944 return i > 0 && RPI.Reg1 == AArch64::FP &&
1945 CSI[i - 1].getReg() == AArch64::LR;
1946 };
1947
1948 // Save the offset to frame record so that the FP register can point to the
1949 // innermost frame record (spilled FP and LR registers).
1950 if (NeedsFrameRecord && isFrameRecord())
1952
1953 RegPairs.push_back(RPI);
1954 if (RPI.isPaired())
1955 i += RegInc;
1956 }
1957 if (IsWindows) {
1958 // If we need an alignment gap in the stack, align the topmost stack
1959 // object. A stack frame with a gap looks like this, bottom up:
1960 // x19, d8. d9, gap.
1961 // Set extra alignment on the topmost stack object (the first element in
1962 // CSI, which goes top down), to create the gap above it.
1963 if (AFI->hasCalleeSaveStackFreeSpace())
1964 MFI.setObjectAlignment(CSI[0].getFrameIdx(), Align(16));
1965 // We iterated bottom up over the registers; flip RegPairs back to top
1966 // down order.
1967 std::reverse(RegPairs.begin(), RegPairs.end());
1968 }
1969}
1970
1974 MachineFunction &MF = *MBB.getParent();
1975 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
1976 auto &TLI = *Subtarget.getTargetLowering();
1977 const AArch64InstrInfo &TII = *Subtarget.getInstrInfo();
1978 bool NeedsWinCFI = needsWinCFI(MF);
1979 DebugLoc DL;
1981
1982 computeCalleeSaveRegisterPairs(*this, MF, CSI, TRI, RegPairs, hasFP(MF));
1983
1984 MachineRegisterInfo &MRI = MF.getRegInfo();
1985 // Refresh the reserved regs in case there are any potential changes since the
1986 // last freeze.
1987 MRI.freezeReservedRegs();
1988
1989 if (homogeneousPrologEpilog(MF)) {
1990 auto MIB = BuildMI(MBB, MI, DL, TII.get(AArch64::HOM_Prolog))
1992
1993 for (auto &RPI : RegPairs) {
1994 MIB.addReg(RPI.Reg1);
1995 MIB.addReg(RPI.Reg2);
1996
1997 // Update register live in.
1998 if (!MRI.isReserved(RPI.Reg1))
1999 MBB.addLiveIn(RPI.Reg1);
2000 if (RPI.isPaired() && !MRI.isReserved(RPI.Reg2))
2001 MBB.addLiveIn(RPI.Reg2);
2002 }
2003 return true;
2004 }
2005 bool PTrueCreated = false;
2006 for (const RegPairInfo &RPI : llvm::reverse(RegPairs)) {
2007 Register Reg1 = RPI.Reg1;
2008 Register Reg2 = RPI.Reg2;
2009 unsigned StrOpc;
2010
2011 // Issue sequence of spills for cs regs. The first spill may be converted
2012 // to a pre-decrement store later by emitPrologue if the callee-save stack
2013 // area allocation can't be combined with the local stack area allocation.
2014 // For example:
2015 // stp x22, x21, [sp, #0] // addImm(+0)
2016 // stp x20, x19, [sp, #16] // addImm(+2)
2017 // stp fp, lr, [sp, #32] // addImm(+4)
2018 // Rationale: This sequence saves uop updates compared to a sequence of
2019 // pre-increment spills like stp xi,xj,[sp,#-16]!
2020 // Note: Similar rationale and sequence for restores in epilog.
2021 unsigned Size = TRI->getSpillSize(*RPI.RC);
2022 Align Alignment = TRI->getSpillAlign(*RPI.RC);
2023 switch (RPI.Type) {
2024 case RegPairInfo::GPR:
2025 StrOpc = RPI.isPaired() ? AArch64::STPXi : AArch64::STRXui;
2026 break;
2027 case RegPairInfo::FPR64:
2028 StrOpc = RPI.isPaired() ? AArch64::STPDi : AArch64::STRDui;
2029 break;
2030 case RegPairInfo::FPR128:
2031 StrOpc = RPI.isPaired() ? AArch64::STPQi : AArch64::STRQui;
2032 break;
2033 case RegPairInfo::ZPR:
2034 StrOpc = RPI.isPaired() ? AArch64::ST1B_2Z_IMM : AArch64::STR_ZXI;
2035 break;
2036 case RegPairInfo::PPR:
2037 StrOpc = AArch64::STR_PXI;
2038 break;
2039 case RegPairInfo::VG:
2040 StrOpc = AArch64::STRXui;
2041 break;
2042 }
2043
2044 Register X0Scratch;
2045 llvm::scope_exit RestoreX0([&] {
2046 if (X0Scratch != AArch64::NoRegister)
2047 BuildMI(MBB, MI, DL, TII.get(TargetOpcode::COPY), AArch64::X0)
2048 .addReg(X0Scratch)
2050 });
2051
2052 if (Reg1 == AArch64::VG) {
2053 // Find an available register to store value of VG to.
2054 Reg1 = findScratchNonCalleeSaveRegister(&MBB, true);
2055 assert(Reg1 != AArch64::NoRegister);
2056 if (MF.getSubtarget<AArch64Subtarget>().hasSVE()) {
2057 BuildMI(MBB, MI, DL, TII.get(AArch64::CNTD_XPiI), Reg1)
2058 .addImm(31)
2059 .addImm(1)
2061 } else {
2063 if (any_of(MBB.liveins(),
2064 [&STI](const MachineBasicBlock::RegisterMaskPair &LiveIn) {
2065 return STI.getRegisterInfo()->isSuperOrSubRegisterEq(
2066 AArch64::X0, LiveIn.PhysReg);
2067 })) {
2068 X0Scratch = Reg1;
2069 BuildMI(MBB, MI, DL, TII.get(TargetOpcode::COPY), X0Scratch)
2070 .addReg(AArch64::X0)
2072 }
2073
2074 RTLIB::Libcall LC = RTLIB::SMEABI_GET_CURRENT_VG;
2075 const uint32_t *RegMask =
2076 TRI->getCallPreservedMask(MF, TLI.getLibcallCallingConv(LC));
2077 BuildMI(MBB, MI, DL, TII.get(AArch64::BL))
2078 .addExternalSymbol(TLI.getLibcallName(LC))
2079 .addRegMask(RegMask)
2080 .addReg(AArch64::X0, RegState::ImplicitDefine)
2082 Reg1 = AArch64::X0;
2083 }
2084 }
2085
2086 LLVM_DEBUG({
2087 dbgs() << "CSR spill: (" << printReg(Reg1, TRI);
2088 if (RPI.isPaired())
2089 dbgs() << ", " << printReg(Reg2, TRI);
2090 dbgs() << ") -> fi#(" << RPI.FrameIdx;
2091 if (RPI.isPaired())
2092 dbgs() << ", " << RPI.FrameIdx + 1;
2093 dbgs() << ")\n";
2094 });
2095
2096 assert((!isTargetWindows(MF) ||
2097 !(Reg1 == AArch64::LR && Reg2 == AArch64::FP)) &&
2098 "Windows unwdinding requires a consecutive (FP,LR) pair");
2099 // Windows unwind codes require consecutive registers if registers are
2100 // paired. Make the switch here, so that the code below will save (x,x+1)
2101 // and not (x+1,x).
2102 unsigned FrameIdxReg1 = RPI.FrameIdx;
2103 unsigned FrameIdxReg2 = RPI.FrameIdx + 1;
2104 if (isTargetWindows(MF) && RPI.isPaired()) {
2105 std::swap(Reg1, Reg2);
2106 std::swap(FrameIdxReg1, FrameIdxReg2);
2107 }
2108
2109 if (RPI.isPaired() && RPI.isScalable()) {
2110 [[maybe_unused]] const AArch64Subtarget &Subtarget =
2113 unsigned PnReg = AFI->getPredicateRegForFillSpill();
2114 assert((PnReg != 0 && enableMultiVectorSpillFill(Subtarget, MF)) &&
2115 "Expects SVE2.1 or SME2 target and a predicate register");
2116#ifdef EXPENSIVE_CHECKS
2117 auto IsPPR = [](const RegPairInfo &c) {
2118 return c.Reg1 == RegPairInfo::PPR;
2119 };
2120 auto PPRBegin = std::find_if(RegPairs.begin(), RegPairs.end(), IsPPR);
2121 auto IsZPR = [](const RegPairInfo &c) {
2122 return c.Type == RegPairInfo::ZPR;
2123 };
2124 auto ZPRBegin = std::find_if(RegPairs.begin(), RegPairs.end(), IsZPR);
2125 assert(!(PPRBegin < ZPRBegin) &&
2126 "Expected callee save predicate to be handled first");
2127#endif
2128 if (!PTrueCreated) {
2129 PTrueCreated = true;
2130 BuildMI(MBB, MI, DL, TII.get(AArch64::PTRUE_C_B), PnReg)
2132 }
2133 MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(StrOpc));
2134 if (!MRI.isReserved(Reg1))
2135 MBB.addLiveIn(Reg1);
2136 if (!MRI.isReserved(Reg2))
2137 MBB.addLiveIn(Reg2);
2138 MIB.addReg(/*PairRegs*/ AArch64::Z0_Z1 + (RPI.Reg1 - AArch64::Z0));
2140 MachinePointerInfo::getFixedStack(MF, FrameIdxReg2),
2141 MachineMemOperand::MOStore, Size, Alignment));
2142 MIB.addReg(PnReg);
2143 MIB.addReg(AArch64::SP)
2144 .addImm(RPI.Offset / 2) // [sp, #imm*2*vscale],
2145 // where 2*vscale is implicit
2148 MachinePointerInfo::getFixedStack(MF, FrameIdxReg1),
2149 MachineMemOperand::MOStore, Size, Alignment));
2150 if (NeedsWinCFI)
2151 insertSEH(MIB, TII, MachineInstr::FrameSetup);
2152 } else { // The code when the pair of ZReg is not present
2153 MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(StrOpc));
2154 if (!MRI.isReserved(Reg1))
2155 MBB.addLiveIn(Reg1);
2156 if (RPI.isPaired()) {
2157 if (!MRI.isReserved(Reg2))
2158 MBB.addLiveIn(Reg2);
2159 MIB.addReg(Reg2, getPrologueDeath(MF, Reg2));
2161 MachinePointerInfo::getFixedStack(MF, FrameIdxReg2),
2162 MachineMemOperand::MOStore, Size, Alignment));
2163 }
2164 MIB.addReg(Reg1, getPrologueDeath(MF, Reg1))
2165 .addReg(AArch64::SP)
2166 .addImm(RPI.Offset) // [sp, #offset*vscale],
2167 // where factor*vscale is implicit
2170 MachinePointerInfo::getFixedStack(MF, FrameIdxReg1),
2171 MachineMemOperand::MOStore, Size, Alignment));
2172 if (NeedsWinCFI)
2173 insertSEH(MIB, TII, MachineInstr::FrameSetup);
2174 }
2175 // Update the StackIDs of the SVE stack slots.
2176 MachineFrameInfo &MFI = MF.getFrameInfo();
2177 if (RPI.Type == RegPairInfo::ZPR) {
2178 MFI.setStackID(FrameIdxReg1, TargetStackID::ScalableVector);
2179 if (RPI.isPaired())
2180 MFI.setStackID(FrameIdxReg2, TargetStackID::ScalableVector);
2181 } else if (RPI.Type == RegPairInfo::PPR) {
2183 if (RPI.isPaired())
2185 }
2186 }
2187 return true;
2188}
2189
2193 MachineFunction &MF = *MBB.getParent();
2194 const AArch64InstrInfo &TII =
2195 *MF.getSubtarget<AArch64Subtarget>().getInstrInfo();
2196 DebugLoc DL;
2198 bool NeedsWinCFI = needsWinCFI(MF);
2199
2200 if (MBBI != MBB.end())
2201 DL = MBBI->getDebugLoc();
2202
2203 computeCalleeSaveRegisterPairs(*this, MF, CSI, TRI, RegPairs, hasFP(MF));
2204 if (homogeneousPrologEpilog(MF, &MBB)) {
2205 auto MIB = BuildMI(MBB, MBBI, DL, TII.get(AArch64::HOM_Epilog))
2207 for (auto &RPI : RegPairs) {
2208 MIB.addReg(RPI.Reg1, RegState::Define);
2209 MIB.addReg(RPI.Reg2, RegState::Define);
2210 }
2211 return true;
2212 }
2213
2214 // For performance reasons restore SVE register in increasing order
2215 auto IsPPR = [](const RegPairInfo &c) { return c.Type == RegPairInfo::PPR; };
2216 auto PPRBegin = llvm::find_if(RegPairs, IsPPR);
2217 auto PPREnd = std::find_if_not(PPRBegin, RegPairs.end(), IsPPR);
2218 std::reverse(PPRBegin, PPREnd);
2219 auto IsZPR = [](const RegPairInfo &c) { return c.Type == RegPairInfo::ZPR; };
2220 auto ZPRBegin = llvm::find_if(RegPairs, IsZPR);
2221 auto ZPREnd = std::find_if_not(ZPRBegin, RegPairs.end(), IsZPR);
2222 std::reverse(ZPRBegin, ZPREnd);
2223
2224 bool PTrueCreated = false;
2225 for (const RegPairInfo &RPI : RegPairs) {
2226 Register Reg1 = RPI.Reg1;
2227 Register Reg2 = RPI.Reg2;
2228
2229 // Issue sequence of restores for cs regs. The last restore may be converted
2230 // to a post-increment load later by emitEpilogue if the callee-save stack
2231 // area allocation can't be combined with the local stack area allocation.
2232 // For example:
2233 // ldp fp, lr, [sp, #32] // addImm(+4)
2234 // ldp x20, x19, [sp, #16] // addImm(+2)
2235 // ldp x22, x21, [sp, #0] // addImm(+0)
2236 // Note: see comment in spillCalleeSavedRegisters()
2237 unsigned LdrOpc;
2238 unsigned Size = TRI->getSpillSize(*RPI.RC);
2239 Align Alignment = TRI->getSpillAlign(*RPI.RC);
2240 switch (RPI.Type) {
2241 case RegPairInfo::GPR:
2242 LdrOpc = RPI.isPaired() ? AArch64::LDPXi : AArch64::LDRXui;
2243 break;
2244 case RegPairInfo::FPR64:
2245 LdrOpc = RPI.isPaired() ? AArch64::LDPDi : AArch64::LDRDui;
2246 break;
2247 case RegPairInfo::FPR128:
2248 LdrOpc = RPI.isPaired() ? AArch64::LDPQi : AArch64::LDRQui;
2249 break;
2250 case RegPairInfo::ZPR:
2251 LdrOpc = RPI.isPaired() ? AArch64::LD1B_2Z_IMM : AArch64::LDR_ZXI;
2252 break;
2253 case RegPairInfo::PPR:
2254 LdrOpc = AArch64::LDR_PXI;
2255 break;
2256 case RegPairInfo::VG:
2257 continue;
2258 }
2259 LLVM_DEBUG({
2260 dbgs() << "CSR restore: (" << printReg(Reg1, TRI);
2261 if (RPI.isPaired())
2262 dbgs() << ", " << printReg(Reg2, TRI);
2263 dbgs() << ") -> fi#(" << RPI.FrameIdx;
2264 if (RPI.isPaired())
2265 dbgs() << ", " << RPI.FrameIdx + 1;
2266 dbgs() << ")\n";
2267 });
2268
2269 // Windows unwind codes require consecutive registers if registers are
2270 // paired. Make the switch here, so that the code below will save (x,x+1)
2271 // and not (x+1,x).
2272 unsigned FrameIdxReg1 = RPI.FrameIdx;
2273 unsigned FrameIdxReg2 = RPI.FrameIdx + 1;
2274 if (isTargetWindows(MF) && RPI.isPaired()) {
2275 std::swap(Reg1, Reg2);
2276 std::swap(FrameIdxReg1, FrameIdxReg2);
2277 }
2278
2280 if (RPI.isPaired() && RPI.isScalable()) {
2281 [[maybe_unused]] const AArch64Subtarget &Subtarget =
2283 unsigned PnReg = AFI->getPredicateRegForFillSpill();
2284 assert((PnReg != 0 && enableMultiVectorSpillFill(Subtarget, MF)) &&
2285 "Expects SVE2.1 or SME2 target and a predicate register");
2286#ifdef EXPENSIVE_CHECKS
2287 assert(!(PPRBegin < ZPRBegin) &&
2288 "Expected callee save predicate to be handled first");
2289#endif
2290 if (!PTrueCreated) {
2291 PTrueCreated = true;
2292 BuildMI(MBB, MBBI, DL, TII.get(AArch64::PTRUE_C_B), PnReg)
2294 }
2295 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII.get(LdrOpc));
2296 MIB.addReg(/*PairRegs*/ AArch64::Z0_Z1 + (RPI.Reg1 - AArch64::Z0),
2297 getDefRegState(true));
2299 MachinePointerInfo::getFixedStack(MF, FrameIdxReg2),
2300 MachineMemOperand::MOLoad, Size, Alignment));
2301 MIB.addReg(PnReg);
2302 MIB.addReg(AArch64::SP)
2303 .addImm(RPI.Offset / 2) // [sp, #imm*2*vscale]
2304 // where 2*vscale is implicit
2307 MachinePointerInfo::getFixedStack(MF, FrameIdxReg1),
2308 MachineMemOperand::MOLoad, Size, Alignment));
2309 if (NeedsWinCFI)
2310 insertSEH(MIB, TII, MachineInstr::FrameDestroy);
2311 } else {
2312 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII.get(LdrOpc));
2313 if (RPI.isPaired()) {
2314 MIB.addReg(Reg2, getDefRegState(true));
2316 MachinePointerInfo::getFixedStack(MF, FrameIdxReg2),
2317 MachineMemOperand::MOLoad, Size, Alignment));
2318 }
2319 MIB.addReg(Reg1, getDefRegState(true));
2320 MIB.addReg(AArch64::SP)
2321 .addImm(RPI.Offset) // [sp, #offset*vscale]
2322 // where factor*vscale is implicit
2325 MachinePointerInfo::getFixedStack(MF, FrameIdxReg1),
2326 MachineMemOperand::MOLoad, Size, Alignment));
2327 if (NeedsWinCFI)
2328 insertSEH(MIB, TII, MachineInstr::FrameDestroy);
2329 }
2330 }
2331 return true;
2332}
2333
2334// Return the FrameID for a MMO.
2335static std::optional<int> getMMOFrameID(MachineMemOperand *MMO,
2336 const MachineFrameInfo &MFI) {
2337 auto *PSV =
2339 if (PSV)
2340 return std::optional<int>(PSV->getFrameIndex());
2341
2342 if (MMO->getValue()) {
2343 if (auto *Al = dyn_cast<AllocaInst>(getUnderlyingObject(MMO->getValue()))) {
2344 for (int FI = MFI.getObjectIndexBegin(); FI < MFI.getObjectIndexEnd();
2345 FI++)
2346 if (MFI.getObjectAllocation(FI) == Al)
2347 return FI;
2348 }
2349 }
2350
2351 return std::nullopt;
2352}
2353
2354// Return the FrameID for a Load/Store instruction by looking at the first MMO.
2355static std::optional<int> getLdStFrameID(const MachineInstr &MI,
2356 const MachineFrameInfo &MFI) {
2357 if (!MI.mayLoadOrStore() || MI.getNumMemOperands() < 1)
2358 return std::nullopt;
2359
2360 return getMMOFrameID(*MI.memoperands_begin(), MFI);
2361}
2362
2363// Returns true if the LDST MachineInstr \p MI is a PPR access.
2364static bool isPPRAccess(const MachineInstr &MI) {
2365 return AArch64::PPRRegClass.contains(MI.getOperand(0).getReg());
2366}
2367
2368// Check if a Hazard slot is needed for the current function, and if so create
2369// one for it. The index is stored in AArch64FunctionInfo->StackHazardSlotIndex,
2370// which can be used to determine if any hazard padding is needed.
2371void AArch64FrameLowering::determineStackHazardSlot(
2372 MachineFunction &MF, BitVector &SavedRegs) const {
2373 unsigned StackHazardSize = getStackHazardSize(MF);
2374 auto *AFI = MF.getInfo<AArch64FunctionInfo>();
2375 if (StackHazardSize == 0 || StackHazardSize % 16 != 0 ||
2377 return;
2378
2379 // Stack hazards are only needed in streaming functions.
2380 SMEAttrs Attrs = AFI->getSMEFnAttrs();
2381 if (!StackHazardInNonStreaming && Attrs.hasNonStreamingInterfaceAndBody())
2382 return;
2383
2384 MachineFrameInfo &MFI = MF.getFrameInfo();
2385
2386 // Add a hazard slot if there are any CSR FPR registers, or are any fp-only
2387 // stack objects.
2388 bool HasFPRCSRs = any_of(SavedRegs.set_bits(), [](unsigned Reg) {
2389 return AArch64::FPR64RegClass.contains(Reg) ||
2390 AArch64::FPR128RegClass.contains(Reg) ||
2391 AArch64::ZPRRegClass.contains(Reg);
2392 });
2393 bool HasPPRCSRs = any_of(SavedRegs.set_bits(), [](unsigned Reg) {
2394 return AArch64::PPRRegClass.contains(Reg);
2395 });
2396 bool HasFPRStackObjects = false;
2397 bool HasPPRStackObjects = false;
2398 if (!HasFPRCSRs || SplitSVEObjects) {
2399 enum SlotType : uint8_t {
2400 Unknown = 0,
2401 ZPRorFPR = 1 << 0,
2402 PPR = 1 << 1,
2403 GPR = 1 << 2,
2405 };
2406
2407 // Find stack slots solely used for one kind of register (ZPR, PPR, etc.),
2408 // based on the kinds of accesses used in the function.
2409 SmallVector<SlotType> SlotTypes(MFI.getObjectIndexEnd(), SlotType::Unknown);
2410 for (auto &MBB : MF) {
2411 for (auto &MI : MBB) {
2412 std::optional<int> FI = getLdStFrameID(MI, MFI);
2413 if (!FI || FI < 0 || FI > int(SlotTypes.size()))
2414 continue;
2415 if (MFI.hasScalableStackID(*FI)) {
2416 SlotTypes[*FI] |=
2417 isPPRAccess(MI) ? SlotType::PPR : SlotType::ZPRorFPR;
2418 } else {
2419 SlotTypes[*FI] |= AArch64InstrInfo::isFpOrNEON(MI)
2420 ? SlotType::ZPRorFPR
2421 : SlotType::GPR;
2422 }
2423 }
2424 }
2425
2426 for (int FI = 0; FI < int(SlotTypes.size()); ++FI) {
2427 HasFPRStackObjects |= SlotTypes[FI] == SlotType::ZPRorFPR;
2428 // For SplitSVEObjects remember that this stack slot is a predicate, this
2429 // will be needed later when determining the frame layout.
2430 if (SlotTypes[FI] == SlotType::PPR) {
2432 HasPPRStackObjects = true;
2433 }
2434 }
2435 }
2436
2437 if (HasFPRCSRs || HasFPRStackObjects) {
2438 int ID = MFI.CreateStackObject(StackHazardSize, Align(16), false);
2439 LLVM_DEBUG(dbgs() << "Created Hazard slot at " << ID << " size "
2440 << StackHazardSize << "\n");
2442 }
2443
2444 if (!AFI->hasStackHazardSlotIndex())
2445 return;
2446
2447 if (SplitSVEObjects) {
2448 CallingConv::ID CC = MF.getFunction().getCallingConv();
2449 if (AFI->isSVECC() || CC == CallingConv::AArch64_SVE_VectorCall) {
2450 AFI->setSplitSVEObjects(true);
2451 LLVM_DEBUG(dbgs() << "Using SplitSVEObjects for SVE CC function\n");
2452 return;
2453 }
2454
2455 // We only use SplitSVEObjects in non-SVE CC functions if there's a
2456 // possibility of a stack hazard between PPRs and ZPRs/FPRs.
2457 LLVM_DEBUG(dbgs() << "Determining if SplitSVEObjects should be used in "
2458 "non-SVE CC function...\n");
2459
2460 // If another calling convention is explicitly set FPRs can't be promoted to
2461 // ZPR callee-saves.
2463 LLVM_DEBUG(
2464 dbgs()
2465 << "Calling convention is not supported with SplitSVEObjects\n");
2466 return;
2467 }
2468
2469 if (!HasPPRCSRs && !HasPPRStackObjects) {
2470 LLVM_DEBUG(
2471 dbgs() << "Not using SplitSVEObjects as no PPRs are on the stack\n");
2472 return;
2473 }
2474
2475 if (!HasFPRCSRs && !HasFPRStackObjects) {
2476 LLVM_DEBUG(
2477 dbgs()
2478 << "Not using SplitSVEObjects as no FPRs or ZPRs are on the stack\n");
2479 return;
2480 }
2481
2482 [[maybe_unused]] const AArch64Subtarget &Subtarget =
2483 MF.getSubtarget<AArch64Subtarget>();
2485 "Expected SVE to be available for PPRs");
2486
2487 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
2488 // With SplitSVEObjects the CS hazard padding is placed between the
2489 // PPRs and ZPRs. If there are any FPR CS there would be a hazard between
2490 // them and the CS GRPs. Avoid this by promoting all FPR CS to ZPRs.
2491 BitVector FPRZRegs(SavedRegs.size());
2492 for (size_t Reg = 0, E = SavedRegs.size(); HasFPRCSRs && Reg < E; ++Reg) {
2493 BitVector::reference RegBit = SavedRegs[Reg];
2494 if (!RegBit)
2495 continue;
2496 unsigned SubRegIdx = 0;
2497 if (AArch64::FPR64RegClass.contains(Reg))
2498 SubRegIdx = AArch64::dsub;
2499 else if (AArch64::FPR128RegClass.contains(Reg))
2500 SubRegIdx = AArch64::zsub;
2501 else
2502 continue;
2503 // Clear the bit for the FPR save.
2504 RegBit = false;
2505 // Mark that we should save the corresponding ZPR.
2506 Register ZReg =
2507 TRI->getMatchingSuperReg(Reg, SubRegIdx, &AArch64::ZPRRegClass);
2508 FPRZRegs.set(ZReg);
2509 }
2510 SavedRegs |= FPRZRegs;
2511
2512 AFI->setSplitSVEObjects(true);
2513 LLVM_DEBUG(dbgs() << "SplitSVEObjects enabled!\n");
2514 }
2515}
2516
2518 BitVector &SavedRegs,
2519 RegScavenger *RS) const {
2520 // All calls are tail calls in GHC calling conv, and functions have no
2521 // prologue/epilogue.
2523 return;
2524
2525 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
2526
2528 const AArch64RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
2530 unsigned UnspilledCSGPR = AArch64::NoRegister;
2531 unsigned UnspilledCSGPRPaired = AArch64::NoRegister;
2532
2533 MachineFrameInfo &MFI = MF.getFrameInfo();
2534 const MCPhysReg *CSRegs = MF.getRegInfo().getCalleeSavedRegs();
2535
2536 MCRegister BasePointerReg =
2537 RegInfo->hasBasePointer(MF) ? RegInfo->getBaseRegister() : MCRegister();
2538
2539 unsigned ExtraCSSpill = 0;
2540 bool HasUnpairedGPR64 = false;
2541 bool HasPairZReg = false;
2542 BitVector UserReservedRegs = RegInfo->getUserReservedRegs(MF);
2543 BitVector ReservedRegs = RegInfo->getReservedRegs(MF);
2544
2545 // Figure out which callee-saved registers to save/restore.
2546 for (unsigned i = 0; CSRegs[i]; ++i) {
2547 const MCRegister Reg = CSRegs[i];
2548
2549 // Add the base pointer register to SavedRegs if it is callee-save.
2550 if (Reg == BasePointerReg)
2551 SavedRegs.set(Reg);
2552
2553 // Don't save manually reserved registers set through +reserve-x#i,
2554 // even for callee-saved registers, as per GCC's behavior.
2555 if (UserReservedRegs[Reg]) {
2556 SavedRegs.reset(Reg);
2557 continue;
2558 }
2559
2560 bool RegUsed = SavedRegs.test(Reg);
2561 MCRegister PairedReg;
2562 const bool RegIsGPR64 = AArch64::GPR64RegClass.contains(Reg);
2563 if (RegIsGPR64 || AArch64::FPR64RegClass.contains(Reg) ||
2564 AArch64::FPR128RegClass.contains(Reg)) {
2565 // Compensate for odd numbers of GP CSRs.
2566 // For now, all the known cases of odd number of CSRs are of GPRs.
2567 if (HasUnpairedGPR64)
2568 PairedReg = CSRegs[i % 2 == 0 ? i - 1 : i + 1];
2569 else
2570 PairedReg = CSRegs[i ^ 1];
2571 }
2572
2573 // If the function requires all the GP registers to save (SavedRegs),
2574 // and there are an odd number of GP CSRs at the same time (CSRegs),
2575 // PairedReg could be in a different register class from Reg, which would
2576 // lead to a FPR (usually D8) accidentally being marked saved.
2577 if (RegIsGPR64 && !AArch64::GPR64RegClass.contains(PairedReg)) {
2578 PairedReg = AArch64::NoRegister;
2579 HasUnpairedGPR64 = true;
2580 }
2581 assert(PairedReg == AArch64::NoRegister ||
2582 AArch64::GPR64RegClass.contains(Reg, PairedReg) ||
2583 AArch64::FPR64RegClass.contains(Reg, PairedReg) ||
2584 AArch64::FPR128RegClass.contains(Reg, PairedReg));
2585
2586 if (!RegUsed) {
2587 if (AArch64::GPR64RegClass.contains(Reg) && !ReservedRegs[Reg]) {
2588 UnspilledCSGPR = Reg;
2589 UnspilledCSGPRPaired = PairedReg;
2590 }
2591 continue;
2592 }
2593
2594 // MachO's compact unwind format relies on all registers being stored in
2595 // pairs.
2596 // FIXME: the usual format is actually better if unwinding isn't needed.
2597 if (producePairRegisters(MF) && PairedReg != AArch64::NoRegister &&
2598 !SavedRegs.test(PairedReg)) {
2599 SavedRegs.set(PairedReg);
2600 if (AArch64::GPR64RegClass.contains(PairedReg) &&
2601 !ReservedRegs[PairedReg])
2602 ExtraCSSpill = PairedReg;
2603 }
2604 // Check if there is a pair of ZRegs, so it can select PReg for spill/fill
2605 HasPairZReg |= (AArch64::ZPRRegClass.contains(Reg, CSRegs[i ^ 1]) &&
2606 SavedRegs.test(CSRegs[i ^ 1]));
2607 }
2608
2609 if (HasPairZReg && enableMultiVectorSpillFill(Subtarget, MF)) {
2611 // Find a suitable predicate register for the multi-vector spill/fill
2612 // instructions.
2613 MCRegister PnReg = findFreePredicateReg(SavedRegs);
2614 if (PnReg.isValid())
2615 AFI->setPredicateRegForFillSpill(PnReg);
2616 // If no free callee-save has been found assign one.
2617 if (!AFI->getPredicateRegForFillSpill() &&
2618 MF.getFunction().getCallingConv() ==
2620 SavedRegs.set(AArch64::P8);
2621 AFI->setPredicateRegForFillSpill(AArch64::PN8);
2622 }
2623
2624 assert(!ReservedRegs[AFI->getPredicateRegForFillSpill()] &&
2625 "Predicate cannot be a reserved register");
2626 }
2627
2629 !Subtarget.isTargetWindows()) {
2630 // For Windows calling convention on a non-windows OS, where X18 is treated
2631 // as reserved, back up X18 when entering non-windows code (marked with the
2632 // Windows calling convention) and restore when returning regardless of
2633 // whether the individual function uses it - it might call other functions
2634 // that clobber it.
2635 SavedRegs.set(AArch64::X18);
2636 }
2637
2638 // Determine if a Hazard slot should be used and where it should go.
2639 // If SplitSVEObjects is used, the hazard padding is placed between the PPRs
2640 // and ZPRs. Otherwise, it goes in the callee save area.
2641 determineStackHazardSlot(MF, SavedRegs);
2642
2643 // Calculates the callee saved stack size.
2644 unsigned CSStackSize = 0;
2645 unsigned ZPRCSStackSize = 0;
2646 unsigned PPRCSStackSize = 0;
2648 for (unsigned Reg : SavedRegs.set_bits()) {
2649 auto *RC = TRI->getMinimalPhysRegClass(MCRegister(Reg));
2650 assert(RC && "expected register class!");
2651 auto SpillSize = TRI->getSpillSize(*RC);
2652 bool IsZPR = AArch64::ZPRRegClass.contains(Reg);
2653 bool IsPPR = !IsZPR && AArch64::PPRRegClass.contains(Reg);
2654 if (IsZPR)
2655 ZPRCSStackSize += SpillSize;
2656 else if (IsPPR)
2657 PPRCSStackSize += SpillSize;
2658 else {
2659 // A register and its super-register can both appear in SavedRegs.
2660 // Only the widest register is actually spilled, so skip such
2661 // sub-registers here to avoid double-counting the overlap.
2662 bool SavedSuper = any_of(TRI->superregs(Reg), [&](MCPhysReg SuperReg) {
2663 return SavedRegs.test(SuperReg);
2664 });
2665 if (!SavedSuper)
2666 CSStackSize += SpillSize;
2667 }
2668 }
2669
2670 // Save number of saved regs, so we can easily update CSStackSize later to
2671 // account for any additional 64-bit GPR saves. Note: After this point
2672 // only 64-bit GPRs can be added to SavedRegs.
2673 unsigned NumSavedRegs = SavedRegs.count();
2674
2675 // If we have hazard padding in the CS area add that to the size.
2677 CSStackSize += getStackHazardSize(MF);
2678
2679 // Increase the callee-saved stack size if the function has streaming mode
2680 // changes, as we will need to spill the value of the VG register.
2681 if (requiresSaveVG(MF))
2682 CSStackSize += 8;
2683
2684 // If we must call __arm_get_current_vg in the prologue preserve the LR.
2685 if (requiresSaveVG(MF) && !Subtarget.hasSVE())
2686 SavedRegs.set(AArch64::LR);
2687
2688 // The frame record needs to be created by saving the appropriate registers
2689 uint64_t EstimatedStackSize = MFI.estimateStackSize(MF);
2690 if (hasFP(MF) ||
2691 windowsRequiresStackProbe(MF, EstimatedStackSize + CSStackSize + 16)) {
2692 SavedRegs.set(AArch64::FP);
2693 SavedRegs.set(AArch64::LR);
2694 }
2695
2696 LLVM_DEBUG({
2697 dbgs() << "*** determineCalleeSaves\nSaved CSRs:";
2698 for (unsigned Reg : SavedRegs.set_bits())
2699 dbgs() << ' ' << printReg(MCRegister(Reg), RegInfo);
2700 dbgs() << "\n";
2701 });
2702
2703 // If any callee-saved registers are used, the frame cannot be eliminated.
2704 auto [ZPRLocalStackSize, PPRLocalStackSize] =
2706 uint64_t SVELocals = ZPRLocalStackSize + PPRLocalStackSize;
2707 uint64_t SVEStackSize =
2708 alignTo(ZPRCSStackSize + PPRCSStackSize + SVELocals, 16);
2709 bool CanEliminateFrame = (SavedRegs.count() == 0) && !SVEStackSize;
2710
2711 // The CSR spill slots have not been allocated yet, so estimateStackSize
2712 // won't include them.
2713 unsigned EstimatedStackSizeLimit = estimateRSStackSizeLimit(MF);
2714
2715 // We may address some of the stack above the canonical frame address, either
2716 // for our own arguments or during a call. Include that in calculating whether
2717 // we have complicated addressing concerns.
2718 int64_t CalleeStackUsed = 0;
2719 for (int I = MFI.getObjectIndexBegin(); I != 0; ++I) {
2720 int64_t FixedOff = MFI.getObjectOffset(I);
2721 if (FixedOff > CalleeStackUsed)
2722 CalleeStackUsed = FixedOff;
2723 }
2724
2725 // Conservatively always assume BigStack when there are SVE spills.
2726 bool BigStack = SVEStackSize || (EstimatedStackSize + CSStackSize +
2727 CalleeStackUsed) > EstimatedStackSizeLimit;
2728 if (BigStack || !CanEliminateFrame || RegInfo->cannotEliminateFrame(MF))
2729 AFI->setHasStackFrame(true);
2730
2731 // Estimate if we might need to scavenge a register at some point in order
2732 // to materialize a stack offset. If so, either spill one additional
2733 // callee-saved register or reserve a special spill slot to facilitate
2734 // register scavenging. If we already spilled an extra callee-saved register
2735 // above to keep the number of spills even, we don't need to do anything else
2736 // here.
2737 if (BigStack) {
2738 if (!ExtraCSSpill && UnspilledCSGPR != AArch64::NoRegister) {
2739 LLVM_DEBUG(dbgs() << "Spilling " << printReg(UnspilledCSGPR, RegInfo)
2740 << " to get a scratch register.\n");
2741 SavedRegs.set(UnspilledCSGPR);
2742 ExtraCSSpill = UnspilledCSGPR;
2743
2744 // MachO's compact unwind format relies on all registers being stored in
2745 // pairs, so if we need to spill one extra for BigStack, then we need to
2746 // store the pair.
2747 if (producePairRegisters(MF)) {
2748 if (UnspilledCSGPRPaired == AArch64::NoRegister) {
2749 // Failed to make a pair for compact unwind format, revert spilling.
2750 if (produceCompactUnwindFrame(*this, MF)) {
2751 SavedRegs.reset(UnspilledCSGPR);
2752 ExtraCSSpill = AArch64::NoRegister;
2753 }
2754 } else
2755 SavedRegs.set(UnspilledCSGPRPaired);
2756 }
2757 }
2758
2759 // If we didn't find an extra callee-saved register to spill, create
2760 // an emergency spill slot.
2761 if (!ExtraCSSpill || MF.getRegInfo().isPhysRegUsed(ExtraCSSpill)) {
2763 const TargetRegisterClass &RC = AArch64::GPR64RegClass;
2764 unsigned Size = TRI->getSpillSize(RC);
2765 Align Alignment = TRI->getSpillAlign(RC);
2766 int FI = MFI.CreateSpillStackObject(Size, Alignment);
2767 RS->addScavengingFrameIndex(FI);
2768 LLVM_DEBUG(dbgs() << "No available CS registers, allocated fi#" << FI
2769 << " as the emergency spill slot.\n");
2770 }
2771 }
2772
2773 // Adding the size of additional 64bit GPR saves.
2774 CSStackSize += 8 * (SavedRegs.count() - NumSavedRegs);
2775
2776 // A Swift asynchronous context extends the frame record with a pointer
2777 // directly before FP.
2778 if (hasFP(MF) && AFI->hasSwiftAsyncContext())
2779 CSStackSize += 8;
2780
2781 uint64_t AlignedCSStackSize = alignTo(CSStackSize, 16);
2782 LLVM_DEBUG(dbgs() << "Estimated stack frame size: "
2783 << EstimatedStackSize + AlignedCSStackSize << " bytes.\n");
2784
2786 AFI->getCalleeSavedStackSize() == AlignedCSStackSize) &&
2787 "Should not invalidate callee saved info");
2788
2789 // Round up to register pair alignment to avoid additional SP adjustment
2790 // instructions.
2791 AFI->setCalleeSavedStackSize(AlignedCSStackSize);
2792 AFI->setCalleeSaveStackHasFreeSpace(AlignedCSStackSize != CSStackSize);
2793 AFI->setSVECalleeSavedStackSize(ZPRCSStackSize, alignTo(PPRCSStackSize, 16));
2794}
2795
2797 MachineFunction &MF, const TargetRegisterInfo *RegInfo,
2798 std::vector<CalleeSavedInfo> &CSI) const {
2799 bool IsWindows = isTargetWindows(MF);
2800 unsigned StackHazardSize = getStackHazardSize(MF);
2801 // To match the canonical windows frame layout, reverse the list of
2802 // callee saved registers to get them laid out by PrologEpilogInserter
2803 // in the right order. (PrologEpilogInserter allocates stack objects top
2804 // down. Windows canonical prologs store higher numbered registers at
2805 // the top, thus have the CSI array start from the highest registers.)
2806 if (IsWindows)
2807 std::reverse(CSI.begin(), CSI.end());
2808
2809 if (CSI.empty())
2810 return true; // Early exit if no callee saved registers are modified!
2811
2812 // Now that we know which registers need to be saved and restored, allocate
2813 // stack slots for them.
2814 MachineFrameInfo &MFI = MF.getFrameInfo();
2815 auto *AFI = MF.getInfo<AArch64FunctionInfo>();
2816
2817 if (IsWindows && hasFP(MF) && AFI->hasSwiftAsyncContext()) {
2818 int FrameIdx = MFI.CreateStackObject(8, Align(16), true);
2819 AFI->setSwiftAsyncContextFrameIdx(FrameIdx);
2820 MFI.setIsCalleeSavedObjectIndex(FrameIdx, true);
2821 }
2822
2823 // Insert VG into the list of CSRs, immediately before LR if saved.
2824 if (requiresSaveVG(MF)) {
2825 CalleeSavedInfo VGInfo(AArch64::VG);
2826 auto It =
2827 find_if(CSI, [](auto &Info) { return Info.getReg() == AArch64::LR; });
2828 if (It != CSI.end())
2829 CSI.insert(It, VGInfo);
2830 else
2831 CSI.push_back(VGInfo);
2832 }
2833
2834 Register LastReg = 0;
2835 int HazardSlotIndex = std::numeric_limits<int>::max();
2836 for (auto &CS : CSI) {
2837 MCRegister Reg = CS.getReg();
2838 const TargetRegisterClass *RC = RegInfo->getMinimalPhysRegClass(Reg);
2839
2840 // Create a hazard slot as we switch between GPR and FPR CSRs.
2842 (!LastReg || !AArch64InstrInfo::isFpOrNEON(LastReg)) &&
2844 assert(HazardSlotIndex == std::numeric_limits<int>::max() &&
2845 "Unexpected register order for hazard slot");
2846 HazardSlotIndex = MFI.CreateStackObject(StackHazardSize, Align(8), true);
2847 LLVM_DEBUG(dbgs() << "Created CSR Hazard at slot " << HazardSlotIndex
2848 << "\n");
2849 AFI->setStackHazardCSRSlotIndex(HazardSlotIndex);
2850 MFI.setIsCalleeSavedObjectIndex(HazardSlotIndex, true);
2851 }
2852
2853 unsigned Size = RegInfo->getSpillSize(*RC);
2854 Align Alignment(RegInfo->getSpillAlign(*RC));
2855 int FrameIdx = MFI.CreateStackObject(Size, Alignment, true);
2856 CS.setFrameIdx(FrameIdx);
2857 MFI.setIsCalleeSavedObjectIndex(FrameIdx, true);
2858
2859 // Grab 8 bytes below FP for the extended asynchronous frame info.
2860 if (hasFP(MF) && AFI->hasSwiftAsyncContext() && !IsWindows &&
2861 Reg == AArch64::FP) {
2862 FrameIdx = MFI.CreateStackObject(8, Alignment, true);
2863 AFI->setSwiftAsyncContextFrameIdx(FrameIdx);
2864 MFI.setIsCalleeSavedObjectIndex(FrameIdx, true);
2865 }
2866 LastReg = Reg;
2867 }
2868
2869 // Add hazard slot in the case where no FPR CSRs are present.
2871 HazardSlotIndex == std::numeric_limits<int>::max()) {
2872 HazardSlotIndex = MFI.CreateStackObject(StackHazardSize, Align(8), true);
2873 LLVM_DEBUG(dbgs() << "Created CSR Hazard at slot " << HazardSlotIndex
2874 << "\n");
2875 AFI->setStackHazardCSRSlotIndex(HazardSlotIndex);
2876 MFI.setIsCalleeSavedObjectIndex(HazardSlotIndex, true);
2877 }
2878
2879 return true;
2880}
2881
2883 const MachineFunction &MF) const {
2885 // If the function has streaming-mode changes, don't scavenge a
2886 // spillslot in the callee-save area, as that might require an
2887 // 'addvl' in the streaming-mode-changing call-sequence when the
2888 // function doesn't use a FP.
2889 if (AFI->hasStreamingModeChanges() && !hasFP(MF))
2890 return false;
2891 // Don't allow register salvaging with hazard slots, in case it moves objects
2892 // into the wrong place.
2893 if (AFI->hasStackHazardSlotIndex())
2894 return false;
2895 return AFI->hasCalleeSaveStackFreeSpace();
2896}
2897
2898/// returns true if there are any SVE callee saves.
2900 int &Min, int &Max) {
2901 Min = std::numeric_limits<int>::max();
2902 Max = std::numeric_limits<int>::min();
2903
2904 if (!MFI.isCalleeSavedInfoValid())
2905 return false;
2906
2907 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
2908 for (auto &CS : CSI) {
2909 if (AArch64::ZPRRegClass.contains(CS.getReg()) ||
2910 AArch64::PPRRegClass.contains(CS.getReg())) {
2911 assert((Max == std::numeric_limits<int>::min() ||
2912 Max + 1 == CS.getFrameIdx()) &&
2913 "SVE CalleeSaves are not consecutive");
2914 Min = std::min(Min, CS.getFrameIdx());
2915 Max = std::max(Max, CS.getFrameIdx());
2916 }
2917 }
2918 return Min != std::numeric_limits<int>::max();
2919}
2920
2922 AssignObjectOffsets AssignOffsets) {
2923 MachineFrameInfo &MFI = MF.getFrameInfo();
2924 auto *AFI = MF.getInfo<AArch64FunctionInfo>();
2925
2926 SVEStackSizes SVEStack{};
2927
2928 // With SplitSVEObjects we maintain separate stack offsets for predicates
2929 // (PPRs) and SVE vectors (ZPRs). When SplitSVEObjects is disabled predicates
2930 // are included in the SVE vector area.
2931 uint64_t &ZPRStackTop = SVEStack.ZPRStackSize;
2932 uint64_t &PPRStackTop =
2933 AFI->hasSplitSVEObjects() ? SVEStack.PPRStackSize : SVEStack.ZPRStackSize;
2934
2935#ifndef NDEBUG
2936 // First process all fixed stack objects.
2937 for (int I = MFI.getObjectIndexBegin(); I != 0; ++I)
2938 assert(!MFI.hasScalableStackID(I) &&
2939 "SVE vectors should never be passed on the stack by value, only by "
2940 "reference.");
2941#endif
2942
2943 auto AllocateObject = [&](int FI) {
2945 ? ZPRStackTop
2946 : PPRStackTop;
2947
2948 // FIXME: Given that the length of SVE vectors is not necessarily a power of
2949 // two, we'd need to align every object dynamically at runtime if the
2950 // alignment is larger than 16. This is not yet supported.
2951 Align Alignment = MFI.getObjectAlign(FI);
2952 if (Alignment > Align(16))
2954 "Alignment of scalable vectors > 16 bytes is not yet supported");
2955
2956 StackTop += MFI.getObjectSize(FI);
2957 StackTop = alignTo(StackTop, Alignment);
2958
2959 assert(StackTop < (uint64_t)std::numeric_limits<int64_t>::max() &&
2960 "SVE StackTop far too large?!");
2961
2962 int64_t Offset = -int64_t(StackTop);
2963 if (AssignOffsets == AssignObjectOffsets::Yes)
2964 MFI.setObjectOffset(FI, Offset);
2965
2966 LLVM_DEBUG(dbgs() << "alloc FI(" << FI << ") at SP[" << Offset << "]\n");
2967 };
2968
2969 // Then process all callee saved slots.
2970 int MinCSFrameIndex, MaxCSFrameIndex;
2971 if (getSVECalleeSaveSlotRange(MFI, MinCSFrameIndex, MaxCSFrameIndex)) {
2972 for (int FI = MinCSFrameIndex; FI <= MaxCSFrameIndex; ++FI)
2973 AllocateObject(FI);
2974 }
2975
2976 // Ensure the CS area is 16-byte aligned.
2977 PPRStackTop = alignTo(PPRStackTop, Align(16U));
2978 ZPRStackTop = alignTo(ZPRStackTop, Align(16U));
2979
2980 // Create a buffer of SVE objects to allocate and sort it.
2981 SmallVector<int, 8> ObjectsToAllocate;
2982 // If we have a stack protector, and we've previously decided that we have SVE
2983 // objects on the stack and thus need it to go in the SVE stack area, then it
2984 // needs to go first.
2985 int StackProtectorFI = -1;
2986 if (MFI.hasStackProtectorIndex()) {
2987 StackProtectorFI = MFI.getStackProtectorIndex();
2988 if (MFI.getStackID(StackProtectorFI) == TargetStackID::ScalableVector)
2989 ObjectsToAllocate.push_back(StackProtectorFI);
2990 }
2991
2992 for (int FI = 0, E = MFI.getObjectIndexEnd(); FI != E; ++FI) {
2993 if (FI == StackProtectorFI || MFI.isDeadObjectIndex(FI) ||
2995 continue;
2996
2999 continue;
3000
3001 ObjectsToAllocate.push_back(FI);
3002 }
3003
3004 // Allocate all SVE locals and spills
3005 for (unsigned FI : ObjectsToAllocate)
3006 AllocateObject(FI);
3007
3008 PPRStackTop = alignTo(PPRStackTop, Align(16U));
3009 ZPRStackTop = alignTo(ZPRStackTop, Align(16U));
3010
3011 if (AssignOffsets == AssignObjectOffsets::Yes)
3012 AFI->setStackSizeSVE(SVEStack.ZPRStackSize, SVEStack.PPRStackSize);
3013
3014 return SVEStack;
3015}
3016
3018 MachineFunction &MF, RegScavenger *RS) const {
3020 "Upwards growing stack unsupported");
3021
3023
3024 // If this function isn't doing Win64-style C++ EH, we don't need to do
3025 // anything.
3026 if (!MF.hasEHFunclets())
3027 return;
3028
3029 MachineFrameInfo &MFI = MF.getFrameInfo();
3030 auto *AFI = MF.getInfo<AArch64FunctionInfo>();
3031
3032 // Win64 C++ EH needs to allocate space for the catch objects in the fixed
3033 // object area right next to the UnwindHelp object.
3034 WinEHFuncInfo &EHInfo = *MF.getWinEHFuncInfo();
3035 int64_t CurrentOffset =
3037 for (WinEHTryBlockMapEntry &TBME : EHInfo.TryBlockMap) {
3038 for (WinEHHandlerType &H : TBME.HandlerArray) {
3039 int FrameIndex = H.CatchObj.FrameIndex;
3040 if ((FrameIndex != INT_MAX) && MFI.getObjectOffset(FrameIndex) == 0) {
3041 CurrentOffset =
3042 alignTo(CurrentOffset, MFI.getObjectAlign(FrameIndex).value());
3043 CurrentOffset += MFI.getObjectSize(FrameIndex);
3044 MFI.setObjectOffset(FrameIndex, -CurrentOffset);
3045 }
3046 }
3047 }
3048
3049 // Create an UnwindHelp object.
3050 // The UnwindHelp object is allocated at the start of the fixed object area
3051 int64_t UnwindHelpOffset = alignTo(CurrentOffset + 8, Align(16));
3052 assert(UnwindHelpOffset == getFixedObjectSize(MF, AFI, /*IsWin64*/ true,
3053 /*IsFunclet*/ false) &&
3054 "UnwindHelpOffset must be at the start of the fixed object area");
3055 int UnwindHelpFI = MFI.CreateFixedObject(/*Size*/ 8, -UnwindHelpOffset,
3056 /*IsImmutable=*/false);
3057 EHInfo.UnwindHelpFrameIdx = UnwindHelpFI;
3058
3059 MachineBasicBlock &MBB = MF.front();
3060 auto MBBI = MBB.begin();
3061 while (MBBI != MBB.end() && MBBI->getFlag(MachineInstr::FrameSetup))
3062 ++MBBI;
3063
3064 // We need to store -2 into the UnwindHelp object at the start of the
3065 // function.
3066 DebugLoc DL;
3067 RS->enterBasicBlockEnd(MBB);
3068 RS->backward(MBBI);
3069 Register DstReg = RS->FindUnusedReg(&AArch64::GPR64commonRegClass);
3070 assert(DstReg && "There must be a free register after frame setup");
3071 const AArch64InstrInfo &TII =
3072 *MF.getSubtarget<AArch64Subtarget>().getInstrInfo();
3073 BuildMI(MBB, MBBI, DL, TII.get(AArch64::MOVi64imm), DstReg).addImm(-2);
3074 BuildMI(MBB, MBBI, DL, TII.get(AArch64::STURXi))
3075 .addReg(DstReg, getKillRegState(true))
3076 .addFrameIndex(UnwindHelpFI)
3077 .addImm(0);
3078}
3079
3080namespace {
3081struct TagStoreInstr {
3083 int64_t Offset, Size;
3084 explicit TagStoreInstr(MachineInstr *MI, int64_t Offset, int64_t Size)
3085 : MI(MI), Offset(Offset), Size(Size) {}
3086};
3087
3088class TagStoreEdit {
3089 MachineFunction *MF;
3090 MachineBasicBlock *MBB;
3091 MachineRegisterInfo *MRI;
3092 // Tag store instructions that are being replaced.
3094 // Combined memref arguments of the above instructions.
3096
3097 // Replace allocation tags in [FrameReg + FrameRegOffset, FrameReg +
3098 // FrameRegOffset + Size) with the address tag of SP.
3099 Register FrameReg;
3100 StackOffset FrameRegOffset;
3101 int64_t Size;
3102 // If not std::nullopt, move FrameReg to (FrameReg + FrameRegUpdate) at the
3103 // end.
3104 std::optional<int64_t> FrameRegUpdate;
3105 // MIFlags for any FrameReg updating instructions.
3106 unsigned FrameRegUpdateFlags;
3107
3108 // Use zeroing instruction variants.
3109 bool ZeroData;
3110 DebugLoc DL;
3111
3112 void emitUnrolled(MachineBasicBlock::iterator InsertI);
3113 void emitLoop(MachineBasicBlock::iterator InsertI);
3114
3115public:
3116 TagStoreEdit(MachineBasicBlock *MBB, bool ZeroData)
3117 : MBB(MBB), ZeroData(ZeroData) {
3118 MF = MBB->getParent();
3119 MRI = &MF->getRegInfo();
3120 }
3121 // Add an instruction to be replaced. Instructions must be added in the
3122 // ascending order of Offset, and have to be adjacent.
3123 void addInstruction(TagStoreInstr I) {
3124 assert((TagStores.empty() ||
3125 TagStores.back().Offset + TagStores.back().Size == I.Offset) &&
3126 "Non-adjacent tag store instructions.");
3127 TagStores.push_back(I);
3128 }
3129 void clear() { TagStores.clear(); }
3130 // Emit equivalent code at the given location, and erase the current set of
3131 // instructions. May skip if the replacement is not profitable. May invalidate
3132 // the input iterator and replace it with a valid one.
3133 void emitCode(MachineBasicBlock::iterator &InsertI,
3134 const AArch64FrameLowering *TFI, bool TryMergeSPUpdate);
3135};
3136
3137void TagStoreEdit::emitUnrolled(MachineBasicBlock::iterator InsertI) {
3138 const AArch64InstrInfo *TII =
3139 MF->getSubtarget<AArch64Subtarget>().getInstrInfo();
3140
3141 const int64_t kMinOffset = -256 * 16;
3142 const int64_t kMaxOffset = 255 * 16;
3143
3144 Register BaseReg = FrameReg;
3145 int64_t BaseRegOffsetBytes = FrameRegOffset.getFixed();
3146 if (BaseRegOffsetBytes < kMinOffset ||
3147 BaseRegOffsetBytes + (Size - Size % 32) > kMaxOffset ||
3148 // BaseReg can be FP, which is not necessarily aligned to 16-bytes. In
3149 // that case, BaseRegOffsetBytes will not be aligned to 16 bytes, which
3150 // is required for the offset of ST2G.
3151 BaseRegOffsetBytes % 16 != 0) {
3152 Register ScratchReg = MRI->createVirtualRegister(&AArch64::GPR64RegClass);
3153 emitFrameOffset(*MBB, InsertI, DL, ScratchReg, BaseReg,
3154 StackOffset::getFixed(BaseRegOffsetBytes), TII);
3155 BaseReg = ScratchReg;
3156 BaseRegOffsetBytes = 0;
3157 }
3158
3159 MachineInstr *LastI = nullptr;
3160 while (Size) {
3161 int64_t InstrSize = (Size > 16) ? 32 : 16;
3162 unsigned Opcode =
3163 InstrSize == 16
3164 ? (ZeroData ? AArch64::STZGi : AArch64::STGi)
3165 : (ZeroData ? AArch64::STZ2Gi : AArch64::ST2Gi);
3166 assert(BaseRegOffsetBytes % 16 == 0);
3167 MachineInstr *I = BuildMI(*MBB, InsertI, DL, TII->get(Opcode))
3168 .addReg(AArch64::SP)
3169 .addReg(BaseReg)
3170 .addImm(BaseRegOffsetBytes / 16)
3171 .setMemRefs(CombinedMemRefs);
3172 // A store to [BaseReg, #0] should go last for an opportunity to fold the
3173 // final SP adjustment in the epilogue.
3174 if (BaseRegOffsetBytes == 0)
3175 LastI = I;
3176 BaseRegOffsetBytes += InstrSize;
3177 Size -= InstrSize;
3178 }
3179
3180 if (LastI)
3181 MBB->splice(InsertI, MBB, LastI);
3182}
3183
3184void TagStoreEdit::emitLoop(MachineBasicBlock::iterator InsertI) {
3185 const AArch64InstrInfo *TII =
3186 MF->getSubtarget<AArch64Subtarget>().getInstrInfo();
3187
3188 Register BaseReg = FrameRegUpdate
3189 ? FrameReg
3190 : MRI->createVirtualRegister(&AArch64::GPR64RegClass);
3191 Register SizeReg = MRI->createVirtualRegister(&AArch64::GPR64RegClass);
3192
3193 emitFrameOffset(*MBB, InsertI, DL, BaseReg, FrameReg, FrameRegOffset, TII);
3194
3195 int64_t LoopSize = Size;
3196 // If the loop size is not a multiple of 32, split off one 16-byte store at
3197 // the end to fold BaseReg update into.
3198 if (FrameRegUpdate && *FrameRegUpdate)
3199 LoopSize -= LoopSize % 32;
3200 MachineInstr *LoopI = BuildMI(*MBB, InsertI, DL,
3201 TII->get(ZeroData ? AArch64::STZGloop_wback
3202 : AArch64::STGloop_wback))
3203 .addDef(SizeReg)
3204 .addDef(BaseReg)
3205 .addImm(LoopSize)
3206 .addReg(BaseReg)
3207 .setMemRefs(CombinedMemRefs);
3208 if (FrameRegUpdate)
3209 LoopI->setFlags(FrameRegUpdateFlags);
3210
3211 int64_t ExtraBaseRegUpdate =
3212 FrameRegUpdate ? (*FrameRegUpdate - FrameRegOffset.getFixed() - Size) : 0;
3213 LLVM_DEBUG(dbgs() << "TagStoreEdit::emitLoop: LoopSize=" << LoopSize
3214 << ", Size=" << Size
3215 << ", ExtraBaseRegUpdate=" << ExtraBaseRegUpdate
3216 << ", FrameRegUpdate=" << FrameRegUpdate
3217 << ", FrameRegOffset.getFixed()="
3218 << FrameRegOffset.getFixed() << "\n");
3219 if (LoopSize < Size) {
3220 assert(FrameRegUpdate);
3221 assert(Size - LoopSize == 16);
3222 // Tag 16 more bytes at BaseReg and update BaseReg.
3223 int64_t STGOffset = ExtraBaseRegUpdate + 16;
3224 assert(STGOffset % 16 == 0 && STGOffset >= -4096 && STGOffset <= 4080 &&
3225 "STG immediate out of range");
3226 BuildMI(*MBB, InsertI, DL,
3227 TII->get(ZeroData ? AArch64::STZGPostIndex : AArch64::STGPostIndex))
3228 .addDef(BaseReg)
3229 .addReg(BaseReg)
3230 .addReg(BaseReg)
3231 .addImm(STGOffset / 16)
3232 .setMemRefs(CombinedMemRefs)
3233 .setMIFlags(FrameRegUpdateFlags);
3234 } else if (ExtraBaseRegUpdate) {
3235 // Update BaseReg.
3236 int64_t AddSubOffset = std::abs(ExtraBaseRegUpdate);
3237 assert(AddSubOffset <= 4095 && "ADD/SUB immediate out of range");
3238 BuildMI(
3239 *MBB, InsertI, DL,
3240 TII->get(ExtraBaseRegUpdate > 0 ? AArch64::ADDXri : AArch64::SUBXri))
3241 .addDef(BaseReg)
3242 .addReg(BaseReg)
3243 .addImm(AddSubOffset)
3244 .addImm(0)
3245 .setMIFlags(FrameRegUpdateFlags);
3246 }
3247}
3248
3249// Check if *II is a register update that can be merged into STGloop that ends
3250// at (Reg + Size). RemainingOffset is the required adjustment to Reg after the
3251// end of the loop.
3252bool canMergeRegUpdate(MachineBasicBlock::iterator II, unsigned Reg,
3253 int64_t Size, int64_t *TotalOffset) {
3254 MachineInstr &MI = *II;
3255 if ((MI.getOpcode() == AArch64::ADDXri ||
3256 MI.getOpcode() == AArch64::SUBXri) &&
3257 MI.getOperand(0).getReg() == Reg && MI.getOperand(1).getReg() == Reg) {
3258 unsigned Shift = AArch64_AM::getShiftValue(MI.getOperand(3).getImm());
3259 int64_t Offset = MI.getOperand(2).getImm() << Shift;
3260 if (MI.getOpcode() == AArch64::SUBXri)
3261 Offset = -Offset;
3262 int64_t PostOffset = Offset - Size;
3263 // TagStoreEdit::emitLoop might emit either an ADD/SUB after the loop, or
3264 // an STGPostIndex which does the last 16 bytes of tag write. Which one is
3265 // chosen depends on the alignment of the loop size, but the difference
3266 // between the valid ranges for the two instructions is small, so we
3267 // conservatively assume that it could be either case here.
3268 //
3269 // Max offset of STGPostIndex, minus the 16 byte tag write folded into that
3270 // instruction.
3271 const int64_t kMaxOffset = 4080 - 16;
3272 // Max offset of SUBXri.
3273 const int64_t kMinOffset = -4095;
3274 if (PostOffset <= kMaxOffset && PostOffset >= kMinOffset &&
3275 PostOffset % 16 == 0) {
3276 *TotalOffset = Offset;
3277 return true;
3278 }
3279 }
3280 return false;
3281}
3282
3283void mergeMemRefs(const SmallVectorImpl<TagStoreInstr> &TSE,
3285 MemRefs.clear();
3286 for (auto &TS : TSE) {
3287 MachineInstr *MI = TS.MI;
3288 // An instruction without memory operands may access anything. Be
3289 // conservative and return an empty list.
3290 if (MI->memoperands_empty()) {
3291 MemRefs.clear();
3292 return;
3293 }
3294 MemRefs.append(MI->memoperands_begin(), MI->memoperands_end());
3295 }
3296}
3297
3298void TagStoreEdit::emitCode(MachineBasicBlock::iterator &InsertI,
3299 const AArch64FrameLowering *TFI,
3300 bool TryMergeSPUpdate) {
3301 if (TagStores.empty())
3302 return;
3303 TagStoreInstr &FirstTagStore = TagStores[0];
3304 TagStoreInstr &LastTagStore = TagStores[TagStores.size() - 1];
3305 Size = LastTagStore.Offset - FirstTagStore.Offset + LastTagStore.Size;
3306 DL = TagStores[0].MI->getDebugLoc();
3307
3308 Register Reg;
3309 FrameRegOffset = TFI->resolveFrameOffsetReference(
3310 *MF, FirstTagStore.Offset, false /*isFixed*/,
3311 TargetStackID::Default /*StackID*/, Reg,
3312 /*PreferFP=*/false, /*ForSimm=*/true);
3313 FrameReg = Reg;
3314 FrameRegUpdate = std::nullopt;
3315
3316 mergeMemRefs(TagStores, CombinedMemRefs);
3317
3318 LLVM_DEBUG({
3319 dbgs() << "Replacing adjacent STG instructions:\n";
3320 for (const auto &Instr : TagStores) {
3321 dbgs() << " " << *Instr.MI;
3322 }
3323 });
3324
3325 // Size threshold where a loop becomes shorter than a linear sequence of
3326 // tagging instructions.
3327 const int kSetTagLoopThreshold = 176;
3328 if (Size < kSetTagLoopThreshold) {
3329 if (TagStores.size() < 2)
3330 return;
3331 emitUnrolled(InsertI);
3332 } else {
3333 MachineInstr *UpdateInstr = nullptr;
3334 int64_t TotalOffset = 0;
3335 if (TryMergeSPUpdate) {
3336 // See if we can merge base register update into the STGloop.
3337 // This is done in AArch64LoadStoreOptimizer for "normal" stores,
3338 // but STGloop is way too unusual for that, and also it only
3339 // realistically happens in function epilogue. Also, STGloop is expanded
3340 // before that pass.
3341 if (InsertI != MBB->end() &&
3342 canMergeRegUpdate(InsertI, FrameReg, FrameRegOffset.getFixed() + Size,
3343 &TotalOffset)) {
3344 UpdateInstr = &*InsertI++;
3345 LLVM_DEBUG(dbgs() << "Folding SP update into loop:\n "
3346 << *UpdateInstr);
3347 }
3348 }
3349
3350 if (!UpdateInstr && TagStores.size() < 2)
3351 return;
3352
3353 if (UpdateInstr) {
3354 FrameRegUpdate = TotalOffset;
3355 FrameRegUpdateFlags = UpdateInstr->getFlags();
3356 }
3357 emitLoop(InsertI);
3358 if (UpdateInstr)
3359 UpdateInstr->eraseFromParent();
3360 }
3361
3362 for (auto &TS : TagStores)
3363 TS.MI->eraseFromParent();
3364}
3365
3366bool isMergeableStackTaggingInstruction(MachineInstr &MI, int64_t &Offset,
3367 int64_t &Size, bool &ZeroData) {
3368 MachineFunction &MF = *MI.getParent()->getParent();
3369 const MachineFrameInfo &MFI = MF.getFrameInfo();
3370
3371 unsigned Opcode = MI.getOpcode();
3372 ZeroData = (Opcode == AArch64::STZGloop || Opcode == AArch64::STZGi ||
3373 Opcode == AArch64::STZ2Gi);
3374
3375 if (Opcode == AArch64::STGloop || Opcode == AArch64::STZGloop) {
3376 if (!MI.getOperand(0).isDead() || !MI.getOperand(1).isDead())
3377 return false;
3378 if (!MI.getOperand(2).isImm() || !MI.getOperand(3).isFI())
3379 return false;
3380 Offset = MFI.getObjectOffset(MI.getOperand(3).getIndex());
3381 Size = MI.getOperand(2).getImm();
3382 return true;
3383 }
3384
3385 if (Opcode == AArch64::STGi || Opcode == AArch64::STZGi)
3386 Size = 16;
3387 else if (Opcode == AArch64::ST2Gi || Opcode == AArch64::STZ2Gi)
3388 Size = 32;
3389 else
3390 return false;
3391
3392 if (MI.getOperand(0).getReg() != AArch64::SP || !MI.getOperand(1).isFI())
3393 return false;
3394
3395 Offset = MFI.getObjectOffset(MI.getOperand(1).getIndex()) +
3396 16 * MI.getOperand(2).getImm();
3397 return true;
3398}
3399
3400static size_t countAvailableScavengerSlots(LivePhysRegs &LiveRegs,
3402 RegScavenger *RS) {
3403 auto FreeGPRs =
3404 llvm::count_if(AArch64::GPR64RegClass, [&LiveRegs, &MRI](auto Reg) {
3405 return LiveRegs.available(MRI, Reg);
3406 });
3407
3408 size_t NumEmergencySlots = 0;
3409 if (RS)
3410 NumEmergencySlots = RS->getNumScavengingFrameIndices();
3411
3412 return FreeGPRs + NumEmergencySlots;
3413}
3414
3415// Detect a run of memory tagging instructions for adjacent stack frame slots,
3416// and replace them with a shorter instruction sequence:
3417// * replace STG + STG with ST2G
3418// * replace STGloop + STGloop with STGloop
3419// This code needs to run when stack slot offsets are already known, but before
3420// FrameIndex operands in STG instructions are eliminated.
3422 const AArch64FrameLowering *TFI,
3423 RegScavenger *RS) {
3424 bool FirstZeroData;
3425 int64_t Size, Offset;
3426 MachineInstr &MI = *II;
3427 MachineBasicBlock *MBB = MI.getParent();
3429 if (&MI == &MBB->instr_back())
3430 return II;
3431 if (!isMergeableStackTaggingInstruction(MI, Offset, Size, FirstZeroData))
3432 return II;
3433
3435 Instrs.emplace_back(&MI, Offset, Size);
3436
3437 constexpr int kScanLimit = 10;
3438 int Count = 0;
3440 NextI != E && Count < kScanLimit; ++NextI) {
3441 MachineInstr &MI = *NextI;
3442 bool ZeroData;
3443 int64_t Size, Offset;
3444 // Collect instructions that update memory tags with a FrameIndex operand
3445 // and (when applicable) constant size, and whose output registers are dead
3446 // (the latter is almost always the case in practice). Since these
3447 // instructions effectively have no inputs or outputs, we are free to skip
3448 // any non-aliasing instructions in between without tracking used registers.
3449 if (isMergeableStackTaggingInstruction(MI, Offset, Size, ZeroData)) {
3450 if (ZeroData != FirstZeroData)
3451 break;
3452 Instrs.emplace_back(&MI, Offset, Size);
3453 continue;
3454 }
3455
3456 // Only count non-transient, non-tagging instructions toward the scan
3457 // limit.
3458 if (!MI.isTransient())
3459 ++Count;
3460
3461 // Just in case, stop before the epilogue code starts.
3462 if (MI.getFlag(MachineInstr::FrameSetup) ||
3464 break;
3465
3466 // Reject anything that may alias the collected instructions.
3467 if (MI.mayLoadOrStore() || MI.hasUnmodeledSideEffects() || MI.isCall())
3468 break;
3469 }
3470
3471 // New code will be inserted after the last tagging instruction we've found.
3472 MachineBasicBlock::iterator InsertI = Instrs.back().MI;
3473
3474 // All the gathered stack tag instructions are merged and placed after
3475 // last tag store in the list. The check should be made if the nzcv
3476 // flag is live at the point where we are trying to insert. Otherwise
3477 // the nzcv flag might get clobbered if any stg loops are present.
3478
3479 // FIXME : This approach of bailing out from merge is conservative in
3480 // some ways like even if stg loops are not present after merge the
3481 // insert list, this liveness check is done (which is not needed).
3483 LiveRegs.addLiveOuts(*MBB);
3484 for (auto I = MBB->rbegin();; ++I) {
3485 MachineInstr &MI = *I;
3486 if (MI == InsertI)
3487 break;
3488 LiveRegs.stepBackward(*I);
3489 }
3490 InsertI++;
3491 if (LiveRegs.contains(AArch64::NZCV))
3492 return InsertI;
3493
3494 // Emitting an MTE loop requires two physical registers (BaseReg and
3495 // SizeReg). If the function is under register pressure, the register
3496 // scavenger will crash trying to allocate them. If we don't have at least
3497 // two free slots (free registers + emergency slots), bail out and fall back
3498 // to the unrolled sequence.
3499 if (countAvailableScavengerSlots(LiveRegs, MBB->getParent()->getRegInfo(),
3500 RS) < 2) {
3501 LLVM_DEBUG(
3502 dbgs() << "Failed to merge MTE stack tagging instructions into loop "
3503 << "due to high register pressure.\n");
3504 return InsertI;
3505 }
3506
3507 llvm::stable_sort(Instrs,
3508 [](const TagStoreInstr &Left, const TagStoreInstr &Right) {
3509 return Left.Offset < Right.Offset;
3510 });
3511
3512 // Make sure that we don't have any overlapping stores.
3513 int64_t CurOffset = Instrs[0].Offset;
3514 for (auto &Instr : Instrs) {
3515 if (CurOffset > Instr.Offset)
3516 return NextI;
3517 CurOffset = Instr.Offset + Instr.Size;
3518 }
3519
3520 // Find contiguous runs of tagged memory and emit shorter instruction
3521 // sequences for them when possible.
3522 TagStoreEdit TSE(MBB, FirstZeroData);
3523 std::optional<int64_t> EndOffset;
3524 for (auto &Instr : Instrs) {
3525 if (EndOffset && *EndOffset != Instr.Offset) {
3526 // Found a gap.
3527 TSE.emitCode(InsertI, TFI, /*TryMergeSPUpdate = */ false);
3528 TSE.clear();
3529 }
3530
3531 TSE.addInstruction(Instr);
3532 EndOffset = Instr.Offset + Instr.Size;
3533 }
3534
3535 const MachineFunction *MF = MBB->getParent();
3536 // Multiple FP/SP updates in a loop cannot be described by CFI instructions.
3537 TSE.emitCode(
3538 InsertI, TFI, /*TryMergeSPUpdate = */
3540
3541 return InsertI;
3542}
3543} // namespace
3544
3546 MachineFunction &MF, RegScavenger *RS = nullptr) const {
3547 for (auto &BB : MF)
3548 for (MachineBasicBlock::iterator II = BB.begin(); II != BB.end();) {
3550 II = tryMergeAdjacentSTG(II, this, RS);
3551 }
3552
3553 // By the time this method is called, most of the prologue/epilogue code is
3554 // already emitted, whether its location was affected by the shrink-wrapping
3555 // optimization or not.
3556 if (!MF.getFunction().hasFnAttribute(Attribute::Naked) &&
3557 shouldSignReturnAddressEverywhere(MF))
3559}
3560
3561/// For Win64 AArch64 EH, the offset to the Unwind object is from the SP
3562/// before the update. This is easily retrieved as it is exactly the offset
3563/// that is set in processFunctionBeforeFrameFinalized.
3565 const MachineFunction &MF, int FI, Register &FrameReg,
3566 bool IgnoreSPUpdates) const {
3567 const MachineFrameInfo &MFI = MF.getFrameInfo();
3568 if (IgnoreSPUpdates) {
3569 LLVM_DEBUG(dbgs() << "Offset from the SP for " << FI << " is "
3570 << MFI.getObjectOffset(FI) << "\n");
3571 FrameReg = AArch64::SP;
3572 return StackOffset::getFixed(MFI.getObjectOffset(FI));
3573 }
3574
3575 // Go to common code if we cannot provide sp + offset.
3576 if (MFI.hasVarSizedObjects() ||
3579 return getFrameIndexReference(MF, FI, FrameReg);
3580
3581 FrameReg = AArch64::SP;
3582 return getStackOffset(MF, MFI.getObjectOffset(FI));
3583}
3584
3585/// The parent frame offset (aka dispFrame) is only used on X86_64 to retrieve
3586/// the parent's frame pointer
3588 const MachineFunction &MF) const {
3589 return 0;
3590}
3591
3592/// Funclets only need to account for space for the callee saved registers,
3593/// as the locals are accounted for in the parent's stack frame.
3595 const MachineFunction &MF) const {
3596 // This is the size of the pushed CSRs.
3597 unsigned CSSize =
3598 MF.getInfo<AArch64FunctionInfo>()->getCalleeSavedStackSize();
3599 // This is the amount of stack a funclet needs to allocate.
3600 return alignTo(CSSize + MF.getFrameInfo().getMaxCallFrameSize(),
3601 getStackAlign());
3602}
3603
3604namespace {
3605struct FrameObject {
3606 bool IsValid = false;
3607 // Index of the object in MFI.
3608 int ObjectIndex = 0;
3609 // Group ID this object belongs to.
3610 int GroupIndex = -1;
3611 // This object should be placed first (closest to SP).
3612 bool ObjectFirst = false;
3613 // This object's group (which always contains the object with
3614 // ObjectFirst==true) should be placed first.
3615 bool GroupFirst = false;
3616
3617 // Used to distinguish between FP and GPR accesses. The values are decided so
3618 // that they sort FPR < Hazard < GPR and they can be or'd together.
3619 unsigned Accesses = 0;
3620 enum { AccessFPR = 1, AccessHazard = 2, AccessGPR = 4 };
3621};
3622
3623class GroupBuilder {
3624 SmallVector<int, 8> CurrentMembers;
3625 int NextGroupIndex = 0;
3626 std::vector<FrameObject> &Objects;
3627
3628public:
3629 GroupBuilder(std::vector<FrameObject> &Objects) : Objects(Objects) {}
3630 void AddMember(int Index) { CurrentMembers.push_back(Index); }
3631 void EndCurrentGroup() {
3632 if (CurrentMembers.size() > 1) {
3633 // Create a new group with the current member list. This might remove them
3634 // from their pre-existing groups. That's OK, dealing with overlapping
3635 // groups is too hard and unlikely to make a difference.
3636 LLVM_DEBUG(dbgs() << "group:");
3637 for (int Index : CurrentMembers) {
3638 Objects[Index].GroupIndex = NextGroupIndex;
3639 LLVM_DEBUG(dbgs() << " " << Index);
3640 }
3641 LLVM_DEBUG(dbgs() << "\n");
3642 NextGroupIndex++;
3643 }
3644 CurrentMembers.clear();
3645 }
3646};
3647
3648bool FrameObjectCompare(const FrameObject &A, const FrameObject &B) {
3649 // Objects at a lower index are closer to FP; objects at a higher index are
3650 // closer to SP.
3651 //
3652 // For consistency in our comparison, all invalid objects are placed
3653 // at the end. This also allows us to stop walking when we hit the
3654 // first invalid item after it's all sorted.
3655 //
3656 // If we want to include a stack hazard region, order FPR accesses < the
3657 // hazard object < GPRs accesses in order to create a separation between the
3658 // two. For the Accesses field 1 = FPR, 2 = Hazard Object, 4 = GPR.
3659 //
3660 // Otherwise the "first" object goes first (closest to SP), followed by the
3661 // members of the "first" group.
3662 //
3663 // The rest are sorted by the group index to keep the groups together.
3664 // Higher numbered groups are more likely to be around longer (i.e. untagged
3665 // in the function epilogue and not at some earlier point). Place them closer
3666 // to SP.
3667 //
3668 // If all else equal, sort by the object index to keep the objects in the
3669 // original order.
3670 return std::make_tuple(!A.IsValid, A.Accesses, A.ObjectFirst, A.GroupFirst,
3671 A.GroupIndex, A.ObjectIndex) <
3672 std::make_tuple(!B.IsValid, B.Accesses, B.ObjectFirst, B.GroupFirst,
3673 B.GroupIndex, B.ObjectIndex);
3674}
3675} // namespace
3676
3678 const MachineFunction &MF, SmallVectorImpl<int> &ObjectsToAllocate) const {
3680
3681 if ((!OrderFrameObjects && !AFI.hasSplitSVEObjects()) ||
3682 ObjectsToAllocate.empty())
3683 return;
3684
3685 const MachineFrameInfo &MFI = MF.getFrameInfo();
3686 std::vector<FrameObject> FrameObjects(MFI.getObjectIndexEnd());
3687 for (auto &Obj : ObjectsToAllocate) {
3688 FrameObjects[Obj].IsValid = true;
3689 FrameObjects[Obj].ObjectIndex = Obj;
3690 }
3691
3692 // Identify FPR vs GPR slots for hazards, and stack slots that are tagged at
3693 // the same time.
3694 GroupBuilder GB(FrameObjects);
3695 for (auto &MBB : MF) {
3696 for (auto &MI : MBB) {
3697 if (MI.isDebugInstr())
3698 continue;
3699
3700 if (AFI.hasStackHazardSlotIndex()) {
3701 std::optional<int> FI = getLdStFrameID(MI, MFI);
3702 if (FI && *FI >= 0 && *FI < (int)FrameObjects.size()) {
3703 if (MFI.getStackID(*FI) == TargetStackID::ScalableVector ||
3705 FrameObjects[*FI].Accesses |= FrameObject::AccessFPR;
3706 else
3707 FrameObjects[*FI].Accesses |= FrameObject::AccessGPR;
3708 }
3709 }
3710
3711 int OpIndex;
3712 switch (MI.getOpcode()) {
3713 case AArch64::STGloop:
3714 case AArch64::STZGloop:
3715 OpIndex = 3;
3716 break;
3717 case AArch64::STGi:
3718 case AArch64::STZGi:
3719 case AArch64::ST2Gi:
3720 case AArch64::STZ2Gi:
3721 OpIndex = 1;
3722 break;
3723 default:
3724 OpIndex = -1;
3725 }
3726
3727 int TaggedFI = -1;
3728 if (OpIndex >= 0) {
3729 const MachineOperand &MO = MI.getOperand(OpIndex);
3730 if (MO.isFI()) {
3731 int FI = MO.getIndex();
3732 if (FI >= 0 && FI < MFI.getObjectIndexEnd() &&
3733 FrameObjects[FI].IsValid)
3734 TaggedFI = FI;
3735 }
3736 }
3737
3738 // If this is a stack tagging instruction for a slot that is not part of a
3739 // group yet, either start a new group or add it to the current one.
3740 if (TaggedFI >= 0)
3741 GB.AddMember(TaggedFI);
3742 else
3743 GB.EndCurrentGroup();
3744 }
3745 // Groups should never span multiple basic blocks.
3746 GB.EndCurrentGroup();
3747 }
3748
3749 if (AFI.hasStackHazardSlotIndex()) {
3750 FrameObjects[AFI.getStackHazardSlotIndex()].Accesses =
3751 FrameObject::AccessHazard;
3752 // If a stack object is unknown or both GPR and FPR, sort it into GPR.
3753 for (auto &Obj : FrameObjects)
3754 if (!Obj.Accesses ||
3755 Obj.Accesses == (FrameObject::AccessGPR | FrameObject::AccessFPR))
3756 Obj.Accesses = FrameObject::AccessGPR;
3757 }
3758
3759 // If the function's tagged base pointer is pinned to a stack slot, we want to
3760 // put that slot first when possible. This will likely place it at SP + 0,
3761 // and save one instruction when generating the base pointer because IRG does
3762 // not allow an immediate offset.
3763 std::optional<int> TBPI = AFI.getTaggedBasePointerIndex();
3764 if (TBPI) {
3765 FrameObjects[*TBPI].ObjectFirst = true;
3766 FrameObjects[*TBPI].GroupFirst = true;
3767 int FirstGroupIndex = FrameObjects[*TBPI].GroupIndex;
3768 if (FirstGroupIndex >= 0)
3769 for (FrameObject &Object : FrameObjects)
3770 if (Object.GroupIndex == FirstGroupIndex)
3771 Object.GroupFirst = true;
3772 }
3773
3774 llvm::stable_sort(FrameObjects, FrameObjectCompare);
3775
3776 int i = 0;
3777 for (auto &Obj : FrameObjects) {
3778 // All invalid items are sorted at the end, so it's safe to stop.
3779 if (!Obj.IsValid)
3780 break;
3781 ObjectsToAllocate[i++] = Obj.ObjectIndex;
3782 }
3783
3784 LLVM_DEBUG({
3785 dbgs() << "Final frame order:\n";
3786 for (auto &Obj : FrameObjects) {
3787 if (!Obj.IsValid)
3788 break;
3789 dbgs() << " " << Obj.ObjectIndex << ": group " << Obj.GroupIndex;
3790 if (Obj.ObjectFirst)
3791 dbgs() << ", first";
3792 if (Obj.GroupFirst)
3793 dbgs() << ", group-first";
3794 dbgs() << "\n";
3795 }
3796 });
3797}
3798
3799/// Emit a loop to decrement SP until it is equal to TargetReg, with probes at
3800/// least every ProbeSize bytes. Returns an iterator of the first instruction
3801/// after the loop. The difference between SP and TargetReg must be an exact
3802/// multiple of ProbeSize.
3804AArch64FrameLowering::inlineStackProbeLoopExactMultiple(
3805 MachineBasicBlock::iterator MBBI, int64_t ProbeSize,
3806 Register TargetReg) const {
3807 MachineBasicBlock &MBB = *MBBI->getParent();
3808 MachineFunction &MF = *MBB.getParent();
3809 const AArch64InstrInfo *TII =
3810 MF.getSubtarget<AArch64Subtarget>().getInstrInfo();
3811 DebugLoc DL = MBB.findDebugLoc(MBBI);
3812
3813 MachineFunction::iterator MBBInsertPoint = std::next(MBB.getIterator());
3814 MachineBasicBlock *LoopMBB = MF.CreateMachineBasicBlock(MBB.getBasicBlock());
3815 MF.insert(MBBInsertPoint, LoopMBB);
3816 MachineBasicBlock *ExitMBB = MF.CreateMachineBasicBlock(MBB.getBasicBlock());
3817 MF.insert(MBBInsertPoint, ExitMBB);
3818
3819 // SUB SP, SP, #ProbeSize (or equivalent if ProbeSize is not encodable
3820 // in SUB).
3821 emitFrameOffset(*LoopMBB, LoopMBB->end(), DL, AArch64::SP, AArch64::SP,
3822 StackOffset::getFixed(-ProbeSize), TII,
3824 // LDR XZR, [SP]
3825 BuildMI(*LoopMBB, LoopMBB->end(), DL, TII->get(AArch64::LDRXui))
3826 .addDef(AArch64::XZR)
3827 .addReg(AArch64::SP)
3828 .addImm(0)
3832 Align(8)))
3834 // CMP SP, TargetReg
3835 BuildMI(*LoopMBB, LoopMBB->end(), DL, TII->get(AArch64::SUBSXrx64),
3836 AArch64::XZR)
3837 .addReg(AArch64::SP)
3838 .addReg(TargetReg)
3841 // B.CC Loop
3842 BuildMI(*LoopMBB, LoopMBB->end(), DL, TII->get(AArch64::Bcc))
3844 .addMBB(LoopMBB)
3846
3847 LoopMBB->addSuccessor(ExitMBB);
3848 LoopMBB->addSuccessor(LoopMBB);
3849 // Synthesize the exit MBB.
3850 ExitMBB->splice(ExitMBB->end(), &MBB, MBBI, MBB.end());
3852 MBB.addSuccessor(LoopMBB);
3853 // Update liveins.
3854 fullyRecomputeLiveIns({ExitMBB, LoopMBB});
3855
3856 return ExitMBB->begin();
3857}
3858
3859void AArch64FrameLowering::inlineStackProbeFixed(
3860 MachineBasicBlock::iterator MBBI, Register ScratchReg, int64_t FrameSize,
3861 StackOffset CFAOffset) const {
3862 MachineBasicBlock *MBB = MBBI->getParent();
3863 MachineFunction &MF = *MBB->getParent();
3864 const AArch64InstrInfo *TII =
3865 MF.getSubtarget<AArch64Subtarget>().getInstrInfo();
3866 AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
3867 bool EmitAsyncCFI = AFI->needsAsyncDwarfUnwindInfo(MF);
3868 bool HasFP = hasFP(MF);
3869
3870 DebugLoc DL;
3871 int64_t ProbeSize = MF.getInfo<AArch64FunctionInfo>()->getStackProbeSize();
3872 int64_t NumBlocks = FrameSize / ProbeSize;
3873 int64_t ResidualSize = FrameSize % ProbeSize;
3874
3875 LLVM_DEBUG(dbgs() << "Stack probing: total " << FrameSize << " bytes, "
3876 << NumBlocks << " blocks of " << ProbeSize
3877 << " bytes, plus " << ResidualSize << " bytes\n");
3878
3879 // Decrement SP by NumBlock * ProbeSize bytes, with either unrolled or
3880 // ordinary loop.
3881 if (NumBlocks <= AArch64::StackProbeMaxLoopUnroll) {
3882 for (int i = 0; i < NumBlocks; ++i) {
3883 // SUB SP, SP, #ProbeSize (or equivalent if ProbeSize is not
3884 // encodable in a SUB).
3885 emitFrameOffset(*MBB, MBBI, DL, AArch64::SP, AArch64::SP,
3886 StackOffset::getFixed(-ProbeSize), TII,
3887 MachineInstr::FrameSetup, false, false, nullptr,
3888 EmitAsyncCFI && !HasFP, CFAOffset);
3889 CFAOffset += StackOffset::getFixed(ProbeSize);
3890 // LDR XZR, [SP]
3891 BuildMI(*MBB, MBBI, DL, TII->get(AArch64::LDRXui))
3892 .addDef(AArch64::XZR)
3893 .addReg(AArch64::SP)
3894 .addImm(0)
3898 Align(8)))
3900 }
3901 } else if (NumBlocks != 0) {
3902 // SUB ScratchReg, SP, #FrameSize (or equivalent if FrameSize is not
3903 // encodable in ADD). ScrathReg may temporarily become the CFA register.
3904 emitFrameOffset(*MBB, MBBI, DL, ScratchReg, AArch64::SP,
3905 StackOffset::getFixed(-ProbeSize * NumBlocks), TII,
3906 MachineInstr::FrameSetup, false, false, nullptr,
3907 EmitAsyncCFI && !HasFP, CFAOffset);
3908 CFAOffset += StackOffset::getFixed(ProbeSize * NumBlocks);
3909 MBBI = inlineStackProbeLoopExactMultiple(MBBI, ProbeSize, ScratchReg);
3910 MBB = MBBI->getParent();
3911 if (EmitAsyncCFI && !HasFP) {
3912 // Set the CFA register back to SP.
3913 CFIInstBuilder(*MBB, MBBI, MachineInstr::FrameSetup)
3914 .buildDefCFARegister(AArch64::SP);
3915 }
3916 }
3917
3918 if (ResidualSize != 0) {
3919 // SUB SP, SP, #ResidualSize (or equivalent if ResidualSize is not encodable
3920 // in SUB).
3921 emitFrameOffset(*MBB, MBBI, DL, AArch64::SP, AArch64::SP,
3922 StackOffset::getFixed(-ResidualSize), TII,
3923 MachineInstr::FrameSetup, false, false, nullptr,
3924 EmitAsyncCFI && !HasFP, CFAOffset);
3925 if (ResidualSize > AArch64::StackProbeMaxUnprobedStack) {
3926 // LDR XZR, [SP]
3927 BuildMI(*MBB, MBBI, DL, TII->get(AArch64::LDRXui))
3928 .addDef(AArch64::XZR)
3929 .addReg(AArch64::SP)
3930 .addImm(0)
3934 Align(8)))
3936 }
3937 }
3938}
3939
3940void AArch64FrameLowering::inlineStackProbe(MachineFunction &MF,
3941 MachineBasicBlock &MBB) const {
3942 // Get the instructions that need to be replaced. We emit at most two of
3943 // these. Remember them in order to avoid complications coming from the need
3944 // to traverse the block while potentially creating more blocks.
3945 SmallVector<MachineInstr *, 4> ToReplace;
3946 for (MachineInstr &MI : MBB)
3947 if (MI.getOpcode() == AArch64::PROBED_STACKALLOC ||
3948 MI.getOpcode() == AArch64::PROBED_STACKALLOC_VAR)
3949 ToReplace.push_back(&MI);
3950
3951 for (MachineInstr *MI : ToReplace) {
3952 if (MI->getOpcode() == AArch64::PROBED_STACKALLOC) {
3953 Register ScratchReg = MI->getOperand(0).getReg();
3954 int64_t FrameSize = MI->getOperand(1).getImm();
3955 StackOffset CFAOffset = StackOffset::get(MI->getOperand(2).getImm(),
3956 MI->getOperand(3).getImm());
3957 inlineStackProbeFixed(MI->getIterator(), ScratchReg, FrameSize,
3958 CFAOffset);
3959 } else {
3960 assert(MI->getOpcode() == AArch64::PROBED_STACKALLOC_VAR &&
3961 "Stack probe pseudo-instruction expected");
3962 const AArch64InstrInfo *TII =
3963 MI->getMF()->getSubtarget<AArch64Subtarget>().getInstrInfo();
3964 Register TargetReg = MI->getOperand(0).getReg();
3965 (void)TII->probedStackAlloc(MI->getIterator(), TargetReg, true);
3966 }
3967 MI->eraseFromParent();
3968 }
3969}
3970
3973 NotAccessed = 0, // Stack object not accessed by load/store instructions.
3974 GPR = 1 << 0, // A general purpose register.
3975 PPR = 1 << 1, // A predicate register.
3976 FPR = 1 << 2, // A floating point/Neon/SVE register.
3977 };
3978
3979 int Idx;
3981 int64_t Size;
3982 unsigned AccessTypes;
3983
3985
3986 bool operator<(const StackAccess &Rhs) const {
3987 return std::make_tuple(start(), Idx) <
3988 std::make_tuple(Rhs.start(), Rhs.Idx);
3989 }
3990
3991 bool isCPU() const {
3992 // Predicate register load and store instructions execute on the CPU.
3994 }
3995 bool isSME() const { return AccessTypes & AccessType::FPR; }
3996 bool isMixed() const { return isCPU() && isSME(); }
3997
3998 int64_t start() const { return Offset.getFixed() + Offset.getScalable(); }
3999 int64_t end() const { return start() + Size; }
4000
4001 std::string getTypeString() const {
4002 switch (AccessTypes) {
4003 case AccessType::FPR:
4004 return "FPR";
4005 case AccessType::PPR:
4006 return "PPR";
4007 case AccessType::GPR:
4008 return "GPR";
4010 return "NA";
4011 default:
4012 return "Mixed";
4013 }
4014 }
4015
4016 void print(raw_ostream &OS) const {
4017 OS << getTypeString() << " stack object at [SP"
4018 << (Offset.getFixed() < 0 ? "" : "+") << Offset.getFixed();
4019 if (Offset.getScalable())
4020 OS << (Offset.getScalable() < 0 ? "" : "+") << Offset.getScalable()
4021 << " * vscale";
4022 OS << "]";
4023 }
4024};
4025
4026static inline raw_ostream &operator<<(raw_ostream &OS, const StackAccess &SA) {
4027 SA.print(OS);
4028 return OS;
4029}
4030
4031void AArch64FrameLowering::emitRemarks(
4032 const MachineFunction &MF, MachineOptimizationRemarkEmitter *ORE) const {
4033
4034 auto *AFI = MF.getInfo<AArch64FunctionInfo>();
4036 return;
4037
4038 unsigned StackHazardSize = getStackHazardSize(MF);
4039 const uint64_t HazardSize =
4040 (StackHazardSize) ? StackHazardSize : StackHazardRemarkSize;
4041
4042 if (HazardSize == 0)
4043 return;
4044
4045 const MachineFrameInfo &MFI = MF.getFrameInfo();
4046 // Bail if function has no stack objects.
4047 if (!MFI.hasStackObjects())
4048 return;
4049
4050 std::vector<StackAccess> StackAccesses(MFI.getNumObjects());
4051
4052 size_t NumFPLdSt = 0;
4053 size_t NumNonFPLdSt = 0;
4054
4055 // Collect stack accesses via Load/Store instructions.
4056 for (const MachineBasicBlock &MBB : MF) {
4057 for (const MachineInstr &MI : MBB) {
4058 if (!MI.mayLoadOrStore() || MI.getNumMemOperands() < 1)
4059 continue;
4060 for (MachineMemOperand *MMO : MI.memoperands()) {
4061 std::optional<int> FI = getMMOFrameID(MMO, MFI);
4062 if (FI && !MFI.isDeadObjectIndex(*FI)) {
4063 int FrameIdx = *FI;
4064
4065 size_t ArrIdx = FrameIdx + MFI.getNumFixedObjects();
4066 if (StackAccesses[ArrIdx].AccessTypes == StackAccess::NotAccessed) {
4067 StackAccesses[ArrIdx].Idx = FrameIdx;
4068 StackAccesses[ArrIdx].Offset =
4069 getFrameIndexReferenceFromSP(MF, FrameIdx);
4070 StackAccesses[ArrIdx].Size = MFI.getObjectSize(FrameIdx);
4071 }
4072
4073 unsigned RegTy = StackAccess::AccessType::GPR;
4074 if (MFI.hasScalableStackID(FrameIdx))
4077 RegTy = StackAccess::FPR;
4078
4079 StackAccesses[ArrIdx].AccessTypes |= RegTy;
4080
4081 if (RegTy == StackAccess::FPR)
4082 ++NumFPLdSt;
4083 else
4084 ++NumNonFPLdSt;
4085 }
4086 }
4087 }
4088 }
4089
4090 if (NumFPLdSt == 0 || NumNonFPLdSt == 0)
4091 return;
4092
4093 llvm::sort(StackAccesses);
4094 llvm::erase_if(StackAccesses, [](const StackAccess &S) {
4096 });
4097
4100
4101 if (StackAccesses.front().isMixed())
4102 MixedObjects.push_back(&StackAccesses.front());
4103
4104 for (auto It = StackAccesses.begin(), End = std::prev(StackAccesses.end());
4105 It != End; ++It) {
4106 const auto &First = *It;
4107 const auto &Second = *(It + 1);
4108
4109 if (Second.isMixed())
4110 MixedObjects.push_back(&Second);
4111
4112 if ((First.isSME() && Second.isCPU()) ||
4113 (First.isCPU() && Second.isSME())) {
4114 uint64_t Distance = static_cast<uint64_t>(Second.start() - First.end());
4115 if (Distance < HazardSize)
4116 HazardPairs.emplace_back(&First, &Second);
4117 }
4118 }
4119
4120 auto EmitRemark = [&](llvm::StringRef Str) {
4121 ORE->emit([&]() {
4122 auto R = MachineOptimizationRemarkAnalysis(
4123 "sme", "StackHazard", MF.getFunction().getSubprogram(), &MF.front());
4124 return R << formatv("stack hazard in '{0}': ", MF.getName()).str() << Str;
4125 });
4126 };
4127
4128 for (const auto &P : HazardPairs)
4129 EmitRemark(formatv("{0} is too close to {1}", *P.first, *P.second).str());
4130
4131 for (const auto *Obj : MixedObjects)
4132 EmitRemark(
4133 formatv("{0} accessed by both GP and FP instructions", *Obj).str());
4134}
static void getLiveRegsForEntryMBB(LivePhysRegs &LiveRegs, const MachineBasicBlock &MBB)
static const unsigned DefaultSafeSPDisplacement
This is the biggest offset to the stack pointer we can encode in aarch64 instructions (without using ...
static RegState getPrologueDeath(MachineFunction &MF, unsigned Reg)
static bool produceCompactUnwindFrame(const AArch64FrameLowering &, MachineFunction &MF)
static cl::opt< bool > StackTaggingMergeSetTag("stack-tagging-merge-settag", cl::desc("merge settag instruction in function epilog"), cl::init(true), cl::Hidden)
bool enableMultiVectorSpillFill(const AArch64Subtarget &Subtarget, MachineFunction &MF)
static std::optional< int > getLdStFrameID(const MachineInstr &MI, const MachineFrameInfo &MFI)
static cl::opt< bool > SplitSVEObjects("aarch64-split-sve-objects", cl::desc("Split allocation of ZPR & PPR objects"), cl::init(true), cl::Hidden)
static cl::opt< bool > StackHazardInNonStreaming("aarch64-stack-hazard-in-non-streaming", cl::init(false), cl::Hidden)
void computeCalleeSaveRegisterPairs(const AArch64FrameLowering &AFL, MachineFunction &MF, ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI, SmallVectorImpl< RegPairInfo > &RegPairs, bool NeedsFrameRecord)
static cl::opt< bool > OrderFrameObjects("aarch64-order-frame-objects", cl::desc("sort stack allocations"), cl::init(true), cl::Hidden)
static cl::opt< bool > DisableMultiVectorSpillFill("aarch64-disable-multivector-spill-fill", cl::desc("Disable use of LD/ST pairs for SME2 or SVE2p1"), cl::init(false), cl::Hidden)
static cl::opt< bool > EnableRedZone("aarch64-redzone", cl::desc("enable use of redzone on AArch64"), cl::init(false), cl::Hidden)
static bool invalidateRegisterPairing(bool SpillExtendedVolatile, unsigned SpillCount, unsigned Reg1, unsigned Reg2, bool UsesWinAAPCS, bool NeedsWinCFI, bool NeedsFrameRecord, const TargetRegisterInfo *TRI)
Returns true if Reg1 and Reg2 cannot be paired using a ldp/stp instruction.
cl::opt< bool > EnableHomogeneousPrologEpilog("homogeneous-prolog-epilog", cl::Hidden, cl::desc("Emit homogeneous prologue and epilogue for the size " "optimization (default = off)"))
static bool isLikelyToHaveSVEStack(const AArch64FrameLowering &AFL, const MachineFunction &MF)
static bool invalidateWindowsRegisterPairing(bool SpillExtendedVolatile, unsigned SpillCount, unsigned Reg1, unsigned Reg2, bool NeedsWinCFI, const TargetRegisterInfo *TRI)
static SVEStackSizes determineSVEStackSizes(MachineFunction &MF, AssignObjectOffsets AssignOffsets)
Process all the SVE stack objects and the SVE stack size and offsets for each object.
static bool isTargetWindows(const MachineFunction &MF)
static unsigned estimateRSStackSizeLimit(MachineFunction &MF)
Look at each instruction that references stack frames and return the stack size limit beyond which so...
static bool getSVECalleeSaveSlotRange(const MachineFrameInfo &MFI, int &Min, int &Max)
returns true if there are any SVE callee saves.
static cl::opt< unsigned > StackHazardRemarkSize("aarch64-stack-hazard-remark-size", cl::init(0), cl::Hidden)
static MCRegister getRegisterOrZero(MCRegister Reg, bool HasSVE)
static unsigned getStackHazardSize(const MachineFunction &MF)
MCRegister findFreePredicateReg(BitVector &SavedRegs)
static bool isPPRAccess(const MachineInstr &MI)
static std::optional< int > getMMOFrameID(MachineMemOperand *MMO, const MachineFrameInfo &MFI)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file contains the declaration of the AArch64PrologueEmitter and AArch64EpilogueEmitter classes,...
static const int kSetTagLoopThreshold
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
This file contains the simple types necessary to represent the attributes associated with functions a...
#define CASE(ATTRNAME, AANAME,...)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
DXIL Forward Handle Accesses
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
static std::string getTypeString(Type *T)
Definition LLParser.cpp:68
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define H(x, y, z)
Definition MD5.cpp:56
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
uint64_t IntrinsicInst * II
#define P(N)
This file declares the machine register scavenger class.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition Value.cpp:484
This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...
This file defines the SmallVector class.
#define LLVM_DEBUG(...)
Definition Debug.h:119
StackOffset getSVEStackSize(const MachineFunction &MF) const
Returns the size of the entire SVE stackframe (PPRs + ZPRs).
StackOffset getZPRStackSize(const MachineFunction &MF) const
Returns the size of the entire ZPR stackframe (calleesaves + spills).
void processFunctionBeforeFrameIndicesReplaced(MachineFunction &MF, RegScavenger *RS) const override
processFunctionBeforeFrameIndicesReplaced - This method is called immediately before MO_FrameIndex op...
MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const override
This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy p...
bool canUseAsPrologue(const MachineBasicBlock &MBB) const override
Check whether or not the given MBB can be used as a prologue for the target.
bool enableStackSlotScavenging(const MachineFunction &MF) const override
Returns true if the stack slot holes in the fixed and callee-save stack area should be used when allo...
bool assignCalleeSavedSpillSlots(MachineFunction &MF, const TargetRegisterInfo *TRI, std::vector< CalleeSavedInfo > &CSI) const override
assignCalleeSavedSpillSlots - Allows target to override spill slot assignment logic.
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const override
spillCalleeSavedRegisters - Issues instruction(s) to spill all callee saved registers and returns tru...
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, MutableArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const override
restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee saved registers and returns...
bool enableFullCFIFixup(const MachineFunction &MF) const override
enableFullCFIFixup - Returns true if we may need to fix the unwind information such that it is accura...
StackOffset getFrameIndexReferenceFromSP(const MachineFunction &MF, int FI) const override
getFrameIndexReferenceFromSP - This method returns the offset from the stack pointer to the slot of t...
bool enableCFIFixup(const MachineFunction &MF) const override
Returns true if we may need to fix the unwind information for the function.
StackOffset getNonLocalFrameIndexReference(const MachineFunction &MF, int FI) const override
getNonLocalFrameIndexReference - This method returns the offset used to reference a frame index locat...
TargetStackID::Value getStackIDForScalableVectors() const override
Returns the StackID that scalable vectors should be associated with.
bool hasFPImpl(const MachineFunction &MF) const override
hasFPImpl - Return true if the specified function should have a dedicated frame pointer register.
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
void resetCFIToInitialState(MachineBasicBlock &MBB) const override
Emit CFI instructions that recreate the state of the unwind information upon function entry.
bool hasReservedCallFrame(const MachineFunction &MF) const override
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
bool hasSVECalleeSavesAboveFrameRecord(const MachineFunction &MF) const
StackOffset resolveFrameOffsetReference(const MachineFunction &MF, int64_t ObjectOffset, bool isFixed, TargetStackID::Value StackID, Register &FrameReg, bool PreferFP, bool ForSimm) const
bool canUseRedZone(const MachineFunction &MF) const
Can this function use the red zone for local allocations.
bool needsWinCFI(const MachineFunction &MF) const
bool isFPReserved(const MachineFunction &MF) const
Should the Frame Pointer be reserved for the current function?
void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS) const override
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
int getSEHFrameIndexOffset(const MachineFunction &MF, int FI) const
unsigned getWinEHFuncletFrameSize(const MachineFunction &MF) const
Funclets only need to account for space for the callee saved registers, as the locals are accounted f...
void orderFrameObjects(const MachineFunction &MF, SmallVectorImpl< int > &ObjectsToAllocate) const override
Order the symbols in the local stack frame.
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
StackOffset getPPRStackSize(const MachineFunction &MF) const
Returns the size of the entire PPR stackframe (calleesaves + spills + hazard padding).
int64_t getArgumentStackToRestore(MachineFunction &MF, MachineBasicBlock &MBB) const
Returns how much of the incoming argument stack area (in bytes) we should clean up in an epilogue.
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const override
getFrameIndexReference - Provide a base+offset reference to an FI slot for debug info.
StackOffset getFrameIndexReferencePreferSP(const MachineFunction &MF, int FI, Register &FrameReg, bool IgnoreSPUpdates) const override
For Win64 AArch64 EH, the offset to the Unwind object is from the SP before the update.
StackOffset resolveFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg, bool PreferFP, bool ForSimm) const
unsigned getWinEHParentFrameOffset(const MachineFunction &MF) const override
The parent frame offset (aka dispFrame) is only used on X86_64 to retrieve the parent's frame pointer...
bool requiresSaveVG(const MachineFunction &MF) const
void emitPacRetPlusLeafHardening(MachineFunction &MF) const
Harden the entire function with pac-ret.
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
unsigned getCalleeSavedStackSize(const MachineFrameInfo &MFI) const
void setCalleeSaveBaseToFrameRecordOffset(int Offset)
SignReturnAddress getSignReturnAddressCondition() const
void setStackSizeSVE(uint64_t ZPR, uint64_t PPR)
std::optional< int > getTaggedBasePointerIndex() const
bool needsDwarfUnwindInfo(const MachineFunction &MF) const
void setSVECalleeSavedStackSize(unsigned ZPR, unsigned PPR)
bool needsAsyncDwarfUnwindInfo(const MachineFunction &MF) const
static bool isTailCallReturnInst(const MachineInstr &MI)
Returns true if MI is one of the TCRETURN* instructions.
static bool isFpOrNEON(Register Reg)
Returns whether the physical register is FP or NEON.
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....
const AArch64InstrInfo * getInstrInfo() const override
const AArch64TargetLowering * getTargetLowering() const override
bool isSVEorStreamingSVEAvailable() const
Returns true if the target has access to either the full range of SVE instructions,...
bool isStreaming() const
Returns true if the function has a streaming body.
bool hasInlineStackProbe(const MachineFunction &MF) const override
True if stack clash protection is enabled for this functions.
unsigned getRedZoneSize(const Function &F) const
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
bool test(unsigned Idx) const
Returns true if bit Idx is set.
Definition BitVector.h:482
BitVector & reset()
Reset all bits in the bitvector.
Definition BitVector.h:409
size_type count() const
Returns the number of bits which are set.
Definition BitVector.h:181
BitVector & set()
Set all bits in the bitvector.
Definition BitVector.h:366
iterator_range< const_set_bits_iterator > set_bits() const
Definition BitVector.h:159
size_type size() const
Returns the number of bits in this bitvector.
Definition BitVector.h:178
Helper class for creating CFI instructions and inserting them into MIR.
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
A debug info location.
Definition DebugLoc.h:126
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
Definition Function.h:685
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition Function.h:272
AttributeList getAttributes() const
Return the attribute list for this Function.
Definition Function.h:328
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition Function.h:229
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:723
A set of physical registers with utility functions to track liveness when walking backward/forward th...
bool usesWindowsCFI() const
Definition MCAsmInfo.h:674
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
reverse_iterator rbegin()
iterator insertAfter(iterator I, MachineInstr *MI)
Insert MI into the instruction list after I.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
const AllocaInst * getObjectAllocation(int ObjectIdx) const
Return the underlying Alloca of the specified stack object if it exists.
LLVM_ABI int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
bool hasCalls() const
Return true if the current function has any function calls.
bool isFrameAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
void setObjectOffset(int ObjectIdx, int64_t SPOffset)
Set the stack frame offset of the specified object.
bool isCalleeSavedObjectIndex(int ObjectIdx) const
uint64_t getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
bool hasPatchPoint() const
This method may be called any time after instruction selection is complete to determine if there is a...
bool hasScalableStackID(int ObjectIdx) const
int getStackProtectorIndex() const
Return the index for the stack protector object.
LLVM_ABI uint64_t estimateStackSize(const MachineFunction &MF) const
Estimate and return the size of the stack frame.
void setStackID(int ObjectIdx, uint8_t ID)
bool isCalleeSavedInfoValid() const
Has the callee saved info been calculated yet?
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
bool isMaxCallFrameSizeComputed() const
bool hasStackMap() const
This method may be called any time after instruction selection is complete to determine if there is a...
LLVM_ABI int CreateSpillStackObject(uint64_t Size, Align Alignment, TargetStackID::Value StackID=TargetStackID::Default)
Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
unsigned getNumObjects() const
Return the number of objects.
int getObjectIndexEnd() const
Return one past the maximum frame object index.
bool hasStackProtectorIndex() const
bool hasStackObjects() const
Return true if there are any stack objects in this function.
uint8_t getStackID(int ObjectIdx) const
unsigned getNumFixedObjects() const
Return the number of fixed objects.
void setIsCalleeSavedObjectIndex(int ObjectIdx, bool IsCalleeSaved)
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
int getObjectIndexBegin() const
Return the minimum frame object index.
void setObjectAlignment(int ObjectIdx, Align Alignment)
setObjectAlignment - Change the alignment of the specified stack object.
bool isDeadObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a dead object.
const WinEHFuncInfo * getWinEHFuncInfo() const
getWinEHFuncInfo - Return information about how the current function uses Windows exception handling.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineBasicBlock & front() const
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & setMemRefs(ArrayRef< MachineMemOperand * > MMOs) const
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
void setFlags(unsigned flags)
uint32_t getFlags() const
Return the MI flags bitvector.
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
A description of a memory reference used in the backend.
const PseudoSourceValue * getPseudoValue() const
@ MOVolatile
The memory access is volatile.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
const Value * getValue() const
Return the base address of the memory access.
MachineOperand class - Representation of each machine instruction operand.
int64_t getImm() const
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
LLVM_ABI void emit(DiagnosticInfoOptimizationBase &OptDiag)
Emit an optimization remark.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI void freezeReservedRegs()
freezeReservedRegs - Called by the register allocator to freeze the set of reserved registers before ...
bool isReserved(MCRegister PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLVM_ABI bool isLiveIn(Register Reg) const
LLVM_ABI const MCPhysReg * getCalleeSavedRegs() const
Returns list of callee saved registers.
LLVM_ABI bool isPhysRegUsed(MCRegister PhysReg, bool SkipRegMaskTest=false) const
Return true if the specified register is modified or read in this function.
Represent a mutable reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:294
Wrapper class representing virtual and physical registers.
Definition Register.h:20
constexpr bool isValid() const
Definition Register.h:112
SMEAttrs is a utility class to parse the SME ACLE attributes on functions.
bool hasStreamingInterface() const
bool hasNonStreamingInterfaceAndBody() const
bool hasStreamingBody() const
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:151
A SetVector that performs no allocations if smaller than a certain size.
Definition SetVector.h:339
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset holds a fixed and a scalable offset in bytes.
Definition TypeSize.h:30
int64_t getFixed() const
Returns the fixed component of the stack.
Definition TypeSize.h:46
int64_t getScalable() const
Returns the scalable component of the stack.
Definition TypeSize.h:49
static StackOffset get(int64_t Fixed, int64_t Scalable)
Definition TypeSize.h:41
static StackOffset getScalable(int64_t Scalable)
Definition TypeSize.h:40
static StackOffset getFixed(int64_t Fixed)
Definition TypeSize.h:39
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
int getOffsetOfLocalArea() const
getOffsetOfLocalArea - This method returns the offset of the local area from the stack pointer on ent...
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
StackDirection getStackGrowthDirection() const
getStackGrowthDirection - Return the direction the stack grows
virtual bool enableCFIFixup(const MachineFunction &MF) const
Returns true if we may need to fix the unwind information for the function.
Primary interface to the complete machine description for the target machine.
const Triple & getTargetTriple() const
const MCAsmInfo & getMCAsmInfo() const
Return target specific asm information.
TargetOptions Options
LLVM_ABI bool FramePointerIsReserved(const MachineFunction &MF) const
FramePointerIsReserved - This returns true if the frame pointer must always either point to a new fra...
LLVM_ABI bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
bool hasStackRealignment(const MachineFunction &MF) const
True if stack realignment is required and still possible.
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:47
bool isOSBinFormatMachO() const
Tests whether the environment is MachO.
Definition Triple.h:872
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
static unsigned getArithExtendImm(AArch64_AM::ShiftExtendType ET, unsigned Imm)
getArithExtendImm - Encode the extend type and shift amount for an arithmetic instruction: imm: 3-bit...
const unsigned StackProbeMaxLoopUnroll
Maximum number of iterations to unroll for a constant size probing loop.
const unsigned StackProbeMaxUnprobedStack
Maximum allowed number of unprobed bytes above SP at an ABI boundary.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ AArch64_SVE_VectorCall
Used between AArch64 SVE functions.
@ PreserveMost
Used for runtime calls that preserves most registers.
Definition CallingConv.h:63
@ CXX_FAST_TLS
Used for access functions.
Definition CallingConv.h:72
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
Definition CallingConv.h:50
@ PreserveAll
Used for runtime calls that preserves (almost) all registers.
Definition CallingConv.h:66
@ 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.
@ 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
initializer< Ty > init(const Ty &Val)
NodeAddr< InstrNode * > Instr
Definition RDFGraph.h:391
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
Definition SFrame.h:77
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:573
void stable_sort(R &&Range)
Definition STLExtras.h:2116
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
int isAArch64FrameOffsetLegal(const MachineInstr &MI, StackOffset &Offset, bool *OutUseUnscaledOp=nullptr, unsigned *OutUnscaledOp=nullptr, int64_t *EmittableOffset=nullptr)
Check if the Offset is a valid frame offset for MI.
@ Unknown
Not known to have no common set bits.
RegState
Flags to represent properties of register accesses.
@ Define
Register definition.
constexpr RegState getKillRegState(bool B)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
@ AArch64FrameOffsetCannotUpdate
Offset cannot apply.
constexpr T alignDown(U Value, V Align, W Skew=0)
Returns the largest unsigned integer less than or equal to Value and is Skew mod Align.
Definition MathExtras.h:546
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
auto reverse(ContainerTy &&C)
Definition STLExtras.h:407
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1636
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
void emitFrameOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, StackOffset Offset, const TargetInstrInfo *TII, MachineInstr::MIFlag=MachineInstr::NoFlags, bool SetNZCV=false, bool NeedsWinCFI=false, bool *HasWinCFI=nullptr, bool EmitCFAOffset=false, StackOffset InitialOffset={}, unsigned FrameReg=AArch64::SP)
emitFrameOffset - Emit instructions as needed to set DestReg to SrcReg plus Offset.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
constexpr RegState getDefRegState(bool B)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Definition ModRef.h:74
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
Definition STLExtras.h:2019
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1772
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
Definition STLExtras.h:2192
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1947
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
void fullyRecomputeLiveIns(ArrayRef< MachineBasicBlock * > MBBs)
Convenience function for recomputing live-in's for a set of MBBs until the computation converges.
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:862
bool operator<(const StackAccess &Rhs) const
void print(raw_ostream &OS) const
int64_t start() const
std::string getTypeString() const
int64_t end() const
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:77
Pair of physical register and lane mask.
static LLVM_ABI MachinePointerInfo getUnknownStack(MachineFunction &MF)
Stack memory without other information.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
SmallVector< WinEHTryBlockMapEntry, 4 > TryBlockMap
SmallVector< WinEHHandlerType, 1 > HandlerArray