LLVM 24.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/IR/Module.h"
250#include "llvm/MC/MCAsmInfo.h"
251#include "llvm/MC/MCDwarf.h"
252#include "llvm/Support/Debug.h"
258#include <cassert>
259#include <cstdint>
260#include <iterator>
261#include <optional>
262#include <vector>
263
264using namespace llvm;
265
266#define DEBUG_TYPE "frame-info"
267
268int64_t
270 MachineBasicBlock &MBB) const {
271 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
273 bool IsTailCallReturn = (MBB.end() != MBBI)
275 : false;
276
277 int64_t ArgumentPopSize = 0;
278 if (IsTailCallReturn) {
279 MachineOperand &StackAdjust = MBBI->getOperand(1);
280
281 // For a tail-call in a callee-pops-arguments environment, some or all of
282 // the stack may actually be in use for the call's arguments, this is
283 // calculated during LowerCall and consumed here...
284 ArgumentPopSize = StackAdjust.getImm();
285 } else {
286 // ... otherwise the amount to pop is *all* of the argument space,
287 // conveniently stored in the MachineFunctionInfo by
288 // LowerFormalArguments. This will, of course, be zero for the C calling
289 // convention.
290 ArgumentPopSize = AFI->getArgumentStackToRestore();
291 }
292
293 return ArgumentPopSize;
294}
295
298 if (!MF.needsWinCFI() ||
300 return false;
301
302 // Funclets don't tail call, and are not what the unwind info is about.
303 MachineBasicBlock::iterator LastI = MBB.getLastNonDebugInstr();
304 if (LastI != MBB.end() && (LastI->getOpcode() == AArch64::CATCHRET ||
305 LastI->getOpcode() == AArch64::CLEANUPRET))
306 return false;
307
308 return getArgumentStackToRestore(MF, MBB) != 0;
309}
310
312 MachineFunction &MF);
313
314enum class AssignObjectOffsets { No, Yes };
315/// Process all the SVE stack objects and the SVE stack size and offsets for
316/// each object. If AssignOffsets is "Yes", the offsets get assigned (and SVE
317/// stack sizes set). Returns the size of the SVE stack.
319 AssignObjectOffsets AssignOffsets);
320
321static unsigned getStackHazardSize(const MachineFunction &MF) {
322 return MF.getSubtarget<AArch64Subtarget>().getStreamingHazardSize();
323}
324
330
333 // With split SVE objects, the hazard padding is added to the PPR region,
334 // which places it between the [GPR, PPR] area and the [ZPR, FPR] area. This
335 // avoids hazards between both GPRs and FPRs and ZPRs and PPRs.
338 : 0,
339 AFI->getStackSizePPR());
340}
341
342// Conservatively, returns true if the function is likely to have SVE vectors
343// on the stack. This function is safe to be called before callee-saves or
344// object offsets have been determined.
346 const MachineFunction &MF) {
347 auto *AFI = MF.getInfo<AArch64FunctionInfo>();
348 if (AFI->isSVECC())
349 return true;
350
351 if (AFI->hasCalculatedStackSizeSVE())
352 return bool(AFL.getSVEStackSize(MF));
353
354 const MachineFrameInfo &MFI = MF.getFrameInfo();
355 for (int FI = MFI.getObjectIndexBegin(); FI < MFI.getObjectIndexEnd(); FI++) {
356 if (MFI.hasScalableStackID(FI))
357 return true;
358 }
359
360 return false;
361}
362
363static bool isTargetWindows(const MachineFunction &MF) {
364 // Note: UEFI follows the Windows ARM64 ABI and uses Windows CFI. The value
365 // returned here must align with the predicate used for returning the list of
366 // callee saved regs in AArch64RegisterInfo::getCalleeSavedRegs(), so that we
367 // use invalidateWindowsRegisterPairing() where appropriate.
368 return MF.getSubtarget<AArch64Subtarget>().isTargetWindowsOrUEFI();
369}
370
372 const MachineFunction &MF) const {
373 auto *AFI = MF.getInfo<AArch64FunctionInfo>();
374 return isTargetWindows(MF) && AFI->getSVECalleeSavedStackSize();
375}
376
377/// Returns true if a homogeneous prolog or epilog code can be emitted
378/// for the size optimization. If possible, a frame helper call is injected.
379/// When Exit block is given, this check is for epilog.
380bool AArch64FrameLowering::homogeneousPrologEpilog(
381 MachineFunction &MF, MachineBasicBlock *Exit) const {
382 if (!MF.getFunction().hasMinSize())
383 return false;
384 const AArch64Options &CLOpts =
385 MF.getSubtarget<AArch64Subtarget>().getCLOpts();
386 if (!CLOpts.homogeneous_prolog_epilog)
387 return false;
388 if (CLOpts.redzone)
389 return false;
390
391 // TODO: Window is supported yet.
392 if (isTargetWindows(MF))
393 return false;
394
395 // TODO: SVE is not supported yet.
396 if (isLikelyToHaveSVEStack(*this, MF))
397 return false;
398
399 // Bail on stack adjustment needed on return for simplicity.
400 const MachineFrameInfo &MFI = MF.getFrameInfo();
401 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
402 if (MFI.hasVarSizedObjects() || RegInfo->hasStackRealignment(MF))
403 return false;
404 if (Exit && getArgumentStackToRestore(MF, *Exit))
405 return false;
406
407 auto *AFI = MF.getInfo<AArch64FunctionInfo>();
408 if (AFI->hasSwiftAsyncContext() || AFI->hasStreamingModeChanges())
409 return false;
410
411 // If there are an odd number of GPRs before LR and FP in the CSRs list,
412 // they will not be paired into one RegGroupInfo, which is incompatible with
413 // the assumption made by the homogeneous prolog epilog pass.
414 const MCPhysReg *CSRegs = MF.getRegInfo().getCalleeSavedRegs();
415 unsigned NumGPRs = 0;
416 for (unsigned I = 0; CSRegs[I]; ++I) {
417 Register Reg = CSRegs[I];
418 if (Reg == AArch64::LR) {
419 assert(CSRegs[I + 1] == AArch64::FP);
420 if (NumGPRs % 2 != 0)
421 return false;
422 break;
423 }
424 if (AArch64::GPR64RegClass.contains(Reg))
425 ++NumGPRs;
426 }
427
428 return true;
429}
430
431/// Returns true if CSRs should be paired.
432bool AArch64FrameLowering::producePairRegisters(MachineFunction &MF) const {
433 return produceCompactUnwindFrame(*this, MF) || homogeneousPrologEpilog(MF);
434}
435
436/// This is the biggest offset to the stack pointer we can encode in aarch64
437/// instructions (without using a separate calculation and a temp register).
438/// Note that the exception here are vector stores/loads which cannot encode any
439/// displacements (see estimateRSStackSizeLimit(), isAArch64FrameOffsetLegal()).
440static const unsigned DefaultSafeSPDisplacement = 255;
441
442/// Look at each instruction that references stack frames and return the stack
443/// size limit beyond which some of these instructions will require a scratch
444/// register during their expansion later.
446 // FIXME: For now, just conservatively guesstimate based on unscaled indexing
447 // range. We'll end up allocating an unnecessary spill slot a lot, but
448 // realistically that's not a big deal at this stage of the game.
449 for (MachineBasicBlock &MBB : MF) {
450 for (MachineInstr &MI : MBB) {
451 if (MI.isDebugInstr() || MI.isPseudo() ||
452 MI.getOpcode() == AArch64::ADDXri ||
453 MI.getOpcode() == AArch64::ADDSXri)
454 continue;
455
456 for (const MachineOperand &MO : MI.operands()) {
457 if (!MO.isFI())
458 continue;
459
461 if (isAArch64FrameOffsetLegal(MI, Offset, nullptr, nullptr, nullptr) ==
463 return 0;
464 }
465 }
466 }
468}
469
474
475unsigned
476AArch64FrameLowering::getFixedObjectSize(const MachineFunction &MF,
477 const AArch64FunctionInfo *AFI,
478 bool IsWin64, bool IsFunclet) const {
479 assert(AFI->getTailCallReservedStack() % 16 == 0 &&
480 "Tail call reserved stack must be aligned to 16 bytes");
481 if (!IsWin64) {
482 return AFI->getTailCallReservedStack();
483 } else if (IsFunclet) {
484 // A funclet has its own frame; the tail call reserve belongs to the parent
485 // function's incoming argument area.
486 return 0;
487 } else {
488 unsigned FixedObjectSize = AFI->getTailCallReservedStack();
489
490 // Var args are stored here in the primary function.
491 FixedObjectSize += AFI->getVarArgsGPRSize();
492
493 if (MF.hasEHFunclets()) {
494 // Catch objects are stored here in the primary function.
495 const MachineFrameInfo &MFI = MF.getFrameInfo();
496 const WinEHFuncInfo &EHInfo = *MF.getWinEHFuncInfo();
497 SmallSetVector<int, 8> CatchObjFrameIndices;
498 for (const WinEHTryBlockMapEntry &TBME : EHInfo.TryBlockMap) {
499 for (const WinEHHandlerType &H : TBME.HandlerArray) {
500 int FrameIndex = H.CatchObj.FrameIndex;
501 if ((FrameIndex != INT_MAX) &&
502 CatchObjFrameIndices.insert(FrameIndex)) {
503 FixedObjectSize = alignTo(FixedObjectSize,
504 MFI.getObjectAlign(FrameIndex).value()) +
505 MFI.getObjectSize(FrameIndex);
506 }
507 }
508 }
509 // To support EH funclets we allocate an UnwindHelp object
510 FixedObjectSize += 8;
511 }
512 return alignTo(FixedObjectSize, 16);
513 }
514}
515
517 if (!MF.getSubtarget<AArch64Subtarget>().getCLOpts().redzone)
518 return false;
519
520 // Don't use the red zone if the function explicitly asks us not to.
521 // This is typically used for kernel code.
522 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
523 const unsigned RedZoneSize =
525 if (!RedZoneSize)
526 return false;
527
528 const MachineFrameInfo &MFI = MF.getFrameInfo();
530 uint64_t NumBytes = AFI->getLocalStackSize();
531
532 // If neither NEON or SVE are available, a COPY from one Q-reg to
533 // another requires a spill -> reload sequence. We can do that
534 // using a pre-decrementing store/post-decrementing load, but
535 // if we do so, we can't use the Red Zone.
536 bool LowerQRegCopyThroughMem = Subtarget.hasFPARMv8() &&
537 !Subtarget.isNeonAvailable() &&
538 !Subtarget.hasSVE();
539
540 return !(MFI.hasCalls() || hasFP(MF) || NumBytes > RedZoneSize ||
541 AFI->hasSVEStackSize() || LowerQRegCopyThroughMem);
542}
543
544/// hasFPImpl - Return true if the specified function should have a dedicated
545/// frame pointer register.
547 const MachineFrameInfo &MFI = MF.getFrameInfo();
548 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
550
551 // Win64 EH requires a frame pointer if funclets are present, as the locals
552 // are accessed off the frame pointer in both the parent function and the
553 // funclets.
554 if (MF.hasEHFunclets())
555 return true;
556
557 // Unwinding out of a callee that pops stack arguments we reserved in our
558 // prologue leaves SP higher than our unwind info expects, so on Windows we
559 // must be found via the frame pointer instead.
561 return true;
562
563 // When the stack guard is mixed with the frame pointer, a dedicated FP is
564 // required so the guard value remains stable in the presence of dynamic
565 // stack allocations (e.g. _alloca on MSVCRT).
566 if (MFI.hasStackProtectorIndex()) {
567 const auto &Subtarget = MF.getSubtarget<AArch64Subtarget>();
568 if (Subtarget.getTargetLowering()->useStackGuardMixFP())
569 return true;
570 }
571
572 // Retain behavior of always omitting the FP for leaf functions when possible.
574 return true;
575 if (MFI.hasVarSizedObjects() || MFI.isFrameAddressTaken() ||
576 MFI.hasStackMap() || MFI.hasPatchPoint() ||
577 RegInfo->hasStackRealignment(MF))
578 return true;
579
580 // If we:
581 //
582 // 1. Have streaming mode changes
583 // OR:
584 // 2. Have a streaming body with SVE stack objects
585 //
586 // Then the value of VG restored when unwinding to this function may not match
587 // the value of VG used to set up the stack.
588 //
589 // This is a problem as the CFA can be described with an expression of the
590 // form: CFA = SP + NumBytes + VG * NumScalableBytes.
591 //
592 // If the value of VG used in that expression does not match the value used to
593 // set up the stack, an incorrect address for the CFA will be computed, and
594 // unwinding will fail.
595 //
596 // We work around this issue by ensuring the frame-pointer can describe the
597 // CFA in either of these cases.
598 if (AFI.needsDwarfUnwindInfo(MF) &&
601 return true;
602 // With large callframes around we may need to use FP to access the scavenging
603 // emergency spillslot.
604 //
605 // Unfortunately some calls to hasFP() like machine verifier ->
606 // getReservedReg() -> hasFP in the middle of global isel are too early
607 // to know the max call frame size. Hopefully conservatively returning "true"
608 // in those cases is fine.
609 // DefaultSafeSPDisplacement is fine as we only emergency spill GP regs.
610 if (!MFI.isMaxCallFrameSizeComputed() ||
612 return true;
613
614 return false;
615}
616
617/// Should the Frame Pointer be reserved for the current function?
619 const Triple &TT = MF.getFunction().getParent()->getTargetTriple();
620
621 // These OSes require the frame chain is valid, even if the current frame does
622 // not use a frame pointer.
623 if (TT.isOSDarwin() || TT.isOSWindowsOrUEFI())
624 return true;
625
626 // If the function has a frame pointer, it is reserved.
627 if (hasFP(MF))
628 return true;
629
630 // Frontend has requested to preserve the frame pointer.
631 if (MF.framePointerIsReserved())
632 return true;
633
634 return false;
635}
636
637/// hasReservedCallFrame - Under normal circumstances, when a frame pointer is
638/// not required, we reserve argument space for call sites in the function
639/// immediately on entry to the current function. This eliminates the need for
640/// add/sub sp brackets around call sites. Returns true if the call frame is
641/// included as part of the stack frame.
643 const MachineFunction &MF) const {
644 // The stack probing code for the dynamically allocated outgoing arguments
645 // area assumes that the stack is probed at the top - either by the prologue
646 // code, which issues a probe if `hasVarSizedObjects` return true, or by the
647 // most recent variable-sized object allocation. Changing the condition here
648 // may need to be followed up by changes to the probe issuing logic.
649 return !MF.getFrameInfo().hasVarSizedObjects();
650}
651
655
656 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
657 const AArch64InstrInfo *TII = Subtarget.getInstrInfo();
658 const AArch64TargetLowering *TLI = Subtarget.getTargetLowering();
659 [[maybe_unused]] MachineFrameInfo &MFI = MF.getFrameInfo();
660 DebugLoc DL = I->getDebugLoc();
661 unsigned Opc = I->getOpcode();
662 bool IsDestroy = Opc == TII->getCallFrameDestroyOpcode();
663 uint64_t CalleePopAmount = IsDestroy ? I->getOperand(1).getImm() : 0;
664
665 if (!hasReservedCallFrame(MF)) {
666 int64_t Amount = I->getOperand(0).getImm();
667 Amount = alignTo(Amount, getStackAlign());
668 if (!IsDestroy)
669 Amount = -Amount;
670
671 // N.b. if CalleePopAmount is valid but zero (i.e. callee would pop, but it
672 // doesn't have to pop anything), then the first operand will be zero too so
673 // this adjustment is a no-op.
674 if (CalleePopAmount == 0) {
675 // FIXME: in-function stack adjustment for calls is limited to 24-bits
676 // because there's no guaranteed temporary register available.
677 //
678 // ADD/SUB (immediate) has only LSL #0 and LSL #12 available.
679 // 1) For offset <= 12-bit, we use LSL #0
680 // 2) For 12-bit <= offset <= 24-bit, we use two instructions. One uses
681 // LSL #0, and the other uses LSL #12.
682 //
683 // Most call frames will be allocated at the start of a function so
684 // this is OK, but it is a limitation that needs dealing with.
685 assert(Amount > -0xffffff && Amount < 0xffffff && "call frame too large");
686
687 if (TLI->hasInlineStackProbe(MF) &&
689 // When stack probing is enabled, the decrement of SP may need to be
690 // probed. We only need to do this if the call site needs 1024 bytes of
691 // space or more, because a region smaller than that is allowed to be
692 // unprobed at an ABI boundary. We rely on the fact that SP has been
693 // probed exactly at this point, either by the prologue or most recent
694 // dynamic allocation.
696 "non-reserved call frame without var sized objects?");
697 Register ScratchReg =
698 MF.getRegInfo().createVirtualRegister(&AArch64::GPR64RegClass);
699 inlineStackProbeFixed(I, ScratchReg, -Amount, StackOffset::get(0, 0));
700 } else {
701 emitFrameOffset(MBB, I, DL, AArch64::SP, AArch64::SP,
702 StackOffset::getFixed(Amount), TII);
703 }
704 }
705 } else if (CalleePopAmount != 0) {
706 // If the calling convention demands that the callee pops arguments from the
707 // stack, we want to add it back if we have a reserved call frame.
708 assert(CalleePopAmount < 0xffffff && "call frame too large");
709 emitFrameOffset(MBB, I, DL, AArch64::SP, AArch64::SP,
710 StackOffset::getFixed(-(int64_t)CalleePopAmount), TII);
711 }
712 return MBB.erase(I);
713}
714
716 MachineBasicBlock &MBB) const {
717
718 MachineFunction &MF = *MBB.getParent();
719 const auto &Subtarget = MF.getSubtarget<AArch64Subtarget>();
720 const auto &TRI = *Subtarget.getRegisterInfo();
721 const auto &MFI = *MF.getInfo<AArch64FunctionInfo>();
722
723 CFIInstBuilder CFIBuilder(MBB, MBB.begin(), MachineInstr::NoFlags);
724
725 // Reset the CFA to `SP + 0`.
726 CFIBuilder.buildDefCFA(AArch64::SP, 0);
727
728 // Flip the RA sign state.
729 if (MFI.shouldSignReturnAddress(MF)) {
730 if (MFI.branchProtectionPAuthLR()) {
731 CFIBuilder.buildNegateRAStateWithPC();
732 } else if (!MF.getTarget().getTargetTriple().isOSBinFormatMachO()) {
733 CFIBuilder.buildNegateRAState();
734 }
735 }
736
737 // Shadow call stack uses X18, reset it.
738 if (MFI.needsShadowCallStackPrologueEpilogue(MF))
739 CFIBuilder.buildSameValue(AArch64::X18);
740
741 // Emit .cfi_same_value for callee-saved registers.
742 const std::vector<CalleeSavedInfo> &CSI =
744 for (const auto &Info : CSI) {
745 MCRegister Reg = Info.getReg();
746 if (!TRI.regNeedsCFI(Reg, Reg))
747 continue;
748 CFIBuilder.buildSameValue(Reg);
749 }
750}
751
753 switch (Reg.id()) {
754 default:
755 // The called routine is expected to preserve r19-r28
756 // r29 and r30 are used as frame pointer and link register resp.
757 return 0;
758
759 // GPRs
760#define CASE(n) \
761 case AArch64::W##n: \
762 case AArch64::X##n: \
763 return AArch64::X##n
764 CASE(0);
765 CASE(1);
766 CASE(2);
767 CASE(3);
768 CASE(4);
769 CASE(5);
770 CASE(6);
771 CASE(7);
772 CASE(8);
773 CASE(9);
774 CASE(10);
775 CASE(11);
776 CASE(12);
777 CASE(13);
778 CASE(14);
779 CASE(15);
780 CASE(16);
781 CASE(17);
782 CASE(18);
783#undef CASE
784
785 // FPRs
786#define CASE(n) \
787 case AArch64::B##n: \
788 case AArch64::H##n: \
789 case AArch64::S##n: \
790 case AArch64::D##n: \
791 case AArch64::Q##n: \
792 return HasSVE ? AArch64::Z##n : AArch64::Q##n
793 CASE(0);
794 CASE(1);
795 CASE(2);
796 CASE(3);
797 CASE(4);
798 CASE(5);
799 CASE(6);
800 CASE(7);
801 CASE(8);
802 CASE(9);
803 CASE(10);
804 CASE(11);
805 CASE(12);
806 CASE(13);
807 CASE(14);
808 CASE(15);
809 CASE(16);
810 CASE(17);
811 CASE(18);
812 CASE(19);
813 CASE(20);
814 CASE(21);
815 CASE(22);
816 CASE(23);
817 CASE(24);
818 CASE(25);
819 CASE(26);
820 CASE(27);
821 CASE(28);
822 CASE(29);
823 CASE(30);
824 CASE(31);
825#undef CASE
826 }
827}
828
829void AArch64FrameLowering::emitZeroCallUsedRegs(BitVector RegsToZero,
831 RegScavenger *) const {
832 // Insertion point.
834
835 // Fake a debug loc.
836 DebugLoc DL;
837 if (MBBI != MBB.end())
838 DL = MBBI->getDebugLoc();
839
840 const MachineFunction &MF = *MBB.getParent();
841 const AArch64Subtarget &STI = MF.getSubtarget<AArch64Subtarget>();
842 const AArch64RegisterInfo &TRI = *STI.getRegisterInfo();
843
844 BitVector GPRsToZero(TRI.getNumRegs());
845 BitVector FPRsToZero(TRI.getNumRegs());
846 bool HasSVE = STI.isSVEorStreamingSVEAvailable();
847 // Without an FP unit (e.g. -mgeneral-regs-only) the FP/vector registers can't
848 // hold a value and there is no instruction to clear them, so leave them out.
849 bool HasFPR = STI.hasFPARMv8();
850 for (MCRegister Reg : RegsToZero.set_bits()) {
851 if (TRI.isGeneralPurposeRegister(MF, Reg)) {
852 // For GPRs, we only care to clear out the 64-bit register.
853 if (MCRegister XReg = getRegisterOrZero(Reg, HasSVE))
854 GPRsToZero.set(XReg);
855 } else if (HasFPR && AArch64InstrInfo::isFpOrNEON(Reg)) {
856 // For FPRs,
857 if (MCRegister XReg = getRegisterOrZero(Reg, HasSVE))
858 FPRsToZero.set(XReg);
859 }
860 }
861
862 const AArch64InstrInfo &TII = *STI.getInstrInfo();
863
864 // Zero out GPRs.
865 for (MCRegister Reg : GPRsToZero.set_bits())
866 TII.buildClearRegister(Reg, MBB, MBBI, DL);
867
868 // Zero out FP/vector registers.
869 for (MCRegister Reg : FPRsToZero.set_bits())
870 TII.buildClearRegister(Reg, MBB, MBBI, DL);
871
872 if (HasSVE) {
873 for (MCRegister PReg :
874 {AArch64::P0, AArch64::P1, AArch64::P2, AArch64::P3, AArch64::P4,
875 AArch64::P5, AArch64::P6, AArch64::P7, AArch64::P8, AArch64::P9,
876 AArch64::P10, AArch64::P11, AArch64::P12, AArch64::P13, AArch64::P14,
877 AArch64::P15}) {
878 if (RegsToZero[PReg])
879 BuildMI(MBB, MBBI, DL, TII.get(AArch64::PFALSE), PReg);
880 }
881 }
882}
883
884bool AArch64FrameLowering::windowsRequiresStackProbe(
885 const MachineFunction &MF, uint64_t StackSizeInBytes) const {
886 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
887 const AArch64FunctionInfo &MFI = *MF.getInfo<AArch64FunctionInfo>();
888 // TODO: When implementing stack protectors, take that into account
889 // for the probe threshold.
890 return Subtarget.isTargetWindowsOrUEFI() && MFI.hasStackProbing() &&
891 StackSizeInBytes >= uint64_t(MFI.getStackProbeSize());
892}
893
895 const MachineBasicBlock &MBB) {
896 const MachineFunction *MF = MBB.getParent();
897 LiveRegs.addLiveIns(MBB);
898 // Mark callee saved registers as used so we will not choose them.
899 const MCPhysReg *CSRegs = MF->getRegInfo().getCalleeSavedRegs();
900 for (unsigned i = 0; CSRegs[i]; ++i)
901 LiveRegs.addReg(CSRegs[i]);
902}
903
905AArch64FrameLowering::findScratchNonCalleeSaveRegister(MachineBasicBlock *MBB,
906 bool HasCall) const {
908
909 // If MBB is an entry block, use X9 as the scratch register
910 // preserve_none functions may be using X9 to pass arguments,
911 // so prefer to pick an available register below.
912 if (&MF->front() == MBB &&
914 return AArch64::X9;
915
916 const AArch64Subtarget &Subtarget = MF->getSubtarget<AArch64Subtarget>();
917 const AArch64RegisterInfo &TRI = *Subtarget.getRegisterInfo();
918 LivePhysRegs LiveRegs(TRI);
919 getLiveRegsForEntryMBB(LiveRegs, *MBB);
920 if (HasCall) {
921 LiveRegs.addReg(AArch64::X16);
922 LiveRegs.addReg(AArch64::X17);
923 LiveRegs.addReg(AArch64::X18);
924 }
925
926 // Prefer X9 since it was historically used for the prologue scratch reg.
927 const MachineRegisterInfo &MRI = MF->getRegInfo();
928 if (LiveRegs.available(MRI, AArch64::X9))
929 return AArch64::X9;
930
931 for (unsigned Reg : AArch64::GPR64RegClass) {
932 if (LiveRegs.available(MRI, Reg))
933 return Reg;
934 }
935 return Register();
936}
937
939 const MachineBasicBlock &MBB) const {
940 const MachineFunction *MF = MBB.getParent();
941 MachineBasicBlock *TmpMBB = const_cast<MachineBasicBlock *>(&MBB);
942 const AArch64Subtarget &Subtarget = MF->getSubtarget<AArch64Subtarget>();
943 const AArch64RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
944 const AArch64TargetLowering *TLI = Subtarget.getTargetLowering();
946
947 if (AFI->hasSwiftAsyncContext()) {
948 const AArch64RegisterInfo &TRI = *Subtarget.getRegisterInfo();
949 const MachineRegisterInfo &MRI = MF->getRegInfo();
952 // The StoreSwiftAsyncContext clobbers X16 and X17. Make sure they are
953 // available.
954 if (!LiveRegs.available(MRI, AArch64::X16) ||
955 !LiveRegs.available(MRI, AArch64::X17))
956 return false;
957 }
958
959 // Certain stack probing sequences might clobber flags, then we can't use
960 // the block as a prologue if the flags register is a live-in.
962 MBB.isLiveIn(AArch64::NZCV))
963 return false;
964
965 if (RegInfo->hasStackRealignment(*MF) || TLI->hasInlineStackProbe(*MF))
966 if (!findScratchNonCalleeSaveRegister(TmpMBB).isValid())
967 return false;
968
969 // May need a scratch register (for return value) if require making a special
970 // call
971 if (requiresSaveVG(*MF) ||
972 windowsRequiresStackProbe(*MF, std::numeric_limits<uint64_t>::max()))
973 if (!findScratchNonCalleeSaveRegister(TmpMBB, true).isValid())
974 return false;
975
976 return true;
977}
978
979bool AArch64FrameLowering::shouldSignReturnAddressEverywhere(
980 const MachineFunction &MF) const {
981 // FIXME: With WinCFI, extra care should be taken to place SEH_PACSignLR
982 // and SEH_EpilogEnd instructions in the correct order.
983 if (MF.usesWindowsUnwindInfo())
984 return false;
987}
988
989// Given a load or a store instruction, generate an appropriate unwinding SEH
990// code on Windows.
992AArch64FrameLowering::insertSEH(MachineBasicBlock::iterator MBBI,
993 const AArch64InstrInfo &TII,
994 MachineInstr::MIFlag Flag) const {
995 unsigned Opc = MBBI->getOpcode();
996 MachineBasicBlock *MBB = MBBI->getParent();
997 MachineFunction &MF = *MBB->getParent();
998 DebugLoc DL = MBBI->getDebugLoc();
999 unsigned ImmIdx = MBBI->getNumOperands() - 1;
1000 int Imm = MBBI->getOperand(ImmIdx).getImm();
1002 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
1003 const AArch64RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
1004
1005 switch (Opc) {
1006 default:
1007 report_fatal_error("No SEH Opcode for this instruction");
1008 case AArch64::STR_ZXI:
1009 case AArch64::LDR_ZXI: {
1010 unsigned Reg0 = RegInfo->getSEHRegNum(MBBI->getOperand(0).getReg());
1011 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveZReg))
1012 .addImm(Reg0)
1013 .addImm(Imm)
1014 .setMIFlag(Flag);
1015 break;
1016 }
1017 case AArch64::STR_PXI:
1018 case AArch64::LDR_PXI: {
1019 unsigned Reg0 = RegInfo->getSEHRegNum(MBBI->getOperand(0).getReg());
1020 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SavePReg))
1021 .addImm(Reg0)
1022 .addImm(Imm)
1023 .setMIFlag(Flag);
1024 break;
1025 }
1026 case AArch64::LDPDpost:
1027 Imm = -Imm;
1028 [[fallthrough]];
1029 case AArch64::STPDpre: {
1030 unsigned Reg0 = RegInfo->getSEHRegNum(MBBI->getOperand(1).getReg());
1031 unsigned Reg1 = RegInfo->getSEHRegNum(MBBI->getOperand(2).getReg());
1032 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveFRegP_X))
1033 .addImm(Reg0)
1034 .addImm(Reg1)
1035 .addImm(Imm * 8)
1036 .setMIFlag(Flag);
1037 break;
1038 }
1039 case AArch64::LDPXpost:
1040 Imm = -Imm;
1041 [[fallthrough]];
1042 case AArch64::STPXpre: {
1043 Register Reg0 = MBBI->getOperand(1).getReg();
1044 Register Reg1 = MBBI->getOperand(2).getReg();
1045 if (Reg0 == AArch64::FP && Reg1 == AArch64::LR)
1046 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveFPLR_X))
1047 .addImm(Imm * 8)
1048 .setMIFlag(Flag);
1049 else
1050 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveRegP_X))
1051 .addImm(RegInfo->getSEHRegNum(Reg0))
1052 .addImm(RegInfo->getSEHRegNum(Reg1))
1053 .addImm(Imm * 8)
1054 .setMIFlag(Flag);
1055 break;
1056 }
1057 case AArch64::LDRDpost:
1058 Imm = -Imm;
1059 [[fallthrough]];
1060 case AArch64::STRDpre: {
1061 unsigned Reg = RegInfo->getSEHRegNum(MBBI->getOperand(1).getReg());
1062 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveFReg_X))
1063 .addImm(Reg)
1064 .addImm(Imm)
1065 .setMIFlag(Flag);
1066 break;
1067 }
1068 case AArch64::LDRXpost:
1069 Imm = -Imm;
1070 [[fallthrough]];
1071 case AArch64::STRXpre: {
1072 unsigned Reg = RegInfo->getSEHRegNum(MBBI->getOperand(1).getReg());
1073 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveReg_X))
1074 .addImm(Reg)
1075 .addImm(Imm)
1076 .setMIFlag(Flag);
1077 break;
1078 }
1079 case AArch64::STPDi:
1080 case AArch64::LDPDi: {
1081 unsigned Reg0 = RegInfo->getSEHRegNum(MBBI->getOperand(0).getReg());
1082 unsigned Reg1 = RegInfo->getSEHRegNum(MBBI->getOperand(1).getReg());
1083 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveFRegP))
1084 .addImm(Reg0)
1085 .addImm(Reg1)
1086 .addImm(Imm * 8)
1087 .setMIFlag(Flag);
1088 break;
1089 }
1090 case AArch64::STPXi:
1091 case AArch64::LDPXi: {
1092 Register Reg0 = MBBI->getOperand(0).getReg();
1093 Register Reg1 = MBBI->getOperand(1).getReg();
1094
1095 int SEHReg0 = RegInfo->getSEHRegNum(Reg0);
1096 int SEHReg1 = RegInfo->getSEHRegNum(Reg1);
1097
1098 if (Reg0 == AArch64::FP && Reg1 == AArch64::LR)
1099 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveFPLR))
1100 .addImm(Imm * 8)
1101 .setMIFlag(Flag);
1102 else if (SEHReg0 >= 19 && SEHReg1 >= 19)
1103 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveRegP))
1104 .addImm(SEHReg0)
1105 .addImm(SEHReg1)
1106 .addImm(Imm * 8)
1107 .setMIFlag(Flag);
1108 else
1109 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveAnyRegIP))
1110 .addImm(SEHReg0)
1111 .addImm(SEHReg1)
1112 .addImm(Imm * 8)
1113 .setMIFlag(Flag);
1114 break;
1115 }
1116 case AArch64::STRXui:
1117 case AArch64::LDRXui: {
1118 int Reg = RegInfo->getSEHRegNum(MBBI->getOperand(0).getReg());
1119 if (Reg >= 19)
1120 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveReg))
1121 .addImm(Reg)
1122 .addImm(Imm * 8)
1123 .setMIFlag(Flag);
1124 else
1125 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveAnyRegI))
1126 .addImm(Reg)
1127 .addImm(Imm * 8)
1128 .setMIFlag(Flag);
1129 break;
1130 }
1131 case AArch64::STRDui:
1132 case AArch64::LDRDui: {
1133 unsigned Reg = RegInfo->getSEHRegNum(MBBI->getOperand(0).getReg());
1134 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveFReg))
1135 .addImm(Reg)
1136 .addImm(Imm * 8)
1137 .setMIFlag(Flag);
1138 break;
1139 }
1140 case AArch64::STRQui:
1141 case AArch64::LDRQui: {
1142 unsigned Reg = RegInfo->getSEHRegNum(MBBI->getOperand(0).getReg());
1143 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveAnyRegQ))
1144 .addImm(Reg)
1145 .addImm(Imm * 16)
1146 .setMIFlag(Flag);
1147 break;
1148 }
1149 case AArch64::STPQi:
1150 case AArch64::LDPQi: {
1151 unsigned Reg0 = RegInfo->getSEHRegNum(MBBI->getOperand(0).getReg());
1152 unsigned Reg1 = RegInfo->getSEHRegNum(MBBI->getOperand(1).getReg());
1153 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveAnyRegQP))
1154 .addImm(Reg0)
1155 .addImm(Reg1)
1156 .addImm(Imm * 16)
1157 .setMIFlag(Flag);
1158 break;
1159 }
1160 case AArch64::LDRQpost:
1161 Imm = -Imm;
1162 [[fallthrough]];
1163 case AArch64::STRQpre: {
1164 unsigned Reg = RegInfo->getSEHRegNum(MBBI->getOperand(1).getReg());
1165 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveAnyRegQX))
1166 .addImm(Reg)
1167 .addImm(Imm)
1168 .setMIFlag(Flag);
1169 break;
1170 }
1171 case AArch64::LDPQpost:
1172 Imm = -Imm;
1173 [[fallthrough]];
1174 case AArch64::STPQpre: {
1175 unsigned Reg0 = RegInfo->getSEHRegNum(MBBI->getOperand(1).getReg());
1176 unsigned Reg1 = RegInfo->getSEHRegNum(MBBI->getOperand(2).getReg());
1177 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveAnyRegQPX))
1178 .addImm(Reg0)
1179 .addImm(Reg1)
1180 .addImm(Imm * 16)
1181 .setMIFlag(Flag);
1182 break;
1183 }
1184 }
1185 auto I = MBB->insertAfter(MBBI, MIB);
1186 return I;
1187}
1188
1191 if (!AFI->needsDwarfUnwindInfo(MF) || !AFI->hasStreamingModeChanges())
1192 return false;
1193 // For Darwin platforms we don't save VG for non-SVE functions, even if SME
1194 // is enabled with streaming mode changes.
1195 auto &ST = MF.getSubtarget<AArch64Subtarget>();
1196 if (ST.isTargetDarwin())
1197 return ST.hasSVE();
1198 return true;
1199}
1200
1202 MachineFunction &MF) const {
1203 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
1204 const AArch64InstrInfo *TII = Subtarget.getInstrInfo();
1205
1206 auto EmitSignRA = [&](MachineBasicBlock &MBB) {
1207 DebugLoc DL; // Set debug location to unknown.
1209
1210 BuildMI(MBB, MBBI, DL, TII->get(AArch64::PAUTH_PROLOGUE))
1212 };
1213
1214 auto EmitAuthRA = [&](MachineBasicBlock &MBB) {
1215 DebugLoc DL;
1216 MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator();
1217 if (MBBI != MBB.end())
1218 DL = MBBI->getDebugLoc();
1219
1220 TII->createPauthEpilogueInstr(MBB, DL);
1221 };
1222
1223 // This should be in sync with PEIImpl::calculateSaveRestoreBlocks.
1224 EmitSignRA(MF.front());
1225 for (MachineBasicBlock &MBB : MF) {
1226 if (MBB.isEHFuncletEntry())
1227 EmitSignRA(MBB);
1228 if (MBB.isReturnBlock())
1229 EmitAuthRA(MBB);
1230 }
1231}
1232
1234 MachineBasicBlock &MBB) const {
1235 AArch64PrologueEmitter PrologueEmitter(MF, MBB, *this);
1236 PrologueEmitter.emitPrologue();
1237}
1238
1240 MachineBasicBlock &MBB) const {
1241 AArch64EpilogueEmitter EpilogueEmitter(MF, MBB, *this);
1242 EpilogueEmitter.emitEpilogue();
1243}
1244
1247 MF.getInfo<AArch64FunctionInfo>()->needsDwarfUnwindInfo(MF);
1248}
1249
1251 return enableCFIFixup(MF) &&
1252 MF.getInfo<AArch64FunctionInfo>()->needsAsyncDwarfUnwindInfo(MF);
1253}
1254
1255/// getFrameIndexReference - Provide a base+offset reference to an FI slot for
1256/// debug info. It's the same as what we use for resolving the code-gen
1257/// references for now. FIXME: This can go wrong when references are
1258/// SP-relative and simple call frames aren't used.
1261 Register &FrameReg) const {
1263 MF, FI, FrameReg,
1264 /*PreferFP=*/
1265 MF.getFunction().hasFnAttribute(Attribute::SanitizeHWAddress) ||
1266 MF.getFunction().hasFnAttribute(Attribute::SanitizeMemTag),
1267 /*ForSimm=*/false);
1268}
1269
1272 int FI) const {
1273 // This function serves to provide a comparable offset from a single reference
1274 // point (the value of SP at function entry) that can be used for analysis,
1275 // e.g. the stack-frame-layout analysis pass. It is not guaranteed to be
1276 // correct for all objects in the presence of VLA-area objects or dynamic
1277 // stack re-alignment.
1278
1279 const auto &MFI = MF.getFrameInfo();
1280
1281 int64_t ObjectOffset = MFI.getObjectOffset(FI);
1282 StackOffset ZPRStackSize = getZPRStackSize(MF);
1283 StackOffset PPRStackSize = getPPRStackSize(MF);
1284 StackOffset SVEStackSize = ZPRStackSize + PPRStackSize;
1285
1286 // For VLA-area objects, just emit an offset at the end of the stack frame.
1287 // Whilst not quite correct, these objects do live at the end of the frame and
1288 // so it is more useful for analysis for the offset to reflect this.
1289 if (MFI.isVariableSizedObjectIndex(FI)) {
1290 return StackOffset::getFixed(-((int64_t)MFI.getStackSize())) - SVEStackSize;
1291 }
1292
1293 // This is correct in the absence of any SVE stack objects.
1294 if (!SVEStackSize)
1295 return StackOffset::getFixed(ObjectOffset - getOffsetOfLocalArea());
1296
1297 const auto *AFI = MF.getInfo<AArch64FunctionInfo>();
1298 bool FPAfterSVECalleeSaves = hasSVECalleeSavesAboveFrameRecord(MF);
1299 if (MFI.hasScalableStackID(FI)) {
1300 if (FPAfterSVECalleeSaves &&
1301 -ObjectOffset <= (int64_t)AFI->getSVECalleeSavedStackSize()) {
1302 assert(!AFI->hasSplitSVEObjects() &&
1303 "split-sve-objects not supported with FPAfterSVECalleeSaves");
1304 return StackOffset::getScalable(ObjectOffset);
1305 }
1306 StackOffset AccessOffset{};
1307 // The scalable vectors are below (lower address) the scalable predicates
1308 // with split SVE objects, so we must subtract the size of the predicates.
1309 if (AFI->hasSplitSVEObjects() &&
1310 MFI.getStackID(FI) == TargetStackID::ScalableVector)
1311 AccessOffset = -PPRStackSize;
1312 return AccessOffset +
1313 StackOffset::get(-((int64_t)AFI->getCalleeSavedStackSize()),
1314 ObjectOffset);
1315 }
1316
1317 bool IsFixed = MFI.isFixedObjectIndex(FI);
1318 bool IsCSR =
1319 !IsFixed && ObjectOffset >= -((int)AFI->getCalleeSavedStackSize(MFI));
1320
1321 StackOffset ScalableOffset = {};
1322 if (!IsFixed && !IsCSR) {
1323 ScalableOffset = -SVEStackSize;
1324 } else if (FPAfterSVECalleeSaves && IsCSR) {
1325 ScalableOffset =
1327 }
1328
1329 return StackOffset::getFixed(ObjectOffset) + ScalableOffset;
1330}
1331
1337
1338StackOffset AArch64FrameLowering::getFPOffset(const MachineFunction &MF,
1339 int64_t ObjectOffset) const {
1340 const auto *AFI = MF.getInfo<AArch64FunctionInfo>();
1341 const auto &Subtarget = MF.getSubtarget<AArch64Subtarget>();
1342 const Function &F = MF.getFunction();
1343 bool IsWin64 = Subtarget.isCallingConvWin64(F.getCallingConv(), F.isVarArg());
1344 unsigned FixedObject =
1345 getFixedObjectSize(MF, AFI, IsWin64, /*IsFunclet=*/false);
1346 int64_t CalleeSaveSize = AFI->getCalleeSavedStackSize(MF.getFrameInfo());
1347 int64_t FPAdjust =
1348 CalleeSaveSize - AFI->getCalleeSaveBaseToFrameRecordOffset();
1349 return StackOffset::getFixed(ObjectOffset + FixedObject + FPAdjust);
1350}
1351
1352StackOffset AArch64FrameLowering::getStackOffset(const MachineFunction &MF,
1353 int64_t ObjectOffset) const {
1354 const auto &MFI = MF.getFrameInfo();
1355 return StackOffset::getFixed(ObjectOffset + (int64_t)MFI.getStackSize());
1356}
1357
1358// TODO: This function currently does not work for scalable vectors.
1360 int FI) const {
1361 const AArch64RegisterInfo *RegInfo =
1362 MF.getSubtarget<AArch64Subtarget>().getRegisterInfo();
1363 int ObjectOffset = MF.getFrameInfo().getObjectOffset(FI);
1364 return RegInfo->getLocalAddressRegister(MF) == AArch64::FP
1365 ? getFPOffset(MF, ObjectOffset).getFixed()
1366 : getStackOffset(MF, ObjectOffset).getFixed();
1367}
1368
1370 const MachineFunction &MF, int FI, Register &FrameReg, bool PreferFP,
1371 bool ForSimm) const {
1372 const auto &MFI = MF.getFrameInfo();
1373 int64_t ObjectOffset = MFI.getObjectOffset(FI);
1374 bool isFixed = MFI.isFixedObjectIndex(FI);
1375 auto StackID = static_cast<TargetStackID::Value>(MFI.getStackID(FI));
1376 return resolveFrameOffsetReference(MF, ObjectOffset, isFixed, StackID,
1377 FrameReg, PreferFP, ForSimm);
1378}
1379
1381 const MachineFunction &MF, int64_t ObjectOffset, bool isFixed,
1382 TargetStackID::Value StackID, Register &FrameReg, bool PreferFP,
1383 bool ForSimm) const {
1384 const auto &MFI = MF.getFrameInfo();
1385 const auto &Subtarget = MF.getSubtarget<AArch64Subtarget>();
1386 const AArch64RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
1387 const auto *AFI = MF.getInfo<AArch64FunctionInfo>();
1388
1389 int64_t FPOffset = getFPOffset(MF, ObjectOffset).getFixed();
1390 int64_t Offset = getStackOffset(MF, ObjectOffset).getFixed();
1391
1392 // The fixed object area sits above the callee-saved area and can grow
1393 // large enough to displace it; account for that displacement here so CSR
1394 // objects aren't misclassified as locals and addressed via the base
1395 // pointer.
1396 bool IsWin64 = Subtarget.isCallingConvWin64(MF.getFunction().getCallingConv(),
1397 MF.getFunction().isVarArg());
1398 const int64_t FixedObjectSize =
1399 getFixedObjectSize(MF, AFI, IsWin64, /*IsFunclet*/ false);
1400 bool isCSR =
1401 !isFixed && ObjectOffset >= -((int64_t)AFI->getCalleeSavedStackSize(MFI) +
1402 FixedObjectSize);
1403 bool isSVE = MFI.isScalableStackID(StackID);
1404
1405 StackOffset ZPRStackSize = getZPRStackSize(MF);
1406 StackOffset PPRStackSize = getPPRStackSize(MF);
1407 StackOffset SVEStackSize = ZPRStackSize + PPRStackSize;
1408
1409 // Use frame pointer to reference fixed objects. Use it for locals if
1410 // there are VLAs or a dynamically realigned SP (and thus the SP isn't
1411 // reliable as a base). Make sure useFPForScavengingIndex() does the
1412 // right thing for the emergency spill slot.
1413 bool UseFP = false;
1414 if (AFI->hasStackFrame() && !isSVE) {
1415 // We shouldn't prefer using the FP to access fixed-sized stack objects when
1416 // there are scalable (SVE) objects in between the FP and the fixed-sized
1417 // objects.
1418 PreferFP &= !SVEStackSize;
1419
1420 // Note: Keeping the following as multiple 'if' statements rather than
1421 // merging to a single expression for readability.
1422 //
1423 // Argument access should always use the FP.
1424 if (isFixed) {
1425 UseFP = hasFP(MF);
1426 } else if (isCSR && RegInfo->hasStackRealignment(MF)) {
1427 // References to the CSR area must use FP if we're re-aligning the stack
1428 // since the dynamically-sized alignment padding is between the SP/BP and
1429 // the CSR area.
1430 assert(hasFP(MF) && "Re-aligned stack must have frame pointer");
1431 UseFP = true;
1432 } else if (hasFP(MF) && !RegInfo->hasStackRealignment(MF)) {
1433 // If the FPOffset is negative and we're producing a signed immediate, we
1434 // have to keep in mind that the available offset range for negative
1435 // offsets is smaller than for positive ones. If an offset is available
1436 // via the FP and the SP, use whichever is closest.
1437 bool FPOffsetFits = !ForSimm || FPOffset >= -256;
1438 PreferFP |= Offset > -FPOffset && !SVEStackSize;
1439
1440 if (FPOffset >= 0) {
1441 // If the FPOffset is positive, that'll always be best, as the SP/BP
1442 // will be even further away.
1443 UseFP = true;
1444 } else if (MFI.hasVarSizedObjects()) {
1445 // If we have variable sized objects, we can use either FP or BP, as the
1446 // SP offset is unknown. We can use the base pointer if we have one and
1447 // FP is not preferred. If not, we're stuck with using FP.
1448 bool CanUseBP = RegInfo->hasBasePointer(MF);
1449 if (FPOffsetFits && CanUseBP) // Both are ok. Pick the best.
1450 UseFP = PreferFP;
1451 else if (!CanUseBP) // Can't use BP. Forced to use FP.
1452 UseFP = true;
1453 // else we can use BP and FP, but the offset from FP won't fit.
1454 // That will make us scavenge registers which we can probably avoid by
1455 // using BP. If it won't fit for BP either, we'll scavenge anyway.
1456 } else if (MF.hasEHFunclets() && !RegInfo->hasBasePointer(MF)) {
1457 // Funclets access the locals contained in the parent's stack frame
1458 // via the frame pointer, so we have to use the FP in the parent
1459 // function.
1460 (void) Subtarget;
1461 assert(Subtarget.isCallingConvWin64(MF.getFunction().getCallingConv(),
1462 MF.getFunction().isVarArg()) &&
1463 "Funclets should only be present on Win64");
1464 UseFP = true;
1465 } else {
1466 // We have the choice between FP and (SP or BP).
1467 if (FPOffsetFits && PreferFP) // If FP is the best fit, use it.
1468 UseFP = true;
1469 }
1470 }
1471 }
1472
1473 assert(
1474 ((isFixed || isCSR) || !RegInfo->hasStackRealignment(MF) || !UseFP) &&
1475 "In the presence of dynamic stack pointer realignment, "
1476 "non-argument/CSR objects cannot be accessed through the frame pointer");
1477
1478 bool FPAfterSVECalleeSaves = hasSVECalleeSavesAboveFrameRecord(MF);
1479
1480 if (isSVE) {
1481 StackOffset FPOffset = StackOffset::get(
1482 -AFI->getCalleeSaveBaseToFrameRecordOffset(), ObjectOffset);
1483 StackOffset SPOffset =
1484 SVEStackSize +
1485 StackOffset::get(MFI.getStackSize() - AFI->getCalleeSavedStackSize(),
1486 ObjectOffset);
1487
1488 // With split SVE objects the ObjectOffset is relative to the split area
1489 // (i.e. the PPR area or ZPR area respectively).
1490 if (AFI->hasSplitSVEObjects() && StackID == TargetStackID::ScalableVector) {
1491 // If we're accessing an SVE vector with split SVE objects...
1492 // - From the FP we need to move down past the PPR area:
1493 FPOffset -= PPRStackSize;
1494 // - From the SP we only need to move up to the ZPR area:
1495 SPOffset -= PPRStackSize;
1496 // Note: `SPOffset = SVEStackSize + ...`, so `-= PPRStackSize` results in
1497 // `SPOffset = ZPRStackSize + ...`.
1498 }
1499
1500 if (FPAfterSVECalleeSaves) {
1502 if (-ObjectOffset <= (int64_t)AFI->getSVECalleeSavedStackSize()) {
1505 }
1506 }
1507
1508 // Always use the FP for SVE spills if available and beneficial.
1509 if (hasFP(MF) && (SPOffset.getFixed() ||
1510 FPOffset.getScalable() < SPOffset.getScalable() ||
1511 RegInfo->hasStackRealignment(MF))) {
1512 FrameReg = RegInfo->getFrameRegister(MF);
1513 return FPOffset;
1514 }
1515 FrameReg = RegInfo->hasBasePointer(MF) ? RegInfo->getBaseRegister()
1516 : MCRegister(AArch64::SP);
1517
1518 return SPOffset;
1519 }
1520
1521 StackOffset SVEAreaOffset = {};
1522 if (FPAfterSVECalleeSaves) {
1523 // In this stack layout, the FP is in between the callee saves and other
1524 // SVE allocations.
1525 StackOffset SVECalleeSavedStack =
1527 if (UseFP) {
1528 if (isFixed)
1529 SVEAreaOffset = SVECalleeSavedStack;
1530 else if (!isCSR)
1531 SVEAreaOffset = SVECalleeSavedStack - SVEStackSize;
1532 } else {
1533 if (isFixed)
1534 SVEAreaOffset = SVEStackSize;
1535 else if (isCSR)
1536 SVEAreaOffset = SVEStackSize - SVECalleeSavedStack;
1537 }
1538 } else {
1539 if (UseFP && !(isFixed || isCSR))
1540 SVEAreaOffset = -SVEStackSize;
1541 if (!UseFP && (isFixed || isCSR))
1542 SVEAreaOffset = SVEStackSize;
1543 }
1544
1545 if (UseFP) {
1546 FrameReg = RegInfo->getFrameRegister(MF);
1547 return StackOffset::getFixed(FPOffset) + SVEAreaOffset;
1548 }
1549
1550 // Use the base pointer if we have one.
1551 if (RegInfo->hasBasePointer(MF))
1552 FrameReg = RegInfo->getBaseRegister();
1553 else {
1554 assert(!MFI.hasVarSizedObjects() &&
1555 "Can't use SP when we have var sized objects.");
1556 FrameReg = AArch64::SP;
1557 // If we're using the red zone for this function, the SP won't actually
1558 // be adjusted, so the offsets will be negative. They're also all
1559 // within range of the signed 9-bit immediate instructions.
1560 if (canUseRedZone(MF))
1561 Offset -= AFI->getLocalStackSize();
1562 }
1563
1564 return StackOffset::getFixed(Offset) + SVEAreaOffset;
1565}
1566
1568 // Do not set a kill flag on values that are also marked as live-in. This
1569 // happens with the @llvm-returnaddress intrinsic and with arguments passed in
1570 // callee saved registers.
1571 // Omitting the kill flags is conservatively correct even if the live-in
1572 // is not used after all.
1573 bool IsLiveIn = MF.getRegInfo().isLiveIn(Reg);
1574 return getKillRegState(!IsLiveIn);
1575}
1576
1578 MachineFunction &MF) {
1579 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
1582 return Subtarget.isTargetMachO() &&
1583 !(Subtarget.getTargetLowering()->supportSwiftError() &&
1584 Attrs.hasAttrSomewhere(Attribute::SwiftError)) &&
1586 !AFL.requiresSaveVG(MF) && !AFI->isSVECC();
1587}
1588
1589static bool invalidateWindowsRegisterPairing(bool SpillExtendedVolatile,
1590 int PairOffset, unsigned Reg1,
1591 unsigned Reg2, bool NeedsWinCFI,
1592 const TargetRegisterInfo *TRI) {
1593 // If we are generating register pairs for a Windows function that requires
1594 // EH support, then pair consecutive registers only. There are no unwind
1595 // opcodes for saves/restores of non-consecutive register pairs.
1596 // The unwind opcodes are save_regp, save_regp_x, save_fregp, save_frepg_x,
1597 // save_lrpair.
1598 // https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling
1599
1600 if (Reg2 == AArch64::FP)
1601 return true;
1602 if (!NeedsWinCFI)
1603 return false;
1604
1605 // ARM64EC introduced `save_any_regp`, which expects 16-byte alignment.
1606 // This is handled by only allowing paired spills for registers spilled at
1607 // even positions (which should be 16-byte aligned, as other GPRs/FPRs are
1608 // 8-bytes). We carve out an exception for {FP,LR}, which does not require
1609 // 16-byte alignment in the uop representation.
1610 if (TRI->getEncodingValue(Reg2) == TRI->getEncodingValue(Reg1) + 1)
1611 return SpillExtendedVolatile
1612 ? !((Reg1 == AArch64::FP && Reg2 == AArch64::LR) ||
1613 (PairOffset % 16) == 0)
1614 : false;
1615
1616 // If pairing a GPR with LR, the pair can be described by the save_lrpair
1617 // opcode. The save_lrpair opcode requires the first register to be odd.
1618 if (Reg1 >= AArch64::X19 && Reg1 <= AArch64::X27 &&
1619 (Reg1 - AArch64::X19) % 2 == 0 && Reg2 == AArch64::LR)
1620 return false;
1621 return true;
1622}
1623
1624/// Returns true if Reg1 and Reg2 cannot be paired using a ldp/stp instruction.
1625/// WindowsCFI requires that only consecutive registers can be paired.
1626/// LR and FP need to be allocated together when the frame needs to save
1627/// the frame-record. This means any other register pairing with LR is invalid.
1628static bool invalidateRegisterPairing(bool SpillExtendedVolatile,
1629 int PairOffset, unsigned Reg1,
1630 unsigned Reg2, bool UsesWinAAPCS,
1631 bool NeedsWinCFI, bool NeedsFrameRecord,
1632 const TargetRegisterInfo *TRI) {
1633 if (UsesWinAAPCS)
1634 return invalidateWindowsRegisterPairing(SpillExtendedVolatile, PairOffset,
1635 Reg1, Reg2, NeedsWinCFI, TRI);
1636
1637 // If we need to store the frame record, don't pair any register
1638 // with LR other than FP.
1639 if (NeedsFrameRecord)
1640 return Reg2 == AArch64::LR;
1641
1642 return false;
1643}
1644
1645// Returns true if Offset (in bytes) is aligned to the instruction's scale and
1646// the scaled immediate is within the instruction's valid range.
1647static bool isValidMemOpOffset(const AArch64InstrInfo *TII, unsigned Opcode,
1648 int Offset) {
1649 int64_t MinOff, MaxOff;
1650 TypeSize ScaleValue(0U, false), Width(0U, false);
1651 if (!TII->getMemOpInfo(Opcode, ScaleValue, Width, MinOff, MaxOff))
1652 return false;
1653
1654 if (Offset % ScaleValue.getKnownMinValue() != 0)
1655 return false;
1656
1657 Offset /= ScaleValue.getKnownMinValue();
1658 return Offset >= MinOff && Offset <= MaxOff;
1659}
1660
1661namespace {
1662
1663struct RegGroupInfo {
1664 Register Reg1;
1665 Register Reg2;
1666 int FrameIdx;
1667 int Offset;
1668 enum RegType { GPR, FPR64, FPR128, PPR, ZPR, VG } Type;
1669 const TargetRegisterClass *RC;
1670
1671 RegGroupInfo() = default;
1672
1673 bool isPaired() const { return getNumRegs() == 2; }
1674
1675 bool isQuad() const { return getNumRegs() == 4; }
1676
1677 bool isGrouped() const { return isPaired() || isQuad(); }
1678
1679 unsigned getNumRegs() const {
1680 if (!Reg2.isValid())
1681 return 1;
1682 if (Type != ZPR)
1683 return 2;
1684 // ZPR groups are contiguous with Reg2 holding the lower register.
1685 unsigned NumRegs = (Reg1 - Reg2) + 1;
1686 assert(NumRegs == 2 || NumRegs == 4);
1687 return NumRegs;
1688 }
1689
1690 bool isScalable() const { return Type == PPR || Type == ZPR; }
1691
1692 SmallVector<Register, 4> getRegisters() const {
1693 if (isPaired())
1694 return {Reg1, Reg2};
1695 if (isQuad()) {
1696 assert(Reg1 - 3 == Reg2 && "Quad not contiguous");
1697 return {Reg1, Reg1 - 1, Reg1 - 2, Reg1 - 3};
1698 }
1699 return {Reg1};
1700 }
1701
1702 auto getFrameIndexes() const {
1703 return seq(FrameIdx, FrameIdx + int(getNumRegs()));
1704 }
1705
1706 Register getAsMultiVectorRegister() const {
1707 assert(Type == ZPR && isGrouped() && "Expected ZPR register group");
1708 return (isQuad() ? AArch64::Z0_Z1_Z2_Z3 : AArch64::Z0_Z1) +
1709 (Reg2 - AArch64::Z0);
1710 }
1711
1712 void dump(const TargetRegisterInfo *TRI) const {
1713 dbgs() << "(";
1714 interleaveComma(getRegisters(), dbgs(),
1715 [&](Register Reg) { dbgs() << printReg(Reg, TRI); });
1716 dbgs() << ") -> fi#(";
1717 interleaveComma(getFrameIndexes(), dbgs(),
1718 [&](int FrameIdx) { dbgs() << FrameIdx; });
1719 dbgs() << ")\n";
1720 }
1721};
1722
1723} // end anonymous namespace
1724
1726 for (unsigned PReg = AArch64::P8; PReg <= AArch64::P15; ++PReg) {
1727 if (SavedRegs.test(PReg)) {
1728 unsigned PNReg = PReg - AArch64::P0 + AArch64::PN0;
1729 return MCRegister(PNReg);
1730 }
1731 }
1732 return MCRegister();
1733}
1734
1735// The multivector LD/ST are available only for SME or SVE2p1 targets
1737 MachineFunction &MF) {
1738 if (Subtarget.getCLOpts().disable_multivector_spill_fill)
1739 return false;
1740
1741 SMEAttrs FuncAttrs = MF.getInfo<AArch64FunctionInfo>()->getSMEFnAttrs();
1742 bool IsLocallyStreaming =
1743 FuncAttrs.hasStreamingBody() && !FuncAttrs.hasStreamingInterface();
1744
1745 // Only when in streaming mode SME2 instructions can be safely used.
1746 // It is not safe to use SME2 instructions when in streaming compatible or
1747 // locally streaming mode.
1748 return Subtarget.hasSVE2p1() ||
1749 (Subtarget.hasSME2() &&
1750 (!IsLocallyStreaming && Subtarget.isStreaming()));
1751}
1752
1754 MachineFunction &MF,
1756 const TargetRegisterInfo *TRI,
1758 bool NeedsFrameRecord) {
1759
1760 if (CSI.empty())
1761 return;
1762
1763 const AArch64InstrInfo *TII =
1764 MF.getSubtarget<AArch64Subtarget>().getInstrInfo();
1765 bool IsWindows = isTargetWindows(MF);
1766 bool NeedsWinCFI = MF.needsWinCFI();
1768 unsigned StackHazardSize = getStackHazardSize(MF);
1769 MachineFrameInfo &MFI = MF.getFrameInfo();
1771 unsigned Count = CSI.size();
1772 (void)CC;
1773 // MachO's compact unwind format relies on all registers being stored in
1774 // pairs.
1775 assert((!produceCompactUnwindFrame(AFL, MF) ||
1778 (Count & 1) == 0) &&
1779 "Odd number of callee-saved regs to spill!");
1780 int ByteOffset = AFI->getCalleeSavedStackSize();
1781 int StackFillDir = -1;
1782 int RegInc = 1;
1783 unsigned FirstReg = 0;
1784 if (IsWindows) {
1785 // For WinCFI, fill the stack from the bottom up.
1786 ByteOffset = 0;
1787 StackFillDir = 1;
1788 // As the CSI array is reversed to match PrologEpilogInserter, iterate
1789 // backwards, to pair up registers starting from lower numbered registers.
1790 RegInc = -1;
1791 FirstReg = Count - 1;
1792 }
1793
1794 bool FPAfterSVECalleeSaves = AFL.hasSVECalleeSavesAboveFrameRecord(MF);
1795 // Windows AAPCS has x9-x15 as volatile registers, x16-x17 as intra-procedural
1796 // scratch, x18 as platform reserved. However, clang has extended calling
1797 // convensions such as preserve_most and preserve_all which treat these as
1798 // CSR. As such, the ARM64 unwind uOPs bias registers by 19. We use ARM64EC
1799 // uOPs which have separate restrictions. We need to check for that.
1800 //
1801 // NOTE: we currently do not account for the D registers as LLVM does not
1802 // support non-ABI compliant D register spills.
1803 bool SpillExtendedVolatile =
1804 IsWindows && llvm::any_of(CSI, [](const CalleeSavedInfo &CSI) {
1805 const auto &Reg = CSI.getReg();
1806 return Reg >= AArch64::X0 && Reg <= AArch64::X18;
1807 });
1808
1809 int ZPRByteOffset = 0;
1810 int PPRByteOffset = 0;
1811 bool SplitPPRs = AFI->hasSplitSVEObjects();
1812 if (SplitPPRs) {
1813 ZPRByteOffset = AFI->getZPRCalleeSavedStackSize();
1814 PPRByteOffset = AFI->getPPRCalleeSavedStackSize();
1815 } else if (!FPAfterSVECalleeSaves) {
1816 ZPRByteOffset =
1818 // Unused: Everything goes in ZPR space.
1819 PPRByteOffset = 0;
1820 }
1821
1822 bool NeedGapToAlignStack = AFI->hasCalleeSaveStackFreeSpace();
1823 Register LastReg = 0;
1824 bool HasCSHazardPadding = AFI->hasStackHazardSlotIndex() && !SplitPPRs;
1825
1826 auto AlignOffset = [StackFillDir](int Offset, int Align) {
1827 if (StackFillDir < 0)
1828 return alignDown(Offset, Align);
1829 return alignTo(Offset, Align);
1830 };
1831
1832 // When iterating backwards, the loop condition relies on unsigned wraparound.
1833 for (unsigned i = FirstReg; i < Count; i += RegInc) {
1834 RegGroupInfo RGI;
1835 RGI.Reg1 = CSI[i].getReg();
1836
1837 if (AArch64::GPR64RegClass.contains(RGI.Reg1)) {
1838 RGI.Type = RegGroupInfo::GPR;
1839 RGI.RC = &AArch64::GPR64RegClass;
1840 } else if (AArch64::FPR64RegClass.contains(RGI.Reg1)) {
1841 RGI.Type = RegGroupInfo::FPR64;
1842 RGI.RC = &AArch64::FPR64RegClass;
1843 } else if (AArch64::FPR128RegClass.contains(RGI.Reg1)) {
1844 RGI.Type = RegGroupInfo::FPR128;
1845 RGI.RC = &AArch64::FPR128RegClass;
1846 } else if (AArch64::ZPRRegClass.contains(RGI.Reg1)) {
1847 RGI.Type = RegGroupInfo::ZPR;
1848 RGI.RC = &AArch64::ZPRRegClass;
1849 } else if (AArch64::PPRRegClass.contains(RGI.Reg1)) {
1850 RGI.Type = RegGroupInfo::PPR;
1851 RGI.RC = &AArch64::PPRRegClass;
1852 } else if (RGI.Reg1 == AArch64::VG) {
1853 RGI.Type = RegGroupInfo::VG;
1854 RGI.RC = &AArch64::FIXED_REGSRegClass;
1855 } else {
1856 llvm_unreachable("Unsupported register class.");
1857 }
1858
1859 int &ScalableByteOffset = RGI.Type == RegGroupInfo::PPR && SplitPPRs
1860 ? PPRByteOffset
1861 : ZPRByteOffset;
1862
1863 // Add the stack hazard size as we transition from GPR->FPR CSRs.
1864 if (HasCSHazardPadding &&
1865 (!LastReg || !AArch64InstrInfo::isFpOrNEON(LastReg)) &&
1867 ByteOffset += StackFillDir * StackHazardSize;
1868 LastReg = RGI.Reg1;
1869
1870 int Scale = TRI->getSpillSize(*RGI.RC);
1871 // Add the next reg to the pair if it is in the same register class.
1872 if (unsigned(i + RegInc) < Count && !HasCSHazardPadding) {
1873 MCRegister NextReg = CSI[i + RegInc].getReg();
1874 int Aligned = AlignOffset(ByteOffset, Scale);
1875 int PairOffset = IsWindows ? Aligned : Aligned + StackFillDir * 2 * Scale;
1876 bool PairFitsImmRange =
1877 PairOffset / Scale >= -64 && PairOffset / Scale <= 63;
1878 switch (RGI.Type) {
1879 case RegGroupInfo::GPR:
1880 case RegGroupInfo::FPR64:
1881 case RegGroupInfo::FPR128: {
1882 const TargetRegisterClass &SpillRC =
1883 RGI.Type == RegGroupInfo::GPR ? AArch64::GPR64RegClass
1884 : RGI.Type == RegGroupInfo::FPR64 ? AArch64::FPR64RegClass
1885 : AArch64::FPR128RegClass;
1886
1887 if (SpillRC.contains(NextReg) && PairFitsImmRange &&
1888 !invalidateRegisterPairing(SpillExtendedVolatile, PairOffset,
1889 RGI.Reg1, NextReg, IsWindows,
1890 NeedsWinCFI, NeedsFrameRecord, TRI))
1891 RGI.Reg2 = NextReg;
1892 break;
1893 }
1894 case RegGroupInfo::PPR:
1895 break;
1896 case RegGroupInfo::ZPR: {
1897 // Windows support is possible but the order requirement is reversed.
1898 // Also, WinCFI has no support for group ZPR loads/stores yet.
1899 if (isTargetWindows(MF) || AFI->getPredicateRegForFillSpill() == 0)
1900 break;
1901
1902 // We expect to see pairs and quads in descending order (e.g. [z7, z6,
1903 // z5, z4]). We ensure this in `orderZPRCalleeSavesForGroups()`. This
1904 // is required as (for Linux) StackFillDir is negative (so we start at
1905 // higher addresses) and we need to ensure the lower register in the
1906 // pair has the lower address to store the registers in the correct
1907 // order.
1908 auto GetZPRTupleLowestReg =
1909 [&](unsigned NumRegs) -> std::optional<Register> {
1910 // Check Reg1 is the last register in a tuple.
1911 if (RGI.Reg1 % NumRegs != NumRegs - 1)
1912 return std::nullopt;
1913
1914 // Check there's enough registers for the tuple.
1915 if (i + RegInc * NumRegs > Count)
1916 return std::nullopt;
1917
1918 for (unsigned Idx = 1; Idx < NumRegs; ++Idx) {
1919 Register Reg = CSI[i + RegInc * Idx].getReg();
1920 Register ExpectedReg = RGI.Reg1 - Idx;
1921 if (Reg != ExpectedReg)
1922 return std::nullopt;
1923 }
1924
1925 return RGI.Reg1 - NumRegs + 1;
1926 };
1927
1928 for (unsigned TupleSize : {4, 2}) {
1929 if (auto LowReg = GetZPRTupleLowestReg(TupleSize)) {
1930 // Note: ST1B has the same offset constraints.
1931 unsigned Opcode =
1932 TupleSize == 4 ? AArch64::LD1B_4Z_IMM : AArch64::LD1B_2Z_IMM;
1933 const int Offset =
1934 (ScalableByteOffset + StackFillDir * TupleSize * Scale);
1935 if (isValidMemOpOffset(TII, Opcode, Offset)) {
1936 RGI.Reg2 = *LowReg;
1937 break;
1938 }
1939 }
1940 }
1941
1942 break;
1943 }
1944 case RegGroupInfo::VG:
1945 break;
1946 }
1947 }
1948
1949 // GPRs and FPRs are saved in pairs of 64-bit regs. We expect the CSI
1950 // list to come in sorted by frame index so that we can issue the store
1951 // pair instructions directly. Assert if we see anything otherwise.
1952 //
1953 // The order of the registers in the list is controlled by
1954 // getCalleeSavedRegs(), so they will always be in-order, as well.
1955 [[maybe_unused]] bool RegsOrdered =
1956 all_of(seq(RGI.getNumRegs() - 1), [&](int RegOffset) {
1957 return CSI[i + RegInc * RegOffset].getFrameIdx() + RegInc ==
1958 CSI[i + RegInc * RegOffset + RegInc].getFrameIdx();
1959 });
1960 assert(RegsOrdered && "Out of order callee saved regs!");
1961
1962 assert((!RGI.isQuad() || RGI.Type == RegGroupInfo::ZPR) &&
1963 "Currently only ZPR's support four-register spills");
1964
1965 assert((!RGI.isPaired() || !NeedsFrameRecord || RGI.Reg2 != AArch64::FP ||
1966 RGI.Reg1 == AArch64::LR) &&
1967 "FrameRecord must be allocated together with LR");
1968
1969 // Windows AAPCS has FP and LR reversed.
1970 assert((!RGI.isPaired() || !NeedsFrameRecord || RGI.Reg1 != AArch64::FP ||
1971 RGI.Reg2 == AArch64::LR) &&
1972 "FrameRecord must be allocated together with LR");
1973
1974 // MachO's compact unwind format relies on all registers being stored in
1975 // adjacent register pairs.
1976 assert((!produceCompactUnwindFrame(AFL, MF) ||
1979 (RGI.isPaired() &&
1980 ((RGI.Reg1 == AArch64::LR && RGI.Reg2 == AArch64::FP) ||
1981 RGI.Reg1 + 1 == RGI.Reg2))) &&
1982 "Callee-save registers not saved as adjacent register pair!");
1983
1984 RGI.FrameIdx = CSI[i].getFrameIdx();
1985 if (IsWindows)
1986 // RGI.FrameIdx must be the lower index of the group
1987 RGI.FrameIdx = CSI[i + RegInc * (RGI.getNumRegs() - 1)].getFrameIdx();
1988
1989 // Realign the scalable offset if necessary. This is relevant when spilling
1990 // predicates on Windows.
1991 if (RGI.isScalable() && ScalableByteOffset % Scale != 0)
1992 ScalableByteOffset = AlignOffset(ScalableByteOffset, Scale);
1993
1994 // Realign the fixed offset if necessary. This is relevant when spilling Q
1995 // registers after spilling an odd amount of X registers.
1996 if (!RGI.isScalable() && ByteOffset % Scale != 0)
1997 ByteOffset = AlignOffset(ByteOffset, Scale);
1998
1999 int OffsetPre = RGI.isScalable() ? ScalableByteOffset : ByteOffset;
2000 assert(OffsetPre % Scale == 0);
2001
2002 if (RGI.isScalable())
2003 ScalableByteOffset += StackFillDir * RGI.getNumRegs() * Scale;
2004 else
2005 ByteOffset += StackFillDir * RGI.getNumRegs() * Scale;
2006
2007 // Swift's async context is directly before FP, so allocate an extra
2008 // 8 bytes for it.
2009 if (NeedsFrameRecord && AFI->hasSwiftAsyncContext() &&
2010 ((!IsWindows && RGI.Reg2 == AArch64::FP) ||
2011 (IsWindows && RGI.Reg2 == AArch64::LR)))
2012 ByteOffset += StackFillDir * 8;
2013
2014 // Round up size of non-pair to pair size if we need to pad the
2015 // callee-save area to ensure 16-byte alignment.
2016 if (NeedGapToAlignStack && !IsWindows && !RGI.isScalable() &&
2017 RGI.Type != RegGroupInfo::FPR128 && !RGI.isPaired() &&
2018 ByteOffset % 16 != 0) {
2019 ByteOffset += 8 * StackFillDir;
2020 assert(MFI.getObjectAlign(RGI.FrameIdx) <= Align(16));
2021 // A stack frame with a gap looks like this, bottom up:
2022 // d9, d8. x21, gap, x20, x19.
2023 // Set extra alignment on the x21 object to create the gap above it.
2024 MFI.setObjectAlignment(RGI.FrameIdx, Align(16));
2025 NeedGapToAlignStack = false;
2026 }
2027
2028 int OffsetPost = RGI.isScalable() ? ScalableByteOffset : ByteOffset;
2029 assert(OffsetPost % Scale == 0);
2030 // If filling top down (default), we want the offset after incrementing it.
2031 // If filling bottom up (WinCFI) we need the original offset.
2032 int Offset = IsWindows ? OffsetPre : OffsetPost;
2033
2034 // The FP, LR pair goes 8 bytes into our expanded 24-byte slot so that the
2035 // Swift context can directly precede FP.
2036 if (NeedsFrameRecord && AFI->hasSwiftAsyncContext() &&
2037 ((!IsWindows && RGI.Reg2 == AArch64::FP) ||
2038 (IsWindows && RGI.Reg2 == AArch64::LR)))
2039 Offset += 8;
2040
2041 assert(
2042 (!RGI.isGrouped() || RGI.Type != RegGroupInfo::ZPR ||
2044 TII, (RGI.isQuad() ? AArch64::LD1B_4Z_IMM : AArch64::LD1B_2Z_IMM),
2045 Offset)) &&
2046 "Offset invalid for LD1B/ST1B pair/quad variant immediate");
2047
2048 RGI.Offset = Offset / Scale;
2049 assert((!RGI.isGrouped() || RGI.Type == RegGroupInfo::ZPR ||
2050 (!RGI.isScalable() && RGI.Offset >= -64 && RGI.Offset <= 63) ||
2051 (RGI.isScalable() && RGI.Offset >= -256 && RGI.Offset <= 255)) &&
2052 "Offset out of bounds for LDP/STP immediate");
2053
2054 auto isFrameRecord = [&] {
2055 if (RGI.isPaired())
2056 return IsWindows ? RGI.Reg1 == AArch64::FP && RGI.Reg2 == AArch64::LR
2057 : RGI.Reg1 == AArch64::LR && RGI.Reg2 == AArch64::FP;
2058 // Otherwise, look for the frame record as two unpaired registers. This is
2059 // needed for -aarch64-stack-hazard-size=<val>, which disables register
2060 // pairing (as the padding may be too large for the LDP/STP offset). Note:
2061 // On Windows, this check works out as current reg == FP, next reg == LR,
2062 // and on other platforms current reg == FP, previous reg == LR. This
2063 // works out as the correct pre-increment or post-increment offsets
2064 // respectively.
2065 return i > 0 && RGI.Reg1 == AArch64::FP &&
2066 CSI[i - 1].getReg() == AArch64::LR;
2067 };
2068
2069 // Save the offset to frame record so that the FP register can point to the
2070 // innermost frame record (spilled FP and LR registers).
2071 if (NeedsFrameRecord && isFrameRecord())
2073
2074 RegGroups.push_back(RGI);
2075 i += RegInc * (RGI.getNumRegs() - 1);
2076 }
2077 if (IsWindows) {
2078 // If we need an alignment gap in the stack, align the topmost stack
2079 // object. A stack frame with a gap looks like this, bottom up:
2080 // x19, d8. d9, gap.
2081 // Set extra alignment on the topmost stack object (the first element in
2082 // CSI, which goes top down), to create the gap above it.
2083 if (AFI->hasCalleeSaveStackFreeSpace())
2084 MFI.setObjectAlignment(CSI[0].getFrameIdx(), Align(16));
2085 // We iterated bottom up over the registers; flip RegGroups back to top
2086 // down order.
2087 std::reverse(RegGroups.begin(), RegGroups.end());
2088 }
2089}
2090
2094 MachineFunction &MF = *MBB.getParent();
2095 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
2096 auto &TLI = *Subtarget.getTargetLowering();
2097 const AArch64InstrInfo &TII = *Subtarget.getInstrInfo();
2098 bool NeedsWinCFI = MF.needsWinCFI();
2099 DebugLoc DL;
2101
2102 computeCalleeSaveRegisterGroups(*this, MF, CSI, TRI, RegGroups, hasFP(MF));
2103
2105 // Refresh the reserved regs in case there are any potential changes since the
2106 // last freeze.
2107 MRI.freezeReservedRegs();
2108
2109 if (homogeneousPrologEpilog(MF)) {
2110 auto MIB = BuildMI(MBB, MI, DL, TII.get(AArch64::HOM_Prolog))
2112
2113 for (auto &RGI : RegGroups) {
2114 MIB.addReg(RGI.Reg1);
2115 MIB.addReg(RGI.Reg2);
2116
2117 // Update register live in.
2118 if (!MRI.isReserved(RGI.Reg1))
2119 MBB.addLiveIn(RGI.Reg1);
2120 if (RGI.isPaired() && !MRI.isReserved(RGI.Reg2))
2121 MBB.addLiveIn(RGI.Reg2);
2122 }
2123 return true;
2124 }
2125 bool PTrueCreated = false;
2126 for (const RegGroupInfo &RGI : llvm::reverse(RegGroups)) {
2127 Register Reg1 = RGI.Reg1;
2128 Register Reg2 = RGI.Reg2;
2129 unsigned StrOpc;
2130
2131 // Issue sequence of spills for cs regs. The first spill may be converted
2132 // to a pre-decrement store later by emitPrologue if the callee-save stack
2133 // area allocation can't be combined with the local stack area allocation.
2134 // For example:
2135 // stp x22, x21, [sp, #0] // addImm(+0)
2136 // stp x20, x19, [sp, #16] // addImm(+2)
2137 // stp fp, lr, [sp, #32] // addImm(+4)
2138 // Rationale: This sequence saves uop updates compared to a sequence of
2139 // pre-increment spills like stp xi,xj,[sp,#-16]!
2140 // Note: Similar rationale and sequence for restores in epilog.
2141 unsigned Size = TRI->getSpillSize(*RGI.RC);
2142 Align Alignment = TRI->getSpillAlign(*RGI.RC);
2143 switch (RGI.Type) {
2144 case RegGroupInfo::GPR:
2145 StrOpc = RGI.isPaired() ? AArch64::STPXi : AArch64::STRXui;
2146 break;
2147 case RegGroupInfo::FPR64:
2148 StrOpc = RGI.isPaired() ? AArch64::STPDi : AArch64::STRDui;
2149 break;
2150 case RegGroupInfo::FPR128:
2151 StrOpc = RGI.isPaired() ? AArch64::STPQi : AArch64::STRQui;
2152 break;
2153 case RegGroupInfo::ZPR:
2154 StrOpc = RGI.isQuad()
2155 ? AArch64::ST1B_4Z_IMM
2156 : (RGI.isPaired() ? AArch64::ST1B_2Z_IMM : AArch64::STR_ZXI);
2157 break;
2158 case RegGroupInfo::PPR:
2159 StrOpc = AArch64::STR_PXI;
2160 break;
2161 case RegGroupInfo::VG:
2162 StrOpc = AArch64::STRXui;
2163 break;
2164 }
2165
2166 Register X0Scratch;
2167 llvm::scope_exit RestoreX0([&] {
2168 if (X0Scratch.isValid())
2169 BuildMI(MBB, MI, DL, TII.get(TargetOpcode::COPY), AArch64::X0)
2170 .addReg(X0Scratch)
2172 });
2173
2174 if (Reg1 == AArch64::VG) {
2175 // Find an available register to store value of VG to.
2176 Reg1 = findScratchNonCalleeSaveRegister(&MBB, true);
2177 assert(Reg1.isValid());
2178 if (MF.getSubtarget<AArch64Subtarget>().hasSVE()) {
2179 BuildMI(MBB, MI, DL, TII.get(AArch64::CNTD_XPiI), Reg1)
2180 .addImm(31)
2181 .addImm(1)
2183 } else {
2185 if (any_of(MBB.liveins(),
2186 [&STI](const MachineBasicBlock::RegisterMaskPair &LiveIn) {
2187 return STI.getRegisterInfo()->isSuperOrSubRegisterEq(
2188 AArch64::X0, LiveIn.PhysReg);
2189 })) {
2190 X0Scratch = Reg1;
2191 BuildMI(MBB, MI, DL, TII.get(TargetOpcode::COPY), X0Scratch)
2192 .addReg(AArch64::X0)
2194 }
2195
2196 RTLIB::Libcall LC = RTLIB::SMEABI_GET_CURRENT_VG;
2197 const uint32_t *RegMask =
2198 TRI->getCallPreservedMask(MF, TLI.getLibcallCallingConv(LC));
2199 BuildMI(MBB, MI, DL, TII.get(AArch64::BL))
2200 .addExternalSymbol(TLI.getLibcallName(LC))
2201 .addRegMask(RegMask)
2202 .addReg(AArch64::X0, RegState::ImplicitDefine)
2204 Reg1 = AArch64::X0;
2205 }
2206 }
2207
2208 LLVM_DEBUG(dbgs() << "CSR spill: ");
2209 LLVM_DEBUG(RGI.dump(TRI));
2210
2211 assert((!isTargetWindows(MF) ||
2212 !(Reg1 == AArch64::LR && Reg2 == AArch64::FP)) &&
2213 "Windows unwdinding requires a consecutive (FP,LR) pair");
2214
2216 unsigned PnReg = AFI->getPredicateRegForFillSpill();
2217
2218 if (!PTrueCreated && RGI.isGrouped() && RGI.isScalable()) {
2219 [[maybe_unused]] const AArch64Subtarget &Subtarget =
2221 assert((PnReg != 0 && enableMultiVectorSpillFill(Subtarget, MF)) &&
2222 "Expects SVE2.1 or SME2 target and a predicate register");
2223 PTrueCreated = true;
2224 BuildMI(MBB, MI, DL, TII.get(AArch64::PTRUE_C_B), PnReg)
2226 }
2227
2228 SmallVector<Register, 4> Registers = RGI.getRegisters();
2230 if (!MRI.isReserved(Reg))
2231 MBB.addLiveIn(Reg);
2232
2233 MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(StrOpc));
2234 if (RGI.isGrouped() && RGI.isScalable()) {
2235 assert(!isTargetWindows(MF) &&
2236 "Scalable register groups are not supported by Windows CFI yet");
2237#ifdef EXPENSIVE_CHECKS
2238 auto IsPPR = [](const RegGroupInfo &c) {
2239 return c.Type == RegGroupInfo::PPR;
2240 };
2241 auto PPRBegin = std::find_if(RegGroups.begin(), RegGroups.end(), IsPPR);
2242 auto IsZPR = [](const RegGroupInfo &c) {
2243 return c.Type == RegGroupInfo::ZPR;
2244 };
2245 auto ZPRBegin = std::find_if(RegGroups.begin(), RegGroups.end(), IsZPR);
2246 assert(!(PPRBegin < ZPRBegin) &&
2247 "Expected callee save predicate to be handled first");
2248#endif
2249
2250 assert(RGI.Reg2 < RGI.Reg1 && "Expected reversed ZPR group");
2251 MIB.addReg(RGI.getAsMultiVectorRegister());
2252
2253 MIB.addReg(PnReg);
2254 MIB.addReg(AArch64::SP)
2255 .addImm(RGI.Offset /
2256 RGI.getNumRegs()) // [sp, #imm*size*vscale],
2257 // where size*vscale is implicit
2259 } else { // The code when the pair of ZReg is not present
2260 // Windows unwind codes require consecutive registers if registers are
2261 // paired. Make the switch here, so that the code below will save (x,x+1)
2262 // and not (x+1,x).
2263 if (isTargetWindows(MF) && RGI.isPaired())
2264 std::swap(Reg1, Reg2);
2265 if (RGI.isPaired()) {
2266 MIB.addReg(Reg2, getPrologueDeath(MF, Reg2));
2267 }
2268 MIB.addReg(Reg1, getPrologueDeath(MF, Reg1))
2269 .addReg(AArch64::SP)
2270 .addImm(RGI.Offset) // [sp, #offset*vscale],
2271 // where factor*vscale is implicit
2273 if (NeedsWinCFI)
2274 insertSEH(MIB, TII, MachineInstr::FrameSetup);
2275 }
2276
2277 // Handle the StackIDs.
2278 MachineFrameInfo &MFI = MF.getFrameInfo();
2279 for (int FI :
2280 reverse_conditionally(RGI.getFrameIndexes(), !isTargetWindows(MF))) {
2281 MIB.addMemOperand(
2283 MachineMemOperand::MOStore, Size, Alignment));
2284 if (RGI.Type == RegGroupInfo::ZPR)
2286 else if (RGI.Type == RegGroupInfo::PPR)
2288 }
2289 }
2290 return true;
2291}
2292
2296 MachineFunction &MF = *MBB.getParent();
2297 const AArch64InstrInfo &TII =
2298 *MF.getSubtarget<AArch64Subtarget>().getInstrInfo();
2299 DebugLoc DL;
2301 bool NeedsWinCFI = MF.needsWinCFI();
2302
2303 if (MBBI != MBB.end())
2304 DL = MBBI->getDebugLoc();
2305
2306 computeCalleeSaveRegisterGroups(*this, MF, CSI, TRI, RegGroups, hasFP(MF));
2307 if (homogeneousPrologEpilog(MF, &MBB)) {
2308 auto MIB = BuildMI(MBB, MBBI, DL, TII.get(AArch64::HOM_Epilog))
2310 for (auto &RGI : RegGroups) {
2311 MIB.addReg(RGI.Reg1, RegState::Define);
2312 MIB.addReg(RGI.Reg2, RegState::Define);
2313 }
2314 return true;
2315 }
2316
2317 // For performance reasons restore SVE register in increasing order
2318 auto IsPPR = [](const RegGroupInfo &c) {
2319 return c.Type == RegGroupInfo::PPR;
2320 };
2321 auto PPRBegin = llvm::find_if(RegGroups, IsPPR);
2322 auto PPREnd = std::find_if_not(PPRBegin, RegGroups.end(), IsPPR);
2323 std::reverse(PPRBegin, PPREnd);
2324 auto IsZPR = [](const RegGroupInfo &c) {
2325 return c.Type == RegGroupInfo::ZPR;
2326 };
2327 auto ZPRBegin = llvm::find_if(RegGroups, IsZPR);
2328 auto ZPREnd = std::find_if_not(ZPRBegin, RegGroups.end(), IsZPR);
2329 std::reverse(ZPRBegin, ZPREnd);
2330
2331 // If the return address is authenticated before the epilogue, it stays in LR
2332 // rather than being restored here, as that would replace it with the
2333 // unauthenticated value from the stack.
2334 bool KeepLR = authenticatesReturnAddressEarly(MF, MBB);
2335
2336 bool PTrueCreated = false;
2337 for (const RegGroupInfo &RGI : RegGroups) {
2338 Register Reg1 = RGI.Reg1;
2339 Register Reg2 = RGI.Reg2;
2340
2341 // Issue sequence of restores for cs regs. The last restore may be converted
2342 // to a post-increment load later by emitEpilogue if the callee-save stack
2343 // area allocation can't be combined with the local stack area allocation.
2344 // For example:
2345 // ldp fp, lr, [sp, #32] // addImm(+4)
2346 // ldp x20, x19, [sp, #16] // addImm(+2)
2347 // ldp x22, x21, [sp, #0] // addImm(+0)
2348 // Note: see comment in spillCalleeSavedRegisters()
2349 unsigned LdrOpc;
2350 unsigned Size = TRI->getSpillSize(*RGI.RC);
2351 Align Alignment = TRI->getSpillAlign(*RGI.RC);
2352 switch (RGI.Type) {
2353 case RegGroupInfo::GPR:
2354 LdrOpc = RGI.isPaired() ? AArch64::LDPXi : AArch64::LDRXui;
2355 break;
2356 case RegGroupInfo::FPR64:
2357 LdrOpc = RGI.isPaired() ? AArch64::LDPDi : AArch64::LDRDui;
2358 break;
2359 case RegGroupInfo::FPR128:
2360 LdrOpc = RGI.isPaired() ? AArch64::LDPQi : AArch64::LDRQui;
2361 break;
2362 case RegGroupInfo::ZPR:
2363 LdrOpc = RGI.isQuad()
2364 ? AArch64::LD1B_4Z_IMM
2365 : (RGI.isPaired() ? AArch64::LD1B_2Z_IMM : AArch64::LDR_ZXI);
2366 break;
2367 case RegGroupInfo::PPR:
2368 LdrOpc = AArch64::LDR_PXI;
2369 break;
2370 case RegGroupInfo::VG:
2371 continue;
2372 }
2373
2374 LLVM_DEBUG(dbgs() << "CSR restore: ");
2375 LLVM_DEBUG(RGI.dump(TRI));
2376
2378 unsigned PnReg = AFI->getPredicateRegForFillSpill();
2379
2380 if (!PTrueCreated && RGI.isGrouped() && RGI.isScalable()) {
2381 [[maybe_unused]] const AArch64Subtarget &Subtarget =
2383 assert((PnReg != 0 && enableMultiVectorSpillFill(Subtarget, MF)) &&
2384 "Expects SVE2.1 or SME2 target and a predicate register");
2385 PTrueCreated = true;
2386 BuildMI(MBB, MBBI, DL, TII.get(AArch64::PTRUE_C_B), PnReg)
2388 }
2389
2390 if (KeepLR && RGI.Type == RegGroupInfo::GPR &&
2391 (Reg1 == AArch64::LR || Reg2 == AArch64::LR)) {
2392 // Windows pairs LR with the register before it, which is the one at the
2393 // lower address, so restore just that register. The pair has not been
2394 // swapped yet at this point, so that register is Reg1.
2395 if (!RGI.isPaired())
2396 continue;
2397 assert(Reg2 == AArch64::LR && "Expected LR to be the second of the pair");
2399 BuildMI(MBB, MBBI, DL, TII.get(AArch64::LDRXui));
2400 MIB.addReg(Reg1, getDefRegState(true));
2401 MIB.addReg(AArch64::SP)
2402 .addImm(RGI.Offset)
2405 MachinePointerInfo::getFixedStack(MF, RGI.FrameIdx),
2407 if (NeedsWinCFI)
2408 insertSEH(MIB, TII, MachineInstr::FrameDestroy);
2409 continue;
2410 }
2411
2412 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII.get(LdrOpc));
2413 if (RGI.isGrouped() && RGI.isScalable()) {
2414 assert(!isTargetWindows(MF) &&
2415 "Scalable register groups are not supported by Windows CFI yet");
2416#ifdef EXPENSIVE_CHECKS
2417 assert(!(PPRBegin < ZPRBegin) &&
2418 "Expected callee save predicate to be handled first");
2419#endif
2420 assert(RGI.Reg2 < RGI.Reg1 && "Expected reversed ZPR group");
2421 MIB.addReg(RGI.getAsMultiVectorRegister(), getDefRegState(true));
2422 MIB.addReg(PnReg);
2423 MIB.addReg(AArch64::SP)
2424 .addImm(RGI.Offset /
2425 RGI.getNumRegs()) // [sp, #imm*size*vscale]
2426 // where size*vscale is implicit
2428 } else {
2429 // Windows unwind codes require consecutive registers if registers are
2430 // paired. Make the switch here, so that the code below will save (x,x+1)
2431 // and not (x+1,x).
2432 if (isTargetWindows(MF) && RGI.isPaired())
2433 std::swap(Reg1, Reg2);
2434 if (RGI.isPaired())
2435 MIB.addReg(Reg2, getDefRegState(true));
2436 MIB.addReg(Reg1, getDefRegState(true));
2437 MIB.addReg(AArch64::SP)
2438 .addImm(RGI.Offset) // [sp, #offset*vscale]
2439 // where factor*vscale is implicit
2441 if (NeedsWinCFI)
2442 insertSEH(MIB, TII, MachineInstr::FrameDestroy);
2443 }
2444
2445 for (int FI :
2446 reverse_conditionally(RGI.getFrameIndexes(), !isTargetWindows(MF)))
2447 MIB.addMemOperand(
2449 MachineMemOperand::MOLoad, Size, Alignment));
2450 }
2451 return true;
2452}
2453
2454// Return the FrameID for a MMO.
2455static std::optional<int> getMMOFrameID(MachineMemOperand *MMO,
2456 const MachineFrameInfo &MFI) {
2457 auto *PSV =
2459 if (PSV)
2460 return std::optional<int>(PSV->getFrameIndex());
2461
2462 if (MMO->getValue()) {
2463 if (auto *Al = dyn_cast<AllocaInst>(getUnderlyingObject(MMO->getValue()))) {
2464 for (int FI = MFI.getObjectIndexBegin(); FI < MFI.getObjectIndexEnd();
2465 FI++)
2466 if (MFI.getObjectAllocation(FI) == Al)
2467 return FI;
2468 }
2469 }
2470
2471 return std::nullopt;
2472}
2473
2474// Return the FrameID for a Load/Store instruction by looking at the first MMO.
2475static std::optional<int> getLdStFrameID(const MachineInstr &MI,
2476 const MachineFrameInfo &MFI) {
2477 if (!MI.mayLoadOrStore() || MI.getNumMemOperands() < 1)
2478 return std::nullopt;
2479
2480 return getMMOFrameID(*MI.memoperands_begin(), MFI);
2481}
2482
2483// Returns true if the LDST MachineInstr \p MI is a PPR access.
2484static bool isPPRAccess(const MachineInstr &MI) {
2485 return AArch64::PPRRegClass.contains(MI.getOperand(0).getReg());
2486}
2487
2488// Check if a Hazard slot is needed for the current function, and if so create
2489// one for it. The index is stored in AArch64FunctionInfo->StackHazardSlotIndex,
2490// which can be used to determine if any hazard padding is needed.
2491void AArch64FrameLowering::determineStackHazardSlot(
2492 MachineFunction &MF, BitVector &SavedRegs) const {
2493 unsigned StackHazardSize = getStackHazardSize(MF);
2494 auto *AFI = MF.getInfo<AArch64FunctionInfo>();
2495 if (StackHazardSize == 0 || StackHazardSize % 16 != 0 ||
2497 return;
2498
2499 // Stack hazards are only needed in streaming functions.
2500 SMEAttrs Attrs = AFI->getSMEFnAttrs();
2501 const AArch64Options &CLOpts =
2502 MF.getSubtarget<AArch64Subtarget>().getCLOpts();
2503 if (!CLOpts.stack_hazard_in_non_streaming &&
2504 Attrs.hasNonStreamingInterfaceAndBody())
2505 return;
2506
2507 MachineFrameInfo &MFI = MF.getFrameInfo();
2508
2509 // Add a hazard slot if there are any CSR FPR registers, or are any fp-only
2510 // stack objects.
2511 bool HasFPRCSRs = any_of(SavedRegs.set_bits(), [](unsigned Reg) {
2512 return AArch64::FPR64RegClass.contains(Reg) ||
2513 AArch64::FPR128RegClass.contains(Reg) ||
2514 AArch64::ZPRRegClass.contains(Reg);
2515 });
2516 bool HasPPRCSRs = any_of(SavedRegs.set_bits(), [](unsigned Reg) {
2517 return AArch64::PPRRegClass.contains(Reg);
2518 });
2519 bool HasFPRStackObjects = false;
2520 bool HasPPRStackObjects = false;
2521 if (!HasFPRCSRs || CLOpts.split_sve_objects) {
2522 enum SlotType : uint8_t {
2523 Unknown = 0,
2524 ZPRorFPR = 1 << 0,
2525 PPR = 1 << 1,
2526 GPR = 1 << 2,
2528 };
2529
2530 // Find stack slots solely used for one kind of register (ZPR, PPR, etc.),
2531 // based on the kinds of accesses used in the function.
2532 SmallVector<SlotType> SlotTypes(MFI.getObjectIndexEnd(), SlotType::Unknown);
2533 for (auto &MBB : MF) {
2534 for (auto &MI : MBB) {
2535 std::optional<int> FI = getLdStFrameID(MI, MFI);
2536 if (!FI || FI < 0 || FI > int(SlotTypes.size()))
2537 continue;
2538 if (MFI.hasScalableStackID(*FI)) {
2539 SlotTypes[*FI] |=
2540 isPPRAccess(MI) ? SlotType::PPR : SlotType::ZPRorFPR;
2541 } else {
2542 SlotTypes[*FI] |= AArch64InstrInfo::isFpOrNEON(MI)
2543 ? SlotType::ZPRorFPR
2544 : SlotType::GPR;
2545 }
2546 }
2547 }
2548
2549 for (int FI = 0; FI < int(SlotTypes.size()); ++FI) {
2550 HasFPRStackObjects |= SlotTypes[FI] == SlotType::ZPRorFPR;
2551 // For SplitSVEObjects remember that this stack slot is a predicate, this
2552 // will be needed later when determining the frame layout.
2553 if (SlotTypes[FI] == SlotType::PPR) {
2555 HasPPRStackObjects = true;
2556 }
2557 }
2558 }
2559
2560 if (HasFPRCSRs || HasFPRStackObjects) {
2561 int ID = MFI.CreateStackObject(StackHazardSize, Align(16), false);
2562 LLVM_DEBUG(dbgs() << "Created Hazard slot at " << ID << " size "
2563 << StackHazardSize << "\n");
2564 AFI->setStackHazardSlotIndex(ID);
2565 }
2566
2567 if (!AFI->hasStackHazardSlotIndex())
2568 return;
2569
2570 if (CLOpts.split_sve_objects) {
2571 CallingConv::ID CC = MF.getFunction().getCallingConv();
2573 AFI->setSplitSVEObjects(true);
2574 LLVM_DEBUG(dbgs() << "Using SplitSVEObjects for SVE CC function\n");
2575 return;
2576 }
2577
2578 // We only use SplitSVEObjects in non-SVE CC functions if there's a
2579 // possibility of a stack hazard between PPRs and ZPRs/FPRs.
2580 LLVM_DEBUG(dbgs() << "Determining if SplitSVEObjects should be used in "
2581 "non-SVE CC function...\n");
2582
2583 // If another calling convention is explicitly set FPRs can't be promoted to
2584 // ZPR callee-saves.
2586 LLVM_DEBUG(
2587 dbgs()
2588 << "Calling convention is not supported with SplitSVEObjects\n");
2589 return;
2590 }
2591
2592 if (!HasPPRCSRs && !HasPPRStackObjects) {
2593 LLVM_DEBUG(
2594 dbgs() << "Not using SplitSVEObjects as no PPRs are on the stack\n");
2595 return;
2596 }
2597
2598 if (!HasFPRCSRs && !HasFPRStackObjects) {
2599 LLVM_DEBUG(
2600 dbgs()
2601 << "Not using SplitSVEObjects as no FPRs or ZPRs are on the stack\n");
2602 return;
2603 }
2604
2605 [[maybe_unused]] const AArch64Subtarget &Subtarget =
2606 MF.getSubtarget<AArch64Subtarget>();
2608 "Expected SVE to be available for PPRs");
2609
2610 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
2611 // With SplitSVEObjects the CS hazard padding is placed between the
2612 // PPRs and ZPRs. If there are any FPR CS there would be a hazard between
2613 // them and the CS GRPs. Avoid this by promoting all FPR CS to ZPRs.
2614 BitVector FPRZRegs(SavedRegs.size());
2615 for (size_t Reg = 0, E = SavedRegs.size(); HasFPRCSRs && Reg < E; ++Reg) {
2616 BitVector::reference RegBit = SavedRegs[Reg];
2617 if (!RegBit)
2618 continue;
2619 unsigned SubRegIdx = 0;
2620 if (AArch64::FPR64RegClass.contains(Reg))
2621 SubRegIdx = AArch64::dsub;
2622 else if (AArch64::FPR128RegClass.contains(Reg))
2623 SubRegIdx = AArch64::zsub;
2624 else
2625 continue;
2626 // Clear the bit for the FPR save.
2627 RegBit = false;
2628 // Mark that we should save the corresponding ZPR.
2629 Register ZReg =
2630 TRI->getMatchingSuperReg(Reg, SubRegIdx, &AArch64::ZPRRegClass);
2631 FPRZRegs.set(ZReg);
2632 }
2633 SavedRegs |= FPRZRegs;
2634
2635 AFI->setSplitSVEObjects(true);
2636 LLVM_DEBUG(dbgs() << "SplitSVEObjects enabled!\n");
2637 }
2638}
2639
2641 BitVector &SavedRegs,
2642 RegScavenger *RS) const {
2644 // All calls are tail calls in GHC calling conv, and functions have no
2645 // prologue/epilogue.
2648 AFI->setSVECalleeSavedStackSize(/*ZPR=*/0, /*PPR=*/0);
2649 return;
2650 }
2651
2652 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
2653
2655 const AArch64RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
2656 Register UnspilledCSGPR;
2657 Register UnspilledCSGPRPaired;
2658
2659 MachineFrameInfo &MFI = MF.getFrameInfo();
2660 const MCPhysReg *CSRegs = MF.getRegInfo().getCalleeSavedRegs();
2661
2662 MCRegister BasePointerReg =
2663 RegInfo->hasBasePointer(MF) ? RegInfo->getBaseRegister() : MCRegister();
2664
2665 Register ExtraCSSpill;
2666 bool HasUnpairedGPR64 = false;
2667 bool HasPairZReg = false;
2668 BitVector UserReservedRegs = RegInfo->getUserReservedRegs(MF);
2669 BitVector ReservedRegs = RegInfo->getReservedRegs(MF);
2670
2671 // Figure out which callee-saved registers to save/restore.
2672 for (unsigned i = 0; CSRegs[i]; ++i) {
2673 const MCRegister Reg = CSRegs[i];
2674
2675 // Add the base pointer register to SavedRegs if it is callee-save.
2676 if (Reg == BasePointerReg)
2677 SavedRegs.set(Reg);
2678
2679 // Don't save manually reserved registers set through +reserve-x#i,
2680 // even for callee-saved registers, as per GCC's behavior.
2681 if (UserReservedRegs[Reg]) {
2682 SavedRegs.reset(Reg);
2683 continue;
2684 }
2685
2686 bool RegUsed = SavedRegs.test(Reg);
2687 MCRegister PairedReg;
2688 const bool RegIsGPR64 = AArch64::GPR64RegClass.contains(Reg);
2689 if (RegIsGPR64 || AArch64::FPR64RegClass.contains(Reg) ||
2690 AArch64::FPR128RegClass.contains(Reg)) {
2691 // Compensate for odd numbers of GP CSRs.
2692 // For now, all the known cases of odd number of CSRs are of GPRs.
2693 if (HasUnpairedGPR64)
2694 PairedReg = CSRegs[i % 2 == 0 ? i - 1 : i + 1];
2695 else
2696 PairedReg = CSRegs[i ^ 1];
2697 }
2698
2699 // If the function requires all the GP registers to save (SavedRegs),
2700 // and there are an odd number of GP CSRs at the same time (CSRegs),
2701 // PairedReg could be in a different register class from Reg, which would
2702 // lead to a FPR (usually D8) accidentally being marked saved.
2703 if (RegIsGPR64 && !AArch64::GPR64RegClass.contains(PairedReg)) {
2704 PairedReg = Register();
2705 HasUnpairedGPR64 = true;
2706 }
2707 assert(!PairedReg.isValid() ||
2708 AArch64::GPR64RegClass.contains(Reg, PairedReg) ||
2709 AArch64::FPR64RegClass.contains(Reg, PairedReg) ||
2710 AArch64::FPR128RegClass.contains(Reg, PairedReg));
2711
2712 if (!RegUsed) {
2713 if (AArch64::GPR64RegClass.contains(Reg) && !ReservedRegs[Reg]) {
2714 UnspilledCSGPR = Reg;
2715 UnspilledCSGPRPaired = PairedReg;
2716 }
2717 continue;
2718 }
2719
2720 // MachO's compact unwind format relies on all registers being stored in
2721 // pairs.
2722 // FIXME: the usual format is actually better if unwinding isn't needed.
2723 if (producePairRegisters(MF) && PairedReg.isValid() &&
2724 !SavedRegs.test(PairedReg)) {
2725 SavedRegs.set(PairedReg);
2726 if (AArch64::GPR64RegClass.contains(PairedReg) &&
2727 !ReservedRegs[PairedReg])
2728 ExtraCSSpill = PairedReg;
2729 }
2730 // Check if there is a pair of ZRegs, so it can select PReg for spill/fill
2731 HasPairZReg |= (AArch64::ZPRRegClass.contains(Reg, CSRegs[i ^ 1]) &&
2732 SavedRegs.test(CSRegs[i ^ 1]));
2733 }
2734
2735 if (HasPairZReg && enableMultiVectorSpillFill(Subtarget, MF)) {
2737 // Find a suitable predicate register for the multi-vector spill/fill
2738 // instructions.
2739 MCRegister PnReg = findFreePredicateReg(SavedRegs);
2740 if (PnReg.isValid())
2741 AFI->setPredicateRegForFillSpill(PnReg);
2742 // If no free callee-save has been found assign one.
2743 if (!AFI->getPredicateRegForFillSpill() &&
2744 MF.getFunction().getCallingConv() ==
2746 SavedRegs.set(AArch64::P8);
2747 AFI->setPredicateRegForFillSpill(AArch64::PN8);
2748 }
2749
2750 assert(!ReservedRegs[AFI->getPredicateRegForFillSpill()] &&
2751 "Predicate cannot be a reserved register");
2752 }
2753
2755 !Subtarget.isTargetWindowsOrUEFI()) {
2756 // For Windows calling convention on a non-windows OS, where X18 is treated
2757 // as reserved, back up X18 when entering non-windows code (marked with the
2758 // Windows calling convention) and restore when returning regardless of
2759 // whether the individual function uses it - it might call other functions
2760 // that clobber it.
2761 SavedRegs.set(AArch64::X18);
2762 }
2763
2764 // Determine if a Hazard slot should be used and where it should go.
2765 // If SplitSVEObjects is used, the hazard padding is placed between the PPRs
2766 // and ZPRs. Otherwise, it goes in the callee save area.
2767 determineStackHazardSlot(MF, SavedRegs);
2768
2769 // Calculates the callee saved stack size.
2770 unsigned CSStackSize = 0;
2771 unsigned ZPRCSStackSize = 0;
2772 unsigned PPRCSStackSize = 0;
2774 for (unsigned Reg : SavedRegs.set_bits()) {
2775 auto *RC = TRI->getMinimalPhysRegClass(MCRegister(Reg));
2776 assert(RC && "expected register class!");
2777 auto SpillSize = TRI->getSpillSize(*RC);
2778 bool IsZPR = AArch64::ZPRRegClass.contains(Reg);
2779 bool IsPPR = !IsZPR && AArch64::PPRRegClass.contains(Reg);
2780 if (IsZPR)
2781 ZPRCSStackSize += SpillSize;
2782 else if (IsPPR)
2783 PPRCSStackSize += SpillSize;
2784 else {
2785 // A register and its super-register can both appear in SavedRegs.
2786 // Only the widest register is actually spilled, so skip such
2787 // sub-registers here to avoid double-counting the overlap.
2788 bool SavedSuper = any_of(TRI->superregs(Reg), [&](MCPhysReg SuperReg) {
2789 return SavedRegs.test(SuperReg);
2790 });
2791 if (!SavedSuper)
2792 CSStackSize += SpillSize;
2793 }
2794 }
2795
2796 // Save number of saved regs, so we can easily update CSStackSize later to
2797 // account for any additional 64-bit GPR saves. Note: After this point
2798 // only 64-bit GPRs can be added to SavedRegs.
2799 unsigned NumSavedRegs = SavedRegs.count();
2800
2801 // If we have hazard padding in the CS area add that to the size.
2803 CSStackSize += getStackHazardSize(MF);
2804
2805 // Increase the callee-saved stack size if the function has streaming mode
2806 // changes, as we will need to spill the value of the VG register.
2807 if (requiresSaveVG(MF))
2808 CSStackSize += 8;
2809
2810 // If we must call __arm_get_current_vg in the prologue preserve the LR.
2811 if (requiresSaveVG(MF) && !Subtarget.hasSVE())
2812 SavedRegs.set(AArch64::LR);
2813
2814 // The frame record needs to be created by saving the appropriate registers
2815 uint64_t EstimatedStackSize = MFI.estimateStackSize(MF);
2816 if (hasFP(MF) ||
2817 windowsRequiresStackProbe(MF, EstimatedStackSize + CSStackSize + 16)) {
2818 SavedRegs.set(AArch64::FP);
2819 SavedRegs.set(AArch64::LR);
2820 }
2821
2822 LLVM_DEBUG({
2823 dbgs() << "*** determineCalleeSaves\nSaved CSRs:";
2824 for (unsigned Reg : SavedRegs.set_bits())
2825 dbgs() << ' ' << printReg(MCRegister(Reg), RegInfo);
2826 dbgs() << "\n";
2827 });
2828
2829 // If any callee-saved registers are used, the frame cannot be eliminated.
2830 auto [ZPRLocalStackSize, PPRLocalStackSize] =
2832 uint64_t SVELocals = ZPRLocalStackSize + PPRLocalStackSize;
2833 uint64_t SVEStackSize =
2834 alignTo(ZPRCSStackSize + PPRCSStackSize + SVELocals, 16);
2835 bool CanEliminateFrame = (SavedRegs.count() == 0) && !SVEStackSize;
2836
2837 // The CSR spill slots have not been allocated yet, so estimateStackSize
2838 // won't include them.
2839 unsigned EstimatedStackSizeLimit = estimateRSStackSizeLimit(MF);
2840
2841 // We may address some of the stack above the canonical frame address, either
2842 // for our own arguments or during a call. Include that in calculating whether
2843 // we have complicated addressing concerns.
2844 int64_t CalleeStackUsed = 0;
2845 for (int I = MFI.getObjectIndexBegin(); I != 0; ++I) {
2846 int64_t FixedOff = MFI.getObjectOffset(I);
2847 if (FixedOff > CalleeStackUsed)
2848 CalleeStackUsed = FixedOff;
2849 }
2850
2851 // Conservatively always assume BigStack when there are SVE spills.
2852 bool BigStack = SVEStackSize || (EstimatedStackSize + CSStackSize +
2853 CalleeStackUsed) > EstimatedStackSizeLimit;
2854 if (BigStack || !CanEliminateFrame || RegInfo->cannotEliminateFrame(MF))
2855 AFI->setHasStackFrame(true);
2856
2857 // Estimate if we might need to scavenge a register at some point in order
2858 // to materialize a stack offset. If so, either spill one additional
2859 // callee-saved register or reserve a special spill slot to facilitate
2860 // register scavenging. If we already spilled an extra callee-saved register
2861 // above to keep the number of spills even, we don't need to do anything else
2862 // here.
2863 if (BigStack) {
2864 if (!ExtraCSSpill.isValid() && UnspilledCSGPR.isValid()) {
2865 LLVM_DEBUG(dbgs() << "Spilling " << printReg(UnspilledCSGPR, RegInfo)
2866 << " to get a scratch register.\n");
2867 SavedRegs.set(UnspilledCSGPR);
2868 ExtraCSSpill = UnspilledCSGPR;
2869
2870 // MachO's compact unwind format relies on all registers being stored in
2871 // pairs, so if we need to spill one extra for BigStack, then we need to
2872 // store the pair.
2873 if (producePairRegisters(MF)) {
2874 if (!UnspilledCSGPRPaired.isValid()) {
2875 // Failed to make a pair for compact unwind format, revert spilling.
2876 if (produceCompactUnwindFrame(*this, MF)) {
2877 SavedRegs.reset(UnspilledCSGPR);
2878 ExtraCSSpill = Register();
2879 }
2880 } else
2881 SavedRegs.set(UnspilledCSGPRPaired);
2882 }
2883 }
2884
2885 // If we didn't find an extra callee-saved register to spill, create
2886 // an emergency spill slot.
2887 if (!ExtraCSSpill.isValid() ||
2888 MF.getRegInfo().isPhysRegUsed(ExtraCSSpill)) {
2890 const TargetRegisterClass &RC = AArch64::GPR64RegClass;
2891 unsigned Size = TRI->getSpillSize(RC);
2892 Align Alignment = TRI->getSpillAlign(RC);
2893 int FI = MFI.CreateSpillStackObject(Size, Alignment);
2894 RS->addScavengingFrameIndex(FI);
2895 LLVM_DEBUG(dbgs() << "No available CS registers, allocated fi#" << FI
2896 << " as the emergency spill slot.\n");
2897 }
2898 }
2899
2900 // Adding the size of additional 64bit GPR saves.
2901 CSStackSize += 8 * (SavedRegs.count() - NumSavedRegs);
2902
2903 // A Swift asynchronous context extends the frame record with a pointer
2904 // directly before FP.
2905 if (hasFP(MF) && AFI->hasSwiftAsyncContext())
2906 CSStackSize += 8;
2907
2908 uint64_t AlignedCSStackSize = alignTo(CSStackSize, 16);
2909 LLVM_DEBUG(dbgs() << "Estimated stack frame size: "
2910 << EstimatedStackSize + AlignedCSStackSize << " bytes.\n");
2911
2913 AFI->getCalleeSavedStackSize() == AlignedCSStackSize) &&
2914 "Should not invalidate callee saved info");
2915
2916 // Round up to register pair alignment to avoid additional SP adjustment
2917 // instructions.
2918 AFI->setCalleeSavedStackSize(AlignedCSStackSize);
2919 AFI->setCalleeSaveStackHasFreeSpace(AlignedCSStackSize != CSStackSize);
2920 AFI->setSVECalleeSavedStackSize(ZPRCSStackSize, alignTo(PPRCSStackSize, 16));
2921}
2922
2923// Reorder ZPRs to maximize grouping, quads and pairs. The main condition we try
2924// to satisfy is the offset and the register number.
2925// Quads require a (scaled offset % 4 == 0) && (LowestRegister % 4 == 0),
2926// e.g: (z4, z5, z6, z7) where z4 is at offset 8 would be legal quad
2927// Pairs require a (scaled offset % 2 == 0) && (LowestRegister % 2 == 0).
2928// e.g: (z4, z5) where z4 is at offset 6 would be a legal pair
2931 std::vector<CalleeSavedInfo> &CSI) {
2932 assert(!isTargetWindows(MF) &&
2933 "ZPR callee-save reordering not supported on Windows");
2934
2935 auto *AFI = MF.getInfo<AArch64FunctionInfo>();
2936 if (!AFI->getPredicateRegForFillSpill())
2937 return;
2938
2939 auto IsZPR = [](CalleeSavedInfo &CS) {
2940 return AArch64::ZPRRegClass.contains(CS.getReg());
2941 };
2942
2944 ZPRSaves = ZPRSaves.drop_until(IsZPR).take_while(IsZPR);
2945
2946 if (ZPRSaves.size() < 2)
2947 return;
2948
2949 int ZPRByteOffset = AFI->getZPRCalleeSavedStackSize();
2950 if (!AFI->hasSplitSVEObjects())
2951 ZPRByteOffset += AFI->getPPRCalleeSavedStackSize();
2952
2953 const int Scale = RegInfo->getSpillSize(AArch64::ZPRRegClass);
2954 const int LowestOffset =
2955 (ZPRByteOffset / Scale) - static_cast<int>(ZPRSaves.size());
2956
2957 int NumToAlign = alignTo(LowestOffset, 4) - LowestOffset;
2958 if (NumToAlign > int(ZPRSaves.size()))
2959 return;
2960
2961 sort(ZPRSaves,
2962 [](const auto &A, const auto &B) { return A.getReg() < B.getReg(); });
2963
2967
2968 int ZPRsNeededForAlignment = NumToAlign;
2969 for (size_t i = 0; i < ZPRSaves.size();) {
2970 int ZPRsRemaining = int(ZPRSaves.size()) - i;
2971 if (i + 3 < ZPRSaves.size() &&
2972 (ZPRSaves[i].getReg() - AArch64::Z0) % 4 == 0 &&
2973 ZPRSaves[i].getReg() + 3 == ZPRSaves[i + 3].getReg() &&
2974 ZPRsRemaining - 4 >= ZPRsNeededForAlignment) {
2975 Quads.push_back(
2976 {ZPRSaves[i], ZPRSaves[i + 1], ZPRSaves[i + 2], ZPRSaves[i + 3]});
2977 i += 4;
2978 continue;
2979 }
2980 // We only need to split a pair if there's no singles. If we have a single
2981 // ZPR then all required alignments (1, 2, or 3) can use that single and a
2982 // ZPR pair.
2983 bool MustSplitPairForSingle =
2984 ZPRsNeededForAlignment == 1 && Singles.empty() && ZPRsRemaining == 2;
2985
2986 if (i + 1 < ZPRSaves.size() &&
2987 (ZPRSaves[i].getReg() - AArch64::Z0) % 2 == 0 &&
2988 ZPRSaves[i].getReg() + 1 == ZPRSaves[i + 1].getReg() &&
2989 !MustSplitPairForSingle) {
2990 Pairs.push_back({ZPRSaves[i], ZPRSaves[i + 1]});
2991 // Don't decrement the ZPRs needed if we require one ZPR for alignment and
2992 // we've yet to find a single ZPR. We may still need to split a pair.
2993 if (ZPRsNeededForAlignment != 1 || !Singles.empty())
2994 ZPRsNeededForAlignment -= 2;
2995
2996 i += 2;
2997 continue;
2998 }
2999
3000 Singles.push_back(ZPRSaves[i++]);
3001 ZPRsNeededForAlignment--;
3002 }
3003
3004 if (Quads.empty() && Pairs.empty())
3005 return;
3006
3007 int NumUnassigned = ZPRSaves.size();
3008 auto Emit = [&](ArrayRef<CalleeSavedInfo> Saves) {
3009 // During pair/quad formation, we check for the register groups in reverse
3010 // order. This is to ensures that stack indexes remain consistent with the
3011 // instruction.
3012 for (const CalleeSavedInfo &CS : Saves)
3013 ZPRSaves[--NumUnassigned] = CS;
3014 };
3015
3016 // Align the offset to a multiple of 4 (to allow for the most quads/pairs).
3017 if (NumToAlign & 0b01)
3018 Emit(Singles.pop_back_val());
3019 if (NumToAlign & 0b10) {
3020 if (!Pairs.empty())
3021 Emit(Pairs.pop_back_val());
3022 else
3023 Emit({Singles.pop_back_val(), Singles.pop_back_val()});
3024 }
3025
3026 for (const auto &Quad : Quads)
3027 Emit(Quad);
3028
3029 for (const auto &Pair : Pairs)
3030 Emit(Pair);
3031
3032 for (const auto &Single : Singles)
3033 Emit(Single);
3034}
3035
3037 MachineFunction &MF, const TargetRegisterInfo *RegInfo,
3038 std::vector<CalleeSavedInfo> &CSI) const {
3039 bool IsWindows = isTargetWindows(MF);
3040 unsigned StackHazardSize = getStackHazardSize(MF);
3041 // To match the canonical windows frame layout, reverse the list of
3042 // callee saved registers to get them laid out by PrologEpilogInserter
3043 // in the right order. (PrologEpilogInserter allocates stack objects top
3044 // down. Windows canonical prologs store higher numbered registers at
3045 // the top, thus have the CSI array start from the highest registers.)
3046 if (IsWindows)
3047 std::reverse(CSI.begin(), CSI.end());
3048
3049 if (CSI.empty())
3050 return true; // Early exit if no callee saved registers are modified!
3051
3052 // Now that we know which registers need to be saved and restored, allocate
3053 // stack slots for them.
3054 MachineFrameInfo &MFI = MF.getFrameInfo();
3055 auto *AFI = MF.getInfo<AArch64FunctionInfo>();
3056
3057 // Insert VG into the list of CSRs, immediately before LR if saved.
3058 if (requiresSaveVG(MF)) {
3059 CalleeSavedInfo VGInfo(AArch64::VG);
3060 auto It =
3061 find_if(CSI, [](auto &Info) { return Info.getReg() == AArch64::LR; });
3062 if (It != CSI.end())
3063 CSI.insert(It, VGInfo);
3064 else
3065 CSI.push_back(VGInfo);
3066 }
3067
3068 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
3069 if (!IsWindows && enableMultiVectorSpillFill(Subtarget, MF))
3070 // The Windows stack layout is not supported by this reordering function
3071 // yet.
3072 orderZPRCalleeSavesForGroups(MF, RegInfo, CSI);
3073
3074 Register LastReg = 0;
3075 int HazardSlotIndex = std::numeric_limits<int>::max();
3076 for (auto &CS : CSI) {
3077 MCRegister Reg = CS.getReg();
3078 const TargetRegisterClass *RC = RegInfo->getMinimalPhysRegClass(Reg);
3079
3080 // Create a hazard slot as we switch between GPR and FPR CSRs.
3082 (!LastReg || !AArch64InstrInfo::isFpOrNEON(LastReg)) &&
3084 assert(HazardSlotIndex == std::numeric_limits<int>::max() &&
3085 "Unexpected register order for hazard slot");
3086 HazardSlotIndex = MFI.CreateStackObject(StackHazardSize, Align(8), true);
3087 LLVM_DEBUG(dbgs() << "Created CSR Hazard at slot " << HazardSlotIndex
3088 << "\n");
3089 AFI->setStackHazardCSRSlotIndex(HazardSlotIndex);
3090 MFI.setIsCalleeSavedObjectIndex(HazardSlotIndex, true);
3091 }
3092
3093 unsigned Size = RegInfo->getSpillSize(*RC);
3094 Align Alignment(RegInfo->getSpillAlign(*RC));
3095 int FrameIdx = MFI.CreateStackObject(Size, Alignment, true);
3096 CS.setFrameIdx(FrameIdx);
3097 MFI.setIsCalleeSavedObjectIndex(FrameIdx, true);
3098
3099 // Grab 8 bytes below FP for the extended asynchronous frame info.
3100 if (hasFP(MF) && AFI->hasSwiftAsyncContext() && Reg == AArch64::FP) {
3101 FrameIdx = MFI.CreateStackObject(8, Alignment, true);
3102 AFI->setSwiftAsyncContextFrameIdx(FrameIdx);
3103 MFI.setIsCalleeSavedObjectIndex(FrameIdx, true);
3104 }
3105 LastReg = Reg;
3106 }
3107
3108 // Add hazard slot in the case where no FPR CSRs are present.
3110 HazardSlotIndex == std::numeric_limits<int>::max()) {
3111 HazardSlotIndex = MFI.CreateStackObject(StackHazardSize, Align(8), true);
3112 LLVM_DEBUG(dbgs() << "Created CSR Hazard at slot " << HazardSlotIndex
3113 << "\n");
3114 AFI->setStackHazardCSRSlotIndex(HazardSlotIndex);
3115 MFI.setIsCalleeSavedObjectIndex(HazardSlotIndex, true);
3116 }
3117
3118 return true;
3119}
3120
3122 const MachineFunction &MF) const {
3124 // If the function has streaming-mode changes, don't scavenge a
3125 // spillslot in the callee-save area, as that might require an
3126 // 'addvl' in the streaming-mode-changing call-sequence when the
3127 // function doesn't use a FP.
3128 if (AFI->hasStreamingModeChanges() && !hasFP(MF))
3129 return false;
3130 // Don't allow register salvaging with hazard slots, in case it moves objects
3131 // into the wrong place.
3132 if (AFI->hasStackHazardSlotIndex())
3133 return false;
3134 return AFI->hasCalleeSaveStackFreeSpace();
3135}
3136
3137/// returns true if there are any SVE callee saves.
3139 int &Min, int &Max) {
3140 Min = std::numeric_limits<int>::max();
3141 Max = std::numeric_limits<int>::min();
3142
3143 if (!MFI.isCalleeSavedInfoValid())
3144 return false;
3145
3146 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
3147 for (auto &CS : CSI) {
3148 if (AArch64::ZPRRegClass.contains(CS.getReg()) ||
3149 AArch64::PPRRegClass.contains(CS.getReg())) {
3150 assert((Max == std::numeric_limits<int>::min() ||
3151 Max + 1 == CS.getFrameIdx()) &&
3152 "SVE CalleeSaves are not consecutive");
3153 Min = std::min(Min, CS.getFrameIdx());
3154 Max = std::max(Max, CS.getFrameIdx());
3155 }
3156 }
3157 return Min != std::numeric_limits<int>::max();
3158}
3159
3161 AssignObjectOffsets AssignOffsets) {
3162 MachineFrameInfo &MFI = MF.getFrameInfo();
3163 auto *AFI = MF.getInfo<AArch64FunctionInfo>();
3164
3165 SVEStackSizes SVEStack{};
3166
3167 // With SplitSVEObjects we maintain separate stack offsets for predicates
3168 // (PPRs) and SVE vectors (ZPRs). When SplitSVEObjects is disabled predicates
3169 // are included in the SVE vector area.
3170 uint64_t &ZPRStackTop = SVEStack.ZPRStackSize;
3171 uint64_t &PPRStackTop =
3172 AFI->hasSplitSVEObjects() ? SVEStack.PPRStackSize : SVEStack.ZPRStackSize;
3173
3174#ifndef NDEBUG
3175 // First process all fixed stack objects.
3176 for (int I = MFI.getObjectIndexBegin(); I != 0; ++I)
3177 assert(!MFI.hasScalableStackID(I) &&
3178 "SVE vectors should never be passed on the stack by value, only by "
3179 "reference.");
3180#endif
3181
3182 auto AllocateObject = [&](int FI) {
3184 ? ZPRStackTop
3185 : PPRStackTop;
3186
3187 // FIXME: Given that the length of SVE vectors is not necessarily a power of
3188 // two, we'd need to align every object dynamically at runtime if the
3189 // alignment is larger than 16. This is not yet supported.
3190 Align Alignment = MFI.getObjectAlign(FI);
3191 if (Alignment > Align(16))
3193 "Alignment of scalable vectors > 16 bytes is not yet supported");
3194
3195 StackTop += MFI.getObjectSize(FI);
3196 StackTop = alignTo(StackTop, Alignment);
3197
3198 assert(StackTop < (uint64_t)std::numeric_limits<int64_t>::max() &&
3199 "SVE StackTop far too large?!");
3200
3201 int64_t Offset = -int64_t(StackTop);
3202 if (AssignOffsets == AssignObjectOffsets::Yes)
3203 MFI.setObjectOffset(FI, Offset);
3204
3205 LLVM_DEBUG(dbgs() << "alloc FI(" << FI << ") at SP[" << Offset << "]\n");
3206 };
3207
3208 // Then process all callee saved slots.
3209 int MinCSFrameIndex, MaxCSFrameIndex;
3210 if (getSVECalleeSaveSlotRange(MFI, MinCSFrameIndex, MaxCSFrameIndex)) {
3211 for (int FI = MinCSFrameIndex; FI <= MaxCSFrameIndex; ++FI)
3212 AllocateObject(FI);
3213 }
3214
3215 // Ensure the CS area is 16-byte aligned.
3216 PPRStackTop = alignTo(PPRStackTop, Align(16U));
3217 ZPRStackTop = alignTo(ZPRStackTop, Align(16U));
3218
3219 // Create a buffer of SVE objects to allocate and sort it.
3220 SmallVector<int, 8> ObjectsToAllocate;
3221 // If we have a stack protector, and we've previously decided that we have SVE
3222 // objects on the stack and thus need it to go in the SVE stack area, then it
3223 // needs to go first.
3224 int StackProtectorFI = -1;
3225 if (MFI.hasStackProtectorIndex()) {
3226 StackProtectorFI = MFI.getStackProtectorIndex();
3227 if (MFI.getStackID(StackProtectorFI) == TargetStackID::ScalableVector)
3228 ObjectsToAllocate.push_back(StackProtectorFI);
3229 }
3230
3231 for (int FI = 0, E = MFI.getObjectIndexEnd(); FI != E; ++FI) {
3232 if (FI == StackProtectorFI || MFI.isDeadObjectIndex(FI) ||
3234 continue;
3235
3238 continue;
3239
3240 ObjectsToAllocate.push_back(FI);
3241 }
3242
3243 // Allocate all SVE locals and spills
3244 for (unsigned FI : ObjectsToAllocate)
3245 AllocateObject(FI);
3246
3247 PPRStackTop = alignTo(PPRStackTop, Align(16U));
3248 ZPRStackTop = alignTo(ZPRStackTop, Align(16U));
3249
3250 if (AssignOffsets == AssignObjectOffsets::Yes)
3251 AFI->setStackSizeSVE(SVEStack.ZPRStackSize, SVEStack.PPRStackSize);
3252
3253 return SVEStack;
3254}
3255
3257 MachineFunction &MF, RegScavenger *RS) const {
3259 "Upwards growing stack unsupported");
3260
3262
3263 // If this function isn't doing Win64-style C++ EH, we don't need to do
3264 // anything.
3265 if (!MF.hasEHFunclets())
3266 return;
3267
3268 MachineFrameInfo &MFI = MF.getFrameInfo();
3269 auto *AFI = MF.getInfo<AArch64FunctionInfo>();
3270
3271 // Win64 C++ EH needs to allocate space for the catch objects in the fixed
3272 // object area right next to the UnwindHelp object.
3273 WinEHFuncInfo &EHInfo = *MF.getWinEHFuncInfo();
3274 int64_t CurrentOffset =
3276 for (WinEHTryBlockMapEntry &TBME : EHInfo.TryBlockMap) {
3277 for (WinEHHandlerType &H : TBME.HandlerArray) {
3278 int FrameIndex = H.CatchObj.FrameIndex;
3279 if ((FrameIndex != INT_MAX) && MFI.getObjectOffset(FrameIndex) == 0) {
3280 CurrentOffset =
3281 alignTo(CurrentOffset, MFI.getObjectAlign(FrameIndex).value());
3282 CurrentOffset += MFI.getObjectSize(FrameIndex);
3283 MFI.setObjectOffset(FrameIndex, -CurrentOffset);
3284 }
3285 }
3286 }
3287
3288 // Create an UnwindHelp object.
3289 // The UnwindHelp object is allocated at the start of the fixed object area
3290 int64_t UnwindHelpOffset = alignTo(CurrentOffset + 8, Align(16));
3291 assert(UnwindHelpOffset == getFixedObjectSize(MF, AFI, /*IsWin64*/ true,
3292 /*IsFunclet*/ false) &&
3293 "UnwindHelpOffset must be at the start of the fixed object area");
3294 int UnwindHelpFI = MFI.CreateFixedObject(/*Size*/ 8, -UnwindHelpOffset,
3295 /*IsImmutable=*/false);
3296 EHInfo.UnwindHelpFrameIdx = UnwindHelpFI;
3297
3298 MachineBasicBlock &MBB = MF.front();
3299 auto MBBI = MBB.begin();
3300 while (MBBI != MBB.end() && MBBI->getFlag(MachineInstr::FrameSetup))
3301 ++MBBI;
3302
3303 // We need to store -2 into the UnwindHelp object at the start of the
3304 // function.
3305 DebugLoc DL;
3306 RS->enterBasicBlockEnd(MBB);
3307 RS->backward(MBBI);
3308 Register DstReg = RS->FindUnusedReg(&AArch64::GPR64commonRegClass);
3309 assert(DstReg && "There must be a free register after frame setup");
3310 const AArch64InstrInfo &TII =
3311 *MF.getSubtarget<AArch64Subtarget>().getInstrInfo();
3312 BuildMI(MBB, MBBI, DL, TII.get(AArch64::MOVi64imm), DstReg).addImm(-2);
3313 BuildMI(MBB, MBBI, DL, TII.get(AArch64::STURXi))
3314 .addReg(DstReg, getKillRegState(true))
3315 .addFrameIndex(UnwindHelpFI)
3316 .addImm(0);
3317}
3318
3319namespace {
3320struct TagStoreInstr {
3322 int64_t Offset, Size;
3323 explicit TagStoreInstr(MachineInstr *MI, int64_t Offset, int64_t Size)
3324 : MI(MI), Offset(Offset), Size(Size) {}
3325};
3326
3327class TagStoreEdit {
3328 MachineFunction *MF;
3329 MachineBasicBlock *MBB;
3330 MachineRegisterInfo *MRI;
3331 // Tag store instructions that are being replaced.
3333 // Combined memref arguments of the above instructions.
3335
3336 // Replace allocation tags in [FrameReg + FrameRegOffset, FrameReg +
3337 // FrameRegOffset + Size) with the address tag of SP.
3338 Register FrameReg;
3339 StackOffset FrameRegOffset;
3340 int64_t Size;
3341 // If not std::nullopt, move FrameReg to (FrameReg + FrameRegUpdate) at the
3342 // end.
3343 std::optional<int64_t> FrameRegUpdate;
3344 // MIFlags for any FrameReg updating instructions.
3345 unsigned FrameRegUpdateFlags;
3346
3347 // Use zeroing instruction variants.
3348 bool ZeroData;
3349 DebugLoc DL;
3350
3351 void emitUnrolled(MachineBasicBlock::iterator InsertI);
3352 void emitLoop(MachineBasicBlock::iterator InsertI);
3353
3354public:
3355 TagStoreEdit(MachineBasicBlock *MBB, bool ZeroData)
3356 : MBB(MBB), ZeroData(ZeroData) {
3357 MF = MBB->getParent();
3358 MRI = &MF->getRegInfo();
3359 }
3360 // Add an instruction to be replaced. Instructions must be added in the
3361 // ascending order of Offset, and have to be adjacent.
3362 void addInstruction(TagStoreInstr I) {
3363 assert((TagStores.empty() ||
3364 TagStores.back().Offset + TagStores.back().Size == I.Offset) &&
3365 "Non-adjacent tag store instructions.");
3366 TagStores.push_back(I);
3367 }
3368 void clear() { TagStores.clear(); }
3369 // Emit equivalent code at the given location, and erase the current set of
3370 // instructions. May skip if the replacement is not profitable. May invalidate
3371 // the input iterator and replace it with a valid one.
3372 void emitCode(MachineBasicBlock::iterator &InsertI,
3373 const AArch64FrameLowering *TFI, bool TryMergeSPUpdate);
3374};
3375
3376void TagStoreEdit::emitUnrolled(MachineBasicBlock::iterator InsertI) {
3377 const AArch64InstrInfo *TII =
3378 MF->getSubtarget<AArch64Subtarget>().getInstrInfo();
3379
3380 const int64_t kMinOffset = -256 * 16;
3381 const int64_t kMaxOffset = 255 * 16;
3382
3383 Register BaseReg = FrameReg;
3384 int64_t BaseRegOffsetBytes = FrameRegOffset.getFixed();
3385 if (BaseRegOffsetBytes < kMinOffset ||
3386 BaseRegOffsetBytes + (Size - Size % 32) > kMaxOffset ||
3387 // BaseReg can be FP, which is not necessarily aligned to 16-bytes. In
3388 // that case, BaseRegOffsetBytes will not be aligned to 16 bytes, which
3389 // is required for the offset of ST2G.
3390 BaseRegOffsetBytes % 16 != 0) {
3391 Register ScratchReg = MRI->createVirtualRegister(&AArch64::GPR64RegClass);
3392 emitFrameOffset(*MBB, InsertI, DL, ScratchReg, BaseReg,
3393 StackOffset::getFixed(BaseRegOffsetBytes), TII);
3394 BaseReg = ScratchReg;
3395 BaseRegOffsetBytes = 0;
3396 }
3397
3398 MachineInstr *LastI = nullptr;
3399 while (Size) {
3400 int64_t InstrSize = (Size > 16) ? 32 : 16;
3401 unsigned Opcode =
3402 InstrSize == 16
3403 ? (ZeroData ? AArch64::STZGi : AArch64::STGi)
3404 : (ZeroData ? AArch64::STZ2Gi : AArch64::ST2Gi);
3405 assert(BaseRegOffsetBytes % 16 == 0);
3406 MachineInstr *I = BuildMI(*MBB, InsertI, DL, TII->get(Opcode))
3407 .addReg(AArch64::SP)
3408 .addReg(BaseReg)
3409 .addImm(BaseRegOffsetBytes / 16)
3410 .setMemRefs(CombinedMemRefs);
3411 // A store to [BaseReg, #0] should go last for an opportunity to fold the
3412 // final SP adjustment in the epilogue.
3413 if (BaseRegOffsetBytes == 0)
3414 LastI = I;
3415 BaseRegOffsetBytes += InstrSize;
3416 Size -= InstrSize;
3417 }
3418
3419 if (LastI)
3420 MBB->splice(InsertI, MBB, LastI);
3421}
3422
3423void TagStoreEdit::emitLoop(MachineBasicBlock::iterator InsertI) {
3424 const AArch64InstrInfo *TII =
3425 MF->getSubtarget<AArch64Subtarget>().getInstrInfo();
3426
3427 Register BaseReg = FrameRegUpdate
3428 ? FrameReg
3429 : MRI->createVirtualRegister(&AArch64::GPR64RegClass);
3430 Register SizeReg = MRI->createVirtualRegister(&AArch64::GPR64RegClass);
3431
3432 emitFrameOffset(*MBB, InsertI, DL, BaseReg, FrameReg, FrameRegOffset, TII);
3433
3434 int64_t LoopSize = Size;
3435 // If the loop size is not a multiple of 32, split off one 16-byte store at
3436 // the end to fold BaseReg update into.
3437 if (FrameRegUpdate && *FrameRegUpdate)
3438 LoopSize -= LoopSize % 32;
3439 MachineInstr *LoopI = BuildMI(*MBB, InsertI, DL,
3440 TII->get(ZeroData ? AArch64::STZGloop_wback
3441 : AArch64::STGloop_wback))
3442 .addDef(SizeReg)
3443 .addDef(BaseReg)
3444 .addImm(LoopSize)
3445 .addReg(BaseReg)
3446 .setMemRefs(CombinedMemRefs);
3447 if (FrameRegUpdate)
3448 LoopI->setFlags(FrameRegUpdateFlags);
3449
3450 int64_t ExtraBaseRegUpdate =
3451 FrameRegUpdate ? (*FrameRegUpdate - FrameRegOffset.getFixed() - Size) : 0;
3452 LLVM_DEBUG(dbgs() << "TagStoreEdit::emitLoop: LoopSize=" << LoopSize
3453 << ", Size=" << Size
3454 << ", ExtraBaseRegUpdate=" << ExtraBaseRegUpdate
3455 << ", FrameRegUpdate=" << FrameRegUpdate
3456 << ", FrameRegOffset.getFixed()="
3457 << FrameRegOffset.getFixed() << "\n");
3458 if (LoopSize < Size) {
3459 assert(FrameRegUpdate);
3460 assert(Size - LoopSize == 16);
3461 // Tag 16 more bytes at BaseReg and update BaseReg.
3462 int64_t STGOffset = ExtraBaseRegUpdate + 16;
3463 assert(STGOffset % 16 == 0 && STGOffset >= -4096 && STGOffset <= 4080 &&
3464 "STG immediate out of range");
3465 BuildMI(*MBB, InsertI, DL,
3466 TII->get(ZeroData ? AArch64::STZGPostIndex : AArch64::STGPostIndex))
3467 .addDef(BaseReg)
3468 .addReg(BaseReg)
3469 .addReg(BaseReg)
3470 .addImm(STGOffset / 16)
3471 .setMemRefs(CombinedMemRefs)
3472 .setMIFlags(FrameRegUpdateFlags);
3473 } else if (ExtraBaseRegUpdate) {
3474 // Update BaseReg.
3475 int64_t AddSubOffset = std::abs(ExtraBaseRegUpdate);
3476 assert(AddSubOffset <= 4095 && "ADD/SUB immediate out of range");
3477 BuildMI(
3478 *MBB, InsertI, DL,
3479 TII->get(ExtraBaseRegUpdate > 0 ? AArch64::ADDXri : AArch64::SUBXri))
3480 .addDef(BaseReg)
3481 .addReg(BaseReg)
3482 .addImm(AddSubOffset)
3483 .addImm(0)
3484 .setMIFlags(FrameRegUpdateFlags);
3485 }
3486}
3487
3488// Check if *II is a register update that can be merged into STGloop that ends
3489// at (Reg + Size). RemainingOffset is the required adjustment to Reg after the
3490// end of the loop.
3491bool canMergeRegUpdate(MachineBasicBlock::iterator II, unsigned Reg,
3492 int64_t Size, int64_t *TotalOffset) {
3493 MachineInstr &MI = *II;
3494 if ((MI.getOpcode() == AArch64::ADDXri ||
3495 MI.getOpcode() == AArch64::SUBXri) &&
3496 MI.getOperand(0).getReg() == Reg && MI.getOperand(1).getReg() == Reg) {
3497 unsigned Shift = AArch64_AM::getShiftValue(MI.getOperand(3).getImm());
3498 int64_t Offset = MI.getOperand(2).getImm() << Shift;
3499 if (MI.getOpcode() == AArch64::SUBXri)
3500 Offset = -Offset;
3501 int64_t PostOffset = Offset - Size;
3502 // TagStoreEdit::emitLoop might emit either an ADD/SUB after the loop, or
3503 // an STGPostIndex which does the last 16 bytes of tag write. Which one is
3504 // chosen depends on the alignment of the loop size, but the difference
3505 // between the valid ranges for the two instructions is small, so we
3506 // conservatively assume that it could be either case here.
3507 //
3508 // Max offset of STGPostIndex, minus the 16 byte tag write folded into that
3509 // instruction.
3510 const int64_t kMaxOffset = 4080 - 16;
3511 // Max offset of SUBXri.
3512 const int64_t kMinOffset = -4095;
3513 if (PostOffset <= kMaxOffset && PostOffset >= kMinOffset &&
3514 PostOffset % 16 == 0) {
3515 *TotalOffset = Offset;
3516 return true;
3517 }
3518 }
3519 return false;
3520}
3521
3522void mergeMemRefs(const SmallVectorImpl<TagStoreInstr> &TSE,
3524 MemRefs.clear();
3525 for (auto &TS : TSE) {
3526 MachineInstr *MI = TS.MI;
3527 // An instruction without memory operands may access anything. Be
3528 // conservative and return an empty list.
3529 if (MI->memoperands_empty()) {
3530 MemRefs.clear();
3531 return;
3532 }
3533 MemRefs.append(MI->memoperands_begin(), MI->memoperands_end());
3534 }
3535}
3536
3537void TagStoreEdit::emitCode(MachineBasicBlock::iterator &InsertI,
3538 const AArch64FrameLowering *TFI,
3539 bool TryMergeSPUpdate) {
3540 if (TagStores.empty())
3541 return;
3542 TagStoreInstr &FirstTagStore = TagStores[0];
3543 TagStoreInstr &LastTagStore = TagStores[TagStores.size() - 1];
3544 Size = LastTagStore.Offset - FirstTagStore.Offset + LastTagStore.Size;
3545 DL = TagStores[0].MI->getDebugLoc();
3546
3547 Register Reg;
3548 FrameRegOffset = TFI->resolveFrameOffsetReference(
3549 *MF, FirstTagStore.Offset, false /*isFixed*/,
3550 TargetStackID::Default /*StackID*/, Reg,
3551 /*PreferFP=*/false, /*ForSimm=*/true);
3552 FrameReg = Reg;
3553 FrameRegUpdate = std::nullopt;
3554
3555 mergeMemRefs(TagStores, CombinedMemRefs);
3556
3557 LLVM_DEBUG({
3558 dbgs() << "Replacing adjacent STG instructions:\n";
3559 for (const auto &Instr : TagStores) {
3560 dbgs() << " " << *Instr.MI;
3561 }
3562 });
3563
3564 // Size threshold where a loop becomes shorter than a linear sequence of
3565 // tagging instructions.
3566 const int kSetTagLoopThreshold = 176;
3567 if (Size < kSetTagLoopThreshold) {
3568 if (TagStores.size() < 2)
3569 return;
3570 emitUnrolled(InsertI);
3571 } else {
3572 MachineInstr *UpdateInstr = nullptr;
3573 int64_t TotalOffset = 0;
3574 if (TryMergeSPUpdate) {
3575 // See if we can merge base register update into the STGloop.
3576 // This is done in AArch64LoadStoreOptimizer for "normal" stores,
3577 // but STGloop is way too unusual for that, and also it only
3578 // realistically happens in function epilogue. Also, STGloop is expanded
3579 // before that pass.
3580 if (InsertI != MBB->end() &&
3581 canMergeRegUpdate(InsertI, FrameReg, FrameRegOffset.getFixed() + Size,
3582 &TotalOffset)) {
3583 UpdateInstr = &*InsertI++;
3584 LLVM_DEBUG(dbgs() << "Folding SP update into loop:\n "
3585 << *UpdateInstr);
3586 }
3587 }
3588
3589 if (!UpdateInstr && TagStores.size() < 2)
3590 return;
3591
3592 if (UpdateInstr) {
3593 FrameRegUpdate = TotalOffset;
3594 FrameRegUpdateFlags = UpdateInstr->getFlags();
3595 }
3596 emitLoop(InsertI);
3597 if (UpdateInstr)
3598 UpdateInstr->eraseFromParent();
3599 }
3600
3601 for (auto &TS : TagStores)
3602 TS.MI->eraseFromParent();
3603}
3604
3605bool isMergeableStackTaggingInstruction(MachineInstr &MI, int64_t &Offset,
3606 int64_t &Size, bool &ZeroData) {
3607 MachineFunction &MF = *MI.getParent()->getParent();
3608 const MachineFrameInfo &MFI = MF.getFrameInfo();
3609
3610 unsigned Opcode = MI.getOpcode();
3611 ZeroData = (Opcode == AArch64::STZGloop || Opcode == AArch64::STZGi ||
3612 Opcode == AArch64::STZ2Gi);
3613
3614 if (Opcode == AArch64::STGloop || Opcode == AArch64::STZGloop) {
3615 if (!MI.getOperand(0).isDead() || !MI.getOperand(1).isDead())
3616 return false;
3617 if (!MI.getOperand(2).isImm() || !MI.getOperand(3).isFI())
3618 return false;
3619 Offset = MFI.getObjectOffset(MI.getOperand(3).getIndex());
3620 Size = MI.getOperand(2).getImm();
3621 return true;
3622 }
3623
3624 if (Opcode == AArch64::STGi || Opcode == AArch64::STZGi)
3625 Size = 16;
3626 else if (Opcode == AArch64::ST2Gi || Opcode == AArch64::STZ2Gi)
3627 Size = 32;
3628 else
3629 return false;
3630
3631 if (MI.getOperand(0).getReg() != AArch64::SP || !MI.getOperand(1).isFI())
3632 return false;
3633
3634 Offset = MFI.getObjectOffset(MI.getOperand(1).getIndex()) +
3635 16 * MI.getOperand(2).getImm();
3636 return true;
3637}
3638
3639static size_t countAvailableScavengerSlots(LivePhysRegs &LiveRegs,
3641 RegScavenger *RS) {
3642 auto FreeGPRs =
3643 llvm::count_if(AArch64::GPR64RegClass, [&LiveRegs, &MRI](auto Reg) {
3644 return LiveRegs.available(MRI, Reg);
3645 });
3646
3647 size_t NumEmergencySlots = 0;
3648 if (RS)
3649 NumEmergencySlots = RS->getNumScavengingFrameIndices();
3650
3651 return FreeGPRs + NumEmergencySlots;
3652}
3653
3654// Detect a run of memory tagging instructions for adjacent stack frame slots,
3655// and replace them with a shorter instruction sequence:
3656// * replace STG + STG with ST2G
3657// * replace STGloop + STGloop with STGloop
3658// This code needs to run when stack slot offsets are already known, but before
3659// FrameIndex operands in STG instructions are eliminated.
3661 const AArch64FrameLowering *TFI,
3662 RegScavenger *RS) {
3663 bool FirstZeroData;
3664 int64_t Size, Offset;
3665 MachineInstr &MI = *II;
3668 if (&MI == &MBB->instr_back())
3669 return II;
3670 if (!isMergeableStackTaggingInstruction(MI, Offset, Size, FirstZeroData))
3671 return II;
3672
3674 Instrs.emplace_back(&MI, Offset, Size);
3675
3676 constexpr int kScanLimit = 10;
3677 int Count = 0;
3679 NextI != E && Count < kScanLimit; ++NextI) {
3680 MachineInstr &MI = *NextI;
3681 bool ZeroData;
3682 int64_t Size, Offset;
3683 // Collect instructions that update memory tags with a FrameIndex operand
3684 // and (when applicable) constant size, and whose output registers are dead
3685 // (the latter is almost always the case in practice). Since these
3686 // instructions effectively have no inputs or outputs, we are free to skip
3687 // any non-aliasing instructions in between without tracking used registers.
3688 if (isMergeableStackTaggingInstruction(MI, Offset, Size, ZeroData)) {
3689 if (ZeroData != FirstZeroData)
3690 break;
3691 Instrs.emplace_back(&MI, Offset, Size);
3692 continue;
3693 }
3694
3695 // Only count non-transient, non-tagging instructions toward the scan
3696 // limit.
3697 if (!MI.isTransient())
3698 ++Count;
3699
3700 // Just in case, stop before the epilogue code starts.
3701 if (MI.getFlag(MachineInstr::FrameSetup) ||
3703 break;
3704
3705 // Reject anything that may alias the collected instructions.
3706 if (MI.mayLoadOrStore() || MI.hasUnmodeledSideEffects() || MI.isCall())
3707 break;
3708 }
3709
3710 // New code will be inserted after the last tagging instruction we've found.
3711 MachineBasicBlock::iterator InsertI = Instrs.back().MI;
3712
3713 // All the gathered stack tag instructions are merged and placed after
3714 // last tag store in the list. The check should be made if the nzcv
3715 // flag is live at the point where we are trying to insert. Otherwise
3716 // the nzcv flag might get clobbered if any stg loops are present.
3717
3718 // FIXME : This approach of bailing out from merge is conservative in
3719 // some ways like even if stg loops are not present after merge the
3720 // insert list, this liveness check is done (which is not needed).
3722 LiveRegs.addLiveOuts(*MBB);
3723 for (auto I = MBB->rbegin();; ++I) {
3724 MachineInstr &MI = *I;
3725 if (MI == InsertI)
3726 break;
3727 LiveRegs.stepBackward(*I);
3728 }
3729 InsertI++;
3730 if (LiveRegs.contains(AArch64::NZCV))
3731 return InsertI;
3732
3733 // Emitting an MTE loop requires two physical registers (BaseReg and
3734 // SizeReg). If the function is under register pressure, the register
3735 // scavenger will crash trying to allocate them. If we don't have at least
3736 // two free slots (free registers + emergency slots), bail out and fall back
3737 // to the unrolled sequence.
3738 if (countAvailableScavengerSlots(LiveRegs, MBB->getParent()->getRegInfo(),
3739 RS) < 2) {
3740 LLVM_DEBUG(
3741 dbgs() << "Failed to merge MTE stack tagging instructions into loop "
3742 << "due to high register pressure.\n");
3743 return InsertI;
3744 }
3745
3746 llvm::stable_sort(Instrs,
3747 [](const TagStoreInstr &Left, const TagStoreInstr &Right) {
3748 return Left.Offset < Right.Offset;
3749 });
3750
3751 // Make sure that we don't have any overlapping stores.
3752 int64_t CurOffset = Instrs[0].Offset;
3753 for (auto &Instr : Instrs) {
3754 if (CurOffset > Instr.Offset)
3755 return NextI;
3756 CurOffset = Instr.Offset + Instr.Size;
3757 }
3758
3759 // Find contiguous runs of tagged memory and emit shorter instruction
3760 // sequences for them when possible.
3761 TagStoreEdit TSE(MBB, FirstZeroData);
3762 std::optional<int64_t> EndOffset;
3763 for (auto &Instr : Instrs) {
3764 if (EndOffset && *EndOffset != Instr.Offset) {
3765 // Found a gap.
3766 TSE.emitCode(InsertI, TFI, /*TryMergeSPUpdate = */ false);
3767 TSE.clear();
3768 }
3769
3770 TSE.addInstruction(Instr);
3771 EndOffset = Instr.Offset + Instr.Size;
3772 }
3773
3774 const MachineFunction *MF = MBB->getParent();
3775 // Multiple FP/SP updates in a loop cannot be described by CFI instructions.
3776 TSE.emitCode(
3777 InsertI, TFI, /*TryMergeSPUpdate = */
3779
3780 return InsertI;
3781}
3782} // namespace
3783
3785 MachineFunction &MF, RegScavenger *RS = nullptr) const {
3786 bool MergeSetTag = MF.getSubtarget<AArch64Subtarget>()
3787 .getCLOpts()
3788 .stack_tagging_merge_settag;
3789 for (auto &BB : MF)
3790 for (MachineBasicBlock::iterator II = BB.begin(); II != BB.end();) {
3791 if (MergeSetTag)
3792 II = tryMergeAdjacentSTG(II, this, RS);
3793 }
3794
3795 // By the time this method is called, most of the prologue/epilogue code is
3796 // already emitted, whether its location was affected by the shrink-wrapping
3797 // optimization or not.
3798 if (!MF.getFunction().hasFnAttribute(Attribute::Naked) &&
3799 shouldSignReturnAddressEverywhere(MF))
3801}
3802
3803/// For Win64 AArch64 EH, the offset to the Unwind object is from the SP
3804/// before the update. This is easily retrieved as it is exactly the offset
3805/// that is set in processFunctionBeforeFrameFinalized.
3807 const MachineFunction &MF, int FI, Register &FrameReg,
3808 bool IgnoreSPUpdates) const {
3809 const MachineFrameInfo &MFI = MF.getFrameInfo();
3810 if (IgnoreSPUpdates) {
3811 LLVM_DEBUG(dbgs() << "Offset from the SP for " << FI << " is "
3812 << MFI.getObjectOffset(FI) << "\n");
3813 FrameReg = AArch64::SP;
3814 return StackOffset::getFixed(MFI.getObjectOffset(FI));
3815 }
3816
3817 // Go to common code if we cannot provide sp + offset.
3818 if (MFI.hasVarSizedObjects() ||
3821 return getFrameIndexReference(MF, FI, FrameReg);
3822
3823 FrameReg = AArch64::SP;
3824 return getStackOffset(MF, MFI.getObjectOffset(FI));
3825}
3826
3827/// The parent frame offset (aka dispFrame) is only used on X86_64 to retrieve
3828/// the parent's frame pointer
3830 const MachineFunction &MF) const {
3831 return 0;
3832}
3833
3834/// Funclets only need to account for space for the callee saved registers,
3835/// as the locals are accounted for in the parent's stack frame.
3837 const MachineFunction &MF) const {
3838 // This is the size of the pushed CSRs.
3839 unsigned CSSize =
3840 MF.getInfo<AArch64FunctionInfo>()->getCalleeSavedStackSize();
3841 // This is the amount of stack a funclet needs to allocate.
3842 return alignTo(CSSize + MF.getFrameInfo().getMaxCallFrameSize(),
3843 getStackAlign());
3844}
3845
3846namespace {
3847struct FrameObject {
3848 bool IsValid = false;
3849 // Index of the object in MFI.
3850 int ObjectIndex = 0;
3851 // Group ID this object belongs to.
3852 int GroupIndex = -1;
3853 // This object should be placed first (closest to SP).
3854 bool ObjectFirst = false;
3855 // This object's group (which always contains the object with
3856 // ObjectFirst==true) should be placed first.
3857 bool GroupFirst = false;
3858
3859 // Used to distinguish between FP and GPR accesses. The values are decided so
3860 // that they sort FPR < Hazard < GPR and they can be or'd together.
3861 unsigned Accesses = 0;
3862 enum { AccessFPR = 1, AccessHazard = 2, AccessGPR = 4 };
3863};
3864
3865class GroupBuilder {
3866 SmallVector<int, 8> CurrentMembers;
3867 int NextGroupIndex = 0;
3868 std::vector<FrameObject> &Objects;
3869
3870public:
3871 GroupBuilder(std::vector<FrameObject> &Objects) : Objects(Objects) {}
3872 void AddMember(int Index) { CurrentMembers.push_back(Index); }
3873 void EndCurrentGroup() {
3874 if (CurrentMembers.size() > 1) {
3875 // Create a new group with the current member list. This might remove them
3876 // from their pre-existing groups. That's OK, dealing with overlapping
3877 // groups is too hard and unlikely to make a difference.
3878 LLVM_DEBUG(dbgs() << "group:");
3879 for (int Index : CurrentMembers) {
3880 Objects[Index].GroupIndex = NextGroupIndex;
3881 LLVM_DEBUG(dbgs() << " " << Index);
3882 }
3883 LLVM_DEBUG(dbgs() << "\n");
3884 NextGroupIndex++;
3885 }
3886 CurrentMembers.clear();
3887 }
3888};
3889
3890bool FrameObjectCompare(const FrameObject &A, const FrameObject &B) {
3891 // Objects at a lower index are closer to FP; objects at a higher index are
3892 // closer to SP.
3893 //
3894 // For consistency in our comparison, all invalid objects are placed
3895 // at the end. This also allows us to stop walking when we hit the
3896 // first invalid item after it's all sorted.
3897 //
3898 // If we want to include a stack hazard region, order FPR accesses < the
3899 // hazard object < GPRs accesses in order to create a separation between the
3900 // two. For the Accesses field 1 = FPR, 2 = Hazard Object, 4 = GPR.
3901 //
3902 // Otherwise the "first" object goes first (closest to SP), followed by the
3903 // members of the "first" group.
3904 //
3905 // The rest are sorted by the group index to keep the groups together.
3906 // Higher numbered groups are more likely to be around longer (i.e. untagged
3907 // in the function epilogue and not at some earlier point). Place them closer
3908 // to SP.
3909 //
3910 // If all else equal, sort by the object index to keep the objects in the
3911 // original order.
3912 return std::make_tuple(!A.IsValid, A.Accesses, A.ObjectFirst, A.GroupFirst,
3913 A.GroupIndex, A.ObjectIndex) <
3914 std::make_tuple(!B.IsValid, B.Accesses, B.ObjectFirst, B.GroupFirst,
3915 B.GroupIndex, B.ObjectIndex);
3916}
3917} // namespace
3918
3920 const MachineFunction &MF, SmallVectorImpl<int> &ObjectsToAllocate) const {
3922
3923 if ((!MF.getSubtarget<AArch64Subtarget>().getCLOpts().order_frame_objects &&
3924 !AFI.hasSplitSVEObjects()) ||
3925 ObjectsToAllocate.empty())
3926 return;
3927
3928 const MachineFrameInfo &MFI = MF.getFrameInfo();
3929 std::vector<FrameObject> FrameObjects(MFI.getObjectIndexEnd());
3930 for (auto &Obj : ObjectsToAllocate) {
3931 FrameObjects[Obj].IsValid = true;
3932 FrameObjects[Obj].ObjectIndex = Obj;
3933 }
3934
3935 // Identify FPR vs GPR slots for hazards, and stack slots that are tagged at
3936 // the same time.
3937 GroupBuilder GB(FrameObjects);
3938 for (auto &MBB : MF) {
3939 for (auto &MI : MBB) {
3940 if (MI.isDebugInstr())
3941 continue;
3942
3943 if (AFI.hasStackHazardSlotIndex()) {
3944 std::optional<int> FI = getLdStFrameID(MI, MFI);
3945 if (FI && *FI >= 0 && *FI < (int)FrameObjects.size()) {
3946 if (MFI.getStackID(*FI) == TargetStackID::ScalableVector ||
3948 FrameObjects[*FI].Accesses |= FrameObject::AccessFPR;
3949 else
3950 FrameObjects[*FI].Accesses |= FrameObject::AccessGPR;
3951 }
3952 }
3953
3954 int OpIndex;
3955 switch (MI.getOpcode()) {
3956 case AArch64::STGloop:
3957 case AArch64::STZGloop:
3958 OpIndex = 3;
3959 break;
3960 case AArch64::STGi:
3961 case AArch64::STZGi:
3962 case AArch64::ST2Gi:
3963 case AArch64::STZ2Gi:
3964 OpIndex = 1;
3965 break;
3966 default:
3967 OpIndex = -1;
3968 }
3969
3970 int TaggedFI = -1;
3971 if (OpIndex >= 0) {
3972 const MachineOperand &MO = MI.getOperand(OpIndex);
3973 if (MO.isFI()) {
3974 int FI = MO.getIndex();
3975 if (FI >= 0 && FI < MFI.getObjectIndexEnd() &&
3976 FrameObjects[FI].IsValid)
3977 TaggedFI = FI;
3978 }
3979 }
3980
3981 // If this is a stack tagging instruction for a slot that is not part of a
3982 // group yet, either start a new group or add it to the current one.
3983 if (TaggedFI >= 0)
3984 GB.AddMember(TaggedFI);
3985 else
3986 GB.EndCurrentGroup();
3987 }
3988 // Groups should never span multiple basic blocks.
3989 GB.EndCurrentGroup();
3990 }
3991
3992 if (AFI.hasStackHazardSlotIndex()) {
3993 FrameObjects[AFI.getStackHazardSlotIndex()].Accesses =
3994 FrameObject::AccessHazard;
3995 // If a stack object is unknown or both GPR and FPR, sort it into GPR.
3996 for (auto &Obj : FrameObjects)
3997 if (!Obj.Accesses ||
3998 Obj.Accesses == (FrameObject::AccessGPR | FrameObject::AccessFPR))
3999 Obj.Accesses = FrameObject::AccessGPR;
4000 }
4001
4002 // If the function's tagged base pointer is pinned to a stack slot, we want to
4003 // put that slot first when possible. This will likely place it at SP + 0,
4004 // and save one instruction when generating the base pointer because IRG does
4005 // not allow an immediate offset.
4006 std::optional<int> TBPI = AFI.getTaggedBasePointerIndex();
4007 if (TBPI) {
4008 FrameObjects[*TBPI].ObjectFirst = true;
4009 FrameObjects[*TBPI].GroupFirst = true;
4010 int FirstGroupIndex = FrameObjects[*TBPI].GroupIndex;
4011 if (FirstGroupIndex >= 0)
4012 for (FrameObject &Object : FrameObjects)
4013 if (Object.GroupIndex == FirstGroupIndex)
4014 Object.GroupFirst = true;
4015 }
4016
4017 llvm::stable_sort(FrameObjects, FrameObjectCompare);
4018
4019 int i = 0;
4020 for (auto &Obj : FrameObjects) {
4021 // All invalid items are sorted at the end, so it's safe to stop.
4022 if (!Obj.IsValid)
4023 break;
4024 ObjectsToAllocate[i++] = Obj.ObjectIndex;
4025 }
4026
4027 LLVM_DEBUG({
4028 dbgs() << "Final frame order:\n";
4029 for (auto &Obj : FrameObjects) {
4030 if (!Obj.IsValid)
4031 break;
4032 dbgs() << " " << Obj.ObjectIndex << ": group " << Obj.GroupIndex;
4033 if (Obj.ObjectFirst)
4034 dbgs() << ", first";
4035 if (Obj.GroupFirst)
4036 dbgs() << ", group-first";
4037 dbgs() << "\n";
4038 }
4039 });
4040}
4041
4042/// Emit a loop to decrement SP until it is equal to TargetReg, with probes at
4043/// least every ProbeSize bytes. Returns an iterator of the first instruction
4044/// after the loop. The difference between SP and TargetReg must be an exact
4045/// multiple of ProbeSize.
4047AArch64FrameLowering::inlineStackProbeLoopExactMultiple(
4048 MachineBasicBlock::iterator MBBI, int64_t ProbeSize,
4049 Register TargetReg) const {
4050 MachineBasicBlock &MBB = *MBBI->getParent();
4051 MachineFunction &MF = *MBB.getParent();
4052 const AArch64InstrInfo *TII =
4053 MF.getSubtarget<AArch64Subtarget>().getInstrInfo();
4054 DebugLoc DL = MBB.findDebugLoc(MBBI);
4055
4056 MachineFunction::iterator MBBInsertPoint = std::next(MBB.getIterator());
4057 MachineBasicBlock *LoopMBB = MF.CreateMachineBasicBlock(MBB.getBasicBlock());
4058 MF.insert(MBBInsertPoint, LoopMBB);
4059 MachineBasicBlock *ExitMBB = MF.CreateMachineBasicBlock(MBB.getBasicBlock());
4060 MF.insert(MBBInsertPoint, ExitMBB);
4061
4062 // SUB SP, SP, #ProbeSize (or equivalent if ProbeSize is not encodable
4063 // in SUB).
4064 emitFrameOffset(*LoopMBB, LoopMBB->end(), DL, AArch64::SP, AArch64::SP,
4065 StackOffset::getFixed(-ProbeSize), TII,
4067 // LDR XZR, [SP]
4068 BuildMI(*LoopMBB, LoopMBB->end(), DL, TII->get(AArch64::LDRXui))
4069 .addDef(AArch64::XZR)
4070 .addReg(AArch64::SP)
4071 .addImm(0)
4075 Align(8)))
4077 // CMP SP, TargetReg
4078 BuildMI(*LoopMBB, LoopMBB->end(), DL, TII->get(AArch64::SUBSXrx64),
4079 AArch64::XZR)
4080 .addReg(AArch64::SP)
4081 .addReg(TargetReg)
4084 // B.CC Loop
4085 BuildMI(*LoopMBB, LoopMBB->end(), DL, TII->get(AArch64::Bcc))
4087 .addMBB(LoopMBB)
4089
4090 LoopMBB->addSuccessor(ExitMBB);
4091 LoopMBB->addSuccessor(LoopMBB);
4092 // Synthesize the exit MBB.
4093 ExitMBB->splice(ExitMBB->end(), &MBB, MBBI, MBB.end());
4095 MBB.addSuccessor(LoopMBB);
4096 // Update liveins.
4097 fullyRecomputeLiveIns({ExitMBB, LoopMBB});
4098
4099 return ExitMBB->begin();
4100}
4101
4102void AArch64FrameLowering::inlineStackProbeFixed(
4103 MachineBasicBlock::iterator MBBI, Register ScratchReg, int64_t FrameSize,
4104 StackOffset CFAOffset) const {
4105 MachineBasicBlock *MBB = MBBI->getParent();
4106 MachineFunction &MF = *MBB->getParent();
4107 const AArch64InstrInfo *TII =
4108 MF.getSubtarget<AArch64Subtarget>().getInstrInfo();
4109 AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
4110 bool EmitAsyncCFI = AFI->needsAsyncDwarfUnwindInfo(MF);
4111 bool HasFP = hasFP(MF);
4112
4113 DebugLoc DL;
4114 int64_t ProbeSize = MF.getInfo<AArch64FunctionInfo>()->getStackProbeSize();
4115 int64_t NumBlocks = FrameSize / ProbeSize;
4116 int64_t ResidualSize = FrameSize % ProbeSize;
4117
4118 LLVM_DEBUG(dbgs() << "Stack probing: total " << FrameSize << " bytes, "
4119 << NumBlocks << " blocks of " << ProbeSize
4120 << " bytes, plus " << ResidualSize << " bytes\n");
4121
4122 // Decrement SP by NumBlock * ProbeSize bytes, with either unrolled or
4123 // ordinary loop.
4124 if (NumBlocks <= AArch64::StackProbeMaxLoopUnroll) {
4125 for (int i = 0; i < NumBlocks; ++i) {
4126 // SUB SP, SP, #ProbeSize (or equivalent if ProbeSize is not
4127 // encodable in a SUB).
4128 emitFrameOffset(*MBB, MBBI, DL, AArch64::SP, AArch64::SP,
4129 StackOffset::getFixed(-ProbeSize), TII,
4130 MachineInstr::FrameSetup, false, false, nullptr,
4131 EmitAsyncCFI && !HasFP, CFAOffset);
4132 CFAOffset += StackOffset::getFixed(ProbeSize);
4133 // LDR XZR, [SP]
4134 BuildMI(*MBB, MBBI, DL, TII->get(AArch64::LDRXui))
4135 .addDef(AArch64::XZR)
4136 .addReg(AArch64::SP)
4137 .addImm(0)
4141 Align(8)))
4143 }
4144 } else if (NumBlocks != 0) {
4145 // SUB ScratchReg, SP, #FrameSize (or equivalent if FrameSize is not
4146 // encodable in ADD). ScrathReg may temporarily become the CFA register.
4147 emitFrameOffset(*MBB, MBBI, DL, ScratchReg, AArch64::SP,
4148 StackOffset::getFixed(-ProbeSize * NumBlocks), TII,
4149 MachineInstr::FrameSetup, false, false, nullptr,
4150 EmitAsyncCFI && !HasFP, CFAOffset);
4151 CFAOffset += StackOffset::getFixed(ProbeSize * NumBlocks);
4152 MBBI = inlineStackProbeLoopExactMultiple(MBBI, ProbeSize, ScratchReg);
4153 MBB = MBBI->getParent();
4154 if (EmitAsyncCFI && !HasFP) {
4155 // Set the CFA register back to SP.
4156 CFIInstBuilder(*MBB, MBBI, MachineInstr::FrameSetup)
4157 .buildDefCFARegister(AArch64::SP);
4158 }
4159 }
4160
4161 if (ResidualSize != 0) {
4162 // SUB SP, SP, #ResidualSize (or equivalent if ResidualSize is not encodable
4163 // in SUB).
4164 emitFrameOffset(*MBB, MBBI, DL, AArch64::SP, AArch64::SP,
4165 StackOffset::getFixed(-ResidualSize), TII,
4166 MachineInstr::FrameSetup, false, false, nullptr,
4167 EmitAsyncCFI && !HasFP, CFAOffset);
4168 if (ResidualSize > AArch64::StackProbeMaxUnprobedStack) {
4169 // LDR XZR, [SP]
4170 BuildMI(*MBB, MBBI, DL, TII->get(AArch64::LDRXui))
4171 .addDef(AArch64::XZR)
4172 .addReg(AArch64::SP)
4173 .addImm(0)
4177 Align(8)))
4179 }
4180 }
4181}
4182
4183void AArch64FrameLowering::inlineStackProbe(MachineFunction &MF,
4184 MachineBasicBlock &MBB) const {
4185 // Get the instructions that need to be replaced. We emit at most two of
4186 // these. Remember them in order to avoid complications coming from the need
4187 // to traverse the block while potentially creating more blocks.
4188 SmallVector<MachineInstr *, 4> ToReplace;
4189 for (MachineInstr &MI : MBB)
4190 if (MI.getOpcode() == AArch64::PROBED_STACKALLOC ||
4191 MI.getOpcode() == AArch64::PROBED_STACKALLOC_VAR)
4192 ToReplace.push_back(&MI);
4193
4194 for (MachineInstr *MI : ToReplace) {
4195 if (MI->getOpcode() == AArch64::PROBED_STACKALLOC) {
4196 Register ScratchReg = MI->getOperand(0).getReg();
4197 int64_t FrameSize = MI->getOperand(1).getImm();
4198 StackOffset CFAOffset = StackOffset::get(MI->getOperand(2).getImm(),
4199 MI->getOperand(3).getImm());
4200 inlineStackProbeFixed(MI->getIterator(), ScratchReg, FrameSize,
4201 CFAOffset);
4202 } else {
4203 assert(MI->getOpcode() == AArch64::PROBED_STACKALLOC_VAR &&
4204 "Stack probe pseudo-instruction expected");
4205 const AArch64InstrInfo *TII =
4206 MI->getMF()->getSubtarget<AArch64Subtarget>().getInstrInfo();
4207 Register TargetReg = MI->getOperand(0).getReg();
4208 (void)TII->probedStackAlloc(MI->getIterator(), TargetReg, true);
4209 }
4210 MI->eraseFromParent();
4211 }
4212}
4213
4216 NotAccessed = 0, // Stack object not accessed by load/store instructions.
4217 GPR = 1 << 0, // A general purpose register.
4218 PPR = 1 << 1, // A predicate register.
4219 FPR = 1 << 2, // A floating point/Neon/SVE register.
4220 };
4221
4222 int Idx;
4224 int64_t Size;
4225 unsigned AccessTypes;
4226
4228
4229 bool operator<(const StackAccess &Rhs) const {
4230 return std::make_tuple(start(), Idx) <
4231 std::make_tuple(Rhs.start(), Rhs.Idx);
4232 }
4233
4234 bool isCPU() const {
4235 // Predicate register load and store instructions execute on the CPU.
4237 }
4238 bool isSME() const { return AccessTypes & AccessType::FPR; }
4239 bool isMixed() const { return isCPU() && isSME(); }
4240
4241 int64_t start() const { return Offset.getFixed() + Offset.getScalable(); }
4242 int64_t end() const { return start() + Size; }
4243
4244 std::string getTypeString() const {
4245 switch (AccessTypes) {
4246 case AccessType::FPR:
4247 return "FPR";
4248 case AccessType::PPR:
4249 return "PPR";
4250 case AccessType::GPR:
4251 return "GPR";
4253 return "NA";
4254 default:
4255 return "Mixed";
4256 }
4257 }
4258
4259 void print(raw_ostream &OS) const {
4260 OS << getTypeString() << " stack object at [SP"
4261 << (Offset.getFixed() < 0 ? "" : "+") << Offset.getFixed();
4262 if (Offset.getScalable())
4263 OS << (Offset.getScalable() < 0 ? "" : "+") << Offset.getScalable()
4264 << " * vscale";
4265 OS << "]";
4266 }
4267};
4268
4269static inline raw_ostream &operator<<(raw_ostream &OS, const StackAccess &SA) {
4270 SA.print(OS);
4271 return OS;
4272}
4273
4274void AArch64FrameLowering::emitRemarks(
4275 const MachineFunction &MF, MachineOptimizationRemarkEmitter *ORE) const {
4276
4277 auto *AFI = MF.getInfo<AArch64FunctionInfo>();
4279 return;
4280
4281 uint64_t HazardSize = getStackHazardSize(MF);
4282 if (!HazardSize)
4283 HazardSize = MF.getSubtarget<AArch64Subtarget>()
4284 .getCLOpts()
4285 .stack_hazard_remark_size;
4286
4287 if (HazardSize == 0)
4288 return;
4289
4290 const MachineFrameInfo &MFI = MF.getFrameInfo();
4291 // Bail if function has no stack objects.
4292 if (!MFI.hasStackObjects())
4293 return;
4294
4295 std::vector<StackAccess> StackAccesses(MFI.getNumObjects());
4296
4297 size_t NumFPLdSt = 0;
4298 size_t NumNonFPLdSt = 0;
4299
4300 // Collect stack accesses via Load/Store instructions.
4301 for (const MachineBasicBlock &MBB : MF) {
4302 for (const MachineInstr &MI : MBB) {
4303 if (!MI.mayLoadOrStore() || MI.getNumMemOperands() < 1)
4304 continue;
4305 for (MachineMemOperand *MMO : MI.memoperands()) {
4306 std::optional<int> FI = getMMOFrameID(MMO, MFI);
4307 if (FI && !MFI.isDeadObjectIndex(*FI)) {
4308 int FrameIdx = *FI;
4309
4310 size_t ArrIdx = FrameIdx + MFI.getNumFixedObjects();
4311 if (StackAccesses[ArrIdx].AccessTypes == StackAccess::NotAccessed) {
4312 StackAccesses[ArrIdx].Idx = FrameIdx;
4313 StackAccesses[ArrIdx].Offset =
4314 getFrameIndexReferenceFromSP(MF, FrameIdx);
4315 StackAccesses[ArrIdx].Size = MFI.getObjectSize(FrameIdx);
4316 }
4317
4318 unsigned RegTy = StackAccess::AccessType::GPR;
4319 if (MFI.hasScalableStackID(FrameIdx))
4322 RegTy = StackAccess::FPR;
4323
4324 StackAccesses[ArrIdx].AccessTypes |= RegTy;
4325
4326 if (RegTy == StackAccess::FPR)
4327 ++NumFPLdSt;
4328 else
4329 ++NumNonFPLdSt;
4330 }
4331 }
4332 }
4333 }
4334
4335 if (NumFPLdSt == 0 || NumNonFPLdSt == 0)
4336 return;
4337
4338 llvm::sort(StackAccesses);
4339 llvm::erase_if(StackAccesses, [](const StackAccess &S) {
4341 });
4342
4345
4346 if (StackAccesses.front().isMixed())
4347 MixedObjects.push_back(&StackAccesses.front());
4348
4349 for (auto It = StackAccesses.begin(), End = std::prev(StackAccesses.end());
4350 It != End; ++It) {
4351 const auto &First = *It;
4352 const auto &Second = *(It + 1);
4353
4354 if (Second.isMixed())
4355 MixedObjects.push_back(&Second);
4356
4357 if ((First.isSME() && Second.isCPU()) ||
4358 (First.isCPU() && Second.isSME())) {
4359 uint64_t Distance = static_cast<uint64_t>(Second.start() - First.end());
4360 if (Distance < HazardSize)
4361 HazardPairs.emplace_back(&First, &Second);
4362 }
4363 }
4364
4365 auto EmitRemark = [&](llvm::StringRef Str) {
4366 ORE->emit([&]() {
4367 auto R = MachineOptimizationRemarkAnalysis(
4368 "sme", "StackHazard", MF.getFunction().getSubprogram(), &MF.front());
4369 return R << formatv("stack hazard in '{0}': ", MF.getName()).str() << Str;
4370 });
4371 };
4372
4373 for (const auto &P : HazardPairs)
4374 EmitRemark(formatv("{0} is too close to {1}", *P.first, *P.second).str());
4375
4376 for (const auto *Obj : MixedObjects)
4377 EmitRemark(
4378 formatv("{0} accessed by both GP and FP instructions", *Obj).str());
4379}
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 bool invalidateWindowsRegisterPairing(bool SpillExtendedVolatile, int PairOffset, unsigned Reg1, unsigned Reg2, bool NeedsWinCFI, const TargetRegisterInfo *TRI)
bool enableMultiVectorSpillFill(const AArch64Subtarget &Subtarget, MachineFunction &MF)
static std::optional< int > getLdStFrameID(const MachineInstr &MI, const MachineFrameInfo &MFI)
static void orderZPRCalleeSavesForGroups(MachineFunction &MF, const TargetRegisterInfo *RegInfo, std::vector< CalleeSavedInfo > &CSI)
void computeCalleeSaveRegisterGroups(const AArch64FrameLowering &AFL, MachineFunction &MF, ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI, SmallVectorImpl< RegGroupInfo > &RegGroups, bool NeedsFrameRecord)
static bool invalidateRegisterPairing(bool SpillExtendedVolatile, int PairOffset, 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.
static bool isLikelyToHaveSVEStack(const AArch64FrameLowering &AFL, const MachineFunction &MF)
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 MCRegister getRegisterOrZero(MCRegister Reg, bool HasSVE)
static unsigned getStackHazardSize(const MachineFunction &MF)
static bool isValidMemOpOffset(const AArch64InstrInfo *TII, unsigned Opcode, int Offset)
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
uint64_t uint64_t
uint64_t Imm
AMDGPU Reserve WWM Registers
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
Module.h This file contains the declarations for the Module class.
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)
RISCVCC::CondCode CC
MachineRegisterInfo & MRI
This file declares the machine register scavenger class.
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition Value.cpp:480
This file defines the scope_exit class, which executes user-defined cleanup logic at scope exit.
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 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.
bool authenticatesReturnAddressEarly(MachineFunction &MF, MachineBasicBlock &MBB) const
Whether the return address is authenticated before the epilogue starts, in the return block MBB,...
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
static bool shouldSignReturnAddress(SignReturnAddress Condition, bool IsLRSpilled)
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 AArch64Options & getCLOpts() const
const AArch64TargetLowering * getTargetLowering() const override
bool isSVEorStreamingSVEAvailable() const
Returns true if the target has access to either the full range of SVE instructions,...
bool isTargetWindowsOrUEFI() const
UEFI follows the Windows ARM64 ABI and produces PE/COFF images, so most of the Windows specific ABI h...
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:696
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition Function.h:273
AttributeList getAttributes() const
Return the attribute list for this Function.
Definition Function.h:329
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition Function.h:230
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:731
Module * getParent()
Get the module that this global value is contained inside of...
A set of physical registers with utility functions to track liveness when walking backward/forward th...
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
constexpr bool isValid() const
Definition MCRegister.h:84
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.
bool framePointerIsReserved() const
Returns true if the frame pointer must always either point to a new frame record or be un-modified in...
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
bool needsWinCFI() const
True if this function uses SEH unwind opcodes and needs an unwind table entry.
Function & getFunction()
Return the LLVM function that this machine code represents.
bool usesWindowsUnwindInfo() const
True if this function describes its unwind information with Windows SEH unwind opcodes (....
BasicBlockListType::iterator iterator
bool disableFramePointerElim() const
Returns true if frame pointer elimination should be disabled for this function.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineBasicBlock & front() const
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
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 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.
const Triple & getTargetTriple() const
Get the target triple which is a string describing the target host.
Definition Module.h:328
Represent a mutable reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:294
MutableArrayRef< T > drop_until(PredicateT Pred) const
Return a copy of *this with the first N elements not satisfying the given predicate removed.
Definition ArrayRef.h:403
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:157
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:31
int64_t getFixed() const
Returns the fixed component of the stack.
Definition TypeSize.h:47
int64_t getScalable() const
Returns the scalable component of the stack.
Definition TypeSize.h:50
static StackOffset get(int64_t Fixed, int64_t Scalable)
Definition TypeSize.h:42
static StackOffset getScalable(int64_t Scalable)
Definition TypeSize.h:41
static StackOffset getFixed(int64_t Fixed)
Definition TypeSize.h:40
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.
const Triple & getTargetTriple() const
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:48
bool isOSBinFormatMachO() const
Tests whether the environment is MachO.
Definition Triple.h:876
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 AArch64MCOptions & getCLOpts(const MCTargetOptions &Options)
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
NodeAddr< InstrNode * > Instr
Definition RDFGraph.h:389
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
Definition SFrame.h:77
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
@ Offset
Definition DWP.cpp:577
void stable_sort(R &&Range)
Definition STLExtras.h:2132
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1755
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
void interleaveComma(const Container &c, StreamT &os, UnaryFunctor each_fn)
Definition STLExtras.h:2329
@ 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:1762
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1652
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:149
constexpr RegState getDefRegState(bool B)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth, bool MustPreserveProvenance=false)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
auto reverse_conditionally(ContainerTy &&C, bool ShouldReverse)
Return a range that conditionally reverses C.
Definition STLExtras.h:1439
@ 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:2035
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:1788
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:341
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:2208
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
@ End
Run the machine verifier once, at the end of the pipeline.
Definition CodeGen.h:320
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:880
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:82
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