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