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