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::STPQi:
1141 case AArch64::LDPQi: {
1142 unsigned Reg0 = RegInfo->getSEHRegNum(MBBI->getOperand(0).getReg());
1143 unsigned Reg1 = RegInfo->getSEHRegNum(MBBI->getOperand(1).getReg());
1144 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveAnyRegQP))
1145 .addImm(Reg0)
1146 .addImm(Reg1)
1147 .addImm(Imm * 16)
1148 .setMIFlag(Flag);
1149 break;
1150 }
1151 case AArch64::LDPQpost:
1152 Imm = -Imm;
1153 [[fallthrough]];
1154 case AArch64::STPQpre: {
1155 unsigned Reg0 = RegInfo->getSEHRegNum(MBBI->getOperand(1).getReg());
1156 unsigned Reg1 = RegInfo->getSEHRegNum(MBBI->getOperand(2).getReg());
1157 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveAnyRegQPX))
1158 .addImm(Reg0)
1159 .addImm(Reg1)
1160 .addImm(Imm * 16)
1161 .setMIFlag(Flag);
1162 break;
1163 }
1164 }
1165 auto I = MBB->insertAfter(MBBI, MIB);
1166 return I;
1167}
1168
1171 if (!AFI->needsDwarfUnwindInfo(MF) || !AFI->hasStreamingModeChanges())
1172 return false;
1173 // For Darwin platforms we don't save VG for non-SVE functions, even if SME
1174 // is enabled with streaming mode changes.
1175 auto &ST = MF.getSubtarget<AArch64Subtarget>();
1176 if (ST.isTargetDarwin())
1177 return ST.hasSVE();
1178 return true;
1179}
1180
1182 MachineFunction &MF) const {
1183 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
1184 const AArch64InstrInfo *TII = Subtarget.getInstrInfo();
1185
1186 auto EmitSignRA = [&](MachineBasicBlock &MBB) {
1187 DebugLoc DL; // Set debug location to unknown.
1189
1190 BuildMI(MBB, MBBI, DL, TII->get(AArch64::PAUTH_PROLOGUE))
1192 };
1193
1194 auto EmitAuthRA = [&](MachineBasicBlock &MBB) {
1195 DebugLoc DL;
1196 MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator();
1197 if (MBBI != MBB.end())
1198 DL = MBBI->getDebugLoc();
1199
1200 TII->createPauthEpilogueInstr(MBB, DL);
1201 };
1202
1203 // This should be in sync with PEIImpl::calculateSaveRestoreBlocks.
1204 EmitSignRA(MF.front());
1205 for (MachineBasicBlock &MBB : MF) {
1206 if (MBB.isEHFuncletEntry())
1207 EmitSignRA(MBB);
1208 if (MBB.isReturnBlock())
1209 EmitAuthRA(MBB);
1210 }
1211}
1212
1214 MachineBasicBlock &MBB) const {
1215 AArch64PrologueEmitter PrologueEmitter(MF, MBB, *this);
1216 PrologueEmitter.emitPrologue();
1217}
1218
1220 MachineBasicBlock &MBB) const {
1221 AArch64EpilogueEmitter EpilogueEmitter(MF, MBB, *this);
1222 EpilogueEmitter.emitEpilogue();
1223}
1224
1227 MF.getInfo<AArch64FunctionInfo>()->needsDwarfUnwindInfo(MF);
1228}
1229
1231 return enableCFIFixup(MF) &&
1232 MF.getInfo<AArch64FunctionInfo>()->needsAsyncDwarfUnwindInfo(MF);
1233}
1234
1235/// getFrameIndexReference - Provide a base+offset reference to an FI slot for
1236/// debug info. It's the same as what we use for resolving the code-gen
1237/// references for now. FIXME: This can go wrong when references are
1238/// SP-relative and simple call frames aren't used.
1241 Register &FrameReg) const {
1243 MF, FI, FrameReg,
1244 /*PreferFP=*/
1245 MF.getFunction().hasFnAttribute(Attribute::SanitizeHWAddress) ||
1246 MF.getFunction().hasFnAttribute(Attribute::SanitizeMemTag),
1247 /*ForSimm=*/false);
1248}
1249
1252 int FI) const {
1253 // This function serves to provide a comparable offset from a single reference
1254 // point (the value of SP at function entry) that can be used for analysis,
1255 // e.g. the stack-frame-layout analysis pass. It is not guaranteed to be
1256 // correct for all objects in the presence of VLA-area objects or dynamic
1257 // stack re-alignment.
1258
1259 const auto &MFI = MF.getFrameInfo();
1260
1261 int64_t ObjectOffset = MFI.getObjectOffset(FI);
1262 StackOffset ZPRStackSize = getZPRStackSize(MF);
1263 StackOffset PPRStackSize = getPPRStackSize(MF);
1264 StackOffset SVEStackSize = ZPRStackSize + PPRStackSize;
1265
1266 // For VLA-area objects, just emit an offset at the end of the stack frame.
1267 // Whilst not quite correct, these objects do live at the end of the frame and
1268 // so it is more useful for analysis for the offset to reflect this.
1269 if (MFI.isVariableSizedObjectIndex(FI)) {
1270 return StackOffset::getFixed(-((int64_t)MFI.getStackSize())) - SVEStackSize;
1271 }
1272
1273 // This is correct in the absence of any SVE stack objects.
1274 if (!SVEStackSize)
1275 return StackOffset::getFixed(ObjectOffset - getOffsetOfLocalArea());
1276
1277 const auto *AFI = MF.getInfo<AArch64FunctionInfo>();
1278 bool FPAfterSVECalleeSaves = hasSVECalleeSavesAboveFrameRecord(MF);
1279 if (MFI.hasScalableStackID(FI)) {
1280 if (FPAfterSVECalleeSaves &&
1281 -ObjectOffset <= (int64_t)AFI->getSVECalleeSavedStackSize()) {
1282 assert(!AFI->hasSplitSVEObjects() &&
1283 "split-sve-objects not supported with FPAfterSVECalleeSaves");
1284 return StackOffset::getScalable(ObjectOffset);
1285 }
1286 StackOffset AccessOffset{};
1287 // The scalable vectors are below (lower address) the scalable predicates
1288 // with split SVE objects, so we must subtract the size of the predicates.
1289 if (AFI->hasSplitSVEObjects() &&
1290 MFI.getStackID(FI) == TargetStackID::ScalableVector)
1291 AccessOffset = -PPRStackSize;
1292 return AccessOffset +
1293 StackOffset::get(-((int64_t)AFI->getCalleeSavedStackSize()),
1294 ObjectOffset);
1295 }
1296
1297 bool IsFixed = MFI.isFixedObjectIndex(FI);
1298 bool IsCSR =
1299 !IsFixed && ObjectOffset >= -((int)AFI->getCalleeSavedStackSize(MFI));
1300
1301 StackOffset ScalableOffset = {};
1302 if (!IsFixed && !IsCSR) {
1303 ScalableOffset = -SVEStackSize;
1304 } else if (FPAfterSVECalleeSaves && IsCSR) {
1305 ScalableOffset =
1307 }
1308
1309 return StackOffset::getFixed(ObjectOffset) + ScalableOffset;
1310}
1311
1317
1318StackOffset AArch64FrameLowering::getFPOffset(const MachineFunction &MF,
1319 int64_t ObjectOffset) const {
1320 const auto *AFI = MF.getInfo<AArch64FunctionInfo>();
1321 const auto &Subtarget = MF.getSubtarget<AArch64Subtarget>();
1322 const Function &F = MF.getFunction();
1323 bool IsWin64 = Subtarget.isCallingConvWin64(F.getCallingConv(), F.isVarArg());
1324 unsigned FixedObject =
1325 getFixedObjectSize(MF, AFI, IsWin64, /*IsFunclet=*/false);
1326 int64_t CalleeSaveSize = AFI->getCalleeSavedStackSize(MF.getFrameInfo());
1327 int64_t FPAdjust =
1328 CalleeSaveSize - AFI->getCalleeSaveBaseToFrameRecordOffset();
1329 return StackOffset::getFixed(ObjectOffset + FixedObject + FPAdjust);
1330}
1331
1332StackOffset AArch64FrameLowering::getStackOffset(const MachineFunction &MF,
1333 int64_t ObjectOffset) const {
1334 const auto &MFI = MF.getFrameInfo();
1335 return StackOffset::getFixed(ObjectOffset + (int64_t)MFI.getStackSize());
1336}
1337
1338// TODO: This function currently does not work for scalable vectors.
1340 int FI) const {
1341 const AArch64RegisterInfo *RegInfo =
1342 MF.getSubtarget<AArch64Subtarget>().getRegisterInfo();
1343 int ObjectOffset = MF.getFrameInfo().getObjectOffset(FI);
1344 return RegInfo->getLocalAddressRegister(MF) == AArch64::FP
1345 ? getFPOffset(MF, ObjectOffset).getFixed()
1346 : getStackOffset(MF, ObjectOffset).getFixed();
1347}
1348
1350 const MachineFunction &MF, int FI, Register &FrameReg, bool PreferFP,
1351 bool ForSimm) const {
1352 const auto &MFI = MF.getFrameInfo();
1353 int64_t ObjectOffset = MFI.getObjectOffset(FI);
1354 bool isFixed = MFI.isFixedObjectIndex(FI);
1355 auto StackID = static_cast<TargetStackID::Value>(MFI.getStackID(FI));
1356 return resolveFrameOffsetReference(MF, ObjectOffset, isFixed, StackID,
1357 FrameReg, PreferFP, ForSimm);
1358}
1359
1361 const MachineFunction &MF, int64_t ObjectOffset, bool isFixed,
1362 TargetStackID::Value StackID, Register &FrameReg, bool PreferFP,
1363 bool ForSimm) const {
1364 const auto &MFI = MF.getFrameInfo();
1365 const auto &Subtarget = MF.getSubtarget<AArch64Subtarget>();
1366 const AArch64RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
1367 const auto *AFI = MF.getInfo<AArch64FunctionInfo>();
1368
1369 int64_t FPOffset = getFPOffset(MF, ObjectOffset).getFixed();
1370 int64_t Offset = getStackOffset(MF, ObjectOffset).getFixed();
1371
1372 // The fixed object area sits above the callee-saved area and can grow
1373 // large enough to displace it; account for that displacement here so CSR
1374 // objects aren't misclassified as locals and addressed via the base
1375 // pointer.
1376 bool IsWin64 = Subtarget.isCallingConvWin64(MF.getFunction().getCallingConv(),
1377 MF.getFunction().isVarArg());
1378 const int64_t FixedObjectSize =
1379 getFixedObjectSize(MF, AFI, IsWin64, /*IsFunclet*/ false);
1380 bool isCSR =
1381 !isFixed && ObjectOffset >= -((int64_t)AFI->getCalleeSavedStackSize(MFI) +
1382 FixedObjectSize);
1383 bool isSVE = MFI.isScalableStackID(StackID);
1384
1385 StackOffset ZPRStackSize = getZPRStackSize(MF);
1386 StackOffset PPRStackSize = getPPRStackSize(MF);
1387 StackOffset SVEStackSize = ZPRStackSize + PPRStackSize;
1388
1389 // Use frame pointer to reference fixed objects. Use it for locals if
1390 // there are VLAs or a dynamically realigned SP (and thus the SP isn't
1391 // reliable as a base). Make sure useFPForScavengingIndex() does the
1392 // right thing for the emergency spill slot.
1393 bool UseFP = false;
1394 if (AFI->hasStackFrame() && !isSVE) {
1395 // We shouldn't prefer using the FP to access fixed-sized stack objects when
1396 // there are scalable (SVE) objects in between the FP and the fixed-sized
1397 // objects.
1398 PreferFP &= !SVEStackSize;
1399
1400 // Note: Keeping the following as multiple 'if' statements rather than
1401 // merging to a single expression for readability.
1402 //
1403 // Argument access should always use the FP.
1404 if (isFixed) {
1405 UseFP = hasFP(MF);
1406 } else if (isCSR && RegInfo->hasStackRealignment(MF)) {
1407 // References to the CSR area must use FP if we're re-aligning the stack
1408 // since the dynamically-sized alignment padding is between the SP/BP and
1409 // the CSR area.
1410 assert(hasFP(MF) && "Re-aligned stack must have frame pointer");
1411 UseFP = true;
1412 } else if (hasFP(MF) && !RegInfo->hasStackRealignment(MF)) {
1413 // If the FPOffset is negative and we're producing a signed immediate, we
1414 // have to keep in mind that the available offset range for negative
1415 // offsets is smaller than for positive ones. If an offset is available
1416 // via the FP and the SP, use whichever is closest.
1417 bool FPOffsetFits = !ForSimm || FPOffset >= -256;
1418 PreferFP |= Offset > -FPOffset && !SVEStackSize;
1419
1420 if (FPOffset >= 0) {
1421 // If the FPOffset is positive, that'll always be best, as the SP/BP
1422 // will be even further away.
1423 UseFP = true;
1424 } else if (MFI.hasVarSizedObjects()) {
1425 // If we have variable sized objects, we can use either FP or BP, as the
1426 // SP offset is unknown. We can use the base pointer if we have one and
1427 // FP is not preferred. If not, we're stuck with using FP.
1428 bool CanUseBP = RegInfo->hasBasePointer(MF);
1429 if (FPOffsetFits && CanUseBP) // Both are ok. Pick the best.
1430 UseFP = PreferFP;
1431 else if (!CanUseBP) // Can't use BP. Forced to use FP.
1432 UseFP = true;
1433 // else we can use BP and FP, but the offset from FP won't fit.
1434 // That will make us scavenge registers which we can probably avoid by
1435 // using BP. If it won't fit for BP either, we'll scavenge anyway.
1436 } else if (MF.hasEHFunclets() && !RegInfo->hasBasePointer(MF)) {
1437 // Funclets access the locals contained in the parent's stack frame
1438 // via the frame pointer, so we have to use the FP in the parent
1439 // function.
1440 (void) Subtarget;
1441 assert(Subtarget.isCallingConvWin64(MF.getFunction().getCallingConv(),
1442 MF.getFunction().isVarArg()) &&
1443 "Funclets should only be present on Win64");
1444 UseFP = true;
1445 } else {
1446 // We have the choice between FP and (SP or BP).
1447 if (FPOffsetFits && PreferFP) // If FP is the best fit, use it.
1448 UseFP = true;
1449 }
1450 }
1451 }
1452
1453 assert(
1454 ((isFixed || isCSR) || !RegInfo->hasStackRealignment(MF) || !UseFP) &&
1455 "In the presence of dynamic stack pointer realignment, "
1456 "non-argument/CSR objects cannot be accessed through the frame pointer");
1457
1458 bool FPAfterSVECalleeSaves = hasSVECalleeSavesAboveFrameRecord(MF);
1459
1460 if (isSVE) {
1461 StackOffset FPOffset = StackOffset::get(
1462 -AFI->getCalleeSaveBaseToFrameRecordOffset(), ObjectOffset);
1463 StackOffset SPOffset =
1464 SVEStackSize +
1465 StackOffset::get(MFI.getStackSize() - AFI->getCalleeSavedStackSize(),
1466 ObjectOffset);
1467
1468 // With split SVE objects the ObjectOffset is relative to the split area
1469 // (i.e. the PPR area or ZPR area respectively).
1470 if (AFI->hasSplitSVEObjects() && StackID == TargetStackID::ScalableVector) {
1471 // If we're accessing an SVE vector with split SVE objects...
1472 // - From the FP we need to move down past the PPR area:
1473 FPOffset -= PPRStackSize;
1474 // - From the SP we only need to move up to the ZPR area:
1475 SPOffset -= PPRStackSize;
1476 // Note: `SPOffset = SVEStackSize + ...`, so `-= PPRStackSize` results in
1477 // `SPOffset = ZPRStackSize + ...`.
1478 }
1479
1480 if (FPAfterSVECalleeSaves) {
1482 if (-ObjectOffset <= (int64_t)AFI->getSVECalleeSavedStackSize()) {
1485 }
1486 }
1487
1488 // Always use the FP for SVE spills if available and beneficial.
1489 if (hasFP(MF) && (SPOffset.getFixed() ||
1490 FPOffset.getScalable() < SPOffset.getScalable() ||
1491 RegInfo->hasStackRealignment(MF))) {
1492 FrameReg = RegInfo->getFrameRegister(MF);
1493 return FPOffset;
1494 }
1495 FrameReg = RegInfo->hasBasePointer(MF) ? RegInfo->getBaseRegister()
1496 : MCRegister(AArch64::SP);
1497
1498 return SPOffset;
1499 }
1500
1501 StackOffset SVEAreaOffset = {};
1502 if (FPAfterSVECalleeSaves) {
1503 // In this stack layout, the FP is in between the callee saves and other
1504 // SVE allocations.
1505 StackOffset SVECalleeSavedStack =
1507 if (UseFP) {
1508 if (isFixed)
1509 SVEAreaOffset = SVECalleeSavedStack;
1510 else if (!isCSR)
1511 SVEAreaOffset = SVECalleeSavedStack - SVEStackSize;
1512 } else {
1513 if (isFixed)
1514 SVEAreaOffset = SVEStackSize;
1515 else if (isCSR)
1516 SVEAreaOffset = SVEStackSize - SVECalleeSavedStack;
1517 }
1518 } else {
1519 if (UseFP && !(isFixed || isCSR))
1520 SVEAreaOffset = -SVEStackSize;
1521 if (!UseFP && (isFixed || isCSR))
1522 SVEAreaOffset = SVEStackSize;
1523 }
1524
1525 if (UseFP) {
1526 FrameReg = RegInfo->getFrameRegister(MF);
1527 return StackOffset::getFixed(FPOffset) + SVEAreaOffset;
1528 }
1529
1530 // Use the base pointer if we have one.
1531 if (RegInfo->hasBasePointer(MF))
1532 FrameReg = RegInfo->getBaseRegister();
1533 else {
1534 assert(!MFI.hasVarSizedObjects() &&
1535 "Can't use SP when we have var sized objects.");
1536 FrameReg = AArch64::SP;
1537 // If we're using the red zone for this function, the SP won't actually
1538 // be adjusted, so the offsets will be negative. They're also all
1539 // within range of the signed 9-bit immediate instructions.
1540 if (canUseRedZone(MF))
1541 Offset -= AFI->getLocalStackSize();
1542 }
1543
1544 return StackOffset::getFixed(Offset) + SVEAreaOffset;
1545}
1546
1548 // Do not set a kill flag on values that are also marked as live-in. This
1549 // happens with the @llvm-returnaddress intrinsic and with arguments passed in
1550 // callee saved registers.
1551 // Omitting the kill flags is conservatively correct even if the live-in
1552 // is not used after all.
1553 bool IsLiveIn = MF.getRegInfo().isLiveIn(Reg);
1554 return getKillRegState(!IsLiveIn);
1555}
1556
1558 MachineFunction &MF) {
1559 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
1562 return Subtarget.isTargetMachO() &&
1563 !(Subtarget.getTargetLowering()->supportSwiftError() &&
1564 Attrs.hasAttrSomewhere(Attribute::SwiftError)) &&
1566 !AFL.requiresSaveVG(MF) && !AFI->isSVECC();
1567}
1568
1569static bool invalidateWindowsRegisterPairing(bool SpillExtendedVolatile,
1570 unsigned SpillCount, unsigned Reg1,
1571 unsigned Reg2, bool NeedsWinCFI,
1572 const TargetRegisterInfo *TRI) {
1573 // If we are generating register pairs for a Windows function that requires
1574 // EH support, then pair consecutive registers only. There are no unwind
1575 // opcodes for saves/restores of non-consecutive register pairs.
1576 // The unwind opcodes are save_regp, save_regp_x, save_fregp, save_frepg_x,
1577 // save_lrpair.
1578 // https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling
1579
1580 if (Reg2 == AArch64::FP)
1581 return true;
1582 if (!NeedsWinCFI)
1583 return false;
1584
1585 // ARM64EC introduced `save_any_regp`, which expects 16-byte alignment.
1586 // This is handled by only allowing paired spills for registers spilled at
1587 // even positions (which should be 16-byte aligned, as other GPRs/FPRs are
1588 // 8-bytes). We carve out an exception for {FP,LR}, which does not require
1589 // 16-byte alignment in the uop representation.
1590 if (TRI->getEncodingValue(Reg2) == TRI->getEncodingValue(Reg1) + 1)
1591 return SpillExtendedVolatile
1592 ? !((Reg1 == AArch64::FP && Reg2 == AArch64::LR) ||
1593 (SpillCount % 2) == 0)
1594 : false;
1595
1596 // If pairing a GPR with LR, the pair can be described by the save_lrpair
1597 // opcode. The save_lrpair opcode requires the first register to be odd.
1598 if (Reg1 >= AArch64::X19 && Reg1 <= AArch64::X27 &&
1599 (Reg1 - AArch64::X19) % 2 == 0 && Reg2 == AArch64::LR)
1600 return false;
1601 return true;
1602}
1603
1604/// Returns true if Reg1 and Reg2 cannot be paired using a ldp/stp instruction.
1605/// WindowsCFI requires that only consecutive registers can be paired.
1606/// LR and FP need to be allocated together when the frame needs to save
1607/// the frame-record. This means any other register pairing with LR is invalid.
1608static bool invalidateRegisterPairing(bool SpillExtendedVolatile,
1609 unsigned SpillCount, unsigned Reg1,
1610 unsigned Reg2, bool UsesWinAAPCS,
1611 bool NeedsWinCFI, bool NeedsFrameRecord,
1612 const TargetRegisterInfo *TRI) {
1613 if (UsesWinAAPCS)
1614 return invalidateWindowsRegisterPairing(SpillExtendedVolatile, SpillCount,
1615 Reg1, Reg2, NeedsWinCFI, TRI);
1616
1617 // If we need to store the frame record, don't pair any register
1618 // with LR other than FP.
1619 if (NeedsFrameRecord)
1620 return Reg2 == AArch64::LR;
1621
1622 return false;
1623}
1624
1625// Returns true if Offset (in bytes) is aligned to the instruction's scale and
1626// the scaled immediate is within the instruction's valid range.
1627static bool isValidMemOpOffset(const AArch64InstrInfo *TII, unsigned Opcode,
1628 int Offset) {
1629 int64_t MinOff, MaxOff;
1630 TypeSize ScaleValue(0U, false), Width(0U, false);
1631 if (!TII->getMemOpInfo(Opcode, ScaleValue, Width, MinOff, MaxOff))
1632 return false;
1633
1634 if (Offset % ScaleValue.getKnownMinValue() != 0)
1635 return false;
1636
1637 Offset /= ScaleValue.getKnownMinValue();
1638 return Offset >= MinOff && Offset <= MaxOff;
1639}
1640
1641namespace {
1642
1643struct RegGroupInfo {
1644 Register Reg1;
1645 Register Reg2;
1646 int FrameIdx;
1647 int Offset;
1648 enum RegType { GPR, FPR64, FPR128, PPR, ZPR, VG } Type;
1649 const TargetRegisterClass *RC;
1650
1651 RegGroupInfo() = default;
1652
1653 bool isPaired() const { return getNumRegs() == 2; }
1654
1655 bool isQuad() const { return getNumRegs() == 4; }
1656
1657 bool isGrouped() const { return isPaired() || isQuad(); }
1658
1659 unsigned getNumRegs() const {
1660 if (!Reg2.isValid())
1661 return 1;
1662 if (Type != ZPR)
1663 return 2;
1664 // ZPR groups are contiguous with Reg2 holding the lower register.
1665 unsigned NumRegs = (Reg1 - Reg2) + 1;
1666 assert(NumRegs == 2 || NumRegs == 4);
1667 return NumRegs;
1668 }
1669
1670 bool isScalable() const { return Type == PPR || Type == ZPR; }
1671
1672 SmallVector<Register, 4> getRegisters() const {
1673 if (isPaired())
1674 return {Reg1, Reg2};
1675 if (isQuad()) {
1676 assert(Reg1 - 3 == Reg2 && "Quad not contiguous");
1677 return {Reg1, Reg1 - 1, Reg1 - 2, Reg1 - 3};
1678 }
1679 return {Reg1};
1680 }
1681
1682 auto getFrameIndexes() const {
1683 return seq(FrameIdx, FrameIdx + int(getNumRegs()));
1684 }
1685
1686 Register getAsMultiVectorRegister() const {
1687 assert(Type == ZPR && isGrouped() && "Expected ZPR register group");
1688 return (isQuad() ? AArch64::Z0_Z1_Z2_Z3 : AArch64::Z0_Z1) +
1689 (Reg2 - AArch64::Z0);
1690 }
1691
1692 void dump(const TargetRegisterInfo *TRI) const {
1693 dbgs() << "(";
1694 interleaveComma(getRegisters(), dbgs(),
1695 [&](Register Reg) { dbgs() << printReg(Reg, TRI); });
1696 dbgs() << ") -> fi#(";
1697 interleaveComma(getFrameIndexes(), dbgs(),
1698 [&](int FrameIdx) { dbgs() << FrameIdx; });
1699 dbgs() << ")\n";
1700 }
1701};
1702
1703} // end anonymous namespace
1704
1706 for (unsigned PReg = AArch64::P8; PReg <= AArch64::P15; ++PReg) {
1707 if (SavedRegs.test(PReg)) {
1708 unsigned PNReg = PReg - AArch64::P0 + AArch64::PN0;
1709 return MCRegister(PNReg);
1710 }
1711 }
1712 return MCRegister();
1713}
1714
1715// The multivector LD/ST are available only for SME or SVE2p1 targets
1717 MachineFunction &MF) {
1718 if (Subtarget.getCLOpts().disable_multivector_spill_fill)
1719 return false;
1720
1721 SMEAttrs FuncAttrs = MF.getInfo<AArch64FunctionInfo>()->getSMEFnAttrs();
1722 bool IsLocallyStreaming =
1723 FuncAttrs.hasStreamingBody() && !FuncAttrs.hasStreamingInterface();
1724
1725 // Only when in streaming mode SME2 instructions can be safely used.
1726 // It is not safe to use SME2 instructions when in streaming compatible or
1727 // locally streaming mode.
1728 return Subtarget.hasSVE2p1() ||
1729 (Subtarget.hasSME2() &&
1730 (!IsLocallyStreaming && Subtarget.isStreaming()));
1731}
1732
1734 MachineFunction &MF,
1736 const TargetRegisterInfo *TRI,
1738 bool NeedsFrameRecord) {
1739
1740 if (CSI.empty())
1741 return;
1742
1743 const AArch64InstrInfo *TII =
1744 MF.getSubtarget<AArch64Subtarget>().getInstrInfo();
1745 bool IsWindows = isTargetWindows(MF);
1746 bool NeedsWinCFI = MF.needsWinCFI();
1748 unsigned StackHazardSize = getStackHazardSize(MF);
1749 MachineFrameInfo &MFI = MF.getFrameInfo();
1751 unsigned Count = CSI.size();
1752 (void)CC;
1753 // MachO's compact unwind format relies on all registers being stored in
1754 // pairs.
1755 assert((!produceCompactUnwindFrame(AFL, MF) ||
1758 (Count & 1) == 0) &&
1759 "Odd number of callee-saved regs to spill!");
1760 int ByteOffset = AFI->getCalleeSavedStackSize();
1761 int StackFillDir = -1;
1762 int RegInc = 1;
1763 unsigned FirstReg = 0;
1764 if (IsWindows) {
1765 // For WinCFI, fill the stack from the bottom up.
1766 ByteOffset = 0;
1767 StackFillDir = 1;
1768 // As the CSI array is reversed to match PrologEpilogInserter, iterate
1769 // backwards, to pair up registers starting from lower numbered registers.
1770 RegInc = -1;
1771 FirstReg = Count - 1;
1772 }
1773
1774 bool FPAfterSVECalleeSaves = AFL.hasSVECalleeSavesAboveFrameRecord(MF);
1775 // Windows AAPCS has x9-x15 as volatile registers, x16-x17 as intra-procedural
1776 // scratch, x18 as platform reserved. However, clang has extended calling
1777 // convensions such as preserve_most and preserve_all which treat these as
1778 // CSR. As such, the ARM64 unwind uOPs bias registers by 19. We use ARM64EC
1779 // uOPs which have separate restrictions. We need to check for that.
1780 //
1781 // NOTE: we currently do not account for the D registers as LLVM does not
1782 // support non-ABI compliant D register spills.
1783 bool SpillExtendedVolatile =
1784 IsWindows && llvm::any_of(CSI, [](const CalleeSavedInfo &CSI) {
1785 const auto &Reg = CSI.getReg();
1786 return Reg >= AArch64::X0 && Reg <= AArch64::X18;
1787 });
1788
1789 int ZPRByteOffset = 0;
1790 int PPRByteOffset = 0;
1791 bool SplitPPRs = AFI->hasSplitSVEObjects();
1792 if (SplitPPRs) {
1793 ZPRByteOffset = AFI->getZPRCalleeSavedStackSize();
1794 PPRByteOffset = AFI->getPPRCalleeSavedStackSize();
1795 } else if (!FPAfterSVECalleeSaves) {
1796 ZPRByteOffset =
1798 // Unused: Everything goes in ZPR space.
1799 PPRByteOffset = 0;
1800 }
1801
1802 bool NeedGapToAlignStack = AFI->hasCalleeSaveStackFreeSpace();
1803 Register LastReg = 0;
1804 bool HasCSHazardPadding = AFI->hasStackHazardSlotIndex() && !SplitPPRs;
1805
1806 auto AlignOffset = [StackFillDir](int Offset, int Align) {
1807 if (StackFillDir < 0)
1808 return alignDown(Offset, Align);
1809 return alignTo(Offset, Align);
1810 };
1811
1812 // When iterating backwards, the loop condition relies on unsigned wraparound.
1813 for (unsigned i = FirstReg; i < Count; i += RegInc) {
1814 RegGroupInfo RGI;
1815 RGI.Reg1 = CSI[i].getReg();
1816
1817 if (AArch64::GPR64RegClass.contains(RGI.Reg1)) {
1818 RGI.Type = RegGroupInfo::GPR;
1819 RGI.RC = &AArch64::GPR64RegClass;
1820 } else if (AArch64::FPR64RegClass.contains(RGI.Reg1)) {
1821 RGI.Type = RegGroupInfo::FPR64;
1822 RGI.RC = &AArch64::FPR64RegClass;
1823 } else if (AArch64::FPR128RegClass.contains(RGI.Reg1)) {
1824 RGI.Type = RegGroupInfo::FPR128;
1825 RGI.RC = &AArch64::FPR128RegClass;
1826 } else if (AArch64::ZPRRegClass.contains(RGI.Reg1)) {
1827 RGI.Type = RegGroupInfo::ZPR;
1828 RGI.RC = &AArch64::ZPRRegClass;
1829 } else if (AArch64::PPRRegClass.contains(RGI.Reg1)) {
1830 RGI.Type = RegGroupInfo::PPR;
1831 RGI.RC = &AArch64::PPRRegClass;
1832 } else if (RGI.Reg1 == AArch64::VG) {
1833 RGI.Type = RegGroupInfo::VG;
1834 RGI.RC = &AArch64::FIXED_REGSRegClass;
1835 } else {
1836 llvm_unreachable("Unsupported register class.");
1837 }
1838
1839 int &ScalableByteOffset = RGI.Type == RegGroupInfo::PPR && SplitPPRs
1840 ? PPRByteOffset
1841 : ZPRByteOffset;
1842
1843 // Add the stack hazard size as we transition from GPR->FPR CSRs.
1844 if (HasCSHazardPadding &&
1845 (!LastReg || !AArch64InstrInfo::isFpOrNEON(LastReg)) &&
1847 ByteOffset += StackFillDir * StackHazardSize;
1848 LastReg = RGI.Reg1;
1849
1850 int Scale = TRI->getSpillSize(*RGI.RC);
1851 // Add the next reg to the pair if it is in the same register class.
1852 if (unsigned(i + RegInc) < Count && !HasCSHazardPadding) {
1853 MCRegister NextReg = CSI[i + RegInc].getReg();
1854 unsigned SpillCount = NeedsWinCFI ? FirstReg - i : i;
1855 int Aligned = AlignOffset(ByteOffset, Scale);
1856 int PairOffset = IsWindows ? Aligned : Aligned + StackFillDir * 2 * Scale;
1857 bool PairFitsImmRange =
1858 PairOffset / Scale >= -64 && PairOffset / Scale <= 63;
1859 switch (RGI.Type) {
1860 case RegGroupInfo::GPR:
1861 if (AArch64::GPR64RegClass.contains(NextReg) && PairFitsImmRange &&
1862 !invalidateRegisterPairing(SpillExtendedVolatile, SpillCount,
1863 RGI.Reg1, NextReg, IsWindows,
1864 NeedsWinCFI, NeedsFrameRecord, TRI))
1865 RGI.Reg2 = NextReg;
1866 break;
1867 case RegGroupInfo::FPR64:
1868 if (AArch64::FPR64RegClass.contains(NextReg) && PairFitsImmRange &&
1869 !invalidateRegisterPairing(SpillExtendedVolatile, SpillCount,
1870 RGI.Reg1, NextReg, IsWindows,
1871 NeedsWinCFI, NeedsFrameRecord, TRI))
1872 RGI.Reg2 = NextReg;
1873 break;
1874 case RegGroupInfo::FPR128:
1875 if (AArch64::FPR128RegClass.contains(NextReg) && PairFitsImmRange)
1876 RGI.Reg2 = NextReg;
1877 break;
1878 case RegGroupInfo::PPR:
1879 break;
1880 case RegGroupInfo::ZPR: {
1881 // Windows support is possible but the order requirement is reversed.
1882 // Also, WinCFI has no support for group ZPR loads/stores yet.
1883 if (isTargetWindows(MF) || AFI->getPredicateRegForFillSpill() == 0)
1884 break;
1885
1886 // We expect to see pairs and quads in descending order (e.g. [z7, z6,
1887 // z5, z4]). We ensure this in `orderZPRCalleeSavesForGroups()`. This
1888 // is required as (for Linux) StackFillDir is negative (so we start at
1889 // higher addresses) and we need to ensure the lower register in the
1890 // pair has the lower address to store the registers in the correct
1891 // order.
1892 auto GetZPRTupleLowestReg =
1893 [&](unsigned NumRegs) -> std::optional<Register> {
1894 // Check Reg1 is the last register in a tuple.
1895 if (RGI.Reg1 % NumRegs != NumRegs - 1)
1896 return std::nullopt;
1897
1898 // Check there's enough registers for the tuple.
1899 if (i + RegInc * NumRegs > Count)
1900 return std::nullopt;
1901
1902 for (unsigned Idx = 1; Idx < NumRegs; ++Idx) {
1903 Register Reg = CSI[i + RegInc * Idx].getReg();
1904 Register ExpectedReg = RGI.Reg1 - Idx;
1905 if (Reg != ExpectedReg)
1906 return std::nullopt;
1907 }
1908
1909 return RGI.Reg1 - NumRegs + 1;
1910 };
1911
1912 for (unsigned TupleSize : {4, 2}) {
1913 if (auto LowReg = GetZPRTupleLowestReg(TupleSize)) {
1914 // Note: ST1B has the same offset constraints.
1915 unsigned Opcode =
1916 TupleSize == 4 ? AArch64::LD1B_4Z_IMM : AArch64::LD1B_2Z_IMM;
1917 const int Offset =
1918 (ScalableByteOffset + StackFillDir * TupleSize * Scale);
1919 if (isValidMemOpOffset(TII, Opcode, Offset)) {
1920 RGI.Reg2 = *LowReg;
1921 break;
1922 }
1923 }
1924 }
1925
1926 break;
1927 }
1928 case RegGroupInfo::VG:
1929 break;
1930 }
1931 }
1932
1933 // GPRs and FPRs are saved in pairs of 64-bit regs. We expect the CSI
1934 // list to come in sorted by frame index so that we can issue the store
1935 // pair instructions directly. Assert if we see anything otherwise.
1936 //
1937 // The order of the registers in the list is controlled by
1938 // getCalleeSavedRegs(), so they will always be in-order, as well.
1939 [[maybe_unused]] bool RegsOrdered =
1940 all_of(seq(RGI.getNumRegs() - 1), [&](int RegOffset) {
1941 return CSI[i + RegInc * RegOffset].getFrameIdx() + RegInc ==
1942 CSI[i + RegInc * RegOffset + RegInc].getFrameIdx();
1943 });
1944 assert(RegsOrdered && "Out of order callee saved regs!");
1945
1946 assert((!RGI.isQuad() || RGI.Type == RegGroupInfo::ZPR) &&
1947 "Currently only ZPR's support four-register spills");
1948
1949 assert((!RGI.isPaired() || !NeedsFrameRecord || RGI.Reg2 != AArch64::FP ||
1950 RGI.Reg1 == AArch64::LR) &&
1951 "FrameRecord must be allocated together with LR");
1952
1953 // Windows AAPCS has FP and LR reversed.
1954 assert((!RGI.isPaired() || !NeedsFrameRecord || RGI.Reg1 != AArch64::FP ||
1955 RGI.Reg2 == AArch64::LR) &&
1956 "FrameRecord must be allocated together with LR");
1957
1958 // MachO's compact unwind format relies on all registers being stored in
1959 // adjacent register pairs.
1960 assert((!produceCompactUnwindFrame(AFL, MF) ||
1963 (RGI.isPaired() &&
1964 ((RGI.Reg1 == AArch64::LR && RGI.Reg2 == AArch64::FP) ||
1965 RGI.Reg1 + 1 == RGI.Reg2))) &&
1966 "Callee-save registers not saved as adjacent register pair!");
1967
1968 RGI.FrameIdx = CSI[i].getFrameIdx();
1969 if (IsWindows)
1970 // RGI.FrameIdx must be the lower index of the group
1971 RGI.FrameIdx = CSI[i + RegInc * (RGI.getNumRegs() - 1)].getFrameIdx();
1972
1973 // Realign the scalable offset if necessary. This is relevant when spilling
1974 // predicates on Windows.
1975 if (RGI.isScalable() && ScalableByteOffset % Scale != 0)
1976 ScalableByteOffset = AlignOffset(ScalableByteOffset, Scale);
1977
1978 // Realign the fixed offset if necessary. This is relevant when spilling Q
1979 // registers after spilling an odd amount of X registers.
1980 if (!RGI.isScalable() && ByteOffset % Scale != 0)
1981 ByteOffset = AlignOffset(ByteOffset, Scale);
1982
1983 int OffsetPre = RGI.isScalable() ? ScalableByteOffset : ByteOffset;
1984 assert(OffsetPre % Scale == 0);
1985
1986 if (RGI.isScalable())
1987 ScalableByteOffset += StackFillDir * RGI.getNumRegs() * Scale;
1988 else
1989 ByteOffset += StackFillDir * RGI.getNumRegs() * Scale;
1990
1991 // Swift's async context is directly before FP, so allocate an extra
1992 // 8 bytes for it.
1993 if (NeedsFrameRecord && AFI->hasSwiftAsyncContext() &&
1994 ((!IsWindows && RGI.Reg2 == AArch64::FP) ||
1995 (IsWindows && RGI.Reg2 == AArch64::LR)))
1996 ByteOffset += StackFillDir * 8;
1997
1998 // Round up size of non-pair to pair size if we need to pad the
1999 // callee-save area to ensure 16-byte alignment.
2000 if (NeedGapToAlignStack && !IsWindows && !RGI.isScalable() &&
2001 RGI.Type != RegGroupInfo::FPR128 && !RGI.isPaired() &&
2002 ByteOffset % 16 != 0) {
2003 ByteOffset += 8 * StackFillDir;
2004 assert(MFI.getObjectAlign(RGI.FrameIdx) <= Align(16));
2005 // A stack frame with a gap looks like this, bottom up:
2006 // d9, d8. x21, gap, x20, x19.
2007 // Set extra alignment on the x21 object to create the gap above it.
2008 MFI.setObjectAlignment(RGI.FrameIdx, Align(16));
2009 NeedGapToAlignStack = false;
2010 }
2011
2012 int OffsetPost = RGI.isScalable() ? ScalableByteOffset : ByteOffset;
2013 assert(OffsetPost % Scale == 0);
2014 // If filling top down (default), we want the offset after incrementing it.
2015 // If filling bottom up (WinCFI) we need the original offset.
2016 int Offset = IsWindows ? OffsetPre : OffsetPost;
2017
2018 // The FP, LR pair goes 8 bytes into our expanded 24-byte slot so that the
2019 // Swift context can directly precede FP.
2020 if (NeedsFrameRecord && AFI->hasSwiftAsyncContext() &&
2021 ((!IsWindows && RGI.Reg2 == AArch64::FP) ||
2022 (IsWindows && RGI.Reg2 == AArch64::LR)))
2023 Offset += 8;
2024
2025 assert(
2026 (!RGI.isGrouped() || RGI.Type != RegGroupInfo::ZPR ||
2028 TII, (RGI.isQuad() ? AArch64::LD1B_4Z_IMM : AArch64::LD1B_2Z_IMM),
2029 Offset)) &&
2030 "Offset invalid for LD1B/ST1B pair/quad variant immediate");
2031
2032 RGI.Offset = Offset / Scale;
2033 assert((!RGI.isGrouped() || RGI.Type == RegGroupInfo::ZPR ||
2034 (!RGI.isScalable() && RGI.Offset >= -64 && RGI.Offset <= 63) ||
2035 (RGI.isScalable() && RGI.Offset >= -256 && RGI.Offset <= 255)) &&
2036 "Offset out of bounds for LDP/STP immediate");
2037
2038 auto isFrameRecord = [&] {
2039 if (RGI.isPaired())
2040 return IsWindows ? RGI.Reg1 == AArch64::FP && RGI.Reg2 == AArch64::LR
2041 : RGI.Reg1 == AArch64::LR && RGI.Reg2 == AArch64::FP;
2042 // Otherwise, look for the frame record as two unpaired registers. This is
2043 // needed for -aarch64-stack-hazard-size=<val>, which disables register
2044 // pairing (as the padding may be too large for the LDP/STP offset). Note:
2045 // On Windows, this check works out as current reg == FP, next reg == LR,
2046 // and on other platforms current reg == FP, previous reg == LR. This
2047 // works out as the correct pre-increment or post-increment offsets
2048 // respectively.
2049 return i > 0 && RGI.Reg1 == AArch64::FP &&
2050 CSI[i - 1].getReg() == AArch64::LR;
2051 };
2052
2053 // Save the offset to frame record so that the FP register can point to the
2054 // innermost frame record (spilled FP and LR registers).
2055 if (NeedsFrameRecord && isFrameRecord())
2057
2058 RegGroups.push_back(RGI);
2059 i += RegInc * (RGI.getNumRegs() - 1);
2060 }
2061 if (IsWindows) {
2062 // If we need an alignment gap in the stack, align the topmost stack
2063 // object. A stack frame with a gap looks like this, bottom up:
2064 // x19, d8. d9, gap.
2065 // Set extra alignment on the topmost stack object (the first element in
2066 // CSI, which goes top down), to create the gap above it.
2067 if (AFI->hasCalleeSaveStackFreeSpace())
2068 MFI.setObjectAlignment(CSI[0].getFrameIdx(), Align(16));
2069 // We iterated bottom up over the registers; flip RegGroups back to top
2070 // down order.
2071 std::reverse(RegGroups.begin(), RegGroups.end());
2072 }
2073}
2074
2078 MachineFunction &MF = *MBB.getParent();
2079 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
2080 auto &TLI = *Subtarget.getTargetLowering();
2081 const AArch64InstrInfo &TII = *Subtarget.getInstrInfo();
2082 bool NeedsWinCFI = MF.needsWinCFI();
2083 DebugLoc DL;
2085
2086 computeCalleeSaveRegisterGroups(*this, MF, CSI, TRI, RegGroups, hasFP(MF));
2087
2089 // Refresh the reserved regs in case there are any potential changes since the
2090 // last freeze.
2091 MRI.freezeReservedRegs();
2092
2093 if (homogeneousPrologEpilog(MF)) {
2094 auto MIB = BuildMI(MBB, MI, DL, TII.get(AArch64::HOM_Prolog))
2096
2097 for (auto &RGI : RegGroups) {
2098 MIB.addReg(RGI.Reg1);
2099 MIB.addReg(RGI.Reg2);
2100
2101 // Update register live in.
2102 if (!MRI.isReserved(RGI.Reg1))
2103 MBB.addLiveIn(RGI.Reg1);
2104 if (RGI.isPaired() && !MRI.isReserved(RGI.Reg2))
2105 MBB.addLiveIn(RGI.Reg2);
2106 }
2107 return true;
2108 }
2109 bool PTrueCreated = false;
2110 for (const RegGroupInfo &RGI : llvm::reverse(RegGroups)) {
2111 Register Reg1 = RGI.Reg1;
2112 Register Reg2 = RGI.Reg2;
2113 unsigned StrOpc;
2114
2115 // Issue sequence of spills for cs regs. The first spill may be converted
2116 // to a pre-decrement store later by emitPrologue if the callee-save stack
2117 // area allocation can't be combined with the local stack area allocation.
2118 // For example:
2119 // stp x22, x21, [sp, #0] // addImm(+0)
2120 // stp x20, x19, [sp, #16] // addImm(+2)
2121 // stp fp, lr, [sp, #32] // addImm(+4)
2122 // Rationale: This sequence saves uop updates compared to a sequence of
2123 // pre-increment spills like stp xi,xj,[sp,#-16]!
2124 // Note: Similar rationale and sequence for restores in epilog.
2125 unsigned Size = TRI->getSpillSize(*RGI.RC);
2126 Align Alignment = TRI->getSpillAlign(*RGI.RC);
2127 switch (RGI.Type) {
2128 case RegGroupInfo::GPR:
2129 StrOpc = RGI.isPaired() ? AArch64::STPXi : AArch64::STRXui;
2130 break;
2131 case RegGroupInfo::FPR64:
2132 StrOpc = RGI.isPaired() ? AArch64::STPDi : AArch64::STRDui;
2133 break;
2134 case RegGroupInfo::FPR128:
2135 StrOpc = RGI.isPaired() ? AArch64::STPQi : AArch64::STRQui;
2136 break;
2137 case RegGroupInfo::ZPR:
2138 StrOpc = RGI.isQuad()
2139 ? AArch64::ST1B_4Z_IMM
2140 : (RGI.isPaired() ? AArch64::ST1B_2Z_IMM : AArch64::STR_ZXI);
2141 break;
2142 case RegGroupInfo::PPR:
2143 StrOpc = AArch64::STR_PXI;
2144 break;
2145 case RegGroupInfo::VG:
2146 StrOpc = AArch64::STRXui;
2147 break;
2148 }
2149
2150 Register X0Scratch;
2151 llvm::scope_exit RestoreX0([&] {
2152 if (X0Scratch.isValid())
2153 BuildMI(MBB, MI, DL, TII.get(TargetOpcode::COPY), AArch64::X0)
2154 .addReg(X0Scratch)
2156 });
2157
2158 if (Reg1 == AArch64::VG) {
2159 // Find an available register to store value of VG to.
2160 Reg1 = findScratchNonCalleeSaveRegister(&MBB, true);
2161 assert(Reg1.isValid());
2162 if (MF.getSubtarget<AArch64Subtarget>().hasSVE()) {
2163 BuildMI(MBB, MI, DL, TII.get(AArch64::CNTD_XPiI), Reg1)
2164 .addImm(31)
2165 .addImm(1)
2167 } else {
2169 if (any_of(MBB.liveins(),
2170 [&STI](const MachineBasicBlock::RegisterMaskPair &LiveIn) {
2171 return STI.getRegisterInfo()->isSuperOrSubRegisterEq(
2172 AArch64::X0, LiveIn.PhysReg);
2173 })) {
2174 X0Scratch = Reg1;
2175 BuildMI(MBB, MI, DL, TII.get(TargetOpcode::COPY), X0Scratch)
2176 .addReg(AArch64::X0)
2178 }
2179
2180 RTLIB::Libcall LC = RTLIB::SMEABI_GET_CURRENT_VG;
2181 const uint32_t *RegMask =
2182 TRI->getCallPreservedMask(MF, TLI.getLibcallCallingConv(LC));
2183 BuildMI(MBB, MI, DL, TII.get(AArch64::BL))
2184 .addExternalSymbol(TLI.getLibcallName(LC))
2185 .addRegMask(RegMask)
2186 .addReg(AArch64::X0, RegState::ImplicitDefine)
2188 Reg1 = AArch64::X0;
2189 }
2190 }
2191
2192 LLVM_DEBUG(dbgs() << "CSR spill: ");
2193 LLVM_DEBUG(RGI.dump(TRI));
2194
2195 assert((!isTargetWindows(MF) ||
2196 !(Reg1 == AArch64::LR && Reg2 == AArch64::FP)) &&
2197 "Windows unwdinding requires a consecutive (FP,LR) pair");
2198
2200 unsigned PnReg = AFI->getPredicateRegForFillSpill();
2201
2202 if (!PTrueCreated && RGI.isGrouped() && RGI.isScalable()) {
2203 [[maybe_unused]] const AArch64Subtarget &Subtarget =
2205 assert((PnReg != 0 && enableMultiVectorSpillFill(Subtarget, MF)) &&
2206 "Expects SVE2.1 or SME2 target and a predicate register");
2207 PTrueCreated = true;
2208 BuildMI(MBB, MI, DL, TII.get(AArch64::PTRUE_C_B), PnReg)
2210 }
2211
2212 SmallVector<Register, 4> Registers = RGI.getRegisters();
2214 if (!MRI.isReserved(Reg))
2215 MBB.addLiveIn(Reg);
2216
2217 MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(StrOpc));
2218 if (RGI.isGrouped() && RGI.isScalable()) {
2219 assert(!isTargetWindows(MF) &&
2220 "Scalable register groups are not supported by Windows CFI yet");
2221#ifdef EXPENSIVE_CHECKS
2222 auto IsPPR = [](const RegGroupInfo &c) {
2223 return c.Type == RegGroupInfo::PPR;
2224 };
2225 auto PPRBegin = std::find_if(RegGroups.begin(), RegGroups.end(), IsPPR);
2226 auto IsZPR = [](const RegGroupInfo &c) {
2227 return c.Type == RegGroupInfo::ZPR;
2228 };
2229 auto ZPRBegin = std::find_if(RegGroups.begin(), RegGroups.end(), IsZPR);
2230 assert(!(PPRBegin < ZPRBegin) &&
2231 "Expected callee save predicate to be handled first");
2232#endif
2233
2234 assert(RGI.Reg2 < RGI.Reg1 && "Expected reversed ZPR group");
2235 MIB.addReg(RGI.getAsMultiVectorRegister());
2236
2237 MIB.addReg(PnReg);
2238 MIB.addReg(AArch64::SP)
2239 .addImm(RGI.Offset /
2240 RGI.getNumRegs()) // [sp, #imm*size*vscale],
2241 // where size*vscale is implicit
2243 } else { // The code when the pair of ZReg is not present
2244 // Windows unwind codes require consecutive registers if registers are
2245 // paired. Make the switch here, so that the code below will save (x,x+1)
2246 // and not (x+1,x).
2247 if (isTargetWindows(MF) && RGI.isPaired())
2248 std::swap(Reg1, Reg2);
2249 if (RGI.isPaired()) {
2250 MIB.addReg(Reg2, getPrologueDeath(MF, Reg2));
2251 }
2252 MIB.addReg(Reg1, getPrologueDeath(MF, Reg1))
2253 .addReg(AArch64::SP)
2254 .addImm(RGI.Offset) // [sp, #offset*vscale],
2255 // where factor*vscale is implicit
2257 if (NeedsWinCFI)
2258 insertSEH(MIB, TII, MachineInstr::FrameSetup);
2259 }
2260
2261 // Handle the StackIDs.
2262 MachineFrameInfo &MFI = MF.getFrameInfo();
2263 for (int FI :
2264 reverse_conditionally(RGI.getFrameIndexes(), !isTargetWindows(MF))) {
2265 MIB.addMemOperand(
2267 MachineMemOperand::MOStore, Size, Alignment));
2268 if (RGI.Type == RegGroupInfo::ZPR)
2270 else if (RGI.Type == RegGroupInfo::PPR)
2272 }
2273 }
2274 return true;
2275}
2276
2280 MachineFunction &MF = *MBB.getParent();
2281 const AArch64InstrInfo &TII =
2282 *MF.getSubtarget<AArch64Subtarget>().getInstrInfo();
2283 DebugLoc DL;
2285 bool NeedsWinCFI = MF.needsWinCFI();
2286
2287 if (MBBI != MBB.end())
2288 DL = MBBI->getDebugLoc();
2289
2290 computeCalleeSaveRegisterGroups(*this, MF, CSI, TRI, RegGroups, hasFP(MF));
2291 if (homogeneousPrologEpilog(MF, &MBB)) {
2292 auto MIB = BuildMI(MBB, MBBI, DL, TII.get(AArch64::HOM_Epilog))
2294 for (auto &RGI : RegGroups) {
2295 MIB.addReg(RGI.Reg1, RegState::Define);
2296 MIB.addReg(RGI.Reg2, RegState::Define);
2297 }
2298 return true;
2299 }
2300
2301 // For performance reasons restore SVE register in increasing order
2302 auto IsPPR = [](const RegGroupInfo &c) {
2303 return c.Type == RegGroupInfo::PPR;
2304 };
2305 auto PPRBegin = llvm::find_if(RegGroups, IsPPR);
2306 auto PPREnd = std::find_if_not(PPRBegin, RegGroups.end(), IsPPR);
2307 std::reverse(PPRBegin, PPREnd);
2308 auto IsZPR = [](const RegGroupInfo &c) {
2309 return c.Type == RegGroupInfo::ZPR;
2310 };
2311 auto ZPRBegin = llvm::find_if(RegGroups, IsZPR);
2312 auto ZPREnd = std::find_if_not(ZPRBegin, RegGroups.end(), IsZPR);
2313 std::reverse(ZPRBegin, ZPREnd);
2314
2315 // If the return address is authenticated before the epilogue, it stays in LR
2316 // rather than being restored here, as that would replace it with the
2317 // unauthenticated value from the stack.
2318 bool KeepLR = authenticatesReturnAddressEarly(MF, MBB);
2319
2320 bool PTrueCreated = false;
2321 for (const RegGroupInfo &RGI : RegGroups) {
2322 Register Reg1 = RGI.Reg1;
2323 Register Reg2 = RGI.Reg2;
2324
2325 // Issue sequence of restores for cs regs. The last restore may be converted
2326 // to a post-increment load later by emitEpilogue if the callee-save stack
2327 // area allocation can't be combined with the local stack area allocation.
2328 // For example:
2329 // ldp fp, lr, [sp, #32] // addImm(+4)
2330 // ldp x20, x19, [sp, #16] // addImm(+2)
2331 // ldp x22, x21, [sp, #0] // addImm(+0)
2332 // Note: see comment in spillCalleeSavedRegisters()
2333 unsigned LdrOpc;
2334 unsigned Size = TRI->getSpillSize(*RGI.RC);
2335 Align Alignment = TRI->getSpillAlign(*RGI.RC);
2336 switch (RGI.Type) {
2337 case RegGroupInfo::GPR:
2338 LdrOpc = RGI.isPaired() ? AArch64::LDPXi : AArch64::LDRXui;
2339 break;
2340 case RegGroupInfo::FPR64:
2341 LdrOpc = RGI.isPaired() ? AArch64::LDPDi : AArch64::LDRDui;
2342 break;
2343 case RegGroupInfo::FPR128:
2344 LdrOpc = RGI.isPaired() ? AArch64::LDPQi : AArch64::LDRQui;
2345 break;
2346 case RegGroupInfo::ZPR:
2347 LdrOpc = RGI.isQuad()
2348 ? AArch64::LD1B_4Z_IMM
2349 : (RGI.isPaired() ? AArch64::LD1B_2Z_IMM : AArch64::LDR_ZXI);
2350 break;
2351 case RegGroupInfo::PPR:
2352 LdrOpc = AArch64::LDR_PXI;
2353 break;
2354 case RegGroupInfo::VG:
2355 continue;
2356 }
2357
2358 LLVM_DEBUG(dbgs() << "CSR restore: ");
2359 LLVM_DEBUG(RGI.dump(TRI));
2360
2362 unsigned PnReg = AFI->getPredicateRegForFillSpill();
2363
2364 if (!PTrueCreated && RGI.isGrouped() && RGI.isScalable()) {
2365 [[maybe_unused]] const AArch64Subtarget &Subtarget =
2367 assert((PnReg != 0 && enableMultiVectorSpillFill(Subtarget, MF)) &&
2368 "Expects SVE2.1 or SME2 target and a predicate register");
2369 PTrueCreated = true;
2370 BuildMI(MBB, MBBI, DL, TII.get(AArch64::PTRUE_C_B), PnReg)
2372 }
2373
2374 if (KeepLR && RGI.Type == RegGroupInfo::GPR &&
2375 (Reg1 == AArch64::LR || Reg2 == AArch64::LR)) {
2376 // Windows pairs LR with the register before it, which is the one at the
2377 // lower address, so restore just that register. The pair has not been
2378 // swapped yet at this point, so that register is Reg1.
2379 if (!RGI.isPaired())
2380 continue;
2381 assert(Reg2 == AArch64::LR && "Expected LR to be the second of the pair");
2383 BuildMI(MBB, MBBI, DL, TII.get(AArch64::LDRXui));
2384 MIB.addReg(Reg1, getDefRegState(true));
2385 MIB.addReg(AArch64::SP)
2386 .addImm(RGI.Offset)
2389 MachinePointerInfo::getFixedStack(MF, RGI.FrameIdx),
2391 if (NeedsWinCFI)
2392 insertSEH(MIB, TII, MachineInstr::FrameDestroy);
2393 continue;
2394 }
2395
2396 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII.get(LdrOpc));
2397 if (RGI.isGrouped() && RGI.isScalable()) {
2398 assert(!isTargetWindows(MF) &&
2399 "Scalable register groups are not supported by Windows CFI yet");
2400#ifdef EXPENSIVE_CHECKS
2401 assert(!(PPRBegin < ZPRBegin) &&
2402 "Expected callee save predicate to be handled first");
2403#endif
2404 assert(RGI.Reg2 < RGI.Reg1 && "Expected reversed ZPR group");
2405 MIB.addReg(RGI.getAsMultiVectorRegister(), getDefRegState(true));
2406 MIB.addReg(PnReg);
2407 MIB.addReg(AArch64::SP)
2408 .addImm(RGI.Offset /
2409 RGI.getNumRegs()) // [sp, #imm*size*vscale]
2410 // where size*vscale is implicit
2412 } else {
2413 // Windows unwind codes require consecutive registers if registers are
2414 // paired. Make the switch here, so that the code below will save (x,x+1)
2415 // and not (x+1,x).
2416 if (isTargetWindows(MF) && RGI.isPaired())
2417 std::swap(Reg1, Reg2);
2418 if (RGI.isPaired())
2419 MIB.addReg(Reg2, getDefRegState(true));
2420 MIB.addReg(Reg1, getDefRegState(true));
2421 MIB.addReg(AArch64::SP)
2422 .addImm(RGI.Offset) // [sp, #offset*vscale]
2423 // where factor*vscale is implicit
2425 if (NeedsWinCFI)
2426 insertSEH(MIB, TII, MachineInstr::FrameDestroy);
2427 }
2428
2429 for (int FI :
2430 reverse_conditionally(RGI.getFrameIndexes(), !isTargetWindows(MF)))
2431 MIB.addMemOperand(
2433 MachineMemOperand::MOLoad, Size, Alignment));
2434 }
2435 return true;
2436}
2437
2438// Return the FrameID for a MMO.
2439static std::optional<int> getMMOFrameID(MachineMemOperand *MMO,
2440 const MachineFrameInfo &MFI) {
2441 auto *PSV =
2443 if (PSV)
2444 return std::optional<int>(PSV->getFrameIndex());
2445
2446 if (MMO->getValue()) {
2447 if (auto *Al = dyn_cast<AllocaInst>(getUnderlyingObject(MMO->getValue()))) {
2448 for (int FI = MFI.getObjectIndexBegin(); FI < MFI.getObjectIndexEnd();
2449 FI++)
2450 if (MFI.getObjectAllocation(FI) == Al)
2451 return FI;
2452 }
2453 }
2454
2455 return std::nullopt;
2456}
2457
2458// Return the FrameID for a Load/Store instruction by looking at the first MMO.
2459static std::optional<int> getLdStFrameID(const MachineInstr &MI,
2460 const MachineFrameInfo &MFI) {
2461 if (!MI.mayLoadOrStore() || MI.getNumMemOperands() < 1)
2462 return std::nullopt;
2463
2464 return getMMOFrameID(*MI.memoperands_begin(), MFI);
2465}
2466
2467// Returns true if the LDST MachineInstr \p MI is a PPR access.
2468static bool isPPRAccess(const MachineInstr &MI) {
2469 return AArch64::PPRRegClass.contains(MI.getOperand(0).getReg());
2470}
2471
2472// Check if a Hazard slot is needed for the current function, and if so create
2473// one for it. The index is stored in AArch64FunctionInfo->StackHazardSlotIndex,
2474// which can be used to determine if any hazard padding is needed.
2475void AArch64FrameLowering::determineStackHazardSlot(
2476 MachineFunction &MF, BitVector &SavedRegs) const {
2477 unsigned StackHazardSize = getStackHazardSize(MF);
2478 auto *AFI = MF.getInfo<AArch64FunctionInfo>();
2479 if (StackHazardSize == 0 || StackHazardSize % 16 != 0 ||
2481 return;
2482
2483 // Stack hazards are only needed in streaming functions.
2484 SMEAttrs Attrs = AFI->getSMEFnAttrs();
2485 const AArch64Options &CLOpts =
2486 MF.getSubtarget<AArch64Subtarget>().getCLOpts();
2487 if (!CLOpts.stack_hazard_in_non_streaming &&
2488 Attrs.hasNonStreamingInterfaceAndBody())
2489 return;
2490
2491 MachineFrameInfo &MFI = MF.getFrameInfo();
2492
2493 // Add a hazard slot if there are any CSR FPR registers, or are any fp-only
2494 // stack objects.
2495 bool HasFPRCSRs = any_of(SavedRegs.set_bits(), [](unsigned Reg) {
2496 return AArch64::FPR64RegClass.contains(Reg) ||
2497 AArch64::FPR128RegClass.contains(Reg) ||
2498 AArch64::ZPRRegClass.contains(Reg);
2499 });
2500 bool HasPPRCSRs = any_of(SavedRegs.set_bits(), [](unsigned Reg) {
2501 return AArch64::PPRRegClass.contains(Reg);
2502 });
2503 bool HasFPRStackObjects = false;
2504 bool HasPPRStackObjects = false;
2505 if (!HasFPRCSRs || CLOpts.split_sve_objects) {
2506 enum SlotType : uint8_t {
2507 Unknown = 0,
2508 ZPRorFPR = 1 << 0,
2509 PPR = 1 << 1,
2510 GPR = 1 << 2,
2512 };
2513
2514 // Find stack slots solely used for one kind of register (ZPR, PPR, etc.),
2515 // based on the kinds of accesses used in the function.
2516 SmallVector<SlotType> SlotTypes(MFI.getObjectIndexEnd(), SlotType::Unknown);
2517 for (auto &MBB : MF) {
2518 for (auto &MI : MBB) {
2519 std::optional<int> FI = getLdStFrameID(MI, MFI);
2520 if (!FI || FI < 0 || FI > int(SlotTypes.size()))
2521 continue;
2522 if (MFI.hasScalableStackID(*FI)) {
2523 SlotTypes[*FI] |=
2524 isPPRAccess(MI) ? SlotType::PPR : SlotType::ZPRorFPR;
2525 } else {
2526 SlotTypes[*FI] |= AArch64InstrInfo::isFpOrNEON(MI)
2527 ? SlotType::ZPRorFPR
2528 : SlotType::GPR;
2529 }
2530 }
2531 }
2532
2533 for (int FI = 0; FI < int(SlotTypes.size()); ++FI) {
2534 HasFPRStackObjects |= SlotTypes[FI] == SlotType::ZPRorFPR;
2535 // For SplitSVEObjects remember that this stack slot is a predicate, this
2536 // will be needed later when determining the frame layout.
2537 if (SlotTypes[FI] == SlotType::PPR) {
2539 HasPPRStackObjects = true;
2540 }
2541 }
2542 }
2543
2544 if (HasFPRCSRs || HasFPRStackObjects) {
2545 int ID = MFI.CreateStackObject(StackHazardSize, Align(16), false);
2546 LLVM_DEBUG(dbgs() << "Created Hazard slot at " << ID << " size "
2547 << StackHazardSize << "\n");
2548 AFI->setStackHazardSlotIndex(ID);
2549 }
2550
2551 if (!AFI->hasStackHazardSlotIndex())
2552 return;
2553
2554 if (CLOpts.split_sve_objects) {
2555 CallingConv::ID CC = MF.getFunction().getCallingConv();
2557 AFI->setSplitSVEObjects(true);
2558 LLVM_DEBUG(dbgs() << "Using SplitSVEObjects for SVE CC function\n");
2559 return;
2560 }
2561
2562 // We only use SplitSVEObjects in non-SVE CC functions if there's a
2563 // possibility of a stack hazard between PPRs and ZPRs/FPRs.
2564 LLVM_DEBUG(dbgs() << "Determining if SplitSVEObjects should be used in "
2565 "non-SVE CC function...\n");
2566
2567 // If another calling convention is explicitly set FPRs can't be promoted to
2568 // ZPR callee-saves.
2570 LLVM_DEBUG(
2571 dbgs()
2572 << "Calling convention is not supported with SplitSVEObjects\n");
2573 return;
2574 }
2575
2576 if (!HasPPRCSRs && !HasPPRStackObjects) {
2577 LLVM_DEBUG(
2578 dbgs() << "Not using SplitSVEObjects as no PPRs are on the stack\n");
2579 return;
2580 }
2581
2582 if (!HasFPRCSRs && !HasFPRStackObjects) {
2583 LLVM_DEBUG(
2584 dbgs()
2585 << "Not using SplitSVEObjects as no FPRs or ZPRs are on the stack\n");
2586 return;
2587 }
2588
2589 [[maybe_unused]] const AArch64Subtarget &Subtarget =
2590 MF.getSubtarget<AArch64Subtarget>();
2592 "Expected SVE to be available for PPRs");
2593
2594 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
2595 // With SplitSVEObjects the CS hazard padding is placed between the
2596 // PPRs and ZPRs. If there are any FPR CS there would be a hazard between
2597 // them and the CS GRPs. Avoid this by promoting all FPR CS to ZPRs.
2598 BitVector FPRZRegs(SavedRegs.size());
2599 for (size_t Reg = 0, E = SavedRegs.size(); HasFPRCSRs && Reg < E; ++Reg) {
2600 BitVector::reference RegBit = SavedRegs[Reg];
2601 if (!RegBit)
2602 continue;
2603 unsigned SubRegIdx = 0;
2604 if (AArch64::FPR64RegClass.contains(Reg))
2605 SubRegIdx = AArch64::dsub;
2606 else if (AArch64::FPR128RegClass.contains(Reg))
2607 SubRegIdx = AArch64::zsub;
2608 else
2609 continue;
2610 // Clear the bit for the FPR save.
2611 RegBit = false;
2612 // Mark that we should save the corresponding ZPR.
2613 Register ZReg =
2614 TRI->getMatchingSuperReg(Reg, SubRegIdx, &AArch64::ZPRRegClass);
2615 FPRZRegs.set(ZReg);
2616 }
2617 SavedRegs |= FPRZRegs;
2618
2619 AFI->setSplitSVEObjects(true);
2620 LLVM_DEBUG(dbgs() << "SplitSVEObjects enabled!\n");
2621 }
2622}
2623
2625 BitVector &SavedRegs,
2626 RegScavenger *RS) const {
2628 // All calls are tail calls in GHC calling conv, and functions have no
2629 // prologue/epilogue.
2632 AFI->setSVECalleeSavedStackSize(/*ZPR=*/0, /*PPR=*/0);
2633 return;
2634 }
2635
2636 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
2637
2639 const AArch64RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
2640 Register UnspilledCSGPR;
2641 Register UnspilledCSGPRPaired;
2642
2643 MachineFrameInfo &MFI = MF.getFrameInfo();
2644 const MCPhysReg *CSRegs = MF.getRegInfo().getCalleeSavedRegs();
2645
2646 MCRegister BasePointerReg =
2647 RegInfo->hasBasePointer(MF) ? RegInfo->getBaseRegister() : MCRegister();
2648
2649 Register ExtraCSSpill;
2650 bool HasUnpairedGPR64 = false;
2651 bool HasPairZReg = false;
2652 BitVector UserReservedRegs = RegInfo->getUserReservedRegs(MF);
2653 BitVector ReservedRegs = RegInfo->getReservedRegs(MF);
2654
2655 // Figure out which callee-saved registers to save/restore.
2656 for (unsigned i = 0; CSRegs[i]; ++i) {
2657 const MCRegister Reg = CSRegs[i];
2658
2659 // Add the base pointer register to SavedRegs if it is callee-save.
2660 if (Reg == BasePointerReg)
2661 SavedRegs.set(Reg);
2662
2663 // Don't save manually reserved registers set through +reserve-x#i,
2664 // even for callee-saved registers, as per GCC's behavior.
2665 if (UserReservedRegs[Reg]) {
2666 SavedRegs.reset(Reg);
2667 continue;
2668 }
2669
2670 bool RegUsed = SavedRegs.test(Reg);
2671 MCRegister PairedReg;
2672 const bool RegIsGPR64 = AArch64::GPR64RegClass.contains(Reg);
2673 if (RegIsGPR64 || AArch64::FPR64RegClass.contains(Reg) ||
2674 AArch64::FPR128RegClass.contains(Reg)) {
2675 // Compensate for odd numbers of GP CSRs.
2676 // For now, all the known cases of odd number of CSRs are of GPRs.
2677 if (HasUnpairedGPR64)
2678 PairedReg = CSRegs[i % 2 == 0 ? i - 1 : i + 1];
2679 else
2680 PairedReg = CSRegs[i ^ 1];
2681 }
2682
2683 // If the function requires all the GP registers to save (SavedRegs),
2684 // and there are an odd number of GP CSRs at the same time (CSRegs),
2685 // PairedReg could be in a different register class from Reg, which would
2686 // lead to a FPR (usually D8) accidentally being marked saved.
2687 if (RegIsGPR64 && !AArch64::GPR64RegClass.contains(PairedReg)) {
2688 PairedReg = Register();
2689 HasUnpairedGPR64 = true;
2690 }
2691 assert(!PairedReg.isValid() ||
2692 AArch64::GPR64RegClass.contains(Reg, PairedReg) ||
2693 AArch64::FPR64RegClass.contains(Reg, PairedReg) ||
2694 AArch64::FPR128RegClass.contains(Reg, PairedReg));
2695
2696 if (!RegUsed) {
2697 if (AArch64::GPR64RegClass.contains(Reg) && !ReservedRegs[Reg]) {
2698 UnspilledCSGPR = Reg;
2699 UnspilledCSGPRPaired = PairedReg;
2700 }
2701 continue;
2702 }
2703
2704 // MachO's compact unwind format relies on all registers being stored in
2705 // pairs.
2706 // FIXME: the usual format is actually better if unwinding isn't needed.
2707 if (producePairRegisters(MF) && PairedReg.isValid() &&
2708 !SavedRegs.test(PairedReg)) {
2709 SavedRegs.set(PairedReg);
2710 if (AArch64::GPR64RegClass.contains(PairedReg) &&
2711 !ReservedRegs[PairedReg])
2712 ExtraCSSpill = PairedReg;
2713 }
2714 // Check if there is a pair of ZRegs, so it can select PReg for spill/fill
2715 HasPairZReg |= (AArch64::ZPRRegClass.contains(Reg, CSRegs[i ^ 1]) &&
2716 SavedRegs.test(CSRegs[i ^ 1]));
2717 }
2718
2719 if (HasPairZReg && enableMultiVectorSpillFill(Subtarget, MF)) {
2721 // Find a suitable predicate register for the multi-vector spill/fill
2722 // instructions.
2723 MCRegister PnReg = findFreePredicateReg(SavedRegs);
2724 if (PnReg.isValid())
2725 AFI->setPredicateRegForFillSpill(PnReg);
2726 // If no free callee-save has been found assign one.
2727 if (!AFI->getPredicateRegForFillSpill() &&
2728 MF.getFunction().getCallingConv() ==
2730 SavedRegs.set(AArch64::P8);
2731 AFI->setPredicateRegForFillSpill(AArch64::PN8);
2732 }
2733
2734 assert(!ReservedRegs[AFI->getPredicateRegForFillSpill()] &&
2735 "Predicate cannot be a reserved register");
2736 }
2737
2739 !Subtarget.isTargetWindowsOrUEFI()) {
2740 // For Windows calling convention on a non-windows OS, where X18 is treated
2741 // as reserved, back up X18 when entering non-windows code (marked with the
2742 // Windows calling convention) and restore when returning regardless of
2743 // whether the individual function uses it - it might call other functions
2744 // that clobber it.
2745 SavedRegs.set(AArch64::X18);
2746 }
2747
2748 // Determine if a Hazard slot should be used and where it should go.
2749 // If SplitSVEObjects is used, the hazard padding is placed between the PPRs
2750 // and ZPRs. Otherwise, it goes in the callee save area.
2751 determineStackHazardSlot(MF, SavedRegs);
2752
2753 // Calculates the callee saved stack size.
2754 unsigned CSStackSize = 0;
2755 unsigned ZPRCSStackSize = 0;
2756 unsigned PPRCSStackSize = 0;
2758 for (unsigned Reg : SavedRegs.set_bits()) {
2759 auto *RC = TRI->getMinimalPhysRegClass(MCRegister(Reg));
2760 assert(RC && "expected register class!");
2761 auto SpillSize = TRI->getSpillSize(*RC);
2762 bool IsZPR = AArch64::ZPRRegClass.contains(Reg);
2763 bool IsPPR = !IsZPR && AArch64::PPRRegClass.contains(Reg);
2764 if (IsZPR)
2765 ZPRCSStackSize += SpillSize;
2766 else if (IsPPR)
2767 PPRCSStackSize += SpillSize;
2768 else {
2769 // A register and its super-register can both appear in SavedRegs.
2770 // Only the widest register is actually spilled, so skip such
2771 // sub-registers here to avoid double-counting the overlap.
2772 bool SavedSuper = any_of(TRI->superregs(Reg), [&](MCPhysReg SuperReg) {
2773 return SavedRegs.test(SuperReg);
2774 });
2775 if (!SavedSuper)
2776 CSStackSize += SpillSize;
2777 }
2778 }
2779
2780 // Save number of saved regs, so we can easily update CSStackSize later to
2781 // account for any additional 64-bit GPR saves. Note: After this point
2782 // only 64-bit GPRs can be added to SavedRegs.
2783 unsigned NumSavedRegs = SavedRegs.count();
2784
2785 // If we have hazard padding in the CS area add that to the size.
2787 CSStackSize += getStackHazardSize(MF);
2788
2789 // Increase the callee-saved stack size if the function has streaming mode
2790 // changes, as we will need to spill the value of the VG register.
2791 if (requiresSaveVG(MF))
2792 CSStackSize += 8;
2793
2794 // If we must call __arm_get_current_vg in the prologue preserve the LR.
2795 if (requiresSaveVG(MF) && !Subtarget.hasSVE())
2796 SavedRegs.set(AArch64::LR);
2797
2798 // The frame record needs to be created by saving the appropriate registers
2799 uint64_t EstimatedStackSize = MFI.estimateStackSize(MF);
2800 if (hasFP(MF) ||
2801 windowsRequiresStackProbe(MF, EstimatedStackSize + CSStackSize + 16)) {
2802 SavedRegs.set(AArch64::FP);
2803 SavedRegs.set(AArch64::LR);
2804 }
2805
2806 LLVM_DEBUG({
2807 dbgs() << "*** determineCalleeSaves\nSaved CSRs:";
2808 for (unsigned Reg : SavedRegs.set_bits())
2809 dbgs() << ' ' << printReg(MCRegister(Reg), RegInfo);
2810 dbgs() << "\n";
2811 });
2812
2813 // If any callee-saved registers are used, the frame cannot be eliminated.
2814 auto [ZPRLocalStackSize, PPRLocalStackSize] =
2816 uint64_t SVELocals = ZPRLocalStackSize + PPRLocalStackSize;
2817 uint64_t SVEStackSize =
2818 alignTo(ZPRCSStackSize + PPRCSStackSize + SVELocals, 16);
2819 bool CanEliminateFrame = (SavedRegs.count() == 0) && !SVEStackSize;
2820
2821 // The CSR spill slots have not been allocated yet, so estimateStackSize
2822 // won't include them.
2823 unsigned EstimatedStackSizeLimit = estimateRSStackSizeLimit(MF);
2824
2825 // We may address some of the stack above the canonical frame address, either
2826 // for our own arguments or during a call. Include that in calculating whether
2827 // we have complicated addressing concerns.
2828 int64_t CalleeStackUsed = 0;
2829 for (int I = MFI.getObjectIndexBegin(); I != 0; ++I) {
2830 int64_t FixedOff = MFI.getObjectOffset(I);
2831 if (FixedOff > CalleeStackUsed)
2832 CalleeStackUsed = FixedOff;
2833 }
2834
2835 // Conservatively always assume BigStack when there are SVE spills.
2836 bool BigStack = SVEStackSize || (EstimatedStackSize + CSStackSize +
2837 CalleeStackUsed) > EstimatedStackSizeLimit;
2838 if (BigStack || !CanEliminateFrame || RegInfo->cannotEliminateFrame(MF))
2839 AFI->setHasStackFrame(true);
2840
2841 // Estimate if we might need to scavenge a register at some point in order
2842 // to materialize a stack offset. If so, either spill one additional
2843 // callee-saved register or reserve a special spill slot to facilitate
2844 // register scavenging. If we already spilled an extra callee-saved register
2845 // above to keep the number of spills even, we don't need to do anything else
2846 // here.
2847 if (BigStack) {
2848 if (!ExtraCSSpill.isValid() && UnspilledCSGPR.isValid()) {
2849 LLVM_DEBUG(dbgs() << "Spilling " << printReg(UnspilledCSGPR, RegInfo)
2850 << " to get a scratch register.\n");
2851 SavedRegs.set(UnspilledCSGPR);
2852 ExtraCSSpill = UnspilledCSGPR;
2853
2854 // MachO's compact unwind format relies on all registers being stored in
2855 // pairs, so if we need to spill one extra for BigStack, then we need to
2856 // store the pair.
2857 if (producePairRegisters(MF)) {
2858 if (!UnspilledCSGPRPaired.isValid()) {
2859 // Failed to make a pair for compact unwind format, revert spilling.
2860 if (produceCompactUnwindFrame(*this, MF)) {
2861 SavedRegs.reset(UnspilledCSGPR);
2862 ExtraCSSpill = Register();
2863 }
2864 } else
2865 SavedRegs.set(UnspilledCSGPRPaired);
2866 }
2867 }
2868
2869 // If we didn't find an extra callee-saved register to spill, create
2870 // an emergency spill slot.
2871 if (!ExtraCSSpill.isValid() ||
2872 MF.getRegInfo().isPhysRegUsed(ExtraCSSpill)) {
2874 const TargetRegisterClass &RC = AArch64::GPR64RegClass;
2875 unsigned Size = TRI->getSpillSize(RC);
2876 Align Alignment = TRI->getSpillAlign(RC);
2877 int FI = MFI.CreateSpillStackObject(Size, Alignment);
2878 RS->addScavengingFrameIndex(FI);
2879 LLVM_DEBUG(dbgs() << "No available CS registers, allocated fi#" << FI
2880 << " as the emergency spill slot.\n");
2881 }
2882 }
2883
2884 // Adding the size of additional 64bit GPR saves.
2885 CSStackSize += 8 * (SavedRegs.count() - NumSavedRegs);
2886
2887 // A Swift asynchronous context extends the frame record with a pointer
2888 // directly before FP.
2889 if (hasFP(MF) && AFI->hasSwiftAsyncContext())
2890 CSStackSize += 8;
2891
2892 uint64_t AlignedCSStackSize = alignTo(CSStackSize, 16);
2893 LLVM_DEBUG(dbgs() << "Estimated stack frame size: "
2894 << EstimatedStackSize + AlignedCSStackSize << " bytes.\n");
2895
2897 AFI->getCalleeSavedStackSize() == AlignedCSStackSize) &&
2898 "Should not invalidate callee saved info");
2899
2900 // Round up to register pair alignment to avoid additional SP adjustment
2901 // instructions.
2902 AFI->setCalleeSavedStackSize(AlignedCSStackSize);
2903 AFI->setCalleeSaveStackHasFreeSpace(AlignedCSStackSize != CSStackSize);
2904 AFI->setSVECalleeSavedStackSize(ZPRCSStackSize, alignTo(PPRCSStackSize, 16));
2905}
2906
2907// Reorder ZPRs to maximize grouping, quads and pairs. The main condition we try
2908// to satisfy is the offset and the register number.
2909// Quads require a (scaled offset % 4 == 0) && (LowestRegister % 4 == 0),
2910// e.g: (z4, z5, z6, z7) where z4 is at offset 8 would be legal quad
2911// Pairs require a (scaled offset % 2 == 0) && (LowestRegister % 2 == 0).
2912// e.g: (z4, z5) where z4 is at offset 6 would be a legal pair
2915 std::vector<CalleeSavedInfo> &CSI) {
2916 assert(!isTargetWindows(MF) &&
2917 "ZPR callee-save reordering not supported on Windows");
2918
2919 auto *AFI = MF.getInfo<AArch64FunctionInfo>();
2920 if (!AFI->getPredicateRegForFillSpill())
2921 return;
2922
2923 auto IsZPR = [](CalleeSavedInfo &CS) {
2924 return AArch64::ZPRRegClass.contains(CS.getReg());
2925 };
2926
2928 ZPRSaves = ZPRSaves.drop_until(IsZPR).take_while(IsZPR);
2929
2930 if (ZPRSaves.size() < 2)
2931 return;
2932
2933 int ZPRByteOffset = AFI->getZPRCalleeSavedStackSize();
2934 if (!AFI->hasSplitSVEObjects())
2935 ZPRByteOffset += AFI->getPPRCalleeSavedStackSize();
2936
2937 const int Scale = RegInfo->getSpillSize(AArch64::ZPRRegClass);
2938 const int LowestOffset =
2939 (ZPRByteOffset / Scale) - static_cast<int>(ZPRSaves.size());
2940
2941 int NumToAlign = alignTo(LowestOffset, 4) - LowestOffset;
2942 if (NumToAlign > int(ZPRSaves.size()))
2943 return;
2944
2945 sort(ZPRSaves,
2946 [](const auto &A, const auto &B) { return A.getReg() < B.getReg(); });
2947
2951
2952 int ZPRsNeededForAlignment = NumToAlign;
2953 for (size_t i = 0; i < ZPRSaves.size();) {
2954 int ZPRsRemaining = int(ZPRSaves.size()) - i;
2955 if (i + 3 < ZPRSaves.size() &&
2956 (ZPRSaves[i].getReg() - AArch64::Z0) % 4 == 0 &&
2957 ZPRSaves[i].getReg() + 3 == ZPRSaves[i + 3].getReg() &&
2958 ZPRsRemaining - 4 >= ZPRsNeededForAlignment) {
2959 Quads.push_back(
2960 {ZPRSaves[i], ZPRSaves[i + 1], ZPRSaves[i + 2], ZPRSaves[i + 3]});
2961 i += 4;
2962 continue;
2963 }
2964 // We only need to split a pair if there's no singles. If we have a single
2965 // ZPR then all required alignments (1, 2, or 3) can use that single and a
2966 // ZPR pair.
2967 bool MustSplitPairForSingle =
2968 ZPRsNeededForAlignment == 1 && Singles.empty() && ZPRsRemaining == 2;
2969
2970 if (i + 1 < ZPRSaves.size() &&
2971 (ZPRSaves[i].getReg() - AArch64::Z0) % 2 == 0 &&
2972 ZPRSaves[i].getReg() + 1 == ZPRSaves[i + 1].getReg() &&
2973 !MustSplitPairForSingle) {
2974 Pairs.push_back({ZPRSaves[i], ZPRSaves[i + 1]});
2975 // Don't decrement the ZPRs needed if we require one ZPR for alignment and
2976 // we've yet to find a single ZPR. We may still need to split a pair.
2977 if (ZPRsNeededForAlignment != 1 || !Singles.empty())
2978 ZPRsNeededForAlignment -= 2;
2979
2980 i += 2;
2981 continue;
2982 }
2983
2984 Singles.push_back(ZPRSaves[i++]);
2985 ZPRsNeededForAlignment--;
2986 }
2987
2988 if (Quads.empty() && Pairs.empty())
2989 return;
2990
2991 int NumUnassigned = ZPRSaves.size();
2992 auto Emit = [&](ArrayRef<CalleeSavedInfo> Saves) {
2993 // During pair/quad formation, we check for the register groups in reverse
2994 // order. This is to ensures that stack indexes remain consistent with the
2995 // instruction.
2996 for (const CalleeSavedInfo &CS : Saves)
2997 ZPRSaves[--NumUnassigned] = CS;
2998 };
2999
3000 // Align the offset to a multiple of 4 (to allow for the most quads/pairs).
3001 if (NumToAlign & 0b01)
3002 Emit(Singles.pop_back_val());
3003 if (NumToAlign & 0b10) {
3004 if (!Pairs.empty())
3005 Emit(Pairs.pop_back_val());
3006 else
3007 Emit({Singles.pop_back_val(), Singles.pop_back_val()});
3008 }
3009
3010 for (const auto &Quad : Quads)
3011 Emit(Quad);
3012
3013 for (const auto &Pair : Pairs)
3014 Emit(Pair);
3015
3016 for (const auto &Single : Singles)
3017 Emit(Single);
3018}
3019
3021 MachineFunction &MF, const TargetRegisterInfo *RegInfo,
3022 std::vector<CalleeSavedInfo> &CSI) const {
3023 bool IsWindows = isTargetWindows(MF);
3024 unsigned StackHazardSize = getStackHazardSize(MF);
3025 // To match the canonical windows frame layout, reverse the list of
3026 // callee saved registers to get them laid out by PrologEpilogInserter
3027 // in the right order. (PrologEpilogInserter allocates stack objects top
3028 // down. Windows canonical prologs store higher numbered registers at
3029 // the top, thus have the CSI array start from the highest registers.)
3030 if (IsWindows)
3031 std::reverse(CSI.begin(), CSI.end());
3032
3033 if (CSI.empty())
3034 return true; // Early exit if no callee saved registers are modified!
3035
3036 // Now that we know which registers need to be saved and restored, allocate
3037 // stack slots for them.
3038 MachineFrameInfo &MFI = MF.getFrameInfo();
3039 auto *AFI = MF.getInfo<AArch64FunctionInfo>();
3040
3041 // Insert VG into the list of CSRs, immediately before LR if saved.
3042 if (requiresSaveVG(MF)) {
3043 CalleeSavedInfo VGInfo(AArch64::VG);
3044 auto It =
3045 find_if(CSI, [](auto &Info) { return Info.getReg() == AArch64::LR; });
3046 if (It != CSI.end())
3047 CSI.insert(It, VGInfo);
3048 else
3049 CSI.push_back(VGInfo);
3050 }
3051
3052 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
3053 if (!IsWindows && enableMultiVectorSpillFill(Subtarget, MF))
3054 // The Windows stack layout is not supported by this reordering function
3055 // yet.
3056 orderZPRCalleeSavesForGroups(MF, RegInfo, CSI);
3057
3058 Register LastReg = 0;
3059 int HazardSlotIndex = std::numeric_limits<int>::max();
3060 for (auto &CS : CSI) {
3061 MCRegister Reg = CS.getReg();
3062 const TargetRegisterClass *RC = RegInfo->getMinimalPhysRegClass(Reg);
3063
3064 // Create a hazard slot as we switch between GPR and FPR CSRs.
3066 (!LastReg || !AArch64InstrInfo::isFpOrNEON(LastReg)) &&
3068 assert(HazardSlotIndex == std::numeric_limits<int>::max() &&
3069 "Unexpected register order for hazard slot");
3070 HazardSlotIndex = MFI.CreateStackObject(StackHazardSize, Align(8), true);
3071 LLVM_DEBUG(dbgs() << "Created CSR Hazard at slot " << HazardSlotIndex
3072 << "\n");
3073 AFI->setStackHazardCSRSlotIndex(HazardSlotIndex);
3074 MFI.setIsCalleeSavedObjectIndex(HazardSlotIndex, true);
3075 }
3076
3077 unsigned Size = RegInfo->getSpillSize(*RC);
3078 Align Alignment(RegInfo->getSpillAlign(*RC));
3079 int FrameIdx = MFI.CreateStackObject(Size, Alignment, true);
3080 CS.setFrameIdx(FrameIdx);
3081 MFI.setIsCalleeSavedObjectIndex(FrameIdx, true);
3082
3083 // Grab 8 bytes below FP for the extended asynchronous frame info.
3084 if (hasFP(MF) && AFI->hasSwiftAsyncContext() && Reg == AArch64::FP) {
3085 FrameIdx = MFI.CreateStackObject(8, Alignment, true);
3086 AFI->setSwiftAsyncContextFrameIdx(FrameIdx);
3087 MFI.setIsCalleeSavedObjectIndex(FrameIdx, true);
3088 }
3089 LastReg = Reg;
3090 }
3091
3092 // Add hazard slot in the case where no FPR CSRs are present.
3094 HazardSlotIndex == std::numeric_limits<int>::max()) {
3095 HazardSlotIndex = MFI.CreateStackObject(StackHazardSize, Align(8), true);
3096 LLVM_DEBUG(dbgs() << "Created CSR Hazard at slot " << HazardSlotIndex
3097 << "\n");
3098 AFI->setStackHazardCSRSlotIndex(HazardSlotIndex);
3099 MFI.setIsCalleeSavedObjectIndex(HazardSlotIndex, true);
3100 }
3101
3102 return true;
3103}
3104
3106 const MachineFunction &MF) const {
3108 // If the function has streaming-mode changes, don't scavenge a
3109 // spillslot in the callee-save area, as that might require an
3110 // 'addvl' in the streaming-mode-changing call-sequence when the
3111 // function doesn't use a FP.
3112 if (AFI->hasStreamingModeChanges() && !hasFP(MF))
3113 return false;
3114 // Don't allow register salvaging with hazard slots, in case it moves objects
3115 // into the wrong place.
3116 if (AFI->hasStackHazardSlotIndex())
3117 return false;
3118 return AFI->hasCalleeSaveStackFreeSpace();
3119}
3120
3121/// returns true if there are any SVE callee saves.
3123 int &Min, int &Max) {
3124 Min = std::numeric_limits<int>::max();
3125 Max = std::numeric_limits<int>::min();
3126
3127 if (!MFI.isCalleeSavedInfoValid())
3128 return false;
3129
3130 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
3131 for (auto &CS : CSI) {
3132 if (AArch64::ZPRRegClass.contains(CS.getReg()) ||
3133 AArch64::PPRRegClass.contains(CS.getReg())) {
3134 assert((Max == std::numeric_limits<int>::min() ||
3135 Max + 1 == CS.getFrameIdx()) &&
3136 "SVE CalleeSaves are not consecutive");
3137 Min = std::min(Min, CS.getFrameIdx());
3138 Max = std::max(Max, CS.getFrameIdx());
3139 }
3140 }
3141 return Min != std::numeric_limits<int>::max();
3142}
3143
3145 AssignObjectOffsets AssignOffsets) {
3146 MachineFrameInfo &MFI = MF.getFrameInfo();
3147 auto *AFI = MF.getInfo<AArch64FunctionInfo>();
3148
3149 SVEStackSizes SVEStack{};
3150
3151 // With SplitSVEObjects we maintain separate stack offsets for predicates
3152 // (PPRs) and SVE vectors (ZPRs). When SplitSVEObjects is disabled predicates
3153 // are included in the SVE vector area.
3154 uint64_t &ZPRStackTop = SVEStack.ZPRStackSize;
3155 uint64_t &PPRStackTop =
3156 AFI->hasSplitSVEObjects() ? SVEStack.PPRStackSize : SVEStack.ZPRStackSize;
3157
3158#ifndef NDEBUG
3159 // First process all fixed stack objects.
3160 for (int I = MFI.getObjectIndexBegin(); I != 0; ++I)
3161 assert(!MFI.hasScalableStackID(I) &&
3162 "SVE vectors should never be passed on the stack by value, only by "
3163 "reference.");
3164#endif
3165
3166 auto AllocateObject = [&](int FI) {
3168 ? ZPRStackTop
3169 : PPRStackTop;
3170
3171 // FIXME: Given that the length of SVE vectors is not necessarily a power of
3172 // two, we'd need to align every object dynamically at runtime if the
3173 // alignment is larger than 16. This is not yet supported.
3174 Align Alignment = MFI.getObjectAlign(FI);
3175 if (Alignment > Align(16))
3177 "Alignment of scalable vectors > 16 bytes is not yet supported");
3178
3179 StackTop += MFI.getObjectSize(FI);
3180 StackTop = alignTo(StackTop, Alignment);
3181
3182 assert(StackTop < (uint64_t)std::numeric_limits<int64_t>::max() &&
3183 "SVE StackTop far too large?!");
3184
3185 int64_t Offset = -int64_t(StackTop);
3186 if (AssignOffsets == AssignObjectOffsets::Yes)
3187 MFI.setObjectOffset(FI, Offset);
3188
3189 LLVM_DEBUG(dbgs() << "alloc FI(" << FI << ") at SP[" << Offset << "]\n");
3190 };
3191
3192 // Then process all callee saved slots.
3193 int MinCSFrameIndex, MaxCSFrameIndex;
3194 if (getSVECalleeSaveSlotRange(MFI, MinCSFrameIndex, MaxCSFrameIndex)) {
3195 for (int FI = MinCSFrameIndex; FI <= MaxCSFrameIndex; ++FI)
3196 AllocateObject(FI);
3197 }
3198
3199 // Ensure the CS area is 16-byte aligned.
3200 PPRStackTop = alignTo(PPRStackTop, Align(16U));
3201 ZPRStackTop = alignTo(ZPRStackTop, Align(16U));
3202
3203 // Create a buffer of SVE objects to allocate and sort it.
3204 SmallVector<int, 8> ObjectsToAllocate;
3205 // If we have a stack protector, and we've previously decided that we have SVE
3206 // objects on the stack and thus need it to go in the SVE stack area, then it
3207 // needs to go first.
3208 int StackProtectorFI = -1;
3209 if (MFI.hasStackProtectorIndex()) {
3210 StackProtectorFI = MFI.getStackProtectorIndex();
3211 if (MFI.getStackID(StackProtectorFI) == TargetStackID::ScalableVector)
3212 ObjectsToAllocate.push_back(StackProtectorFI);
3213 }
3214
3215 for (int FI = 0, E = MFI.getObjectIndexEnd(); FI != E; ++FI) {
3216 if (FI == StackProtectorFI || MFI.isDeadObjectIndex(FI) ||
3218 continue;
3219
3222 continue;
3223
3224 ObjectsToAllocate.push_back(FI);
3225 }
3226
3227 // Allocate all SVE locals and spills
3228 for (unsigned FI : ObjectsToAllocate)
3229 AllocateObject(FI);
3230
3231 PPRStackTop = alignTo(PPRStackTop, Align(16U));
3232 ZPRStackTop = alignTo(ZPRStackTop, Align(16U));
3233
3234 if (AssignOffsets == AssignObjectOffsets::Yes)
3235 AFI->setStackSizeSVE(SVEStack.ZPRStackSize, SVEStack.PPRStackSize);
3236
3237 return SVEStack;
3238}
3239
3241 MachineFunction &MF, RegScavenger *RS) const {
3243 "Upwards growing stack unsupported");
3244
3246
3247 // If this function isn't doing Win64-style C++ EH, we don't need to do
3248 // anything.
3249 if (!MF.hasEHFunclets())
3250 return;
3251
3252 MachineFrameInfo &MFI = MF.getFrameInfo();
3253 auto *AFI = MF.getInfo<AArch64FunctionInfo>();
3254
3255 // Win64 C++ EH needs to allocate space for the catch objects in the fixed
3256 // object area right next to the UnwindHelp object.
3257 WinEHFuncInfo &EHInfo = *MF.getWinEHFuncInfo();
3258 int64_t CurrentOffset =
3260 for (WinEHTryBlockMapEntry &TBME : EHInfo.TryBlockMap) {
3261 for (WinEHHandlerType &H : TBME.HandlerArray) {
3262 int FrameIndex = H.CatchObj.FrameIndex;
3263 if ((FrameIndex != INT_MAX) && MFI.getObjectOffset(FrameIndex) == 0) {
3264 CurrentOffset =
3265 alignTo(CurrentOffset, MFI.getObjectAlign(FrameIndex).value());
3266 CurrentOffset += MFI.getObjectSize(FrameIndex);
3267 MFI.setObjectOffset(FrameIndex, -CurrentOffset);
3268 }
3269 }
3270 }
3271
3272 // Create an UnwindHelp object.
3273 // The UnwindHelp object is allocated at the start of the fixed object area
3274 int64_t UnwindHelpOffset = alignTo(CurrentOffset + 8, Align(16));
3275 assert(UnwindHelpOffset == getFixedObjectSize(MF, AFI, /*IsWin64*/ true,
3276 /*IsFunclet*/ false) &&
3277 "UnwindHelpOffset must be at the start of the fixed object area");
3278 int UnwindHelpFI = MFI.CreateFixedObject(/*Size*/ 8, -UnwindHelpOffset,
3279 /*IsImmutable=*/false);
3280 EHInfo.UnwindHelpFrameIdx = UnwindHelpFI;
3281
3282 MachineBasicBlock &MBB = MF.front();
3283 auto MBBI = MBB.begin();
3284 while (MBBI != MBB.end() && MBBI->getFlag(MachineInstr::FrameSetup))
3285 ++MBBI;
3286
3287 // We need to store -2 into the UnwindHelp object at the start of the
3288 // function.
3289 DebugLoc DL;
3290 RS->enterBasicBlockEnd(MBB);
3291 RS->backward(MBBI);
3292 Register DstReg = RS->FindUnusedReg(&AArch64::GPR64commonRegClass);
3293 assert(DstReg && "There must be a free register after frame setup");
3294 const AArch64InstrInfo &TII =
3295 *MF.getSubtarget<AArch64Subtarget>().getInstrInfo();
3296 BuildMI(MBB, MBBI, DL, TII.get(AArch64::MOVi64imm), DstReg).addImm(-2);
3297 BuildMI(MBB, MBBI, DL, TII.get(AArch64::STURXi))
3298 .addReg(DstReg, getKillRegState(true))
3299 .addFrameIndex(UnwindHelpFI)
3300 .addImm(0);
3301}
3302
3303namespace {
3304struct TagStoreInstr {
3306 int64_t Offset, Size;
3307 explicit TagStoreInstr(MachineInstr *MI, int64_t Offset, int64_t Size)
3308 : MI(MI), Offset(Offset), Size(Size) {}
3309};
3310
3311class TagStoreEdit {
3312 MachineFunction *MF;
3313 MachineBasicBlock *MBB;
3314 MachineRegisterInfo *MRI;
3315 // Tag store instructions that are being replaced.
3317 // Combined memref arguments of the above instructions.
3319
3320 // Replace allocation tags in [FrameReg + FrameRegOffset, FrameReg +
3321 // FrameRegOffset + Size) with the address tag of SP.
3322 Register FrameReg;
3323 StackOffset FrameRegOffset;
3324 int64_t Size;
3325 // If not std::nullopt, move FrameReg to (FrameReg + FrameRegUpdate) at the
3326 // end.
3327 std::optional<int64_t> FrameRegUpdate;
3328 // MIFlags for any FrameReg updating instructions.
3329 unsigned FrameRegUpdateFlags;
3330
3331 // Use zeroing instruction variants.
3332 bool ZeroData;
3333 DebugLoc DL;
3334
3335 void emitUnrolled(MachineBasicBlock::iterator InsertI);
3336 void emitLoop(MachineBasicBlock::iterator InsertI);
3337
3338public:
3339 TagStoreEdit(MachineBasicBlock *MBB, bool ZeroData)
3340 : MBB(MBB), ZeroData(ZeroData) {
3341 MF = MBB->getParent();
3342 MRI = &MF->getRegInfo();
3343 }
3344 // Add an instruction to be replaced. Instructions must be added in the
3345 // ascending order of Offset, and have to be adjacent.
3346 void addInstruction(TagStoreInstr I) {
3347 assert((TagStores.empty() ||
3348 TagStores.back().Offset + TagStores.back().Size == I.Offset) &&
3349 "Non-adjacent tag store instructions.");
3350 TagStores.push_back(I);
3351 }
3352 void clear() { TagStores.clear(); }
3353 // Emit equivalent code at the given location, and erase the current set of
3354 // instructions. May skip if the replacement is not profitable. May invalidate
3355 // the input iterator and replace it with a valid one.
3356 void emitCode(MachineBasicBlock::iterator &InsertI,
3357 const AArch64FrameLowering *TFI, bool TryMergeSPUpdate);
3358};
3359
3360void TagStoreEdit::emitUnrolled(MachineBasicBlock::iterator InsertI) {
3361 const AArch64InstrInfo *TII =
3362 MF->getSubtarget<AArch64Subtarget>().getInstrInfo();
3363
3364 const int64_t kMinOffset = -256 * 16;
3365 const int64_t kMaxOffset = 255 * 16;
3366
3367 Register BaseReg = FrameReg;
3368 int64_t BaseRegOffsetBytes = FrameRegOffset.getFixed();
3369 if (BaseRegOffsetBytes < kMinOffset ||
3370 BaseRegOffsetBytes + (Size - Size % 32) > kMaxOffset ||
3371 // BaseReg can be FP, which is not necessarily aligned to 16-bytes. In
3372 // that case, BaseRegOffsetBytes will not be aligned to 16 bytes, which
3373 // is required for the offset of ST2G.
3374 BaseRegOffsetBytes % 16 != 0) {
3375 Register ScratchReg = MRI->createVirtualRegister(&AArch64::GPR64RegClass);
3376 emitFrameOffset(*MBB, InsertI, DL, ScratchReg, BaseReg,
3377 StackOffset::getFixed(BaseRegOffsetBytes), TII);
3378 BaseReg = ScratchReg;
3379 BaseRegOffsetBytes = 0;
3380 }
3381
3382 MachineInstr *LastI = nullptr;
3383 while (Size) {
3384 int64_t InstrSize = (Size > 16) ? 32 : 16;
3385 unsigned Opcode =
3386 InstrSize == 16
3387 ? (ZeroData ? AArch64::STZGi : AArch64::STGi)
3388 : (ZeroData ? AArch64::STZ2Gi : AArch64::ST2Gi);
3389 assert(BaseRegOffsetBytes % 16 == 0);
3390 MachineInstr *I = BuildMI(*MBB, InsertI, DL, TII->get(Opcode))
3391 .addReg(AArch64::SP)
3392 .addReg(BaseReg)
3393 .addImm(BaseRegOffsetBytes / 16)
3394 .setMemRefs(CombinedMemRefs);
3395 // A store to [BaseReg, #0] should go last for an opportunity to fold the
3396 // final SP adjustment in the epilogue.
3397 if (BaseRegOffsetBytes == 0)
3398 LastI = I;
3399 BaseRegOffsetBytes += InstrSize;
3400 Size -= InstrSize;
3401 }
3402
3403 if (LastI)
3404 MBB->splice(InsertI, MBB, LastI);
3405}
3406
3407void TagStoreEdit::emitLoop(MachineBasicBlock::iterator InsertI) {
3408 const AArch64InstrInfo *TII =
3409 MF->getSubtarget<AArch64Subtarget>().getInstrInfo();
3410
3411 Register BaseReg = FrameRegUpdate
3412 ? FrameReg
3413 : MRI->createVirtualRegister(&AArch64::GPR64RegClass);
3414 Register SizeReg = MRI->createVirtualRegister(&AArch64::GPR64RegClass);
3415
3416 emitFrameOffset(*MBB, InsertI, DL, BaseReg, FrameReg, FrameRegOffset, TII);
3417
3418 int64_t LoopSize = Size;
3419 // If the loop size is not a multiple of 32, split off one 16-byte store at
3420 // the end to fold BaseReg update into.
3421 if (FrameRegUpdate && *FrameRegUpdate)
3422 LoopSize -= LoopSize % 32;
3423 MachineInstr *LoopI = BuildMI(*MBB, InsertI, DL,
3424 TII->get(ZeroData ? AArch64::STZGloop_wback
3425 : AArch64::STGloop_wback))
3426 .addDef(SizeReg)
3427 .addDef(BaseReg)
3428 .addImm(LoopSize)
3429 .addReg(BaseReg)
3430 .setMemRefs(CombinedMemRefs);
3431 if (FrameRegUpdate)
3432 LoopI->setFlags(FrameRegUpdateFlags);
3433
3434 int64_t ExtraBaseRegUpdate =
3435 FrameRegUpdate ? (*FrameRegUpdate - FrameRegOffset.getFixed() - Size) : 0;
3436 LLVM_DEBUG(dbgs() << "TagStoreEdit::emitLoop: LoopSize=" << LoopSize
3437 << ", Size=" << Size
3438 << ", ExtraBaseRegUpdate=" << ExtraBaseRegUpdate
3439 << ", FrameRegUpdate=" << FrameRegUpdate
3440 << ", FrameRegOffset.getFixed()="
3441 << FrameRegOffset.getFixed() << "\n");
3442 if (LoopSize < Size) {
3443 assert(FrameRegUpdate);
3444 assert(Size - LoopSize == 16);
3445 // Tag 16 more bytes at BaseReg and update BaseReg.
3446 int64_t STGOffset = ExtraBaseRegUpdate + 16;
3447 assert(STGOffset % 16 == 0 && STGOffset >= -4096 && STGOffset <= 4080 &&
3448 "STG immediate out of range");
3449 BuildMI(*MBB, InsertI, DL,
3450 TII->get(ZeroData ? AArch64::STZGPostIndex : AArch64::STGPostIndex))
3451 .addDef(BaseReg)
3452 .addReg(BaseReg)
3453 .addReg(BaseReg)
3454 .addImm(STGOffset / 16)
3455 .setMemRefs(CombinedMemRefs)
3456 .setMIFlags(FrameRegUpdateFlags);
3457 } else if (ExtraBaseRegUpdate) {
3458 // Update BaseReg.
3459 int64_t AddSubOffset = std::abs(ExtraBaseRegUpdate);
3460 assert(AddSubOffset <= 4095 && "ADD/SUB immediate out of range");
3461 BuildMI(
3462 *MBB, InsertI, DL,
3463 TII->get(ExtraBaseRegUpdate > 0 ? AArch64::ADDXri : AArch64::SUBXri))
3464 .addDef(BaseReg)
3465 .addReg(BaseReg)
3466 .addImm(AddSubOffset)
3467 .addImm(0)
3468 .setMIFlags(FrameRegUpdateFlags);
3469 }
3470}
3471
3472// Check if *II is a register update that can be merged into STGloop that ends
3473// at (Reg + Size). RemainingOffset is the required adjustment to Reg after the
3474// end of the loop.
3475bool canMergeRegUpdate(MachineBasicBlock::iterator II, unsigned Reg,
3476 int64_t Size, int64_t *TotalOffset) {
3477 MachineInstr &MI = *II;
3478 if ((MI.getOpcode() == AArch64::ADDXri ||
3479 MI.getOpcode() == AArch64::SUBXri) &&
3480 MI.getOperand(0).getReg() == Reg && MI.getOperand(1).getReg() == Reg) {
3481 unsigned Shift = AArch64_AM::getShiftValue(MI.getOperand(3).getImm());
3482 int64_t Offset = MI.getOperand(2).getImm() << Shift;
3483 if (MI.getOpcode() == AArch64::SUBXri)
3484 Offset = -Offset;
3485 int64_t PostOffset = Offset - Size;
3486 // TagStoreEdit::emitLoop might emit either an ADD/SUB after the loop, or
3487 // an STGPostIndex which does the last 16 bytes of tag write. Which one is
3488 // chosen depends on the alignment of the loop size, but the difference
3489 // between the valid ranges for the two instructions is small, so we
3490 // conservatively assume that it could be either case here.
3491 //
3492 // Max offset of STGPostIndex, minus the 16 byte tag write folded into that
3493 // instruction.
3494 const int64_t kMaxOffset = 4080 - 16;
3495 // Max offset of SUBXri.
3496 const int64_t kMinOffset = -4095;
3497 if (PostOffset <= kMaxOffset && PostOffset >= kMinOffset &&
3498 PostOffset % 16 == 0) {
3499 *TotalOffset = Offset;
3500 return true;
3501 }
3502 }
3503 return false;
3504}
3505
3506void mergeMemRefs(const SmallVectorImpl<TagStoreInstr> &TSE,
3508 MemRefs.clear();
3509 for (auto &TS : TSE) {
3510 MachineInstr *MI = TS.MI;
3511 // An instruction without memory operands may access anything. Be
3512 // conservative and return an empty list.
3513 if (MI->memoperands_empty()) {
3514 MemRefs.clear();
3515 return;
3516 }
3517 MemRefs.append(MI->memoperands_begin(), MI->memoperands_end());
3518 }
3519}
3520
3521void TagStoreEdit::emitCode(MachineBasicBlock::iterator &InsertI,
3522 const AArch64FrameLowering *TFI,
3523 bool TryMergeSPUpdate) {
3524 if (TagStores.empty())
3525 return;
3526 TagStoreInstr &FirstTagStore = TagStores[0];
3527 TagStoreInstr &LastTagStore = TagStores[TagStores.size() - 1];
3528 Size = LastTagStore.Offset - FirstTagStore.Offset + LastTagStore.Size;
3529 DL = TagStores[0].MI->getDebugLoc();
3530
3531 Register Reg;
3532 FrameRegOffset = TFI->resolveFrameOffsetReference(
3533 *MF, FirstTagStore.Offset, false /*isFixed*/,
3534 TargetStackID::Default /*StackID*/, Reg,
3535 /*PreferFP=*/false, /*ForSimm=*/true);
3536 FrameReg = Reg;
3537 FrameRegUpdate = std::nullopt;
3538
3539 mergeMemRefs(TagStores, CombinedMemRefs);
3540
3541 LLVM_DEBUG({
3542 dbgs() << "Replacing adjacent STG instructions:\n";
3543 for (const auto &Instr : TagStores) {
3544 dbgs() << " " << *Instr.MI;
3545 }
3546 });
3547
3548 // Size threshold where a loop becomes shorter than a linear sequence of
3549 // tagging instructions.
3550 const int kSetTagLoopThreshold = 176;
3551 if (Size < kSetTagLoopThreshold) {
3552 if (TagStores.size() < 2)
3553 return;
3554 emitUnrolled(InsertI);
3555 } else {
3556 MachineInstr *UpdateInstr = nullptr;
3557 int64_t TotalOffset = 0;
3558 if (TryMergeSPUpdate) {
3559 // See if we can merge base register update into the STGloop.
3560 // This is done in AArch64LoadStoreOptimizer for "normal" stores,
3561 // but STGloop is way too unusual for that, and also it only
3562 // realistically happens in function epilogue. Also, STGloop is expanded
3563 // before that pass.
3564 if (InsertI != MBB->end() &&
3565 canMergeRegUpdate(InsertI, FrameReg, FrameRegOffset.getFixed() + Size,
3566 &TotalOffset)) {
3567 UpdateInstr = &*InsertI++;
3568 LLVM_DEBUG(dbgs() << "Folding SP update into loop:\n "
3569 << *UpdateInstr);
3570 }
3571 }
3572
3573 if (!UpdateInstr && TagStores.size() < 2)
3574 return;
3575
3576 if (UpdateInstr) {
3577 FrameRegUpdate = TotalOffset;
3578 FrameRegUpdateFlags = UpdateInstr->getFlags();
3579 }
3580 emitLoop(InsertI);
3581 if (UpdateInstr)
3582 UpdateInstr->eraseFromParent();
3583 }
3584
3585 for (auto &TS : TagStores)
3586 TS.MI->eraseFromParent();
3587}
3588
3589bool isMergeableStackTaggingInstruction(MachineInstr &MI, int64_t &Offset,
3590 int64_t &Size, bool &ZeroData) {
3591 MachineFunction &MF = *MI.getParent()->getParent();
3592 const MachineFrameInfo &MFI = MF.getFrameInfo();
3593
3594 unsigned Opcode = MI.getOpcode();
3595 ZeroData = (Opcode == AArch64::STZGloop || Opcode == AArch64::STZGi ||
3596 Opcode == AArch64::STZ2Gi);
3597
3598 if (Opcode == AArch64::STGloop || Opcode == AArch64::STZGloop) {
3599 if (!MI.getOperand(0).isDead() || !MI.getOperand(1).isDead())
3600 return false;
3601 if (!MI.getOperand(2).isImm() || !MI.getOperand(3).isFI())
3602 return false;
3603 Offset = MFI.getObjectOffset(MI.getOperand(3).getIndex());
3604 Size = MI.getOperand(2).getImm();
3605 return true;
3606 }
3607
3608 if (Opcode == AArch64::STGi || Opcode == AArch64::STZGi)
3609 Size = 16;
3610 else if (Opcode == AArch64::ST2Gi || Opcode == AArch64::STZ2Gi)
3611 Size = 32;
3612 else
3613 return false;
3614
3615 if (MI.getOperand(0).getReg() != AArch64::SP || !MI.getOperand(1).isFI())
3616 return false;
3617
3618 Offset = MFI.getObjectOffset(MI.getOperand(1).getIndex()) +
3619 16 * MI.getOperand(2).getImm();
3620 return true;
3621}
3622
3623static size_t countAvailableScavengerSlots(LivePhysRegs &LiveRegs,
3625 RegScavenger *RS) {
3626 auto FreeGPRs =
3627 llvm::count_if(AArch64::GPR64RegClass, [&LiveRegs, &MRI](auto Reg) {
3628 return LiveRegs.available(MRI, Reg);
3629 });
3630
3631 size_t NumEmergencySlots = 0;
3632 if (RS)
3633 NumEmergencySlots = RS->getNumScavengingFrameIndices();
3634
3635 return FreeGPRs + NumEmergencySlots;
3636}
3637
3638// Detect a run of memory tagging instructions for adjacent stack frame slots,
3639// and replace them with a shorter instruction sequence:
3640// * replace STG + STG with ST2G
3641// * replace STGloop + STGloop with STGloop
3642// This code needs to run when stack slot offsets are already known, but before
3643// FrameIndex operands in STG instructions are eliminated.
3645 const AArch64FrameLowering *TFI,
3646 RegScavenger *RS) {
3647 bool FirstZeroData;
3648 int64_t Size, Offset;
3649 MachineInstr &MI = *II;
3652 if (&MI == &MBB->instr_back())
3653 return II;
3654 if (!isMergeableStackTaggingInstruction(MI, Offset, Size, FirstZeroData))
3655 return II;
3656
3658 Instrs.emplace_back(&MI, Offset, Size);
3659
3660 constexpr int kScanLimit = 10;
3661 int Count = 0;
3663 NextI != E && Count < kScanLimit; ++NextI) {
3664 MachineInstr &MI = *NextI;
3665 bool ZeroData;
3666 int64_t Size, Offset;
3667 // Collect instructions that update memory tags with a FrameIndex operand
3668 // and (when applicable) constant size, and whose output registers are dead
3669 // (the latter is almost always the case in practice). Since these
3670 // instructions effectively have no inputs or outputs, we are free to skip
3671 // any non-aliasing instructions in between without tracking used registers.
3672 if (isMergeableStackTaggingInstruction(MI, Offset, Size, ZeroData)) {
3673 if (ZeroData != FirstZeroData)
3674 break;
3675 Instrs.emplace_back(&MI, Offset, Size);
3676 continue;
3677 }
3678
3679 // Only count non-transient, non-tagging instructions toward the scan
3680 // limit.
3681 if (!MI.isTransient())
3682 ++Count;
3683
3684 // Just in case, stop before the epilogue code starts.
3685 if (MI.getFlag(MachineInstr::FrameSetup) ||
3687 break;
3688
3689 // Reject anything that may alias the collected instructions.
3690 if (MI.mayLoadOrStore() || MI.hasUnmodeledSideEffects() || MI.isCall())
3691 break;
3692 }
3693
3694 // New code will be inserted after the last tagging instruction we've found.
3695 MachineBasicBlock::iterator InsertI = Instrs.back().MI;
3696
3697 // All the gathered stack tag instructions are merged and placed after
3698 // last tag store in the list. The check should be made if the nzcv
3699 // flag is live at the point where we are trying to insert. Otherwise
3700 // the nzcv flag might get clobbered if any stg loops are present.
3701
3702 // FIXME : This approach of bailing out from merge is conservative in
3703 // some ways like even if stg loops are not present after merge the
3704 // insert list, this liveness check is done (which is not needed).
3706 LiveRegs.addLiveOuts(*MBB);
3707 for (auto I = MBB->rbegin();; ++I) {
3708 MachineInstr &MI = *I;
3709 if (MI == InsertI)
3710 break;
3711 LiveRegs.stepBackward(*I);
3712 }
3713 InsertI++;
3714 if (LiveRegs.contains(AArch64::NZCV))
3715 return InsertI;
3716
3717 // Emitting an MTE loop requires two physical registers (BaseReg and
3718 // SizeReg). If the function is under register pressure, the register
3719 // scavenger will crash trying to allocate them. If we don't have at least
3720 // two free slots (free registers + emergency slots), bail out and fall back
3721 // to the unrolled sequence.
3722 if (countAvailableScavengerSlots(LiveRegs, MBB->getParent()->getRegInfo(),
3723 RS) < 2) {
3724 LLVM_DEBUG(
3725 dbgs() << "Failed to merge MTE stack tagging instructions into loop "
3726 << "due to high register pressure.\n");
3727 return InsertI;
3728 }
3729
3730 llvm::stable_sort(Instrs,
3731 [](const TagStoreInstr &Left, const TagStoreInstr &Right) {
3732 return Left.Offset < Right.Offset;
3733 });
3734
3735 // Make sure that we don't have any overlapping stores.
3736 int64_t CurOffset = Instrs[0].Offset;
3737 for (auto &Instr : Instrs) {
3738 if (CurOffset > Instr.Offset)
3739 return NextI;
3740 CurOffset = Instr.Offset + Instr.Size;
3741 }
3742
3743 // Find contiguous runs of tagged memory and emit shorter instruction
3744 // sequences for them when possible.
3745 TagStoreEdit TSE(MBB, FirstZeroData);
3746 std::optional<int64_t> EndOffset;
3747 for (auto &Instr : Instrs) {
3748 if (EndOffset && *EndOffset != Instr.Offset) {
3749 // Found a gap.
3750 TSE.emitCode(InsertI, TFI, /*TryMergeSPUpdate = */ false);
3751 TSE.clear();
3752 }
3753
3754 TSE.addInstruction(Instr);
3755 EndOffset = Instr.Offset + Instr.Size;
3756 }
3757
3758 const MachineFunction *MF = MBB->getParent();
3759 // Multiple FP/SP updates in a loop cannot be described by CFI instructions.
3760 TSE.emitCode(
3761 InsertI, TFI, /*TryMergeSPUpdate = */
3763
3764 return InsertI;
3765}
3766} // namespace
3767
3769 MachineFunction &MF, RegScavenger *RS = nullptr) const {
3770 bool MergeSetTag = MF.getSubtarget<AArch64Subtarget>()
3771 .getCLOpts()
3772 .stack_tagging_merge_settag;
3773 for (auto &BB : MF)
3774 for (MachineBasicBlock::iterator II = BB.begin(); II != BB.end();) {
3775 if (MergeSetTag)
3776 II = tryMergeAdjacentSTG(II, this, RS);
3777 }
3778
3779 // By the time this method is called, most of the prologue/epilogue code is
3780 // already emitted, whether its location was affected by the shrink-wrapping
3781 // optimization or not.
3782 if (!MF.getFunction().hasFnAttribute(Attribute::Naked) &&
3783 shouldSignReturnAddressEverywhere(MF))
3785}
3786
3787/// For Win64 AArch64 EH, the offset to the Unwind object is from the SP
3788/// before the update. This is easily retrieved as it is exactly the offset
3789/// that is set in processFunctionBeforeFrameFinalized.
3791 const MachineFunction &MF, int FI, Register &FrameReg,
3792 bool IgnoreSPUpdates) const {
3793 const MachineFrameInfo &MFI = MF.getFrameInfo();
3794 if (IgnoreSPUpdates) {
3795 LLVM_DEBUG(dbgs() << "Offset from the SP for " << FI << " is "
3796 << MFI.getObjectOffset(FI) << "\n");
3797 FrameReg = AArch64::SP;
3798 return StackOffset::getFixed(MFI.getObjectOffset(FI));
3799 }
3800
3801 // Go to common code if we cannot provide sp + offset.
3802 if (MFI.hasVarSizedObjects() ||
3805 return getFrameIndexReference(MF, FI, FrameReg);
3806
3807 FrameReg = AArch64::SP;
3808 return getStackOffset(MF, MFI.getObjectOffset(FI));
3809}
3810
3811/// The parent frame offset (aka dispFrame) is only used on X86_64 to retrieve
3812/// the parent's frame pointer
3814 const MachineFunction &MF) const {
3815 return 0;
3816}
3817
3818/// Funclets only need to account for space for the callee saved registers,
3819/// as the locals are accounted for in the parent's stack frame.
3821 const MachineFunction &MF) const {
3822 // This is the size of the pushed CSRs.
3823 unsigned CSSize =
3824 MF.getInfo<AArch64FunctionInfo>()->getCalleeSavedStackSize();
3825 // This is the amount of stack a funclet needs to allocate.
3826 return alignTo(CSSize + MF.getFrameInfo().getMaxCallFrameSize(),
3827 getStackAlign());
3828}
3829
3830namespace {
3831struct FrameObject {
3832 bool IsValid = false;
3833 // Index of the object in MFI.
3834 int ObjectIndex = 0;
3835 // Group ID this object belongs to.
3836 int GroupIndex = -1;
3837 // This object should be placed first (closest to SP).
3838 bool ObjectFirst = false;
3839 // This object's group (which always contains the object with
3840 // ObjectFirst==true) should be placed first.
3841 bool GroupFirst = false;
3842
3843 // Used to distinguish between FP and GPR accesses. The values are decided so
3844 // that they sort FPR < Hazard < GPR and they can be or'd together.
3845 unsigned Accesses = 0;
3846 enum { AccessFPR = 1, AccessHazard = 2, AccessGPR = 4 };
3847};
3848
3849class GroupBuilder {
3850 SmallVector<int, 8> CurrentMembers;
3851 int NextGroupIndex = 0;
3852 std::vector<FrameObject> &Objects;
3853
3854public:
3855 GroupBuilder(std::vector<FrameObject> &Objects) : Objects(Objects) {}
3856 void AddMember(int Index) { CurrentMembers.push_back(Index); }
3857 void EndCurrentGroup() {
3858 if (CurrentMembers.size() > 1) {
3859 // Create a new group with the current member list. This might remove them
3860 // from their pre-existing groups. That's OK, dealing with overlapping
3861 // groups is too hard and unlikely to make a difference.
3862 LLVM_DEBUG(dbgs() << "group:");
3863 for (int Index : CurrentMembers) {
3864 Objects[Index].GroupIndex = NextGroupIndex;
3865 LLVM_DEBUG(dbgs() << " " << Index);
3866 }
3867 LLVM_DEBUG(dbgs() << "\n");
3868 NextGroupIndex++;
3869 }
3870 CurrentMembers.clear();
3871 }
3872};
3873
3874bool FrameObjectCompare(const FrameObject &A, const FrameObject &B) {
3875 // Objects at a lower index are closer to FP; objects at a higher index are
3876 // closer to SP.
3877 //
3878 // For consistency in our comparison, all invalid objects are placed
3879 // at the end. This also allows us to stop walking when we hit the
3880 // first invalid item after it's all sorted.
3881 //
3882 // If we want to include a stack hazard region, order FPR accesses < the
3883 // hazard object < GPRs accesses in order to create a separation between the
3884 // two. For the Accesses field 1 = FPR, 2 = Hazard Object, 4 = GPR.
3885 //
3886 // Otherwise the "first" object goes first (closest to SP), followed by the
3887 // members of the "first" group.
3888 //
3889 // The rest are sorted by the group index to keep the groups together.
3890 // Higher numbered groups are more likely to be around longer (i.e. untagged
3891 // in the function epilogue and not at some earlier point). Place them closer
3892 // to SP.
3893 //
3894 // If all else equal, sort by the object index to keep the objects in the
3895 // original order.
3896 return std::make_tuple(!A.IsValid, A.Accesses, A.ObjectFirst, A.GroupFirst,
3897 A.GroupIndex, A.ObjectIndex) <
3898 std::make_tuple(!B.IsValid, B.Accesses, B.ObjectFirst, B.GroupFirst,
3899 B.GroupIndex, B.ObjectIndex);
3900}
3901} // namespace
3902
3904 const MachineFunction &MF, SmallVectorImpl<int> &ObjectsToAllocate) const {
3906
3907 if ((!MF.getSubtarget<AArch64Subtarget>().getCLOpts().order_frame_objects &&
3908 !AFI.hasSplitSVEObjects()) ||
3909 ObjectsToAllocate.empty())
3910 return;
3911
3912 const MachineFrameInfo &MFI = MF.getFrameInfo();
3913 std::vector<FrameObject> FrameObjects(MFI.getObjectIndexEnd());
3914 for (auto &Obj : ObjectsToAllocate) {
3915 FrameObjects[Obj].IsValid = true;
3916 FrameObjects[Obj].ObjectIndex = Obj;
3917 }
3918
3919 // Identify FPR vs GPR slots for hazards, and stack slots that are tagged at
3920 // the same time.
3921 GroupBuilder GB(FrameObjects);
3922 for (auto &MBB : MF) {
3923 for (auto &MI : MBB) {
3924 if (MI.isDebugInstr())
3925 continue;
3926
3927 if (AFI.hasStackHazardSlotIndex()) {
3928 std::optional<int> FI = getLdStFrameID(MI, MFI);
3929 if (FI && *FI >= 0 && *FI < (int)FrameObjects.size()) {
3930 if (MFI.getStackID(*FI) == TargetStackID::ScalableVector ||
3932 FrameObjects[*FI].Accesses |= FrameObject::AccessFPR;
3933 else
3934 FrameObjects[*FI].Accesses |= FrameObject::AccessGPR;
3935 }
3936 }
3937
3938 int OpIndex;
3939 switch (MI.getOpcode()) {
3940 case AArch64::STGloop:
3941 case AArch64::STZGloop:
3942 OpIndex = 3;
3943 break;
3944 case AArch64::STGi:
3945 case AArch64::STZGi:
3946 case AArch64::ST2Gi:
3947 case AArch64::STZ2Gi:
3948 OpIndex = 1;
3949 break;
3950 default:
3951 OpIndex = -1;
3952 }
3953
3954 int TaggedFI = -1;
3955 if (OpIndex >= 0) {
3956 const MachineOperand &MO = MI.getOperand(OpIndex);
3957 if (MO.isFI()) {
3958 int FI = MO.getIndex();
3959 if (FI >= 0 && FI < MFI.getObjectIndexEnd() &&
3960 FrameObjects[FI].IsValid)
3961 TaggedFI = FI;
3962 }
3963 }
3964
3965 // If this is a stack tagging instruction for a slot that is not part of a
3966 // group yet, either start a new group or add it to the current one.
3967 if (TaggedFI >= 0)
3968 GB.AddMember(TaggedFI);
3969 else
3970 GB.EndCurrentGroup();
3971 }
3972 // Groups should never span multiple basic blocks.
3973 GB.EndCurrentGroup();
3974 }
3975
3976 if (AFI.hasStackHazardSlotIndex()) {
3977 FrameObjects[AFI.getStackHazardSlotIndex()].Accesses =
3978 FrameObject::AccessHazard;
3979 // If a stack object is unknown or both GPR and FPR, sort it into GPR.
3980 for (auto &Obj : FrameObjects)
3981 if (!Obj.Accesses ||
3982 Obj.Accesses == (FrameObject::AccessGPR | FrameObject::AccessFPR))
3983 Obj.Accesses = FrameObject::AccessGPR;
3984 }
3985
3986 // If the function's tagged base pointer is pinned to a stack slot, we want to
3987 // put that slot first when possible. This will likely place it at SP + 0,
3988 // and save one instruction when generating the base pointer because IRG does
3989 // not allow an immediate offset.
3990 std::optional<int> TBPI = AFI.getTaggedBasePointerIndex();
3991 if (TBPI) {
3992 FrameObjects[*TBPI].ObjectFirst = true;
3993 FrameObjects[*TBPI].GroupFirst = true;
3994 int FirstGroupIndex = FrameObjects[*TBPI].GroupIndex;
3995 if (FirstGroupIndex >= 0)
3996 for (FrameObject &Object : FrameObjects)
3997 if (Object.GroupIndex == FirstGroupIndex)
3998 Object.GroupFirst = true;
3999 }
4000
4001 llvm::stable_sort(FrameObjects, FrameObjectCompare);
4002
4003 int i = 0;
4004 for (auto &Obj : FrameObjects) {
4005 // All invalid items are sorted at the end, so it's safe to stop.
4006 if (!Obj.IsValid)
4007 break;
4008 ObjectsToAllocate[i++] = Obj.ObjectIndex;
4009 }
4010
4011 LLVM_DEBUG({
4012 dbgs() << "Final frame order:\n";
4013 for (auto &Obj : FrameObjects) {
4014 if (!Obj.IsValid)
4015 break;
4016 dbgs() << " " << Obj.ObjectIndex << ": group " << Obj.GroupIndex;
4017 if (Obj.ObjectFirst)
4018 dbgs() << ", first";
4019 if (Obj.GroupFirst)
4020 dbgs() << ", group-first";
4021 dbgs() << "\n";
4022 }
4023 });
4024}
4025
4026/// Emit a loop to decrement SP until it is equal to TargetReg, with probes at
4027/// least every ProbeSize bytes. Returns an iterator of the first instruction
4028/// after the loop. The difference between SP and TargetReg must be an exact
4029/// multiple of ProbeSize.
4031AArch64FrameLowering::inlineStackProbeLoopExactMultiple(
4032 MachineBasicBlock::iterator MBBI, int64_t ProbeSize,
4033 Register TargetReg) const {
4034 MachineBasicBlock &MBB = *MBBI->getParent();
4035 MachineFunction &MF = *MBB.getParent();
4036 const AArch64InstrInfo *TII =
4037 MF.getSubtarget<AArch64Subtarget>().getInstrInfo();
4038 DebugLoc DL = MBB.findDebugLoc(MBBI);
4039
4040 MachineFunction::iterator MBBInsertPoint = std::next(MBB.getIterator());
4041 MachineBasicBlock *LoopMBB = MF.CreateMachineBasicBlock(MBB.getBasicBlock());
4042 MF.insert(MBBInsertPoint, LoopMBB);
4043 MachineBasicBlock *ExitMBB = MF.CreateMachineBasicBlock(MBB.getBasicBlock());
4044 MF.insert(MBBInsertPoint, ExitMBB);
4045
4046 // SUB SP, SP, #ProbeSize (or equivalent if ProbeSize is not encodable
4047 // in SUB).
4048 emitFrameOffset(*LoopMBB, LoopMBB->end(), DL, AArch64::SP, AArch64::SP,
4049 StackOffset::getFixed(-ProbeSize), TII,
4051 // LDR XZR, [SP]
4052 BuildMI(*LoopMBB, LoopMBB->end(), DL, TII->get(AArch64::LDRXui))
4053 .addDef(AArch64::XZR)
4054 .addReg(AArch64::SP)
4055 .addImm(0)
4059 Align(8)))
4061 // CMP SP, TargetReg
4062 BuildMI(*LoopMBB, LoopMBB->end(), DL, TII->get(AArch64::SUBSXrx64),
4063 AArch64::XZR)
4064 .addReg(AArch64::SP)
4065 .addReg(TargetReg)
4068 // B.CC Loop
4069 BuildMI(*LoopMBB, LoopMBB->end(), DL, TII->get(AArch64::Bcc))
4071 .addMBB(LoopMBB)
4073
4074 LoopMBB->addSuccessor(ExitMBB);
4075 LoopMBB->addSuccessor(LoopMBB);
4076 // Synthesize the exit MBB.
4077 ExitMBB->splice(ExitMBB->end(), &MBB, MBBI, MBB.end());
4079 MBB.addSuccessor(LoopMBB);
4080 // Update liveins.
4081 fullyRecomputeLiveIns({ExitMBB, LoopMBB});
4082
4083 return ExitMBB->begin();
4084}
4085
4086void AArch64FrameLowering::inlineStackProbeFixed(
4087 MachineBasicBlock::iterator MBBI, Register ScratchReg, int64_t FrameSize,
4088 StackOffset CFAOffset) const {
4089 MachineBasicBlock *MBB = MBBI->getParent();
4090 MachineFunction &MF = *MBB->getParent();
4091 const AArch64InstrInfo *TII =
4092 MF.getSubtarget<AArch64Subtarget>().getInstrInfo();
4093 AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
4094 bool EmitAsyncCFI = AFI->needsAsyncDwarfUnwindInfo(MF);
4095 bool HasFP = hasFP(MF);
4096
4097 DebugLoc DL;
4098 int64_t ProbeSize = MF.getInfo<AArch64FunctionInfo>()->getStackProbeSize();
4099 int64_t NumBlocks = FrameSize / ProbeSize;
4100 int64_t ResidualSize = FrameSize % ProbeSize;
4101
4102 LLVM_DEBUG(dbgs() << "Stack probing: total " << FrameSize << " bytes, "
4103 << NumBlocks << " blocks of " << ProbeSize
4104 << " bytes, plus " << ResidualSize << " bytes\n");
4105
4106 // Decrement SP by NumBlock * ProbeSize bytes, with either unrolled or
4107 // ordinary loop.
4108 if (NumBlocks <= AArch64::StackProbeMaxLoopUnroll) {
4109 for (int i = 0; i < NumBlocks; ++i) {
4110 // SUB SP, SP, #ProbeSize (or equivalent if ProbeSize is not
4111 // encodable in a SUB).
4112 emitFrameOffset(*MBB, MBBI, DL, AArch64::SP, AArch64::SP,
4113 StackOffset::getFixed(-ProbeSize), TII,
4114 MachineInstr::FrameSetup, false, false, nullptr,
4115 EmitAsyncCFI && !HasFP, CFAOffset);
4116 CFAOffset += StackOffset::getFixed(ProbeSize);
4117 // LDR XZR, [SP]
4118 BuildMI(*MBB, MBBI, DL, TII->get(AArch64::LDRXui))
4119 .addDef(AArch64::XZR)
4120 .addReg(AArch64::SP)
4121 .addImm(0)
4125 Align(8)))
4127 }
4128 } else if (NumBlocks != 0) {
4129 // SUB ScratchReg, SP, #FrameSize (or equivalent if FrameSize is not
4130 // encodable in ADD). ScrathReg may temporarily become the CFA register.
4131 emitFrameOffset(*MBB, MBBI, DL, ScratchReg, AArch64::SP,
4132 StackOffset::getFixed(-ProbeSize * NumBlocks), TII,
4133 MachineInstr::FrameSetup, false, false, nullptr,
4134 EmitAsyncCFI && !HasFP, CFAOffset);
4135 CFAOffset += StackOffset::getFixed(ProbeSize * NumBlocks);
4136 MBBI = inlineStackProbeLoopExactMultiple(MBBI, ProbeSize, ScratchReg);
4137 MBB = MBBI->getParent();
4138 if (EmitAsyncCFI && !HasFP) {
4139 // Set the CFA register back to SP.
4140 CFIInstBuilder(*MBB, MBBI, MachineInstr::FrameSetup)
4141 .buildDefCFARegister(AArch64::SP);
4142 }
4143 }
4144
4145 if (ResidualSize != 0) {
4146 // SUB SP, SP, #ResidualSize (or equivalent if ResidualSize is not encodable
4147 // in SUB).
4148 emitFrameOffset(*MBB, MBBI, DL, AArch64::SP, AArch64::SP,
4149 StackOffset::getFixed(-ResidualSize), TII,
4150 MachineInstr::FrameSetup, false, false, nullptr,
4151 EmitAsyncCFI && !HasFP, CFAOffset);
4152 if (ResidualSize > AArch64::StackProbeMaxUnprobedStack) {
4153 // LDR XZR, [SP]
4154 BuildMI(*MBB, MBBI, DL, TII->get(AArch64::LDRXui))
4155 .addDef(AArch64::XZR)
4156 .addReg(AArch64::SP)
4157 .addImm(0)
4161 Align(8)))
4163 }
4164 }
4165}
4166
4167void AArch64FrameLowering::inlineStackProbe(MachineFunction &MF,
4168 MachineBasicBlock &MBB) const {
4169 // Get the instructions that need to be replaced. We emit at most two of
4170 // these. Remember them in order to avoid complications coming from the need
4171 // to traverse the block while potentially creating more blocks.
4172 SmallVector<MachineInstr *, 4> ToReplace;
4173 for (MachineInstr &MI : MBB)
4174 if (MI.getOpcode() == AArch64::PROBED_STACKALLOC ||
4175 MI.getOpcode() == AArch64::PROBED_STACKALLOC_VAR)
4176 ToReplace.push_back(&MI);
4177
4178 for (MachineInstr *MI : ToReplace) {
4179 if (MI->getOpcode() == AArch64::PROBED_STACKALLOC) {
4180 Register ScratchReg = MI->getOperand(0).getReg();
4181 int64_t FrameSize = MI->getOperand(1).getImm();
4182 StackOffset CFAOffset = StackOffset::get(MI->getOperand(2).getImm(),
4183 MI->getOperand(3).getImm());
4184 inlineStackProbeFixed(MI->getIterator(), ScratchReg, FrameSize,
4185 CFAOffset);
4186 } else {
4187 assert(MI->getOpcode() == AArch64::PROBED_STACKALLOC_VAR &&
4188 "Stack probe pseudo-instruction expected");
4189 const AArch64InstrInfo *TII =
4190 MI->getMF()->getSubtarget<AArch64Subtarget>().getInstrInfo();
4191 Register TargetReg = MI->getOperand(0).getReg();
4192 (void)TII->probedStackAlloc(MI->getIterator(), TargetReg, true);
4193 }
4194 MI->eraseFromParent();
4195 }
4196}
4197
4200 NotAccessed = 0, // Stack object not accessed by load/store instructions.
4201 GPR = 1 << 0, // A general purpose register.
4202 PPR = 1 << 1, // A predicate register.
4203 FPR = 1 << 2, // A floating point/Neon/SVE register.
4204 };
4205
4206 int Idx;
4208 int64_t Size;
4209 unsigned AccessTypes;
4210
4212
4213 bool operator<(const StackAccess &Rhs) const {
4214 return std::make_tuple(start(), Idx) <
4215 std::make_tuple(Rhs.start(), Rhs.Idx);
4216 }
4217
4218 bool isCPU() const {
4219 // Predicate register load and store instructions execute on the CPU.
4221 }
4222 bool isSME() const { return AccessTypes & AccessType::FPR; }
4223 bool isMixed() const { return isCPU() && isSME(); }
4224
4225 int64_t start() const { return Offset.getFixed() + Offset.getScalable(); }
4226 int64_t end() const { return start() + Size; }
4227
4228 std::string getTypeString() const {
4229 switch (AccessTypes) {
4230 case AccessType::FPR:
4231 return "FPR";
4232 case AccessType::PPR:
4233 return "PPR";
4234 case AccessType::GPR:
4235 return "GPR";
4237 return "NA";
4238 default:
4239 return "Mixed";
4240 }
4241 }
4242
4243 void print(raw_ostream &OS) const {
4244 OS << getTypeString() << " stack object at [SP"
4245 << (Offset.getFixed() < 0 ? "" : "+") << Offset.getFixed();
4246 if (Offset.getScalable())
4247 OS << (Offset.getScalable() < 0 ? "" : "+") << Offset.getScalable()
4248 << " * vscale";
4249 OS << "]";
4250 }
4251};
4252
4253static inline raw_ostream &operator<<(raw_ostream &OS, const StackAccess &SA) {
4254 SA.print(OS);
4255 return OS;
4256}
4257
4258void AArch64FrameLowering::emitRemarks(
4259 const MachineFunction &MF, MachineOptimizationRemarkEmitter *ORE) const {
4260
4261 auto *AFI = MF.getInfo<AArch64FunctionInfo>();
4263 return;
4264
4265 uint64_t HazardSize = getStackHazardSize(MF);
4266 if (!HazardSize)
4267 HazardSize = MF.getSubtarget<AArch64Subtarget>()
4268 .getCLOpts()
4269 .stack_hazard_remark_size;
4270
4271 if (HazardSize == 0)
4272 return;
4273
4274 const MachineFrameInfo &MFI = MF.getFrameInfo();
4275 // Bail if function has no stack objects.
4276 if (!MFI.hasStackObjects())
4277 return;
4278
4279 std::vector<StackAccess> StackAccesses(MFI.getNumObjects());
4280
4281 size_t NumFPLdSt = 0;
4282 size_t NumNonFPLdSt = 0;
4283
4284 // Collect stack accesses via Load/Store instructions.
4285 for (const MachineBasicBlock &MBB : MF) {
4286 for (const MachineInstr &MI : MBB) {
4287 if (!MI.mayLoadOrStore() || MI.getNumMemOperands() < 1)
4288 continue;
4289 for (MachineMemOperand *MMO : MI.memoperands()) {
4290 std::optional<int> FI = getMMOFrameID(MMO, MFI);
4291 if (FI && !MFI.isDeadObjectIndex(*FI)) {
4292 int FrameIdx = *FI;
4293
4294 size_t ArrIdx = FrameIdx + MFI.getNumFixedObjects();
4295 if (StackAccesses[ArrIdx].AccessTypes == StackAccess::NotAccessed) {
4296 StackAccesses[ArrIdx].Idx = FrameIdx;
4297 StackAccesses[ArrIdx].Offset =
4298 getFrameIndexReferenceFromSP(MF, FrameIdx);
4299 StackAccesses[ArrIdx].Size = MFI.getObjectSize(FrameIdx);
4300 }
4301
4302 unsigned RegTy = StackAccess::AccessType::GPR;
4303 if (MFI.hasScalableStackID(FrameIdx))
4306 RegTy = StackAccess::FPR;
4307
4308 StackAccesses[ArrIdx].AccessTypes |= RegTy;
4309
4310 if (RegTy == StackAccess::FPR)
4311 ++NumFPLdSt;
4312 else
4313 ++NumNonFPLdSt;
4314 }
4315 }
4316 }
4317 }
4318
4319 if (NumFPLdSt == 0 || NumNonFPLdSt == 0)
4320 return;
4321
4322 llvm::sort(StackAccesses);
4323 llvm::erase_if(StackAccesses, [](const StackAccess &S) {
4325 });
4326
4329
4330 if (StackAccesses.front().isMixed())
4331 MixedObjects.push_back(&StackAccesses.front());
4332
4333 for (auto It = StackAccesses.begin(), End = std::prev(StackAccesses.end());
4334 It != End; ++It) {
4335 const auto &First = *It;
4336 const auto &Second = *(It + 1);
4337
4338 if (Second.isMixed())
4339 MixedObjects.push_back(&Second);
4340
4341 if ((First.isSME() && Second.isCPU()) ||
4342 (First.isCPU() && Second.isSME())) {
4343 uint64_t Distance = static_cast<uint64_t>(Second.start() - First.end());
4344 if (Distance < HazardSize)
4345 HazardPairs.emplace_back(&First, &Second);
4346 }
4347 }
4348
4349 auto EmitRemark = [&](llvm::StringRef Str) {
4350 ORE->emit([&]() {
4351 auto R = MachineOptimizationRemarkAnalysis(
4352 "sme", "StackHazard", MF.getFunction().getSubprogram(), &MF.front());
4353 return R << formatv("stack hazard in '{0}': ", MF.getName()).str() << Str;
4354 });
4355 };
4356
4357 for (const auto &P : HazardPairs)
4358 EmitRemark(formatv("{0} is too close to {1}", *P.first, *P.second).str());
4359
4360 for (const auto *Obj : MixedObjects)
4361 EmitRemark(
4362 formatv("{0} accessed by both GP and FP instructions", *Obj).str());
4363}
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)
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, unsigned SpillCount, unsigned Reg1, unsigned Reg2, bool UsesWinAAPCS, bool NeedsWinCFI, bool NeedsFrameRecord, const TargetRegisterInfo *TRI)
Returns true if Reg1 and Reg2 cannot be paired using a ldp/stp instruction.
static bool isLikelyToHaveSVEStack(const AArch64FrameLowering &AFL, const MachineFunction &MF)
static bool invalidateWindowsRegisterPairing(bool SpillExtendedVolatile, unsigned SpillCount, unsigned Reg1, unsigned Reg2, bool NeedsWinCFI, const TargetRegisterInfo *TRI)
static SVEStackSizes determineSVEStackSizes(MachineFunction &MF, AssignObjectOffsets AssignOffsets)
Process all the SVE stack objects and the SVE stack size and offsets for each object.
static bool isTargetWindows(const MachineFunction &MF)
static unsigned estimateRSStackSizeLimit(MachineFunction &MF)
Look at each instruction that references stack frames and return the stack size limit beyond which so...
static bool getSVECalleeSaveSlotRange(const MachineFrameInfo &MFI, int &Min, int &Max)
returns true if there are any SVE callee saves.
static 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...
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