LLVM 20.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// | callee-saved gpr registers | <--.
48// | | | On Darwin platforms these
49// |- - - - - - - - - - - - - - - - - -| | callee saves are swapped,
50// | prev_lr | | (frame record first)
51// | prev_fp | <--'
52// | async context if needed |
53// | (a.k.a. "frame record") |
54// |-----------------------------------| <- fp(=x29)
55// | <hazard padding> |
56// |-----------------------------------|
57// | |
58// | callee-saved fp/simd/SVE regs |
59// | |
60// |-----------------------------------|
61// | |
62// | SVE stack objects |
63// | |
64// |-----------------------------------|
65// |.empty.space.to.make.part.below....|
66// |.aligned.in.case.it.needs.more.than| (size of this area is unknown at
67// |.the.standard.16-byte.alignment....| compile time; if present)
68// |-----------------------------------|
69// | local variables of fixed size |
70// | including spill slots |
71// | <FPR> |
72// | <hazard padding> |
73// | <GPR> |
74// |-----------------------------------| <- bp(not defined by ABI,
75// |.variable-sized.local.variables....| LLVM chooses X19)
76// |.(VLAs)............................| (size of this area is unknown at
77// |...................................| compile time)
78// |-----------------------------------| <- sp
79// | | Lower address
80//
81//
82// To access the data in a frame, at-compile time, a constant offset must be
83// computable from one of the pointers (fp, bp, sp) to access it. The size
84// of the areas with a dotted background cannot be computed at compile-time
85// if they are present, making it required to have all three of fp, bp and
86// sp to be set up to be able to access all contents in the frame areas,
87// assuming all of the frame areas are non-empty.
88//
89// For most functions, some of the frame areas are empty. For those functions,
90// it may not be necessary to set up fp or bp:
91// * A base pointer is definitely needed when there are both VLAs and local
92// variables with more-than-default alignment requirements.
93// * A frame pointer is definitely needed when there are local variables with
94// more-than-default alignment requirements.
95//
96// For Darwin platforms the frame-record (fp, lr) is stored at the top of the
97// callee-saved area, since the unwind encoding does not allow for encoding
98// this dynamically and existing tools depend on this layout. For other
99// platforms, the frame-record is stored at the bottom of the (gpr) callee-saved
100// area to allow SVE stack objects (allocated directly below the callee-saves,
101// if available) to be accessed directly from the framepointer.
102// The SVE spill/fill instructions have VL-scaled addressing modes such
103// as:
104// ldr z8, [fp, #-7 mul vl]
105// For SVE the size of the vector length (VL) is not known at compile-time, so
106// '#-7 mul vl' is an offset that can only be evaluated at runtime. With this
107// layout, we don't need to add an unscaled offset to the framepointer before
108// accessing the SVE object in the frame.
109//
110// In some cases when a base pointer is not strictly needed, it is generated
111// anyway when offsets from the frame pointer to access local variables become
112// so large that the offset can't be encoded in the immediate fields of loads
113// or stores.
114//
115// Outgoing function arguments must be at the bottom of the stack frame when
116// calling another function. If we do not have variable-sized stack objects, we
117// can allocate a "reserved call frame" area at the bottom of the local
118// variable area, large enough for all outgoing calls. If we do have VLAs, then
119// the stack pointer must be decremented and incremented around each call to
120// make space for the arguments below the VLAs.
121//
122// FIXME: also explain the redzone concept.
123//
124// About stack hazards: Under some SME contexts, a coprocessor with its own
125// separate cache can used for FP operations. This can create hazards if the CPU
126// and the SME unit try to access the same area of memory, including if the
127// access is to an area of the stack. To try to alleviate this we attempt to
128// introduce extra padding into the stack frame between FP and GPR accesses,
129// controlled by the aarch64-stack-hazard-size option. Without changing the
130// layout of the stack frame in the diagram above, a stack object of size
131// aarch64-stack-hazard-size is added between GPR and FPR CSRs. Another is added
132// to the stack objects section, and stack objects are sorted so that FPR >
133// Hazard padding slot > GPRs (where possible). Unfortunately some things are
134// not handled well (VLA area, arguments on the stack, objects with both GPR and
135// FPR accesses), but if those are controlled by the user then the entire stack
136// frame becomes GPR at the start/end with FPR in the middle, surrounded by
137// Hazard padding.
138//
139// An example of the prologue:
140//
141// .globl __foo
142// .align 2
143// __foo:
144// Ltmp0:
145// .cfi_startproc
146// .cfi_personality 155, ___gxx_personality_v0
147// Leh_func_begin:
148// .cfi_lsda 16, Lexception33
149//
150// stp xa,bx, [sp, -#offset]!
151// ...
152// stp x28, x27, [sp, #offset-32]
153// stp fp, lr, [sp, #offset-16]
154// add fp, sp, #offset - 16
155// sub sp, sp, #1360
156//
157// The Stack:
158// +-------------------------------------------+
159// 10000 | ........ | ........ | ........ | ........ |
160// 10004 | ........ | ........ | ........ | ........ |
161// +-------------------------------------------+
162// 10008 | ........ | ........ | ........ | ........ |
163// 1000c | ........ | ........ | ........ | ........ |
164// +===========================================+
165// 10010 | X28 Register |
166// 10014 | X28 Register |
167// +-------------------------------------------+
168// 10018 | X27 Register |
169// 1001c | X27 Register |
170// +===========================================+
171// 10020 | Frame Pointer |
172// 10024 | Frame Pointer |
173// +-------------------------------------------+
174// 10028 | Link Register |
175// 1002c | Link Register |
176// +===========================================+
177// 10030 | ........ | ........ | ........ | ........ |
178// 10034 | ........ | ........ | ........ | ........ |
179// +-------------------------------------------+
180// 10038 | ........ | ........ | ........ | ........ |
181// 1003c | ........ | ........ | ........ | ........ |
182// +-------------------------------------------+
183//
184// [sp] = 10030 :: >>initial value<<
185// sp = 10020 :: stp fp, lr, [sp, #-16]!
186// fp = sp == 10020 :: mov fp, sp
187// [sp] == 10020 :: stp x28, x27, [sp, #-16]!
188// sp == 10010 :: >>final value<<
189//
190// The frame pointer (w29) points to address 10020. If we use an offset of
191// '16' from 'w29', we get the CFI offsets of -8 for w30, -16 for w29, -24
192// for w27, and -32 for w28:
193//
194// Ltmp1:
195// .cfi_def_cfa w29, 16
196// Ltmp2:
197// .cfi_offset w30, -8
198// Ltmp3:
199// .cfi_offset w29, -16
200// Ltmp4:
201// .cfi_offset w27, -24
202// Ltmp5:
203// .cfi_offset w28, -32
204//
205//===----------------------------------------------------------------------===//
206
207#include "AArch64FrameLowering.h"
208#include "AArch64InstrInfo.h"
210#include "AArch64RegisterInfo.h"
211#include "AArch64Subtarget.h"
215#include "llvm/ADT/ScopeExit.h"
216#include "llvm/ADT/SmallVector.h"
217#include "llvm/ADT/Statistic.h"
234#include "llvm/IR/Attributes.h"
235#include "llvm/IR/CallingConv.h"
236#include "llvm/IR/DataLayout.h"
237#include "llvm/IR/DebugLoc.h"
238#include "llvm/IR/Function.h"
239#include "llvm/MC/MCAsmInfo.h"
240#include "llvm/MC/MCDwarf.h"
242#include "llvm/Support/Debug.h"
249#include <cassert>
250#include <cstdint>
251#include <iterator>
252#include <optional>
253#include <vector>
254
255using namespace llvm;
256
257#define DEBUG_TYPE "frame-info"
258
259static cl::opt<bool> EnableRedZone("aarch64-redzone",
260 cl::desc("enable use of redzone on AArch64"),
261 cl::init(false), cl::Hidden);
262
264 "stack-tagging-merge-settag",
265 cl::desc("merge settag instruction in function epilog"), cl::init(true),
266 cl::Hidden);
267
268static cl::opt<bool> OrderFrameObjects("aarch64-order-frame-objects",
269 cl::desc("sort stack allocations"),
270 cl::init(true), cl::Hidden);
271
273 "homogeneous-prolog-epilog", cl::Hidden,
274 cl::desc("Emit homogeneous prologue and epilogue for the size "
275 "optimization (default = off)"));
276
277// Stack hazard size for analysis remarks. StackHazardSize takes precedence.
279 StackHazardRemarkSize("aarch64-stack-hazard-remark-size", cl::init(0),
280 cl::Hidden);
281// Whether to insert padding into non-streaming functions (for testing).
282static cl::opt<bool>
283 StackHazardInNonStreaming("aarch64-stack-hazard-in-non-streaming",
284 cl::init(false), cl::Hidden);
285
287 "aarch64-disable-multivector-spill-fill",
288 cl::desc("Disable use of LD/ST pairs for SME2 or SVE2p1"), cl::init(false),
289 cl::Hidden);
290
291STATISTIC(NumRedZoneFunctions, "Number of functions using red zone");
292
293/// Returns how much of the incoming argument stack area (in bytes) we should
294/// clean up in an epilogue. For the C calling convention this will be 0, for
295/// guaranteed tail call conventions it can be positive (a normal return or a
296/// tail call to a function that uses less stack space for arguments) or
297/// negative (for a tail call to a function that needs more stack space than us
298/// for arguments).
303 bool IsTailCallReturn = (MBB.end() != MBBI)
305 : false;
306
307 int64_t ArgumentPopSize = 0;
308 if (IsTailCallReturn) {
309 MachineOperand &StackAdjust = MBBI->getOperand(1);
310
311 // For a tail-call in a callee-pops-arguments environment, some or all of
312 // the stack may actually be in use for the call's arguments, this is
313 // calculated during LowerCall and consumed here...
314 ArgumentPopSize = StackAdjust.getImm();
315 } else {
316 // ... otherwise the amount to pop is *all* of the argument space,
317 // conveniently stored in the MachineFunctionInfo by
318 // LowerFormalArguments. This will, of course, be zero for the C calling
319 // convention.
320 ArgumentPopSize = AFI->getArgumentStackToRestore();
321 }
322
323 return ArgumentPopSize;
324}
325
327static bool needsWinCFI(const MachineFunction &MF);
330
331/// Returns true if a homogeneous prolog or epilog code can be emitted
332/// for the size optimization. If possible, a frame helper call is injected.
333/// When Exit block is given, this check is for epilog.
334bool AArch64FrameLowering::homogeneousPrologEpilog(
335 MachineFunction &MF, MachineBasicBlock *Exit) const {
336 if (!MF.getFunction().hasMinSize())
337 return false;
339 return false;
340 if (EnableRedZone)
341 return false;
342
343 // TODO: Window is supported yet.
344 if (needsWinCFI(MF))
345 return false;
346 // TODO: SVE is not supported yet.
347 if (getSVEStackSize(MF))
348 return false;
349
350 // Bail on stack adjustment needed on return for simplicity.
351 const MachineFrameInfo &MFI = MF.getFrameInfo();
353 if (MFI.hasVarSizedObjects() || RegInfo->hasStackRealignment(MF))
354 return false;
355 if (Exit && getArgumentStackToRestore(MF, *Exit))
356 return false;
357
358 auto *AFI = MF.getInfo<AArch64FunctionInfo>();
359 if (AFI->hasSwiftAsyncContext() || AFI->hasStreamingModeChanges())
360 return false;
361
362 // If there are an odd number of GPRs before LR and FP in the CSRs list,
363 // they will not be paired into one RegPairInfo, which is incompatible with
364 // the assumption made by the homogeneous prolog epilog pass.
365 const MCPhysReg *CSRegs = MF.getRegInfo().getCalleeSavedRegs();
366 unsigned NumGPRs = 0;
367 for (unsigned I = 0; CSRegs[I]; ++I) {
368 Register Reg = CSRegs[I];
369 if (Reg == AArch64::LR) {
370 assert(CSRegs[I + 1] == AArch64::FP);
371 if (NumGPRs % 2 != 0)
372 return false;
373 break;
374 }
375 if (AArch64::GPR64RegClass.contains(Reg))
376 ++NumGPRs;
377 }
378
379 return true;
380}
381
382/// Returns true if CSRs should be paired.
383bool AArch64FrameLowering::producePairRegisters(MachineFunction &MF) const {
384 return produceCompactUnwindFrame(MF) || homogeneousPrologEpilog(MF);
385}
386
387/// This is the biggest offset to the stack pointer we can encode in aarch64
388/// instructions (without using a separate calculation and a temp register).
389/// Note that the exception here are vector stores/loads which cannot encode any
390/// displacements (see estimateRSStackSizeLimit(), isAArch64FrameOffsetLegal()).
391static const unsigned DefaultSafeSPDisplacement = 255;
392
393/// Look at each instruction that references stack frames and return the stack
394/// size limit beyond which some of these instructions will require a scratch
395/// register during their expansion later.
397 // FIXME: For now, just conservatively guestimate based on unscaled indexing
398 // range. We'll end up allocating an unnecessary spill slot a lot, but
399 // realistically that's not a big deal at this stage of the game.
400 for (MachineBasicBlock &MBB : MF) {
401 for (MachineInstr &MI : MBB) {
402 if (MI.isDebugInstr() || MI.isPseudo() ||
403 MI.getOpcode() == AArch64::ADDXri ||
404 MI.getOpcode() == AArch64::ADDSXri)
405 continue;
406
407 for (const MachineOperand &MO : MI.operands()) {
408 if (!MO.isFI())
409 continue;
410
412 if (isAArch64FrameOffsetLegal(MI, Offset, nullptr, nullptr, nullptr) ==
414 return 0;
415 }
416 }
417 }
419}
420
424}
425
426/// Returns the size of the fixed object area (allocated next to sp on entry)
427/// On Win64 this may include a var args area and an UnwindHelp object for EH.
428static unsigned getFixedObjectSize(const MachineFunction &MF,
429 const AArch64FunctionInfo *AFI, bool IsWin64,
430 bool IsFunclet) {
431 if (!IsWin64 || IsFunclet) {
432 return AFI->getTailCallReservedStack();
433 } else {
434 if (AFI->getTailCallReservedStack() != 0 &&
436 Attribute::SwiftAsync))
437 report_fatal_error("cannot generate ABI-changing tail call for Win64");
438 // Var args are stored here in the primary function.
439 const unsigned VarArgsArea = AFI->getVarArgsGPRSize();
440 // To support EH funclets we allocate an UnwindHelp object
441 const unsigned UnwindHelpObject = (MF.hasEHFunclets() ? 8 : 0);
442 return AFI->getTailCallReservedStack() +
443 alignTo(VarArgsArea + UnwindHelpObject, 16);
444 }
445}
446
447/// Returns the size of the entire SVE stackframe (calleesaves + spills).
450 return StackOffset::getScalable((int64_t)AFI->getStackSizeSVE());
451}
452
454 if (!EnableRedZone)
455 return false;
456
457 // Don't use the red zone if the function explicitly asks us not to.
458 // This is typically used for kernel code.
459 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
460 const unsigned RedZoneSize =
462 if (!RedZoneSize)
463 return false;
464
465 const MachineFrameInfo &MFI = MF.getFrameInfo();
467 uint64_t NumBytes = AFI->getLocalStackSize();
468
469 // If neither NEON or SVE are available, a COPY from one Q-reg to
470 // another requires a spill -> reload sequence. We can do that
471 // using a pre-decrementing store/post-decrementing load, but
472 // if we do so, we can't use the Red Zone.
473 bool LowerQRegCopyThroughMem = Subtarget.hasFPARMv8() &&
474 !Subtarget.isNeonAvailable() &&
475 !Subtarget.hasSVE();
476
477 return !(MFI.hasCalls() || hasFP(MF) || NumBytes > RedZoneSize ||
478 getSVEStackSize(MF) || LowerQRegCopyThroughMem);
479}
480
481/// hasFPImpl - Return true if the specified function should have a dedicated
482/// frame pointer register.
484 const MachineFrameInfo &MFI = MF.getFrameInfo();
485 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
486
487 // Win64 EH requires a frame pointer if funclets are present, as the locals
488 // are accessed off the frame pointer in both the parent function and the
489 // funclets.
490 if (MF.hasEHFunclets())
491 return true;
492 // Retain behavior of always omitting the FP for leaf functions when possible.
494 return true;
495 if (MFI.hasVarSizedObjects() || MFI.isFrameAddressTaken() ||
496 MFI.hasStackMap() || MFI.hasPatchPoint() ||
497 RegInfo->hasStackRealignment(MF))
498 return true;
499 // With large callframes around we may need to use FP to access the scavenging
500 // emergency spillslot.
501 //
502 // Unfortunately some calls to hasFP() like machine verifier ->
503 // getReservedReg() -> hasFP in the middle of global isel are too early
504 // to know the max call frame size. Hopefully conservatively returning "true"
505 // in those cases is fine.
506 // DefaultSafeSPDisplacement is fine as we only emergency spill GP regs.
507 if (!MFI.isMaxCallFrameSizeComputed() ||
509 return true;
510
511 return false;
512}
513
514/// hasReservedCallFrame - Under normal circumstances, when a frame pointer is
515/// not required, we reserve argument space for call sites in the function
516/// immediately on entry to the current function. This eliminates the need for
517/// add/sub sp brackets around call sites. Returns true if the call frame is
518/// included as part of the stack frame.
520 const MachineFunction &MF) const {
521 // The stack probing code for the dynamically allocated outgoing arguments
522 // area assumes that the stack is probed at the top - either by the prologue
523 // code, which issues a probe if `hasVarSizedObjects` return true, or by the
524 // most recent variable-sized object allocation. Changing the condition here
525 // may need to be followed up by changes to the probe issuing logic.
526 return !MF.getFrameInfo().hasVarSizedObjects();
527}
528
532 const AArch64InstrInfo *TII =
533 static_cast<const AArch64InstrInfo *>(MF.getSubtarget().getInstrInfo());
534 const AArch64TargetLowering *TLI =
535 MF.getSubtarget<AArch64Subtarget>().getTargetLowering();
536 [[maybe_unused]] MachineFrameInfo &MFI = MF.getFrameInfo();
537 DebugLoc DL = I->getDebugLoc();
538 unsigned Opc = I->getOpcode();
539 bool IsDestroy = Opc == TII->getCallFrameDestroyOpcode();
540 uint64_t CalleePopAmount = IsDestroy ? I->getOperand(1).getImm() : 0;
541
542 if (!hasReservedCallFrame(MF)) {
543 int64_t Amount = I->getOperand(0).getImm();
544 Amount = alignTo(Amount, getStackAlign());
545 if (!IsDestroy)
546 Amount = -Amount;
547
548 // N.b. if CalleePopAmount is valid but zero (i.e. callee would pop, but it
549 // doesn't have to pop anything), then the first operand will be zero too so
550 // this adjustment is a no-op.
551 if (CalleePopAmount == 0) {
552 // FIXME: in-function stack adjustment for calls is limited to 24-bits
553 // because there's no guaranteed temporary register available.
554 //
555 // ADD/SUB (immediate) has only LSL #0 and LSL #12 available.
556 // 1) For offset <= 12-bit, we use LSL #0
557 // 2) For 12-bit <= offset <= 24-bit, we use two instructions. One uses
558 // LSL #0, and the other uses LSL #12.
559 //
560 // Most call frames will be allocated at the start of a function so
561 // this is OK, but it is a limitation that needs dealing with.
562 assert(Amount > -0xffffff && Amount < 0xffffff && "call frame too large");
563
564 if (TLI->hasInlineStackProbe(MF) &&
566 // When stack probing is enabled, the decrement of SP may need to be
567 // probed. We only need to do this if the call site needs 1024 bytes of
568 // space or more, because a region smaller than that is allowed to be
569 // unprobed at an ABI boundary. We rely on the fact that SP has been
570 // probed exactly at this point, either by the prologue or most recent
571 // dynamic allocation.
573 "non-reserved call frame without var sized objects?");
574 Register ScratchReg =
575 MF.getRegInfo().createVirtualRegister(&AArch64::GPR64RegClass);
576 inlineStackProbeFixed(I, ScratchReg, -Amount, StackOffset::get(0, 0));
577 } else {
578 emitFrameOffset(MBB, I, DL, AArch64::SP, AArch64::SP,
579 StackOffset::getFixed(Amount), TII);
580 }
581 }
582 } else if (CalleePopAmount != 0) {
583 // If the calling convention demands that the callee pops arguments from the
584 // stack, we want to add it back if we have a reserved call frame.
585 assert(CalleePopAmount < 0xffffff && "call frame too large");
586 emitFrameOffset(MBB, I, DL, AArch64::SP, AArch64::SP,
587 StackOffset::getFixed(-(int64_t)CalleePopAmount), TII);
588 }
589 return MBB.erase(I);
590}
591
592void AArch64FrameLowering::emitCalleeSavedGPRLocations(
595 MachineFrameInfo &MFI = MF.getFrameInfo();
597 SMEAttrs Attrs(MF.getFunction());
598 bool LocallyStreaming =
599 Attrs.hasStreamingBody() && !Attrs.hasStreamingInterface();
600
601 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
602 if (CSI.empty())
603 return;
604
605 const TargetSubtargetInfo &STI = MF.getSubtarget();
606 const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
607 const TargetInstrInfo &TII = *STI.getInstrInfo();
609
610 for (const auto &Info : CSI) {
611 unsigned FrameIdx = Info.getFrameIdx();
612 if (MFI.getStackID(FrameIdx) == TargetStackID::ScalableVector)
613 continue;
614
615 assert(!Info.isSpilledToReg() && "Spilling to registers not implemented");
616 int64_t DwarfReg = TRI.getDwarfRegNum(Info.getReg(), true);
617 int64_t Offset = MFI.getObjectOffset(FrameIdx) - getOffsetOfLocalArea();
618
619 // The location of VG will be emitted before each streaming-mode change in
620 // the function. Only locally-streaming functions require emitting the
621 // non-streaming VG location here.
622 if ((LocallyStreaming && FrameIdx == AFI->getStreamingVGIdx()) ||
623 (!LocallyStreaming &&
624 DwarfReg == TRI.getDwarfRegNum(AArch64::VG, true)))
625 continue;
626
627 unsigned CFIIndex = MF.addFrameInst(
628 MCCFIInstruction::createOffset(nullptr, DwarfReg, Offset));
629 BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
630 .addCFIIndex(CFIIndex)
632 }
633}
634
635void AArch64FrameLowering::emitCalleeSavedSVELocations(
638 MachineFrameInfo &MFI = MF.getFrameInfo();
639
640 // Add callee saved registers to move list.
641 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
642 if (CSI.empty())
643 return;
644
645 const TargetSubtargetInfo &STI = MF.getSubtarget();
646 const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
647 const TargetInstrInfo &TII = *STI.getInstrInfo();
650
651 for (const auto &Info : CSI) {
652 if (!(MFI.getStackID(Info.getFrameIdx()) == TargetStackID::ScalableVector))
653 continue;
654
655 // Not all unwinders may know about SVE registers, so assume the lowest
656 // common demoninator.
657 assert(!Info.isSpilledToReg() && "Spilling to registers not implemented");
658 unsigned Reg = Info.getReg();
659 if (!static_cast<const AArch64RegisterInfo &>(TRI).regNeedsCFI(Reg, Reg))
660 continue;
661
663 StackOffset::getScalable(MFI.getObjectOffset(Info.getFrameIdx())) -
665
666 unsigned CFIIndex = MF.addFrameInst(createCFAOffset(TRI, Reg, Offset));
667 BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
668 .addCFIIndex(CFIIndex)
670 }
671}
672
676 unsigned DwarfReg) {
677 unsigned CFIIndex =
678 MF.addFrameInst(MCCFIInstruction::createSameValue(nullptr, DwarfReg));
679 BuildMI(MBB, InsertPt, DebugLoc(), Desc).addCFIIndex(CFIIndex);
680}
681
683 MachineBasicBlock &MBB) const {
684
686 const auto &Subtarget = MF.getSubtarget<AArch64Subtarget>();
687 const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
688 const auto &TRI =
689 static_cast<const AArch64RegisterInfo &>(*Subtarget.getRegisterInfo());
690 const auto &MFI = *MF.getInfo<AArch64FunctionInfo>();
691
692 const MCInstrDesc &CFIDesc = TII.get(TargetOpcode::CFI_INSTRUCTION);
693 DebugLoc DL;
694
695 // Reset the CFA to `SP + 0`.
697 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::cfiDefCfa(
698 nullptr, TRI.getDwarfRegNum(AArch64::SP, true), 0));
699 BuildMI(MBB, InsertPt, DL, CFIDesc).addCFIIndex(CFIIndex);
700
701 // Flip the RA sign state.
702 if (MFI.shouldSignReturnAddress(MF)) {
703 auto CFIInst = MFI.branchProtectionPAuthLR()
706 CFIIndex = MF.addFrameInst(CFIInst);
707 BuildMI(MBB, InsertPt, DL, CFIDesc).addCFIIndex(CFIIndex);
708 }
709
710 // Shadow call stack uses X18, reset it.
711 if (MFI.needsShadowCallStackPrologueEpilogue(MF))
712 insertCFISameValue(CFIDesc, MF, MBB, InsertPt,
713 TRI.getDwarfRegNum(AArch64::X18, true));
714
715 // Emit .cfi_same_value for callee-saved registers.
716 const std::vector<CalleeSavedInfo> &CSI =
718 for (const auto &Info : CSI) {
719 unsigned Reg = Info.getReg();
720 if (!TRI.regNeedsCFI(Reg, Reg))
721 continue;
722 insertCFISameValue(CFIDesc, MF, MBB, InsertPt,
723 TRI.getDwarfRegNum(Reg, true));
724 }
725}
726
729 bool SVE) {
731 MachineFrameInfo &MFI = MF.getFrameInfo();
732
733 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
734 if (CSI.empty())
735 return;
736
737 const TargetSubtargetInfo &STI = MF.getSubtarget();
738 const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
739 const TargetInstrInfo &TII = *STI.getInstrInfo();
741
742 for (const auto &Info : CSI) {
743 if (SVE !=
744 (MFI.getStackID(Info.getFrameIdx()) == TargetStackID::ScalableVector))
745 continue;
746
747 unsigned Reg = Info.getReg();
748 if (SVE &&
749 !static_cast<const AArch64RegisterInfo &>(TRI).regNeedsCFI(Reg, Reg))
750 continue;
751
752 if (!Info.isRestored())
753 continue;
754
755 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore(
756 nullptr, TRI.getDwarfRegNum(Info.getReg(), true)));
757 BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
758 .addCFIIndex(CFIIndex)
760 }
761}
762
763void AArch64FrameLowering::emitCalleeSavedGPRRestores(
766}
767
768void AArch64FrameLowering::emitCalleeSavedSVERestores(
771}
772
773// Return the maximum possible number of bytes for `Size` due to the
774// architectural limit on the size of a SVE register.
775static int64_t upperBound(StackOffset Size) {
776 static const int64_t MAX_BYTES_PER_SCALABLE_BYTE = 16;
777 return Size.getScalable() * MAX_BYTES_PER_SCALABLE_BYTE + Size.getFixed();
778}
779
780void AArch64FrameLowering::allocateStackSpace(
782 int64_t RealignmentPadding, StackOffset AllocSize, bool NeedsWinCFI,
783 bool *HasWinCFI, bool EmitCFI, StackOffset InitialOffset,
784 bool FollowupAllocs) const {
785
786 if (!AllocSize)
787 return;
788
789 DebugLoc DL;
791 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
792 const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
794 const MachineFrameInfo &MFI = MF.getFrameInfo();
795
796 const int64_t MaxAlign = MFI.getMaxAlign().value();
797 const uint64_t AndMask = ~(MaxAlign - 1);
798
799 if (!Subtarget.getTargetLowering()->hasInlineStackProbe(MF)) {
800 Register TargetReg = RealignmentPadding
802 : AArch64::SP;
803 // SUB Xd/SP, SP, AllocSize
804 emitFrameOffset(MBB, MBBI, DL, TargetReg, AArch64::SP, -AllocSize, &TII,
805 MachineInstr::FrameSetup, false, NeedsWinCFI, HasWinCFI,
806 EmitCFI, InitialOffset);
807
808 if (RealignmentPadding) {
809 // AND SP, X9, 0b11111...0000
810 BuildMI(MBB, MBBI, DL, TII.get(AArch64::ANDXri), AArch64::SP)
811 .addReg(TargetReg, RegState::Kill)
814 AFI.setStackRealigned(true);
815
816 // No need for SEH instructions here; if we're realigning the stack,
817 // we've set a frame pointer and already finished the SEH prologue.
818 assert(!NeedsWinCFI);
819 }
820 return;
821 }
822
823 //
824 // Stack probing allocation.
825 //
826
827 // Fixed length allocation. If we don't need to re-align the stack and don't
828 // have SVE objects, we can use a more efficient sequence for stack probing.
829 if (AllocSize.getScalable() == 0 && RealignmentPadding == 0) {
831 assert(ScratchReg != AArch64::NoRegister);
832 BuildMI(MBB, MBBI, DL, TII.get(AArch64::PROBED_STACKALLOC))
833 .addDef(ScratchReg)
834 .addImm(AllocSize.getFixed())
835 .addImm(InitialOffset.getFixed())
836 .addImm(InitialOffset.getScalable());
837 // The fixed allocation may leave unprobed bytes at the top of the
838 // stack. If we have subsequent alocation (e.g. if we have variable-sized
839 // objects), we need to issue an extra probe, so these allocations start in
840 // a known state.
841 if (FollowupAllocs) {
842 // STR XZR, [SP]
843 BuildMI(MBB, MBBI, DL, TII.get(AArch64::STRXui))
844 .addReg(AArch64::XZR)
845 .addReg(AArch64::SP)
846 .addImm(0)
848 }
849
850 return;
851 }
852
853 // Variable length allocation.
854
855 // If the (unknown) allocation size cannot exceed the probe size, decrement
856 // the stack pointer right away.
857 int64_t ProbeSize = AFI.getStackProbeSize();
858 if (upperBound(AllocSize) + RealignmentPadding <= ProbeSize) {
859 Register ScratchReg = RealignmentPadding
861 : AArch64::SP;
862 assert(ScratchReg != AArch64::NoRegister);
863 // SUB Xd, SP, AllocSize
864 emitFrameOffset(MBB, MBBI, DL, ScratchReg, AArch64::SP, -AllocSize, &TII,
865 MachineInstr::FrameSetup, false, NeedsWinCFI, HasWinCFI,
866 EmitCFI, InitialOffset);
867 if (RealignmentPadding) {
868 // AND SP, Xn, 0b11111...0000
869 BuildMI(MBB, MBBI, DL, TII.get(AArch64::ANDXri), AArch64::SP)
870 .addReg(ScratchReg, RegState::Kill)
873 AFI.setStackRealigned(true);
874 }
875 if (FollowupAllocs || upperBound(AllocSize) + RealignmentPadding >
877 // STR XZR, [SP]
878 BuildMI(MBB, MBBI, DL, TII.get(AArch64::STRXui))
879 .addReg(AArch64::XZR)
880 .addReg(AArch64::SP)
881 .addImm(0)
883 }
884 return;
885 }
886
887 // Emit a variable-length allocation probing loop.
888 // TODO: As an optimisation, the loop can be "unrolled" into a few parts,
889 // each of them guaranteed to adjust the stack by less than the probe size.
891 assert(TargetReg != AArch64::NoRegister);
892 // SUB Xd, SP, AllocSize
893 emitFrameOffset(MBB, MBBI, DL, TargetReg, AArch64::SP, -AllocSize, &TII,
894 MachineInstr::FrameSetup, false, NeedsWinCFI, HasWinCFI,
895 EmitCFI, InitialOffset);
896 if (RealignmentPadding) {
897 // AND Xn, Xn, 0b11111...0000
898 BuildMI(MBB, MBBI, DL, TII.get(AArch64::ANDXri), TargetReg)
899 .addReg(TargetReg, RegState::Kill)
902 }
903
904 BuildMI(MBB, MBBI, DL, TII.get(AArch64::PROBED_STACKALLOC_VAR))
905 .addReg(TargetReg);
906 if (EmitCFI) {
907 // Set the CFA register back to SP.
908 unsigned Reg =
909 Subtarget.getRegisterInfo()->getDwarfRegNum(AArch64::SP, true);
910 unsigned CFIIndex =
912 BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
913 .addCFIIndex(CFIIndex)
915 }
916 if (RealignmentPadding)
917 AFI.setStackRealigned(true);
918}
919
920static MCRegister getRegisterOrZero(MCRegister Reg, bool HasSVE) {
921 switch (Reg.id()) {
922 default:
923 // The called routine is expected to preserve r19-r28
924 // r29 and r30 are used as frame pointer and link register resp.
925 return 0;
926
927 // GPRs
928#define CASE(n) \
929 case AArch64::W##n: \
930 case AArch64::X##n: \
931 return AArch64::X##n
932 CASE(0);
933 CASE(1);
934 CASE(2);
935 CASE(3);
936 CASE(4);
937 CASE(5);
938 CASE(6);
939 CASE(7);
940 CASE(8);
941 CASE(9);
942 CASE(10);
943 CASE(11);
944 CASE(12);
945 CASE(13);
946 CASE(14);
947 CASE(15);
948 CASE(16);
949 CASE(17);
950 CASE(18);
951#undef CASE
952
953 // FPRs
954#define CASE(n) \
955 case AArch64::B##n: \
956 case AArch64::H##n: \
957 case AArch64::S##n: \
958 case AArch64::D##n: \
959 case AArch64::Q##n: \
960 return HasSVE ? AArch64::Z##n : AArch64::Q##n
961 CASE(0);
962 CASE(1);
963 CASE(2);
964 CASE(3);
965 CASE(4);
966 CASE(5);
967 CASE(6);
968 CASE(7);
969 CASE(8);
970 CASE(9);
971 CASE(10);
972 CASE(11);
973 CASE(12);
974 CASE(13);
975 CASE(14);
976 CASE(15);
977 CASE(16);
978 CASE(17);
979 CASE(18);
980 CASE(19);
981 CASE(20);
982 CASE(21);
983 CASE(22);
984 CASE(23);
985 CASE(24);
986 CASE(25);
987 CASE(26);
988 CASE(27);
989 CASE(28);
990 CASE(29);
991 CASE(30);
992 CASE(31);
993#undef CASE
994 }
995}
996
997void AArch64FrameLowering::emitZeroCallUsedRegs(BitVector RegsToZero,
998 MachineBasicBlock &MBB) const {
999 // Insertion point.
1001
1002 // Fake a debug loc.
1003 DebugLoc DL;
1004 if (MBBI != MBB.end())
1005 DL = MBBI->getDebugLoc();
1006
1007 const MachineFunction &MF = *MBB.getParent();
1009 const AArch64RegisterInfo &TRI = *STI.getRegisterInfo();
1010
1011 BitVector GPRsToZero(TRI.getNumRegs());
1012 BitVector FPRsToZero(TRI.getNumRegs());
1013 bool HasSVE = STI.isSVEorStreamingSVEAvailable();
1014 for (MCRegister Reg : RegsToZero.set_bits()) {
1015 if (TRI.isGeneralPurposeRegister(MF, Reg)) {
1016 // For GPRs, we only care to clear out the 64-bit register.
1017 if (MCRegister XReg = getRegisterOrZero(Reg, HasSVE))
1018 GPRsToZero.set(XReg);
1019 } else if (AArch64InstrInfo::isFpOrNEON(Reg)) {
1020 // For FPRs,
1021 if (MCRegister XReg = getRegisterOrZero(Reg, HasSVE))
1022 FPRsToZero.set(XReg);
1023 }
1024 }
1025
1026 const AArch64InstrInfo &TII = *STI.getInstrInfo();
1027
1028 // Zero out GPRs.
1029 for (MCRegister Reg : GPRsToZero.set_bits())
1030 TII.buildClearRegister(Reg, MBB, MBBI, DL);
1031
1032 // Zero out FP/vector registers.
1033 for (MCRegister Reg : FPRsToZero.set_bits())
1034 TII.buildClearRegister(Reg, MBB, MBBI, DL);
1035
1036 if (HasSVE) {
1037 for (MCRegister PReg :
1038 {AArch64::P0, AArch64::P1, AArch64::P2, AArch64::P3, AArch64::P4,
1039 AArch64::P5, AArch64::P6, AArch64::P7, AArch64::P8, AArch64::P9,
1040 AArch64::P10, AArch64::P11, AArch64::P12, AArch64::P13, AArch64::P14,
1041 AArch64::P15}) {
1042 if (RegsToZero[PReg])
1043 BuildMI(MBB, MBBI, DL, TII.get(AArch64::PFALSE), PReg);
1044 }
1045 }
1046}
1047
1049 const MachineBasicBlock &MBB) {
1050 const MachineFunction *MF = MBB.getParent();
1051 LiveRegs.addLiveIns(MBB);
1052 // Mark callee saved registers as used so we will not choose them.
1053 const MCPhysReg *CSRegs = MF->getRegInfo().getCalleeSavedRegs();
1054 for (unsigned i = 0; CSRegs[i]; ++i)
1055 LiveRegs.addReg(CSRegs[i]);
1056}
1057
1058// Find a scratch register that we can use at the start of the prologue to
1059// re-align the stack pointer. We avoid using callee-save registers since they
1060// may appear to be free when this is called from canUseAsPrologue (during
1061// shrink wrapping), but then no longer be free when this is called from
1062// emitPrologue.
1063//
1064// FIXME: This is a bit conservative, since in the above case we could use one
1065// of the callee-save registers as a scratch temp to re-align the stack pointer,
1066// but we would then have to make sure that we were in fact saving at least one
1067// callee-save register in the prologue, which is additional complexity that
1068// doesn't seem worth the benefit.
1070 MachineFunction *MF = MBB->getParent();
1071
1072 // If MBB is an entry block, use X9 as the scratch register
1073 // preserve_none functions may be using X9 to pass arguments,
1074 // so prefer to pick an available register below.
1075 if (&MF->front() == MBB &&
1077 return AArch64::X9;
1078
1079 const AArch64Subtarget &Subtarget = MF->getSubtarget<AArch64Subtarget>();
1080 const AArch64RegisterInfo &TRI = *Subtarget.getRegisterInfo();
1081 LivePhysRegs LiveRegs(TRI);
1082 getLiveRegsForEntryMBB(LiveRegs, *MBB);
1083
1084 // Prefer X9 since it was historically used for the prologue scratch reg.
1085 const MachineRegisterInfo &MRI = MF->getRegInfo();
1086 if (LiveRegs.available(MRI, AArch64::X9))
1087 return AArch64::X9;
1088
1089 for (unsigned Reg : AArch64::GPR64RegClass) {
1090 if (LiveRegs.available(MRI, Reg))
1091 return Reg;
1092 }
1093 return AArch64::NoRegister;
1094}
1095
1097 const MachineBasicBlock &MBB) const {
1098 const MachineFunction *MF = MBB.getParent();
1099 MachineBasicBlock *TmpMBB = const_cast<MachineBasicBlock *>(&MBB);
1100 const AArch64Subtarget &Subtarget = MF->getSubtarget<AArch64Subtarget>();
1101 const AArch64RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
1102 const AArch64TargetLowering *TLI = Subtarget.getTargetLowering();
1104
1105 if (AFI->hasSwiftAsyncContext()) {
1106 const AArch64RegisterInfo &TRI = *Subtarget.getRegisterInfo();
1107 const MachineRegisterInfo &MRI = MF->getRegInfo();
1108 LivePhysRegs LiveRegs(TRI);
1109 getLiveRegsForEntryMBB(LiveRegs, MBB);
1110 // The StoreSwiftAsyncContext clobbers X16 and X17. Make sure they are
1111 // available.
1112 if (!LiveRegs.available(MRI, AArch64::X16) ||
1113 !LiveRegs.available(MRI, AArch64::X17))
1114 return false;
1115 }
1116
1117 // Certain stack probing sequences might clobber flags, then we can't use
1118 // the block as a prologue if the flags register is a live-in.
1120 MBB.isLiveIn(AArch64::NZCV))
1121 return false;
1122
1123 // Don't need a scratch register if we're not going to re-align the stack or
1124 // emit stack probes.
1125 if (!RegInfo->hasStackRealignment(*MF) && !TLI->hasInlineStackProbe(*MF))
1126 return true;
1127 // Otherwise, we can use any block as long as it has a scratch register
1128 // available.
1129 return findScratchNonCalleeSaveRegister(TmpMBB) != AArch64::NoRegister;
1130}
1131
1133 uint64_t StackSizeInBytes) {
1134 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
1136 // TODO: When implementing stack protectors, take that into account
1137 // for the probe threshold.
1138 return Subtarget.isTargetWindows() && MFI.hasStackProbing() &&
1139 StackSizeInBytes >= uint64_t(MFI.getStackProbeSize());
1140}
1141
1142static bool needsWinCFI(const MachineFunction &MF) {
1143 const Function &F = MF.getFunction();
1144 return MF.getTarget().getMCAsmInfo()->usesWindowsCFI() &&
1145 F.needsUnwindTableEntry();
1146}
1147
1148bool AArch64FrameLowering::shouldCombineCSRLocalStackBump(
1149 MachineFunction &MF, uint64_t StackBumpBytes) const {
1151 const MachineFrameInfo &MFI = MF.getFrameInfo();
1152 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
1153 const AArch64RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
1154 if (homogeneousPrologEpilog(MF))
1155 return false;
1156
1157 if (AFI->getLocalStackSize() == 0)
1158 return false;
1159
1160 // For WinCFI, if optimizing for size, prefer to not combine the stack bump
1161 // (to force a stp with predecrement) to match the packed unwind format,
1162 // provided that there actually are any callee saved registers to merge the
1163 // decrement with.
1164 // This is potentially marginally slower, but allows using the packed
1165 // unwind format for functions that both have a local area and callee saved
1166 // registers. Using the packed unwind format notably reduces the size of
1167 // the unwind info.
1168 if (needsWinCFI(MF) && AFI->getCalleeSavedStackSize() > 0 &&
1169 MF.getFunction().hasOptSize())
1170 return false;
1171
1172 // 512 is the maximum immediate for stp/ldp that will be used for
1173 // callee-save save/restores
1174 if (StackBumpBytes >= 512 || windowsRequiresStackProbe(MF, StackBumpBytes))
1175 return false;
1176
1177 if (MFI.hasVarSizedObjects())
1178 return false;
1179
1180 if (RegInfo->hasStackRealignment(MF))
1181 return false;
1182
1183 // This isn't strictly necessary, but it simplifies things a bit since the
1184 // current RedZone handling code assumes the SP is adjusted by the
1185 // callee-save save/restore code.
1186 if (canUseRedZone(MF))
1187 return false;
1188
1189 // When there is an SVE area on the stack, always allocate the
1190 // callee-saves and spills/locals separately.
1191 if (getSVEStackSize(MF))
1192 return false;
1193
1194 return true;
1195}
1196
1197bool AArch64FrameLowering::shouldCombineCSRLocalStackBumpInEpilogue(
1198 MachineBasicBlock &MBB, uint64_t StackBumpBytes) const {
1199 if (!shouldCombineCSRLocalStackBump(*MBB.getParent(), StackBumpBytes))
1200 return false;
1201 if (MBB.empty())
1202 return true;
1203
1204 // Disable combined SP bump if the last instruction is an MTE tag store. It
1205 // is almost always better to merge SP adjustment into those instructions.
1208 while (LastI != Begin) {
1209 --LastI;
1210 if (LastI->isTransient())
1211 continue;
1212 if (!LastI->getFlag(MachineInstr::FrameDestroy))
1213 break;
1214 }
1215 switch (LastI->getOpcode()) {
1216 case AArch64::STGloop:
1217 case AArch64::STZGloop:
1218 case AArch64::STGi:
1219 case AArch64::STZGi:
1220 case AArch64::ST2Gi:
1221 case AArch64::STZ2Gi:
1222 return false;
1223 default:
1224 return true;
1225 }
1226 llvm_unreachable("unreachable");
1227}
1228
1229// Given a load or a store instruction, generate an appropriate unwinding SEH
1230// code on Windows.
1232 const TargetInstrInfo &TII,
1233 MachineInstr::MIFlag Flag) {
1234 unsigned Opc = MBBI->getOpcode();
1236 MachineFunction &MF = *MBB->getParent();
1237 DebugLoc DL = MBBI->getDebugLoc();
1238 unsigned ImmIdx = MBBI->getNumOperands() - 1;
1239 int Imm = MBBI->getOperand(ImmIdx).getImm();
1241 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
1242 const AArch64RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
1243
1244 switch (Opc) {
1245 default:
1246 llvm_unreachable("No SEH Opcode for this instruction");
1247 case AArch64::LDPDpost:
1248 Imm = -Imm;
1249 [[fallthrough]];
1250 case AArch64::STPDpre: {
1251 unsigned Reg0 = RegInfo->getSEHRegNum(MBBI->getOperand(1).getReg());
1252 unsigned Reg1 = RegInfo->getSEHRegNum(MBBI->getOperand(2).getReg());
1253 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveFRegP_X))
1254 .addImm(Reg0)
1255 .addImm(Reg1)
1256 .addImm(Imm * 8)
1257 .setMIFlag(Flag);
1258 break;
1259 }
1260 case AArch64::LDPXpost:
1261 Imm = -Imm;
1262 [[fallthrough]];
1263 case AArch64::STPXpre: {
1264 Register Reg0 = MBBI->getOperand(1).getReg();
1265 Register Reg1 = MBBI->getOperand(2).getReg();
1266 if (Reg0 == AArch64::FP && Reg1 == AArch64::LR)
1267 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveFPLR_X))
1268 .addImm(Imm * 8)
1269 .setMIFlag(Flag);
1270 else
1271 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveRegP_X))
1272 .addImm(RegInfo->getSEHRegNum(Reg0))
1273 .addImm(RegInfo->getSEHRegNum(Reg1))
1274 .addImm(Imm * 8)
1275 .setMIFlag(Flag);
1276 break;
1277 }
1278 case AArch64::LDRDpost:
1279 Imm = -Imm;
1280 [[fallthrough]];
1281 case AArch64::STRDpre: {
1282 unsigned Reg = RegInfo->getSEHRegNum(MBBI->getOperand(1).getReg());
1283 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveFReg_X))
1284 .addImm(Reg)
1285 .addImm(Imm)
1286 .setMIFlag(Flag);
1287 break;
1288 }
1289 case AArch64::LDRXpost:
1290 Imm = -Imm;
1291 [[fallthrough]];
1292 case AArch64::STRXpre: {
1293 unsigned Reg = RegInfo->getSEHRegNum(MBBI->getOperand(1).getReg());
1294 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveReg_X))
1295 .addImm(Reg)
1296 .addImm(Imm)
1297 .setMIFlag(Flag);
1298 break;
1299 }
1300 case AArch64::STPDi:
1301 case AArch64::LDPDi: {
1302 unsigned Reg0 = RegInfo->getSEHRegNum(MBBI->getOperand(0).getReg());
1303 unsigned Reg1 = RegInfo->getSEHRegNum(MBBI->getOperand(1).getReg());
1304 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveFRegP))
1305 .addImm(Reg0)
1306 .addImm(Reg1)
1307 .addImm(Imm * 8)
1308 .setMIFlag(Flag);
1309 break;
1310 }
1311 case AArch64::STPXi:
1312 case AArch64::LDPXi: {
1313 Register Reg0 = MBBI->getOperand(0).getReg();
1314 Register Reg1 = MBBI->getOperand(1).getReg();
1315 if (Reg0 == AArch64::FP && Reg1 == AArch64::LR)
1316 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveFPLR))
1317 .addImm(Imm * 8)
1318 .setMIFlag(Flag);
1319 else
1320 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveRegP))
1321 .addImm(RegInfo->getSEHRegNum(Reg0))
1322 .addImm(RegInfo->getSEHRegNum(Reg1))
1323 .addImm(Imm * 8)
1324 .setMIFlag(Flag);
1325 break;
1326 }
1327 case AArch64::STRXui:
1328 case AArch64::LDRXui: {
1329 int Reg = RegInfo->getSEHRegNum(MBBI->getOperand(0).getReg());
1330 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveReg))
1331 .addImm(Reg)
1332 .addImm(Imm * 8)
1333 .setMIFlag(Flag);
1334 break;
1335 }
1336 case AArch64::STRDui:
1337 case AArch64::LDRDui: {
1338 unsigned Reg = RegInfo->getSEHRegNum(MBBI->getOperand(0).getReg());
1339 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveFReg))
1340 .addImm(Reg)
1341 .addImm(Imm * 8)
1342 .setMIFlag(Flag);
1343 break;
1344 }
1345 case AArch64::STPQi:
1346 case AArch64::LDPQi: {
1347 unsigned Reg0 = RegInfo->getSEHRegNum(MBBI->getOperand(0).getReg());
1348 unsigned Reg1 = RegInfo->getSEHRegNum(MBBI->getOperand(1).getReg());
1349 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveAnyRegQP))
1350 .addImm(Reg0)
1351 .addImm(Reg1)
1352 .addImm(Imm * 16)
1353 .setMIFlag(Flag);
1354 break;
1355 }
1356 case AArch64::LDPQpost:
1357 Imm = -Imm;
1358 [[fallthrough]];
1359 case AArch64::STPQpre: {
1360 unsigned Reg0 = RegInfo->getSEHRegNum(MBBI->getOperand(1).getReg());
1361 unsigned Reg1 = RegInfo->getSEHRegNum(MBBI->getOperand(2).getReg());
1362 MIB = BuildMI(MF, DL, TII.get(AArch64::SEH_SaveAnyRegQPX))
1363 .addImm(Reg0)
1364 .addImm(Reg1)
1365 .addImm(Imm * 16)
1366 .setMIFlag(Flag);
1367 break;
1368 }
1369 }
1370 auto I = MBB->insertAfter(MBBI, MIB);
1371 return I;
1372}
1373
1374// Fix up the SEH opcode associated with the save/restore instruction.
1376 unsigned LocalStackSize) {
1377 MachineOperand *ImmOpnd = nullptr;
1378 unsigned ImmIdx = MBBI->getNumOperands() - 1;
1379 switch (MBBI->getOpcode()) {
1380 default:
1381 llvm_unreachable("Fix the offset in the SEH instruction");
1382 case AArch64::SEH_SaveFPLR:
1383 case AArch64::SEH_SaveRegP:
1384 case AArch64::SEH_SaveReg:
1385 case AArch64::SEH_SaveFRegP:
1386 case AArch64::SEH_SaveFReg:
1387 case AArch64::SEH_SaveAnyRegQP:
1388 case AArch64::SEH_SaveAnyRegQPX:
1389 ImmOpnd = &MBBI->getOperand(ImmIdx);
1390 break;
1391 }
1392 if (ImmOpnd)
1393 ImmOpnd->setImm(ImmOpnd->getImm() + LocalStackSize);
1394}
1395
1398 return AFI->hasStreamingModeChanges() &&
1399 !MF.getSubtarget<AArch64Subtarget>().hasSVE();
1400}
1401
1404 // For Darwin platforms we don't save VG for non-SVE functions, even if SME
1405 // is enabled with streaming mode changes.
1406 if (!AFI->hasStreamingModeChanges())
1407 return false;
1408 auto &ST = MF.getSubtarget<AArch64Subtarget>();
1409 if (ST.isTargetDarwin())
1410 return ST.hasSVE();
1411 return true;
1412}
1413
1415 unsigned Opc = MBBI->getOpcode();
1416 if (Opc == AArch64::CNTD_XPiI || Opc == AArch64::RDSVLI_XI ||
1417 Opc == AArch64::UBFMXri)
1418 return true;
1419
1420 if (requiresGetVGCall(*MBBI->getMF())) {
1421 if (Opc == AArch64::ORRXrr)
1422 return true;
1423
1424 if (Opc == AArch64::BL) {
1425 auto Op1 = MBBI->getOperand(0);
1426 return Op1.isSymbol() &&
1427 (StringRef(Op1.getSymbolName()) == "__arm_get_current_vg");
1428 }
1429 }
1430
1431 return false;
1432}
1433
1434// Convert callee-save register save/restore instruction to do stack pointer
1435// decrement/increment to allocate/deallocate the callee-save stack area by
1436// converting store/load to use pre/post increment version.
1439 const DebugLoc &DL, const TargetInstrInfo *TII, int CSStackSizeInc,
1440 bool NeedsWinCFI, bool *HasWinCFI, bool EmitCFI,
1442 int CFAOffset = 0) {
1443 unsigned NewOpc;
1444
1445 // If the function contains streaming mode changes, we expect instructions
1446 // to calculate the value of VG before spilling. For locally-streaming
1447 // functions, we need to do this for both the streaming and non-streaming
1448 // vector length. Move past these instructions if necessary.
1449 MachineFunction &MF = *MBB.getParent();
1450 if (requiresSaveVG(MF))
1451 while (isVGInstruction(MBBI))
1452 ++MBBI;
1453
1454 switch (MBBI->getOpcode()) {
1455 default:
1456 llvm_unreachable("Unexpected callee-save save/restore opcode!");
1457 case AArch64::STPXi:
1458 NewOpc = AArch64::STPXpre;
1459 break;
1460 case AArch64::STPDi:
1461 NewOpc = AArch64::STPDpre;
1462 break;
1463 case AArch64::STPQi:
1464 NewOpc = AArch64::STPQpre;
1465 break;
1466 case AArch64::STRXui:
1467 NewOpc = AArch64::STRXpre;
1468 break;
1469 case AArch64::STRDui:
1470 NewOpc = AArch64::STRDpre;
1471 break;
1472 case AArch64::STRQui:
1473 NewOpc = AArch64::STRQpre;
1474 break;
1475 case AArch64::LDPXi:
1476 NewOpc = AArch64::LDPXpost;
1477 break;
1478 case AArch64::LDPDi:
1479 NewOpc = AArch64::LDPDpost;
1480 break;
1481 case AArch64::LDPQi:
1482 NewOpc = AArch64::LDPQpost;
1483 break;
1484 case AArch64::LDRXui:
1485 NewOpc = AArch64::LDRXpost;
1486 break;
1487 case AArch64::LDRDui:
1488 NewOpc = AArch64::LDRDpost;
1489 break;
1490 case AArch64::LDRQui:
1491 NewOpc = AArch64::LDRQpost;
1492 break;
1493 }
1494 TypeSize Scale = TypeSize::getFixed(1), Width = TypeSize::getFixed(0);
1495 int64_t MinOffset, MaxOffset;
1496 bool Success = static_cast<const AArch64InstrInfo *>(TII)->getMemOpInfo(
1497 NewOpc, Scale, Width, MinOffset, MaxOffset);
1498 (void)Success;
1499 assert(Success && "unknown load/store opcode");
1500
1501 // If the first store isn't right where we want SP then we can't fold the
1502 // update in so create a normal arithmetic instruction instead.
1503 if (MBBI->getOperand(MBBI->getNumOperands() - 1).getImm() != 0 ||
1504 CSStackSizeInc < MinOffset * (int64_t)Scale.getFixedValue() ||
1505 CSStackSizeInc > MaxOffset * (int64_t)Scale.getFixedValue()) {
1506 // If we are destroying the frame, make sure we add the increment after the
1507 // last frame operation.
1508 if (FrameFlag == MachineInstr::FrameDestroy) {
1509 ++MBBI;
1510 // Also skip the SEH instruction, if needed
1511 if (NeedsWinCFI && AArch64InstrInfo::isSEHInstruction(*MBBI))
1512 ++MBBI;
1513 }
1514 emitFrameOffset(MBB, MBBI, DL, AArch64::SP, AArch64::SP,
1515 StackOffset::getFixed(CSStackSizeInc), TII, FrameFlag,
1516 false, NeedsWinCFI, HasWinCFI, EmitCFI,
1517 StackOffset::getFixed(CFAOffset));
1518
1519 return std::prev(MBBI);
1520 }
1521
1522 // Get rid of the SEH code associated with the old instruction.
1523 if (NeedsWinCFI) {
1524 auto SEH = std::next(MBBI);
1526 SEH->eraseFromParent();
1527 }
1528
1529 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(NewOpc));
1530 MIB.addReg(AArch64::SP, RegState::Define);
1531
1532 // Copy all operands other than the immediate offset.
1533 unsigned OpndIdx = 0;
1534 for (unsigned OpndEnd = MBBI->getNumOperands() - 1; OpndIdx < OpndEnd;
1535 ++OpndIdx)
1536 MIB.add(MBBI->getOperand(OpndIdx));
1537
1538 assert(MBBI->getOperand(OpndIdx).getImm() == 0 &&
1539 "Unexpected immediate offset in first/last callee-save save/restore "
1540 "instruction!");
1541 assert(MBBI->getOperand(OpndIdx - 1).getReg() == AArch64::SP &&
1542 "Unexpected base register in callee-save save/restore instruction!");
1543 assert(CSStackSizeInc % Scale == 0);
1544 MIB.addImm(CSStackSizeInc / (int)Scale);
1545
1546 MIB.setMIFlags(MBBI->getFlags());
1547 MIB.setMemRefs(MBBI->memoperands());
1548
1549 // Generate a new SEH code that corresponds to the new instruction.
1550 if (NeedsWinCFI) {
1551 *HasWinCFI = true;
1552 InsertSEH(*MIB, *TII, FrameFlag);
1553 }
1554
1555 if (EmitCFI) {
1556 unsigned CFIIndex = MF.addFrameInst(
1557 MCCFIInstruction::cfiDefCfaOffset(nullptr, CFAOffset - CSStackSizeInc));
1558 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
1559 .addCFIIndex(CFIIndex)
1560 .setMIFlags(FrameFlag);
1561 }
1562
1563 return std::prev(MBB.erase(MBBI));
1564}
1565
1566// Fixup callee-save register save/restore instructions to take into account
1567// combined SP bump by adding the local stack size to the stack offsets.
1569 uint64_t LocalStackSize,
1570 bool NeedsWinCFI,
1571 bool *HasWinCFI) {
1573 return;
1574
1575 unsigned Opc = MI.getOpcode();
1576 unsigned Scale;
1577 switch (Opc) {
1578 case AArch64::STPXi:
1579 case AArch64::STRXui:
1580 case AArch64::STPDi:
1581 case AArch64::STRDui:
1582 case AArch64::LDPXi:
1583 case AArch64::LDRXui:
1584 case AArch64::LDPDi:
1585 case AArch64::LDRDui:
1586 Scale = 8;
1587 break;
1588 case AArch64::STPQi:
1589 case AArch64::STRQui:
1590 case AArch64::LDPQi:
1591 case AArch64::LDRQui:
1592 Scale = 16;
1593 break;
1594 default:
1595 llvm_unreachable("Unexpected callee-save save/restore opcode!");
1596 }
1597
1598 unsigned OffsetIdx = MI.getNumExplicitOperands() - 1;
1599 assert(MI.getOperand(OffsetIdx - 1).getReg() == AArch64::SP &&
1600 "Unexpected base register in callee-save save/restore instruction!");
1601 // Last operand is immediate offset that needs fixing.
1602 MachineOperand &OffsetOpnd = MI.getOperand(OffsetIdx);
1603 // All generated opcodes have scaled offsets.
1604 assert(LocalStackSize % Scale == 0);
1605 OffsetOpnd.setImm(OffsetOpnd.getImm() + LocalStackSize / Scale);
1606
1607 if (NeedsWinCFI) {
1608 *HasWinCFI = true;
1609 auto MBBI = std::next(MachineBasicBlock::iterator(MI));
1610 assert(MBBI != MI.getParent()->end() && "Expecting a valid instruction");
1612 "Expecting a SEH instruction");
1613 fixupSEHOpcode(MBBI, LocalStackSize);
1614 }
1615}
1616
1617static bool isTargetWindows(const MachineFunction &MF) {
1619}
1620
1621static unsigned getStackHazardSize(const MachineFunction &MF) {
1622 return MF.getSubtarget<AArch64Subtarget>().getStreamingHazardSize();
1623}
1624
1625// Convenience function to determine whether I is an SVE callee save.
1627 switch (I->getOpcode()) {
1628 default:
1629 return false;
1630 case AArch64::PTRUE_C_B:
1631 case AArch64::LD1B_2Z_IMM:
1632 case AArch64::ST1B_2Z_IMM:
1633 case AArch64::STR_ZXI:
1634 case AArch64::STR_PXI:
1635 case AArch64::LDR_ZXI:
1636 case AArch64::LDR_PXI:
1637 return I->getFlag(MachineInstr::FrameSetup) ||
1638 I->getFlag(MachineInstr::FrameDestroy);
1639 }
1640}
1641
1643 MachineFunction &MF,
1646 const DebugLoc &DL, bool NeedsWinCFI,
1647 bool NeedsUnwindInfo) {
1648 // Shadow call stack prolog: str x30, [x18], #8
1649 BuildMI(MBB, MBBI, DL, TII.get(AArch64::STRXpost))
1650 .addReg(AArch64::X18, RegState::Define)
1651 .addReg(AArch64::LR)
1652 .addReg(AArch64::X18)
1653 .addImm(8)
1655
1656 // This instruction also makes x18 live-in to the entry block.
1657 MBB.addLiveIn(AArch64::X18);
1658
1659 if (NeedsWinCFI)
1660 BuildMI(MBB, MBBI, DL, TII.get(AArch64::SEH_Nop))
1662
1663 if (NeedsUnwindInfo) {
1664 // Emit a CFI instruction that causes 8 to be subtracted from the value of
1665 // x18 when unwinding past this frame.
1666 static const char CFIInst[] = {
1667 dwarf::DW_CFA_val_expression,
1668 18, // register
1669 2, // length
1670 static_cast<char>(unsigned(dwarf::DW_OP_breg18)),
1671 static_cast<char>(-8) & 0x7f, // addend (sleb128)
1672 };
1673 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createEscape(
1674 nullptr, StringRef(CFIInst, sizeof(CFIInst))));
1675 BuildMI(MBB, MBBI, DL, TII.get(AArch64::CFI_INSTRUCTION))
1676 .addCFIIndex(CFIIndex)
1678 }
1679}
1680
1682 MachineFunction &MF,
1685 const DebugLoc &DL) {
1686 // Shadow call stack epilog: ldr x30, [x18, #-8]!
1687 BuildMI(MBB, MBBI, DL, TII.get(AArch64::LDRXpre))
1688 .addReg(AArch64::X18, RegState::Define)
1689 .addReg(AArch64::LR, RegState::Define)
1690 .addReg(AArch64::X18)
1691 .addImm(-8)
1693
1695 unsigned CFIIndex =
1697 BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
1698 .addCFIIndex(CFIIndex)
1700 }
1701}
1702
1703// Define the current CFA rule to use the provided FP.
1706 const DebugLoc &DL, unsigned FixedObject) {
1709 const TargetInstrInfo *TII = STI.getInstrInfo();
1711
1712 const int OffsetToFirstCalleeSaveFromFP =
1715 Register FramePtr = TRI->getFrameRegister(MF);
1716 unsigned Reg = TRI->getDwarfRegNum(FramePtr, true);
1717 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::cfiDefCfa(
1718 nullptr, Reg, FixedObject - OffsetToFirstCalleeSaveFromFP));
1719 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
1720 .addCFIIndex(CFIIndex)
1722}
1723
1724#ifndef NDEBUG
1725/// Collect live registers from the end of \p MI's parent up to (including) \p
1726/// MI in \p LiveRegs.
1728 LivePhysRegs &LiveRegs) {
1729
1730 MachineBasicBlock &MBB = *MI.getParent();
1731 LiveRegs.addLiveOuts(MBB);
1732 for (const MachineInstr &MI :
1733 reverse(make_range(MI.getIterator(), MBB.instr_end())))
1734 LiveRegs.stepBackward(MI);
1735}
1736#endif
1737
1739 MachineBasicBlock &MBB) const {
1741 const MachineFrameInfo &MFI = MF.getFrameInfo();
1742 const Function &F = MF.getFunction();
1743 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
1744 const AArch64RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
1745 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
1746
1748 bool EmitCFI = AFI->needsDwarfUnwindInfo(MF);
1749 bool EmitAsyncCFI = AFI->needsAsyncDwarfUnwindInfo(MF);
1750 bool HasFP = hasFP(MF);
1751 bool NeedsWinCFI = needsWinCFI(MF);
1752 bool HasWinCFI = false;
1753 auto Cleanup = make_scope_exit([&]() { MF.setHasWinCFI(HasWinCFI); });
1754
1756#ifndef NDEBUG
1758 // Collect live register from the end of MBB up to the start of the existing
1759 // frame setup instructions.
1760 MachineBasicBlock::iterator NonFrameStart = MBB.begin();
1761 while (NonFrameStart != End &&
1762 NonFrameStart->getFlag(MachineInstr::FrameSetup))
1763 ++NonFrameStart;
1764
1765 LivePhysRegs LiveRegs(*TRI);
1766 if (NonFrameStart != MBB.end()) {
1767 getLivePhysRegsUpTo(*NonFrameStart, *TRI, LiveRegs);
1768 // Ignore registers used for stack management for now.
1769 LiveRegs.removeReg(AArch64::SP);
1770 LiveRegs.removeReg(AArch64::X19);
1771 LiveRegs.removeReg(AArch64::FP);
1772 LiveRegs.removeReg(AArch64::LR);
1773
1774 // X0 will be clobbered by a call to __arm_get_current_vg in the prologue.
1775 // This is necessary to spill VG if required where SVE is unavailable, but
1776 // X0 is preserved around this call.
1777 if (requiresGetVGCall(MF))
1778 LiveRegs.removeReg(AArch64::X0);
1779 }
1780
1781 auto VerifyClobberOnExit = make_scope_exit([&]() {
1782 if (NonFrameStart == MBB.end())
1783 return;
1784 // Check if any of the newly instructions clobber any of the live registers.
1785 for (MachineInstr &MI :
1786 make_range(MBB.instr_begin(), NonFrameStart->getIterator())) {
1787 for (auto &Op : MI.operands())
1788 if (Op.isReg() && Op.isDef())
1789 assert(!LiveRegs.contains(Op.getReg()) &&
1790 "live register clobbered by inserted prologue instructions");
1791 }
1792 });
1793#endif
1794
1795 bool IsFunclet = MBB.isEHFuncletEntry();
1796
1797 // At this point, we're going to decide whether or not the function uses a
1798 // redzone. In most cases, the function doesn't have a redzone so let's
1799 // assume that's false and set it to true in the case that there's a redzone.
1800 AFI->setHasRedZone(false);
1801
1802 // Debug location must be unknown since the first debug location is used
1803 // to determine the end of the prologue.
1804 DebugLoc DL;
1805
1806 const auto &MFnI = *MF.getInfo<AArch64FunctionInfo>();
1807 if (MFnI.needsShadowCallStackPrologueEpilogue(MF))
1808 emitShadowCallStackPrologue(*TII, MF, MBB, MBBI, DL, NeedsWinCFI,
1809 MFnI.needsDwarfUnwindInfo(MF));
1810
1811 if (MFnI.shouldSignReturnAddress(MF)) {
1812 BuildMI(MBB, MBBI, DL, TII->get(AArch64::PAUTH_PROLOGUE))
1814 if (NeedsWinCFI)
1815 HasWinCFI = true; // AArch64PointerAuth pass will insert SEH_PACSignLR
1816 }
1817
1818 if (EmitCFI && MFnI.isMTETagged()) {
1819 BuildMI(MBB, MBBI, DL, TII->get(AArch64::EMITMTETAGGED))
1821 }
1822
1823 // We signal the presence of a Swift extended frame to external tools by
1824 // storing FP with 0b0001 in bits 63:60. In normal userland operation a simple
1825 // ORR is sufficient, it is assumed a Swift kernel would initialize the TBI
1826 // bits so that is still true.
1827 if (HasFP && AFI->hasSwiftAsyncContext()) {
1830 if (Subtarget.swiftAsyncContextIsDynamicallySet()) {
1831 // The special symbol below is absolute and has a *value* that can be
1832 // combined with the frame pointer to signal an extended frame.
1833 BuildMI(MBB, MBBI, DL, TII->get(AArch64::LOADgot), AArch64::X16)
1834 .addExternalSymbol("swift_async_extendedFramePointerFlags",
1836 if (NeedsWinCFI) {
1837 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop))
1839 HasWinCFI = true;
1840 }
1841 BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXrs), AArch64::FP)
1842 .addUse(AArch64::FP)
1843 .addUse(AArch64::X16)
1844 .addImm(Subtarget.isTargetILP32() ? 32 : 0);
1845 if (NeedsWinCFI) {
1846 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop))
1848 HasWinCFI = true;
1849 }
1850 break;
1851 }
1852 [[fallthrough]];
1853
1855 // ORR x29, x29, #0x1000_0000_0000_0000
1856 BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXri), AArch64::FP)
1857 .addUse(AArch64::FP)
1858 .addImm(0x1100)
1860 if (NeedsWinCFI) {
1861 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop))
1863 HasWinCFI = true;
1864 }
1865 break;
1866
1868 break;
1869 }
1870 }
1871
1872 // All calls are tail calls in GHC calling conv, and functions have no
1873 // prologue/epilogue.
1875 return;
1876
1877 // Set tagged base pointer to the requested stack slot.
1878 // Ideally it should match SP value after prologue.
1879 std::optional<int> TBPI = AFI->getTaggedBasePointerIndex();
1880 if (TBPI)
1882 else
1884
1885 const StackOffset &SVEStackSize = getSVEStackSize(MF);
1886
1887 // getStackSize() includes all the locals in its size calculation. We don't
1888 // include these locals when computing the stack size of a funclet, as they
1889 // are allocated in the parent's stack frame and accessed via the frame
1890 // pointer from the funclet. We only save the callee saved registers in the
1891 // funclet, which are really the callee saved registers of the parent
1892 // function, including the funclet.
1893 int64_t NumBytes =
1894 IsFunclet ? getWinEHFuncletFrameSize(MF) : MFI.getStackSize();
1895 if (!AFI->hasStackFrame() && !windowsRequiresStackProbe(MF, NumBytes)) {
1896 assert(!HasFP && "unexpected function without stack frame but with FP");
1897 assert(!SVEStackSize &&
1898 "unexpected function without stack frame but with SVE objects");
1899 // All of the stack allocation is for locals.
1900 AFI->setLocalStackSize(NumBytes);
1901 if (!NumBytes)
1902 return;
1903 // REDZONE: If the stack size is less than 128 bytes, we don't need
1904 // to actually allocate.
1905 if (canUseRedZone(MF)) {
1906 AFI->setHasRedZone(true);
1907 ++NumRedZoneFunctions;
1908 } else {
1909 emitFrameOffset(MBB, MBBI, DL, AArch64::SP, AArch64::SP,
1910 StackOffset::getFixed(-NumBytes), TII,
1911 MachineInstr::FrameSetup, false, NeedsWinCFI, &HasWinCFI);
1912 if (EmitCFI) {
1913 // Label used to tie together the PROLOG_LABEL and the MachineMoves.
1914 MCSymbol *FrameLabel = MF.getContext().createTempSymbol();
1915 // Encode the stack size of the leaf function.
1916 unsigned CFIIndex = MF.addFrameInst(
1917 MCCFIInstruction::cfiDefCfaOffset(FrameLabel, NumBytes));
1918 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
1919 .addCFIIndex(CFIIndex)
1921 }
1922 }
1923
1924 if (NeedsWinCFI) {
1925 HasWinCFI = true;
1926 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_PrologEnd))
1928 }
1929
1930 return;
1931 }
1932
1933 bool IsWin64 = Subtarget.isCallingConvWin64(F.getCallingConv(), F.isVarArg());
1934 unsigned FixedObject = getFixedObjectSize(MF, AFI, IsWin64, IsFunclet);
1935
1936 auto PrologueSaveSize = AFI->getCalleeSavedStackSize() + FixedObject;
1937 // All of the remaining stack allocations are for locals.
1938 AFI->setLocalStackSize(NumBytes - PrologueSaveSize);
1939 bool CombineSPBump = shouldCombineCSRLocalStackBump(MF, NumBytes);
1940 bool HomPrologEpilog = homogeneousPrologEpilog(MF);
1941 if (CombineSPBump) {
1942 assert(!SVEStackSize && "Cannot combine SP bump with SVE");
1943 emitFrameOffset(MBB, MBBI, DL, AArch64::SP, AArch64::SP,
1944 StackOffset::getFixed(-NumBytes), TII,
1945 MachineInstr::FrameSetup, false, NeedsWinCFI, &HasWinCFI,
1946 EmitAsyncCFI);
1947 NumBytes = 0;
1948 } else if (HomPrologEpilog) {
1949 // Stack has been already adjusted.
1950 NumBytes -= PrologueSaveSize;
1951 } else if (PrologueSaveSize != 0) {
1953 MBB, MBBI, DL, TII, -PrologueSaveSize, NeedsWinCFI, &HasWinCFI,
1954 EmitAsyncCFI);
1955 NumBytes -= PrologueSaveSize;
1956 }
1957 assert(NumBytes >= 0 && "Negative stack allocation size!?");
1958
1959 // Move past the saves of the callee-saved registers, fixing up the offsets
1960 // and pre-inc if we decided to combine the callee-save and local stack
1961 // pointer bump above.
1962 while (MBBI != End && MBBI->getFlag(MachineInstr::FrameSetup) &&
1964 if (CombineSPBump &&
1965 // Only fix-up frame-setup load/store instructions.
1968 NeedsWinCFI, &HasWinCFI);
1969 ++MBBI;
1970 }
1971
1972 // For funclets the FP belongs to the containing function.
1973 if (!IsFunclet && HasFP) {
1974 // Only set up FP if we actually need to.
1975 int64_t FPOffset = AFI->getCalleeSaveBaseToFrameRecordOffset();
1976
1977 if (CombineSPBump)
1978 FPOffset += AFI->getLocalStackSize();
1979
1980 if (AFI->hasSwiftAsyncContext()) {
1981 // Before we update the live FP we have to ensure there's a valid (or
1982 // null) asynchronous context in its slot just before FP in the frame
1983 // record, so store it now.
1984 const auto &Attrs = MF.getFunction().getAttributes();
1985 bool HaveInitialContext = Attrs.hasAttrSomewhere(Attribute::SwiftAsync);
1986 if (HaveInitialContext)
1987 MBB.addLiveIn(AArch64::X22);
1988 Register Reg = HaveInitialContext ? AArch64::X22 : AArch64::XZR;
1989 BuildMI(MBB, MBBI, DL, TII->get(AArch64::StoreSwiftAsyncContext))
1990 .addUse(Reg)
1991 .addUse(AArch64::SP)
1992 .addImm(FPOffset - 8)
1994 if (NeedsWinCFI) {
1995 // WinCFI and arm64e, where StoreSwiftAsyncContext is expanded
1996 // to multiple instructions, should be mutually-exclusive.
1997 assert(Subtarget.getTargetTriple().getArchName() != "arm64e");
1998 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop))
2000 HasWinCFI = true;
2001 }
2002 }
2003
2004 if (HomPrologEpilog) {
2005 auto Prolog = MBBI;
2006 --Prolog;
2007 assert(Prolog->getOpcode() == AArch64::HOM_Prolog);
2008 Prolog->addOperand(MachineOperand::CreateImm(FPOffset));
2009 } else {
2010 // Issue sub fp, sp, FPOffset or
2011 // mov fp,sp when FPOffset is zero.
2012 // Note: All stores of callee-saved registers are marked as "FrameSetup".
2013 // This code marks the instruction(s) that set the FP also.
2014 emitFrameOffset(MBB, MBBI, DL, AArch64::FP, AArch64::SP,
2015 StackOffset::getFixed(FPOffset), TII,
2016 MachineInstr::FrameSetup, false, NeedsWinCFI, &HasWinCFI);
2017 if (NeedsWinCFI && HasWinCFI) {
2018 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_PrologEnd))
2020 // After setting up the FP, the rest of the prolog doesn't need to be
2021 // included in the SEH unwind info.
2022 NeedsWinCFI = false;
2023 }
2024 }
2025 if (EmitAsyncCFI)
2026 emitDefineCFAWithFP(MF, MBB, MBBI, DL, FixedObject);
2027 }
2028
2029 // Now emit the moves for whatever callee saved regs we have (including FP,
2030 // LR if those are saved). Frame instructions for SVE register are emitted
2031 // later, after the instruction which actually save SVE regs.
2032 if (EmitAsyncCFI)
2033 emitCalleeSavedGPRLocations(MBB, MBBI);
2034
2035 // Alignment is required for the parent frame, not the funclet
2036 const bool NeedsRealignment =
2037 NumBytes && !IsFunclet && RegInfo->hasStackRealignment(MF);
2038 const int64_t RealignmentPadding =
2039 (NeedsRealignment && MFI.getMaxAlign() > Align(16))
2040 ? MFI.getMaxAlign().value() - 16
2041 : 0;
2042
2043 if (windowsRequiresStackProbe(MF, NumBytes + RealignmentPadding)) {
2044 uint64_t NumWords = (NumBytes + RealignmentPadding) >> 4;
2045 if (NeedsWinCFI) {
2046 HasWinCFI = true;
2047 // alloc_l can hold at most 256MB, so assume that NumBytes doesn't
2048 // exceed this amount. We need to move at most 2^24 - 1 into x15.
2049 // This is at most two instructions, MOVZ follwed by MOVK.
2050 // TODO: Fix to use multiple stack alloc unwind codes for stacks
2051 // exceeding 256MB in size.
2052 if (NumBytes >= (1 << 28))
2053 report_fatal_error("Stack size cannot exceed 256MB for stack "
2054 "unwinding purposes");
2055
2056 uint32_t LowNumWords = NumWords & 0xFFFF;
2057 BuildMI(MBB, MBBI, DL, TII->get(AArch64::MOVZXi), AArch64::X15)
2058 .addImm(LowNumWords)
2061 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop))
2063 if ((NumWords & 0xFFFF0000) != 0) {
2064 BuildMI(MBB, MBBI, DL, TII->get(AArch64::MOVKXi), AArch64::X15)
2065 .addReg(AArch64::X15)
2066 .addImm((NumWords & 0xFFFF0000) >> 16) // High half
2069 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop))
2071 }
2072 } else {
2073 BuildMI(MBB, MBBI, DL, TII->get(AArch64::MOVi64imm), AArch64::X15)
2074 .addImm(NumWords)
2076 }
2077
2078 const char *ChkStk = Subtarget.getChkStkName();
2079 switch (MF.getTarget().getCodeModel()) {
2080 case CodeModel::Tiny:
2081 case CodeModel::Small:
2082 case CodeModel::Medium:
2083 case CodeModel::Kernel:
2084 BuildMI(MBB, MBBI, DL, TII->get(AArch64::BL))
2085 .addExternalSymbol(ChkStk)
2086 .addReg(AArch64::X15, RegState::Implicit)
2091 if (NeedsWinCFI) {
2092 HasWinCFI = true;
2093 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop))
2095 }
2096 break;
2097 case CodeModel::Large:
2098 BuildMI(MBB, MBBI, DL, TII->get(AArch64::MOVaddrEXT))
2099 .addReg(AArch64::X16, RegState::Define)
2100 .addExternalSymbol(ChkStk)
2101 .addExternalSymbol(ChkStk)
2103 if (NeedsWinCFI) {
2104 HasWinCFI = true;
2105 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop))
2107 }
2108
2109 BuildMI(MBB, MBBI, DL, TII->get(getBLRCallOpcode(MF)))
2110 .addReg(AArch64::X16, RegState::Kill)
2116 if (NeedsWinCFI) {
2117 HasWinCFI = true;
2118 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop))
2120 }
2121 break;
2122 }
2123
2124 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SUBXrx64), AArch64::SP)
2125 .addReg(AArch64::SP, RegState::Kill)
2126 .addReg(AArch64::X15, RegState::Kill)
2129 if (NeedsWinCFI) {
2130 HasWinCFI = true;
2131 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_StackAlloc))
2132 .addImm(NumBytes)
2134 }
2135 NumBytes = 0;
2136
2137 if (RealignmentPadding > 0) {
2138 if (RealignmentPadding >= 4096) {
2139 BuildMI(MBB, MBBI, DL, TII->get(AArch64::MOVi64imm))
2140 .addReg(AArch64::X16, RegState::Define)
2141 .addImm(RealignmentPadding)
2143 BuildMI(MBB, MBBI, DL, TII->get(AArch64::ADDXrx64), AArch64::X15)
2144 .addReg(AArch64::SP)
2145 .addReg(AArch64::X16, RegState::Kill)
2148 } else {
2149 BuildMI(MBB, MBBI, DL, TII->get(AArch64::ADDXri), AArch64::X15)
2150 .addReg(AArch64::SP)
2151 .addImm(RealignmentPadding)
2152 .addImm(0)
2154 }
2155
2156 uint64_t AndMask = ~(MFI.getMaxAlign().value() - 1);
2157 BuildMI(MBB, MBBI, DL, TII->get(AArch64::ANDXri), AArch64::SP)
2158 .addReg(AArch64::X15, RegState::Kill)
2160 AFI->setStackRealigned(true);
2161
2162 // No need for SEH instructions here; if we're realigning the stack,
2163 // we've set a frame pointer and already finished the SEH prologue.
2164 assert(!NeedsWinCFI);
2165 }
2166 }
2167
2168 StackOffset SVECalleeSavesSize = {}, SVELocalsSize = SVEStackSize;
2169 MachineBasicBlock::iterator CalleeSavesBegin = MBBI, CalleeSavesEnd = MBBI;
2170
2171 // Process the SVE callee-saves to determine what space needs to be
2172 // allocated.
2173 if (int64_t CalleeSavedSize = AFI->getSVECalleeSavedStackSize()) {
2174 LLVM_DEBUG(dbgs() << "SVECalleeSavedStackSize = " << CalleeSavedSize
2175 << "\n");
2176 // Find callee save instructions in frame.
2177 CalleeSavesBegin = MBBI;
2178 assert(IsSVECalleeSave(CalleeSavesBegin) && "Unexpected instruction");
2180 ++MBBI;
2181 CalleeSavesEnd = MBBI;
2182
2183 SVECalleeSavesSize = StackOffset::getScalable(CalleeSavedSize);
2184 SVELocalsSize = SVEStackSize - SVECalleeSavesSize;
2185 }
2186
2187 // Allocate space for the callee saves (if any).
2188 StackOffset CFAOffset =
2189 StackOffset::getFixed((int64_t)MFI.getStackSize() - NumBytes);
2190 StackOffset LocalsSize = SVELocalsSize + StackOffset::getFixed(NumBytes);
2191 allocateStackSpace(MBB, CalleeSavesBegin, 0, SVECalleeSavesSize, false,
2192 nullptr, EmitAsyncCFI && !HasFP, CFAOffset,
2193 MFI.hasVarSizedObjects() || LocalsSize);
2194 CFAOffset += SVECalleeSavesSize;
2195
2196 if (EmitAsyncCFI)
2197 emitCalleeSavedSVELocations(MBB, CalleeSavesEnd);
2198
2199 // Allocate space for the rest of the frame including SVE locals. Align the
2200 // stack as necessary.
2201 assert(!(canUseRedZone(MF) && NeedsRealignment) &&
2202 "Cannot use redzone with stack realignment");
2203 if (!canUseRedZone(MF)) {
2204 // FIXME: in the case of dynamic re-alignment, NumBytes doesn't have
2205 // the correct value here, as NumBytes also includes padding bytes,
2206 // which shouldn't be counted here.
2207 allocateStackSpace(MBB, CalleeSavesEnd, RealignmentPadding,
2208 SVELocalsSize + StackOffset::getFixed(NumBytes),
2209 NeedsWinCFI, &HasWinCFI, EmitAsyncCFI && !HasFP,
2210 CFAOffset, MFI.hasVarSizedObjects());
2211 }
2212
2213 // If we need a base pointer, set it up here. It's whatever the value of the
2214 // stack pointer is at this point. Any variable size objects will be allocated
2215 // after this, so we can still use the base pointer to reference locals.
2216 //
2217 // FIXME: Clarify FrameSetup flags here.
2218 // Note: Use emitFrameOffset() like above for FP if the FrameSetup flag is
2219 // needed.
2220 // For funclets the BP belongs to the containing function.
2221 if (!IsFunclet && RegInfo->hasBasePointer(MF)) {
2222 TII->copyPhysReg(MBB, MBBI, DL, RegInfo->getBaseRegister(), AArch64::SP,
2223 false);
2224 if (NeedsWinCFI) {
2225 HasWinCFI = true;
2226 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop))
2228 }
2229 }
2230
2231 // The very last FrameSetup instruction indicates the end of prologue. Emit a
2232 // SEH opcode indicating the prologue end.
2233 if (NeedsWinCFI && HasWinCFI) {
2234 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_PrologEnd))
2236 }
2237
2238 // SEH funclets are passed the frame pointer in X1. If the parent
2239 // function uses the base register, then the base register is used
2240 // directly, and is not retrieved from X1.
2241 if (IsFunclet && F.hasPersonalityFn()) {
2242 EHPersonality Per = classifyEHPersonality(F.getPersonalityFn());
2243 if (isAsynchronousEHPersonality(Per)) {
2244 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::COPY), AArch64::FP)
2245 .addReg(AArch64::X1)
2247 MBB.addLiveIn(AArch64::X1);
2248 }
2249 }
2250
2251 if (EmitCFI && !EmitAsyncCFI) {
2252 if (HasFP) {
2253 emitDefineCFAWithFP(MF, MBB, MBBI, DL, FixedObject);
2254 } else {
2255 StackOffset TotalSize =
2256 SVEStackSize + StackOffset::getFixed((int64_t)MFI.getStackSize());
2257 unsigned CFIIndex = MF.addFrameInst(createDefCFA(
2258 *RegInfo, /*FrameReg=*/AArch64::SP, /*Reg=*/AArch64::SP, TotalSize,
2259 /*LastAdjustmentWasScalable=*/false));
2260 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
2261 .addCFIIndex(CFIIndex)
2263 }
2264 emitCalleeSavedGPRLocations(MBB, MBBI);
2265 emitCalleeSavedSVELocations(MBB, MBBI);
2266 }
2267}
2268
2270 switch (MI.getOpcode()) {
2271 default:
2272 return false;
2273 case AArch64::CATCHRET:
2274 case AArch64::CLEANUPRET:
2275 return true;
2276 }
2277}
2278
2280 MachineBasicBlock &MBB) const {
2282 MachineFrameInfo &MFI = MF.getFrameInfo();
2284 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
2285 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
2286 DebugLoc DL;
2287 bool NeedsWinCFI = needsWinCFI(MF);
2288 bool EmitCFI = AFI->needsAsyncDwarfUnwindInfo(MF);
2289 bool HasWinCFI = false;
2290 bool IsFunclet = false;
2291
2292 if (MBB.end() != MBBI) {
2293 DL = MBBI->getDebugLoc();
2294 IsFunclet = isFuncletReturnInstr(*MBBI);
2295 }
2296
2297 MachineBasicBlock::iterator EpilogStartI = MBB.end();
2298
2299 auto FinishingTouches = make_scope_exit([&]() {
2300 if (AFI->shouldSignReturnAddress(MF)) {
2301 BuildMI(MBB, MBB.getFirstTerminator(), DL,
2302 TII->get(AArch64::PAUTH_EPILOGUE))
2303 .setMIFlag(MachineInstr::FrameDestroy);
2304 if (NeedsWinCFI)
2305 HasWinCFI = true; // AArch64PointerAuth pass will insert SEH_PACSignLR
2306 }
2309 if (EmitCFI)
2310 emitCalleeSavedGPRRestores(MBB, MBB.getFirstTerminator());
2311 if (HasWinCFI) {
2313 TII->get(AArch64::SEH_EpilogEnd))
2315 if (!MF.hasWinCFI())
2316 MF.setHasWinCFI(true);
2317 }
2318 if (NeedsWinCFI) {
2319 assert(EpilogStartI != MBB.end());
2320 if (!HasWinCFI)
2321 MBB.erase(EpilogStartI);
2322 }
2323 });
2324
2325 int64_t NumBytes = IsFunclet ? getWinEHFuncletFrameSize(MF)
2326 : MFI.getStackSize();
2327
2328 // All calls are tail calls in GHC calling conv, and functions have no
2329 // prologue/epilogue.
2331 return;
2332
2333 // How much of the stack used by incoming arguments this function is expected
2334 // to restore in this particular epilogue.
2335 int64_t ArgumentStackToRestore = getArgumentStackToRestore(MF, MBB);
2336 bool IsWin64 = Subtarget.isCallingConvWin64(MF.getFunction().getCallingConv(),
2337 MF.getFunction().isVarArg());
2338 unsigned FixedObject = getFixedObjectSize(MF, AFI, IsWin64, IsFunclet);
2339
2340 int64_t AfterCSRPopSize = ArgumentStackToRestore;
2341 auto PrologueSaveSize = AFI->getCalleeSavedStackSize() + FixedObject;
2342 // We cannot rely on the local stack size set in emitPrologue if the function
2343 // has funclets, as funclets have different local stack size requirements, and
2344 // the current value set in emitPrologue may be that of the containing
2345 // function.
2346 if (MF.hasEHFunclets())
2347 AFI->setLocalStackSize(NumBytes - PrologueSaveSize);
2348 if (homogeneousPrologEpilog(MF, &MBB)) {
2349 assert(!NeedsWinCFI);
2350 auto LastPopI = MBB.getFirstTerminator();
2351 if (LastPopI != MBB.begin()) {
2352 auto HomogeneousEpilog = std::prev(LastPopI);
2353 if (HomogeneousEpilog->getOpcode() == AArch64::HOM_Epilog)
2354 LastPopI = HomogeneousEpilog;
2355 }
2356
2357 // Adjust local stack
2358 emitFrameOffset(MBB, LastPopI, DL, AArch64::SP, AArch64::SP,
2360 MachineInstr::FrameDestroy, false, NeedsWinCFI, &HasWinCFI);
2361
2362 // SP has been already adjusted while restoring callee save regs.
2363 // We've bailed-out the case with adjusting SP for arguments.
2364 assert(AfterCSRPopSize == 0);
2365 return;
2366 }
2367 bool CombineSPBump = shouldCombineCSRLocalStackBumpInEpilogue(MBB, NumBytes);
2368 // Assume we can't combine the last pop with the sp restore.
2369 bool CombineAfterCSRBump = false;
2370 if (!CombineSPBump && PrologueSaveSize != 0) {
2372 while (Pop->getOpcode() == TargetOpcode::CFI_INSTRUCTION ||
2374 Pop = std::prev(Pop);
2375 // Converting the last ldp to a post-index ldp is valid only if the last
2376 // ldp's offset is 0.
2377 const MachineOperand &OffsetOp = Pop->getOperand(Pop->getNumOperands() - 1);
2378 // If the offset is 0 and the AfterCSR pop is not actually trying to
2379 // allocate more stack for arguments (in space that an untimely interrupt
2380 // may clobber), convert it to a post-index ldp.
2381 if (OffsetOp.getImm() == 0 && AfterCSRPopSize >= 0) {
2383 MBB, Pop, DL, TII, PrologueSaveSize, NeedsWinCFI, &HasWinCFI, EmitCFI,
2384 MachineInstr::FrameDestroy, PrologueSaveSize);
2385 } else {
2386 // If not, make sure to emit an add after the last ldp.
2387 // We're doing this by transfering the size to be restored from the
2388 // adjustment *before* the CSR pops to the adjustment *after* the CSR
2389 // pops.
2390 AfterCSRPopSize += PrologueSaveSize;
2391 CombineAfterCSRBump = true;
2392 }
2393 }
2394
2395 // Move past the restores of the callee-saved registers.
2396 // If we plan on combining the sp bump of the local stack size and the callee
2397 // save stack size, we might need to adjust the CSR save and restore offsets.
2400 while (LastPopI != Begin) {
2401 --LastPopI;
2402 if (!LastPopI->getFlag(MachineInstr::FrameDestroy) ||
2403 IsSVECalleeSave(LastPopI)) {
2404 ++LastPopI;
2405 break;
2406 } else if (CombineSPBump)
2408 NeedsWinCFI, &HasWinCFI);
2409 }
2410
2411 if (NeedsWinCFI) {
2412 // Note that there are cases where we insert SEH opcodes in the
2413 // epilogue when we had no SEH opcodes in the prologue. For
2414 // example, when there is no stack frame but there are stack
2415 // arguments. Insert the SEH_EpilogStart and remove it later if it
2416 // we didn't emit any SEH opcodes to avoid generating WinCFI for
2417 // functions that don't need it.
2418 BuildMI(MBB, LastPopI, DL, TII->get(AArch64::SEH_EpilogStart))
2420 EpilogStartI = LastPopI;
2421 --EpilogStartI;
2422 }
2423
2424 if (hasFP(MF) && AFI->hasSwiftAsyncContext()) {
2427 // Avoid the reload as it is GOT relative, and instead fall back to the
2428 // hardcoded value below. This allows a mismatch between the OS and
2429 // application without immediately terminating on the difference.
2430 [[fallthrough]];
2432 // We need to reset FP to its untagged state on return. Bit 60 is
2433 // currently used to show the presence of an extended frame.
2434
2435 // BIC x29, x29, #0x1000_0000_0000_0000
2436 BuildMI(MBB, MBB.getFirstTerminator(), DL, TII->get(AArch64::ANDXri),
2437 AArch64::FP)
2438 .addUse(AArch64::FP)
2439 .addImm(0x10fe)
2441 if (NeedsWinCFI) {
2442 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop))
2444 HasWinCFI = true;
2445 }
2446 break;
2447
2449 break;
2450 }
2451 }
2452
2453 const StackOffset &SVEStackSize = getSVEStackSize(MF);
2454
2455 // If there is a single SP update, insert it before the ret and we're done.
2456 if (CombineSPBump) {
2457 assert(!SVEStackSize && "Cannot combine SP bump with SVE");
2458
2459 // When we are about to restore the CSRs, the CFA register is SP again.
2460 if (EmitCFI && hasFP(MF)) {
2461 const AArch64RegisterInfo &RegInfo = *Subtarget.getRegisterInfo();
2462 unsigned Reg = RegInfo.getDwarfRegNum(AArch64::SP, true);
2463 unsigned CFIIndex =
2464 MF.addFrameInst(MCCFIInstruction::cfiDefCfa(nullptr, Reg, NumBytes));
2465 BuildMI(MBB, LastPopI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
2466 .addCFIIndex(CFIIndex)
2468 }
2469
2470 emitFrameOffset(MBB, MBB.getFirstTerminator(), DL, AArch64::SP, AArch64::SP,
2471 StackOffset::getFixed(NumBytes + (int64_t)AfterCSRPopSize),
2472 TII, MachineInstr::FrameDestroy, false, NeedsWinCFI,
2473 &HasWinCFI, EmitCFI, StackOffset::getFixed(NumBytes));
2474 return;
2475 }
2476
2477 NumBytes -= PrologueSaveSize;
2478 assert(NumBytes >= 0 && "Negative stack allocation size!?");
2479
2480 // Process the SVE callee-saves to determine what space needs to be
2481 // deallocated.
2482 StackOffset DeallocateBefore = {}, DeallocateAfter = SVEStackSize;
2483 MachineBasicBlock::iterator RestoreBegin = LastPopI, RestoreEnd = LastPopI;
2484 if (int64_t CalleeSavedSize = AFI->getSVECalleeSavedStackSize()) {
2485 RestoreBegin = std::prev(RestoreEnd);
2486 while (RestoreBegin != MBB.begin() &&
2487 IsSVECalleeSave(std::prev(RestoreBegin)))
2488 --RestoreBegin;
2489
2490 assert(IsSVECalleeSave(RestoreBegin) &&
2491 IsSVECalleeSave(std::prev(RestoreEnd)) && "Unexpected instruction");
2492
2493 StackOffset CalleeSavedSizeAsOffset =
2494 StackOffset::getScalable(CalleeSavedSize);
2495 DeallocateBefore = SVEStackSize - CalleeSavedSizeAsOffset;
2496 DeallocateAfter = CalleeSavedSizeAsOffset;
2497 }
2498
2499 // Deallocate the SVE area.
2500 if (SVEStackSize) {
2501 // If we have stack realignment or variable sized objects on the stack,
2502 // restore the stack pointer from the frame pointer prior to SVE CSR
2503 // restoration.
2504 if (AFI->isStackRealigned() || MFI.hasVarSizedObjects()) {
2505 if (int64_t CalleeSavedSize = AFI->getSVECalleeSavedStackSize()) {
2506 // Set SP to start of SVE callee-save area from which they can
2507 // be reloaded. The code below will deallocate the stack space
2508 // space by moving FP -> SP.
2509 emitFrameOffset(MBB, RestoreBegin, DL, AArch64::SP, AArch64::FP,
2510 StackOffset::getScalable(-CalleeSavedSize), TII,
2512 }
2513 } else {
2514 if (AFI->getSVECalleeSavedStackSize()) {
2515 // Deallocate the non-SVE locals first before we can deallocate (and
2516 // restore callee saves) from the SVE area.
2518 MBB, RestoreBegin, DL, AArch64::SP, AArch64::SP,
2520 false, false, nullptr, EmitCFI && !hasFP(MF),
2521 SVEStackSize + StackOffset::getFixed(NumBytes + PrologueSaveSize));
2522 NumBytes = 0;
2523 }
2524
2525 emitFrameOffset(MBB, RestoreBegin, DL, AArch64::SP, AArch64::SP,
2526 DeallocateBefore, TII, MachineInstr::FrameDestroy, false,
2527 false, nullptr, EmitCFI && !hasFP(MF),
2528 SVEStackSize +
2529 StackOffset::getFixed(NumBytes + PrologueSaveSize));
2530
2531 emitFrameOffset(MBB, RestoreEnd, DL, AArch64::SP, AArch64::SP,
2532 DeallocateAfter, TII, MachineInstr::FrameDestroy, false,
2533 false, nullptr, EmitCFI && !hasFP(MF),
2534 DeallocateAfter +
2535 StackOffset::getFixed(NumBytes + PrologueSaveSize));
2536 }
2537 if (EmitCFI)
2538 emitCalleeSavedSVERestores(MBB, RestoreEnd);
2539 }
2540
2541 if (!hasFP(MF)) {
2542 bool RedZone = canUseRedZone(MF);
2543 // If this was a redzone leaf function, we don't need to restore the
2544 // stack pointer (but we may need to pop stack args for fastcc).
2545 if (RedZone && AfterCSRPopSize == 0)
2546 return;
2547
2548 // Pop the local variables off the stack. If there are no callee-saved
2549 // registers, it means we are actually positioned at the terminator and can
2550 // combine stack increment for the locals and the stack increment for
2551 // callee-popped arguments into (possibly) a single instruction and be done.
2552 bool NoCalleeSaveRestore = PrologueSaveSize == 0;
2553 int64_t StackRestoreBytes = RedZone ? 0 : NumBytes;
2554 if (NoCalleeSaveRestore)
2555 StackRestoreBytes += AfterCSRPopSize;
2556
2558 MBB, LastPopI, DL, AArch64::SP, AArch64::SP,
2559 StackOffset::getFixed(StackRestoreBytes), TII,
2560 MachineInstr::FrameDestroy, false, NeedsWinCFI, &HasWinCFI, EmitCFI,
2561 StackOffset::getFixed((RedZone ? 0 : NumBytes) + PrologueSaveSize));
2562
2563 // If we were able to combine the local stack pop with the argument pop,
2564 // then we're done.
2565 if (NoCalleeSaveRestore || AfterCSRPopSize == 0) {
2566 return;
2567 }
2568
2569 NumBytes = 0;
2570 }
2571
2572 // Restore the original stack pointer.
2573 // FIXME: Rather than doing the math here, we should instead just use
2574 // non-post-indexed loads for the restores if we aren't actually going to
2575 // be able to save any instructions.
2576 if (!IsFunclet && (MFI.hasVarSizedObjects() || AFI->isStackRealigned())) {
2578 MBB, LastPopI, DL, AArch64::SP, AArch64::FP,
2580 TII, MachineInstr::FrameDestroy, false, NeedsWinCFI, &HasWinCFI);
2581 } else if (NumBytes)
2582 emitFrameOffset(MBB, LastPopI, DL, AArch64::SP, AArch64::SP,
2583 StackOffset::getFixed(NumBytes), TII,
2584 MachineInstr::FrameDestroy, false, NeedsWinCFI, &HasWinCFI);
2585
2586 // When we are about to restore the CSRs, the CFA register is SP again.
2587 if (EmitCFI && hasFP(MF)) {
2588 const AArch64RegisterInfo &RegInfo = *Subtarget.getRegisterInfo();
2589 unsigned Reg = RegInfo.getDwarfRegNum(AArch64::SP, true);
2590 unsigned CFIIndex = MF.addFrameInst(
2591 MCCFIInstruction::cfiDefCfa(nullptr, Reg, PrologueSaveSize));
2592 BuildMI(MBB, LastPopI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
2593 .addCFIIndex(CFIIndex)
2595 }
2596
2597 // This must be placed after the callee-save restore code because that code
2598 // assumes the SP is at the same location as it was after the callee-save save
2599 // code in the prologue.
2600 if (AfterCSRPopSize) {
2601 assert(AfterCSRPopSize > 0 && "attempting to reallocate arg stack that an "
2602 "interrupt may have clobbered");
2603
2605 MBB, MBB.getFirstTerminator(), DL, AArch64::SP, AArch64::SP,
2607 false, NeedsWinCFI, &HasWinCFI, EmitCFI,
2608 StackOffset::getFixed(CombineAfterCSRBump ? PrologueSaveSize : 0));
2609 }
2610}
2611
2614 MF.getInfo<AArch64FunctionInfo>()->needsAsyncDwarfUnwindInfo(MF);
2615}
2616
2617/// getFrameIndexReference - Provide a base+offset reference to an FI slot for
2618/// debug info. It's the same as what we use for resolving the code-gen
2619/// references for now. FIXME: This can go wrong when references are
2620/// SP-relative and simple call frames aren't used.
2623 Register &FrameReg) const {
2625 MF, FI, FrameReg,
2626 /*PreferFP=*/
2627 MF.getFunction().hasFnAttribute(Attribute::SanitizeHWAddress) ||
2628 MF.getFunction().hasFnAttribute(Attribute::SanitizeMemTag),
2629 /*ForSimm=*/false);
2630}
2631
2634 int FI) const {
2635 // This function serves to provide a comparable offset from a single reference
2636 // point (the value of SP at function entry) that can be used for analysis,
2637 // e.g. the stack-frame-layout analysis pass. It is not guaranteed to be
2638 // correct for all objects in the presence of VLA-area objects or dynamic
2639 // stack re-alignment.
2640
2641 const auto &MFI = MF.getFrameInfo();
2642
2643 int64_t ObjectOffset = MFI.getObjectOffset(FI);
2644 StackOffset SVEStackSize = getSVEStackSize(MF);
2645
2646 // For VLA-area objects, just emit an offset at the end of the stack frame.
2647 // Whilst not quite correct, these objects do live at the end of the frame and
2648 // so it is more useful for analysis for the offset to reflect this.
2649 if (MFI.isVariableSizedObjectIndex(FI)) {
2650 return StackOffset::getFixed(-((int64_t)MFI.getStackSize())) - SVEStackSize;
2651 }
2652
2653 // This is correct in the absence of any SVE stack objects.
2654 if (!SVEStackSize)
2655 return StackOffset::getFixed(ObjectOffset - getOffsetOfLocalArea());
2656
2657 const auto *AFI = MF.getInfo<AArch64FunctionInfo>();
2658 if (MFI.getStackID(FI) == TargetStackID::ScalableVector) {
2659 return StackOffset::get(-((int64_t)AFI->getCalleeSavedStackSize()),
2660 ObjectOffset);
2661 }
2662
2663 bool IsFixed = MFI.isFixedObjectIndex(FI);
2664 bool IsCSR =
2665 !IsFixed && ObjectOffset >= -((int)AFI->getCalleeSavedStackSize(MFI));
2666
2667 StackOffset ScalableOffset = {};
2668 if (!IsFixed && !IsCSR)
2669 ScalableOffset = -SVEStackSize;
2670
2671 return StackOffset::getFixed(ObjectOffset) + ScalableOffset;
2672}
2673
2676 int FI) const {
2678}
2679
2681 int64_t ObjectOffset) {
2682 const auto *AFI = MF.getInfo<AArch64FunctionInfo>();
2683 const auto &Subtarget = MF.getSubtarget<AArch64Subtarget>();
2684 const Function &F = MF.getFunction();
2685 bool IsWin64 = Subtarget.isCallingConvWin64(F.getCallingConv(), F.isVarArg());
2686 unsigned FixedObject =
2687 getFixedObjectSize(MF, AFI, IsWin64, /*IsFunclet=*/false);
2688 int64_t CalleeSaveSize = AFI->getCalleeSavedStackSize(MF.getFrameInfo());
2689 int64_t FPAdjust =
2690 CalleeSaveSize - AFI->getCalleeSaveBaseToFrameRecordOffset();
2691 return StackOffset::getFixed(ObjectOffset + FixedObject + FPAdjust);
2692}
2693
2695 int64_t ObjectOffset) {
2696 const auto &MFI = MF.getFrameInfo();
2697 return StackOffset::getFixed(ObjectOffset + (int64_t)MFI.getStackSize());
2698}
2699
2700// TODO: This function currently does not work for scalable vectors.
2702 int FI) const {
2703 const auto *RegInfo = static_cast<const AArch64RegisterInfo *>(
2705 int ObjectOffset = MF.getFrameInfo().getObjectOffset(FI);
2706 return RegInfo->getLocalAddressRegister(MF) == AArch64::FP
2707 ? getFPOffset(MF, ObjectOffset).getFixed()
2708 : getStackOffset(MF, ObjectOffset).getFixed();
2709}
2710
2712 const MachineFunction &MF, int FI, Register &FrameReg, bool PreferFP,
2713 bool ForSimm) const {
2714 const auto &MFI = MF.getFrameInfo();
2715 int64_t ObjectOffset = MFI.getObjectOffset(FI);
2716 bool isFixed = MFI.isFixedObjectIndex(FI);
2717 bool isSVE = MFI.getStackID(FI) == TargetStackID::ScalableVector;
2718 return resolveFrameOffsetReference(MF, ObjectOffset, isFixed, isSVE, FrameReg,
2719 PreferFP, ForSimm);
2720}
2721
2723 const MachineFunction &MF, int64_t ObjectOffset, bool isFixed, bool isSVE,
2724 Register &FrameReg, bool PreferFP, bool ForSimm) const {
2725 const auto &MFI = MF.getFrameInfo();
2726 const auto *RegInfo = static_cast<const AArch64RegisterInfo *>(
2728 const auto *AFI = MF.getInfo<AArch64FunctionInfo>();
2729 const auto &Subtarget = MF.getSubtarget<AArch64Subtarget>();
2730
2731 int64_t FPOffset = getFPOffset(MF, ObjectOffset).getFixed();
2732 int64_t Offset = getStackOffset(MF, ObjectOffset).getFixed();
2733 bool isCSR =
2734 !isFixed && ObjectOffset >= -((int)AFI->getCalleeSavedStackSize(MFI));
2735
2736 const StackOffset &SVEStackSize = getSVEStackSize(MF);
2737
2738 // Use frame pointer to reference fixed objects. Use it for locals if
2739 // there are VLAs or a dynamically realigned SP (and thus the SP isn't
2740 // reliable as a base). Make sure useFPForScavengingIndex() does the
2741 // right thing for the emergency spill slot.
2742 bool UseFP = false;
2743 if (AFI->hasStackFrame() && !isSVE) {
2744 // We shouldn't prefer using the FP to access fixed-sized stack objects when
2745 // there are scalable (SVE) objects in between the FP and the fixed-sized
2746 // objects.
2747 PreferFP &= !SVEStackSize;
2748
2749 // Note: Keeping the following as multiple 'if' statements rather than
2750 // merging to a single expression for readability.
2751 //
2752 // Argument access should always use the FP.
2753 if (isFixed) {
2754 UseFP = hasFP(MF);
2755 } else if (isCSR && RegInfo->hasStackRealignment(MF)) {
2756 // References to the CSR area must use FP if we're re-aligning the stack
2757 // since the dynamically-sized alignment padding is between the SP/BP and
2758 // the CSR area.
2759 assert(hasFP(MF) && "Re-aligned stack must have frame pointer");
2760 UseFP = true;
2761 } else if (hasFP(MF) && !RegInfo->hasStackRealignment(MF)) {
2762 // If the FPOffset is negative and we're producing a signed immediate, we
2763 // have to keep in mind that the available offset range for negative
2764 // offsets is smaller than for positive ones. If an offset is available
2765 // via the FP and the SP, use whichever is closest.
2766 bool FPOffsetFits = !ForSimm || FPOffset >= -256;
2767 PreferFP |= Offset > -FPOffset && !SVEStackSize;
2768
2769 if (FPOffset >= 0) {
2770 // If the FPOffset is positive, that'll always be best, as the SP/BP
2771 // will be even further away.
2772 UseFP = true;
2773 } else if (MFI.hasVarSizedObjects()) {
2774 // If we have variable sized objects, we can use either FP or BP, as the
2775 // SP offset is unknown. We can use the base pointer if we have one and
2776 // FP is not preferred. If not, we're stuck with using FP.
2777 bool CanUseBP = RegInfo->hasBasePointer(MF);
2778 if (FPOffsetFits && CanUseBP) // Both are ok. Pick the best.
2779 UseFP = PreferFP;
2780 else if (!CanUseBP) // Can't use BP. Forced to use FP.
2781 UseFP = true;
2782 // else we can use BP and FP, but the offset from FP won't fit.
2783 // That will make us scavenge registers which we can probably avoid by
2784 // using BP. If it won't fit for BP either, we'll scavenge anyway.
2785 } else if (MF.hasEHFunclets() && !RegInfo->hasBasePointer(MF)) {
2786 // Funclets access the locals contained in the parent's stack frame
2787 // via the frame pointer, so we have to use the FP in the parent
2788 // function.
2789 (void) Subtarget;
2790 assert(Subtarget.isCallingConvWin64(MF.getFunction().getCallingConv(),
2791 MF.getFunction().isVarArg()) &&
2792 "Funclets should only be present on Win64");
2793 UseFP = true;
2794 } else {
2795 // We have the choice between FP and (SP or BP).
2796 if (FPOffsetFits && PreferFP) // If FP is the best fit, use it.
2797 UseFP = true;
2798 }
2799 }
2800 }
2801
2802 assert(
2803 ((isFixed || isCSR) || !RegInfo->hasStackRealignment(MF) || !UseFP) &&
2804 "In the presence of dynamic stack pointer realignment, "
2805 "non-argument/CSR objects cannot be accessed through the frame pointer");
2806
2807 if (isSVE) {
2808 StackOffset FPOffset =
2810 StackOffset SPOffset =
2811 SVEStackSize +
2812 StackOffset::get(MFI.getStackSize() - AFI->getCalleeSavedStackSize(),
2813 ObjectOffset);
2814 // Always use the FP for SVE spills if available and beneficial.
2815 if (hasFP(MF) && (SPOffset.getFixed() ||
2816 FPOffset.getScalable() < SPOffset.getScalable() ||
2817 RegInfo->hasStackRealignment(MF))) {
2818 FrameReg = RegInfo->getFrameRegister(MF);
2819 return FPOffset;
2820 }
2821
2822 FrameReg = RegInfo->hasBasePointer(MF) ? RegInfo->getBaseRegister()
2823 : (unsigned)AArch64::SP;
2824 return SPOffset;
2825 }
2826
2827 StackOffset ScalableOffset = {};
2828 if (UseFP && !(isFixed || isCSR))
2829 ScalableOffset = -SVEStackSize;
2830 if (!UseFP && (isFixed || isCSR))
2831 ScalableOffset = SVEStackSize;
2832
2833 if (UseFP) {
2834 FrameReg = RegInfo->getFrameRegister(MF);
2835 return StackOffset::getFixed(FPOffset) + ScalableOffset;
2836 }
2837
2838 // Use the base pointer if we have one.
2839 if (RegInfo->hasBasePointer(MF))
2840 FrameReg = RegInfo->getBaseRegister();
2841 else {
2842 assert(!MFI.hasVarSizedObjects() &&
2843 "Can't use SP when we have var sized objects.");
2844 FrameReg = AArch64::SP;
2845 // If we're using the red zone for this function, the SP won't actually
2846 // be adjusted, so the offsets will be negative. They're also all
2847 // within range of the signed 9-bit immediate instructions.
2848 if (canUseRedZone(MF))
2849 Offset -= AFI->getLocalStackSize();
2850 }
2851
2852 return StackOffset::getFixed(Offset) + ScalableOffset;
2853}
2854
2855static unsigned getPrologueDeath(MachineFunction &MF, unsigned Reg) {
2856 // Do not set a kill flag on values that are also marked as live-in. This
2857 // happens with the @llvm-returnaddress intrinsic and with arguments passed in
2858 // callee saved registers.
2859 // Omitting the kill flags is conservatively correct even if the live-in
2860 // is not used after all.
2861 bool IsLiveIn = MF.getRegInfo().isLiveIn(Reg);
2862 return getKillRegState(!IsLiveIn);
2863}
2864
2866 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
2869 return Subtarget.isTargetMachO() &&
2870 !(Subtarget.getTargetLowering()->supportSwiftError() &&
2871 Attrs.hasAttrSomewhere(Attribute::SwiftError)) &&
2873 !requiresSaveVG(MF) && AFI->getSVECalleeSavedStackSize() == 0;
2874}
2875
2876static bool invalidateWindowsRegisterPairing(unsigned Reg1, unsigned Reg2,
2877 bool NeedsWinCFI, bool IsFirst,
2878 const TargetRegisterInfo *TRI) {
2879 // If we are generating register pairs for a Windows function that requires
2880 // EH support, then pair consecutive registers only. There are no unwind
2881 // opcodes for saves/restores of non-consectuve register pairs.
2882 // The unwind opcodes are save_regp, save_regp_x, save_fregp, save_frepg_x,
2883 // save_lrpair.
2884 // https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling
2885
2886 if (Reg2 == AArch64::FP)
2887 return true;
2888 if (!NeedsWinCFI)
2889 return false;
2890 if (TRI->getEncodingValue(Reg2) == TRI->getEncodingValue(Reg1) + 1)
2891 return false;
2892 // If pairing a GPR with LR, the pair can be described by the save_lrpair
2893 // opcode. If this is the first register pair, it would end up with a
2894 // predecrement, but there's no save_lrpair_x opcode, so we can only do this
2895 // if LR is paired with something else than the first register.
2896 // The save_lrpair opcode requires the first register to be an odd one.
2897 if (Reg1 >= AArch64::X19 && Reg1 <= AArch64::X27 &&
2898 (Reg1 - AArch64::X19) % 2 == 0 && Reg2 == AArch64::LR && !IsFirst)
2899 return false;
2900 return true;
2901}
2902
2903/// Returns true if Reg1 and Reg2 cannot be paired using a ldp/stp instruction.
2904/// WindowsCFI requires that only consecutive registers can be paired.
2905/// LR and FP need to be allocated together when the frame needs to save
2906/// the frame-record. This means any other register pairing with LR is invalid.
2907static bool invalidateRegisterPairing(unsigned Reg1, unsigned Reg2,
2908 bool UsesWinAAPCS, bool NeedsWinCFI,
2909 bool NeedsFrameRecord, bool IsFirst,
2910 const TargetRegisterInfo *TRI) {
2911 if (UsesWinAAPCS)
2912 return invalidateWindowsRegisterPairing(Reg1, Reg2, NeedsWinCFI, IsFirst,
2913 TRI);
2914
2915 // If we need to store the frame record, don't pair any register
2916 // with LR other than FP.
2917 if (NeedsFrameRecord)
2918 return Reg2 == AArch64::LR;
2919
2920 return false;
2921}
2922
2923namespace {
2924
2925struct RegPairInfo {
2926 unsigned Reg1 = AArch64::NoRegister;
2927 unsigned Reg2 = AArch64::NoRegister;
2928 int FrameIdx;
2929 int Offset;
2930 enum RegType { GPR, FPR64, FPR128, PPR, ZPR, VG } Type;
2931 const TargetRegisterClass *RC;
2932
2933 RegPairInfo() = default;
2934
2935 bool isPaired() const { return Reg2 != AArch64::NoRegister; }
2936
2937 bool isScalable() const { return Type == PPR || Type == ZPR; }
2938};
2939
2940} // end anonymous namespace
2941
2942unsigned findFreePredicateReg(BitVector &SavedRegs) {
2943 for (unsigned PReg = AArch64::P8; PReg <= AArch64::P15; ++PReg) {
2944 if (SavedRegs.test(PReg)) {
2945 unsigned PNReg = PReg - AArch64::P0 + AArch64::PN0;
2946 return PNReg;
2947 }
2948 }
2949 return AArch64::NoRegister;
2950}
2951
2952// The multivector LD/ST are available only for SME or SVE2p1 targets
2954 MachineFunction &MF) {
2956 return false;
2957
2958 SMEAttrs FuncAttrs(MF.getFunction());
2959 bool IsLocallyStreaming =
2960 FuncAttrs.hasStreamingBody() && !FuncAttrs.hasStreamingInterface();
2961
2962 // Only when in streaming mode SME2 instructions can be safely used.
2963 // It is not safe to use SME2 instructions when in streaming compatible or
2964 // locally streaming mode.
2965 return Subtarget.hasSVE2p1() ||
2966 (Subtarget.hasSME2() &&
2967 (!IsLocallyStreaming && Subtarget.isStreaming()));
2968}
2969
2973 bool NeedsFrameRecord) {
2974
2975 if (CSI.empty())
2976 return;
2977
2978 bool IsWindows = isTargetWindows(MF);
2979 bool NeedsWinCFI = needsWinCFI(MF);
2981 unsigned StackHazardSize = getStackHazardSize(MF);
2982 MachineFrameInfo &MFI = MF.getFrameInfo();
2984 unsigned Count = CSI.size();
2985 (void)CC;
2986 // MachO's compact unwind format relies on all registers being stored in
2987 // pairs.
2990 CC == CallingConv::Win64 || (Count & 1) == 0) &&
2991 "Odd number of callee-saved regs to spill!");
2992 int ByteOffset = AFI->getCalleeSavedStackSize();
2993 int StackFillDir = -1;
2994 int RegInc = 1;
2995 unsigned FirstReg = 0;
2996 if (NeedsWinCFI) {
2997 // For WinCFI, fill the stack from the bottom up.
2998 ByteOffset = 0;
2999 StackFillDir = 1;
3000 // As the CSI array is reversed to match PrologEpilogInserter, iterate
3001 // backwards, to pair up registers starting from lower numbered registers.
3002 RegInc = -1;
3003 FirstReg = Count - 1;
3004 }
3005 int ScalableByteOffset = AFI->getSVECalleeSavedStackSize();
3006 bool NeedGapToAlignStack = AFI->hasCalleeSaveStackFreeSpace();
3007 Register LastReg = 0;
3008
3009 // When iterating backwards, the loop condition relies on unsigned wraparound.
3010 for (unsigned i = FirstReg; i < Count; i += RegInc) {
3011 RegPairInfo RPI;
3012 RPI.Reg1 = CSI[i].getReg();
3013
3014 if (AArch64::GPR64RegClass.contains(RPI.Reg1)) {
3015 RPI.Type = RegPairInfo::GPR;
3016 RPI.RC = &AArch64::GPR64RegClass;
3017 } else if (AArch64::FPR64RegClass.contains(RPI.Reg1)) {
3018 RPI.Type = RegPairInfo::FPR64;
3019 RPI.RC = &AArch64::FPR64RegClass;
3020 } else if (AArch64::FPR128RegClass.contains(RPI.Reg1)) {
3021 RPI.Type = RegPairInfo::FPR128;
3022 RPI.RC = &AArch64::FPR128RegClass;
3023 } else if (AArch64::ZPRRegClass.contains(RPI.Reg1)) {
3024 RPI.Type = RegPairInfo::ZPR;
3025 RPI.RC = &AArch64::ZPRRegClass;
3026 } else if (AArch64::PPRRegClass.contains(RPI.Reg1)) {
3027 RPI.Type = RegPairInfo::PPR;
3028 RPI.RC = &AArch64::PPRRegClass;
3029 } else if (RPI.Reg1 == AArch64::VG) {
3030 RPI.Type = RegPairInfo::VG;
3031 RPI.RC = &AArch64::FIXED_REGSRegClass;
3032 } else {
3033 llvm_unreachable("Unsupported register class.");
3034 }
3035
3036 // Add the stack hazard size as we transition from GPR->FPR CSRs.
3037 if (AFI->hasStackHazardSlotIndex() &&
3038 (!LastReg || !AArch64InstrInfo::isFpOrNEON(LastReg)) &&
3040 ByteOffset += StackFillDir * StackHazardSize;
3041 LastReg = RPI.Reg1;
3042
3043 int Scale = TRI->getSpillSize(*RPI.RC);
3044 // Add the next reg to the pair if it is in the same register class.
3045 if (unsigned(i + RegInc) < Count && !AFI->hasStackHazardSlotIndex()) {
3046 Register NextReg = CSI[i + RegInc].getReg();
3047 bool IsFirst = i == FirstReg;
3048 switch (RPI.Type) {
3049 case RegPairInfo::GPR:
3050 if (AArch64::GPR64RegClass.contains(NextReg) &&
3051 !invalidateRegisterPairing(RPI.Reg1, NextReg, IsWindows,
3052 NeedsWinCFI, NeedsFrameRecord, IsFirst,
3053 TRI))
3054 RPI.Reg2 = NextReg;
3055 break;
3056 case RegPairInfo::FPR64:
3057 if (AArch64::FPR64RegClass.contains(NextReg) &&
3058 !invalidateWindowsRegisterPairing(RPI.Reg1, NextReg, NeedsWinCFI,
3059 IsFirst, TRI))
3060 RPI.Reg2 = NextReg;
3061 break;
3062 case RegPairInfo::FPR128:
3063 if (AArch64::FPR128RegClass.contains(NextReg))
3064 RPI.Reg2 = NextReg;
3065 break;
3066 case RegPairInfo::PPR:
3067 break;
3068 case RegPairInfo::ZPR:
3069 if (AFI->getPredicateRegForFillSpill() != 0 &&
3070 ((RPI.Reg1 - AArch64::Z0) & 1) == 0 && (NextReg == RPI.Reg1 + 1)) {
3071 // Calculate offset of register pair to see if pair instruction can be
3072 // used.
3073 int Offset = (ScalableByteOffset + StackFillDir * 2 * Scale) / Scale;
3074 if ((-16 <= Offset && Offset <= 14) && (Offset % 2 == 0))
3075 RPI.Reg2 = NextReg;
3076 }
3077 break;
3078 case RegPairInfo::VG:
3079 break;
3080 }
3081 }
3082
3083 // GPRs and FPRs are saved in pairs of 64-bit regs. We expect the CSI
3084 // list to come in sorted by frame index so that we can issue the store
3085 // pair instructions directly. Assert if we see anything otherwise.
3086 //
3087 // The order of the registers in the list is controlled by
3088 // getCalleeSavedRegs(), so they will always be in-order, as well.
3089 assert((!RPI.isPaired() ||
3090 (CSI[i].getFrameIdx() + RegInc == CSI[i + RegInc].getFrameIdx())) &&
3091 "Out of order callee saved regs!");
3092
3093 assert((!RPI.isPaired() || !NeedsFrameRecord || RPI.Reg2 != AArch64::FP ||
3094 RPI.Reg1 == AArch64::LR) &&
3095 "FrameRecord must be allocated together with LR");
3096
3097 // Windows AAPCS has FP and LR reversed.
3098 assert((!RPI.isPaired() || !NeedsFrameRecord || RPI.Reg1 != AArch64::FP ||
3099 RPI.Reg2 == AArch64::LR) &&
3100 "FrameRecord must be allocated together with LR");
3101
3102 // MachO's compact unwind format relies on all registers being stored in
3103 // adjacent register pairs.
3107 (RPI.isPaired() &&
3108 ((RPI.Reg1 == AArch64::LR && RPI.Reg2 == AArch64::FP) ||
3109 RPI.Reg1 + 1 == RPI.Reg2))) &&
3110 "Callee-save registers not saved as adjacent register pair!");
3111
3112 RPI.FrameIdx = CSI[i].getFrameIdx();
3113 if (NeedsWinCFI &&
3114 RPI.isPaired()) // RPI.FrameIdx must be the lower index of the pair
3115 RPI.FrameIdx = CSI[i + RegInc].getFrameIdx();
3116
3117 int OffsetPre = RPI.isScalable() ? ScalableByteOffset : ByteOffset;
3118 assert(OffsetPre % Scale == 0);
3119
3120 if (RPI.isScalable())
3121 ScalableByteOffset += StackFillDir * (RPI.isPaired() ? 2 * Scale : Scale);
3122 else
3123 ByteOffset += StackFillDir * (RPI.isPaired() ? 2 * Scale : Scale);
3124
3125 // Swift's async context is directly before FP, so allocate an extra
3126 // 8 bytes for it.
3127 if (NeedsFrameRecord && AFI->hasSwiftAsyncContext() &&
3128 ((!IsWindows && RPI.Reg2 == AArch64::FP) ||
3129 (IsWindows && RPI.Reg2 == AArch64::LR)))
3130 ByteOffset += StackFillDir * 8;
3131
3132 // Round up size of non-pair to pair size if we need to pad the
3133 // callee-save area to ensure 16-byte alignment.
3134 if (NeedGapToAlignStack && !NeedsWinCFI && !RPI.isScalable() &&
3135 RPI.Type != RegPairInfo::FPR128 && !RPI.isPaired() &&
3136 ByteOffset % 16 != 0) {
3137 ByteOffset += 8 * StackFillDir;
3138 assert(MFI.getObjectAlign(RPI.FrameIdx) <= Align(16));
3139 // A stack frame with a gap looks like this, bottom up:
3140 // d9, d8. x21, gap, x20, x19.
3141 // Set extra alignment on the x21 object to create the gap above it.
3142 MFI.setObjectAlignment(RPI.FrameIdx, Align(16));
3143 NeedGapToAlignStack = false;
3144 }
3145
3146 int OffsetPost = RPI.isScalable() ? ScalableByteOffset : ByteOffset;
3147 assert(OffsetPost % Scale == 0);
3148 // If filling top down (default), we want the offset after incrementing it.
3149 // If filling bottom up (WinCFI) we need the original offset.
3150 int Offset = NeedsWinCFI ? OffsetPre : OffsetPost;
3151
3152 // The FP, LR pair goes 8 bytes into our expanded 24-byte slot so that the
3153 // Swift context can directly precede FP.
3154 if (NeedsFrameRecord && AFI->hasSwiftAsyncContext() &&
3155 ((!IsWindows && RPI.Reg2 == AArch64::FP) ||
3156 (IsWindows && RPI.Reg2 == AArch64::LR)))
3157 Offset += 8;
3158 RPI.Offset = Offset / Scale;
3159
3160 assert((!RPI.isPaired() ||
3161 (!RPI.isScalable() && RPI.Offset >= -64 && RPI.Offset <= 63) ||
3162 (RPI.isScalable() && RPI.Offset >= -256 && RPI.Offset <= 255)) &&
3163 "Offset out of bounds for LDP/STP immediate");
3164
3165 auto isFrameRecord = [&] {
3166 if (RPI.isPaired())
3167 return IsWindows ? RPI.Reg1 == AArch64::FP && RPI.Reg2 == AArch64::LR
3168 : RPI.Reg1 == AArch64::LR && RPI.Reg2 == AArch64::FP;
3169 // Otherwise, look for the frame record as two unpaired registers. This is
3170 // needed for -aarch64-stack-hazard-size=<val>, which disables register
3171 // pairing (as the padding may be too large for the LDP/STP offset). Note:
3172 // On Windows, this check works out as current reg == FP, next reg == LR,
3173 // and on other platforms current reg == FP, previous reg == LR. This
3174 // works out as the correct pre-increment or post-increment offsets
3175 // respectively.
3176 return i > 0 && RPI.Reg1 == AArch64::FP &&
3177 CSI[i - 1].getReg() == AArch64::LR;
3178 };
3179
3180 // Save the offset to frame record so that the FP register can point to the
3181 // innermost frame record (spilled FP and LR registers).
3182 if (NeedsFrameRecord && isFrameRecord())
3184
3185 RegPairs.push_back(RPI);
3186 if (RPI.isPaired())
3187 i += RegInc;
3188 }
3189 if (NeedsWinCFI) {
3190 // If we need an alignment gap in the stack, align the topmost stack
3191 // object. A stack frame with a gap looks like this, bottom up:
3192 // x19, d8. d9, gap.
3193 // Set extra alignment on the topmost stack object (the first element in
3194 // CSI, which goes top down), to create the gap above it.
3195 if (AFI->hasCalleeSaveStackFreeSpace())
3196 MFI.setObjectAlignment(CSI[0].getFrameIdx(), Align(16));
3197 // We iterated bottom up over the registers; flip RegPairs back to top
3198 // down order.
3199 std::reverse(RegPairs.begin(), RegPairs.end());
3200 }
3201}
3202
3206 MachineFunction &MF = *MBB.getParent();
3209 bool NeedsWinCFI = needsWinCFI(MF);
3210 DebugLoc DL;
3212
3213 computeCalleeSaveRegisterPairs(MF, CSI, TRI, RegPairs, hasFP(MF));
3214
3216 // Refresh the reserved regs in case there are any potential changes since the
3217 // last freeze.
3218 MRI.freezeReservedRegs();
3219
3220 if (homogeneousPrologEpilog(MF)) {
3221 auto MIB = BuildMI(MBB, MI, DL, TII.get(AArch64::HOM_Prolog))
3223
3224 for (auto &RPI : RegPairs) {
3225 MIB.addReg(RPI.Reg1);
3226 MIB.addReg(RPI.Reg2);
3227
3228 // Update register live in.
3229 if (!MRI.isReserved(RPI.Reg1))
3230 MBB.addLiveIn(RPI.Reg1);
3231 if (RPI.isPaired() && !MRI.isReserved(RPI.Reg2))
3232 MBB.addLiveIn(RPI.Reg2);
3233 }
3234 return true;
3235 }
3236 bool PTrueCreated = false;
3237 for (const RegPairInfo &RPI : llvm::reverse(RegPairs)) {
3238 unsigned Reg1 = RPI.Reg1;
3239 unsigned Reg2 = RPI.Reg2;
3240 unsigned StrOpc;
3241
3242 // Issue sequence of spills for cs regs. The first spill may be converted
3243 // to a pre-decrement store later by emitPrologue if the callee-save stack
3244 // area allocation can't be combined with the local stack area allocation.
3245 // For example:
3246 // stp x22, x21, [sp, #0] // addImm(+0)
3247 // stp x20, x19, [sp, #16] // addImm(+2)
3248 // stp fp, lr, [sp, #32] // addImm(+4)
3249 // Rationale: This sequence saves uop updates compared to a sequence of
3250 // pre-increment spills like stp xi,xj,[sp,#-16]!
3251 // Note: Similar rationale and sequence for restores in epilog.
3252 unsigned Size = TRI->getSpillSize(*RPI.RC);
3253 Align Alignment = TRI->getSpillAlign(*RPI.RC);
3254 switch (RPI.Type) {
3255 case RegPairInfo::GPR:
3256 StrOpc = RPI.isPaired() ? AArch64::STPXi : AArch64::STRXui;
3257 break;
3258 case RegPairInfo::FPR64:
3259 StrOpc = RPI.isPaired() ? AArch64::STPDi : AArch64::STRDui;
3260 break;
3261 case RegPairInfo::FPR128:
3262 StrOpc = RPI.isPaired() ? AArch64::STPQi : AArch64::STRQui;
3263 break;
3264 case RegPairInfo::ZPR:
3265 StrOpc = RPI.isPaired() ? AArch64::ST1B_2Z_IMM : AArch64::STR_ZXI;
3266 break;
3267 case RegPairInfo::PPR:
3268 StrOpc = AArch64::STR_PXI;
3269 break;
3270 case RegPairInfo::VG:
3271 StrOpc = AArch64::STRXui;
3272 break;
3273 }
3274
3275 unsigned X0Scratch = AArch64::NoRegister;
3276 if (Reg1 == AArch64::VG) {
3277 // Find an available register to store value of VG to.
3279 assert(Reg1 != AArch64::NoRegister);
3280 SMEAttrs Attrs(MF.getFunction());
3281
3282 if (Attrs.hasStreamingBody() && !Attrs.hasStreamingInterface() &&
3283 AFI->getStreamingVGIdx() == std::numeric_limits<int>::max()) {
3284 // For locally-streaming functions, we need to store both the streaming
3285 // & non-streaming VG. Spill the streaming value first.
3286 BuildMI(MBB, MI, DL, TII.get(AArch64::RDSVLI_XI), Reg1)
3287 .addImm(1)
3289 BuildMI(MBB, MI, DL, TII.get(AArch64::UBFMXri), Reg1)
3290 .addReg(Reg1)
3291 .addImm(3)
3292 .addImm(63)
3294
3295 AFI->setStreamingVGIdx(RPI.FrameIdx);
3296 } else if (MF.getSubtarget<AArch64Subtarget>().hasSVE()) {
3297 BuildMI(MBB, MI, DL, TII.get(AArch64::CNTD_XPiI), Reg1)
3298 .addImm(31)
3299 .addImm(1)
3301 AFI->setVGIdx(RPI.FrameIdx);
3302 } else {
3304 if (llvm::any_of(
3305 MBB.liveins(),
3306 [&STI](const MachineBasicBlock::RegisterMaskPair &LiveIn) {
3307 return STI.getRegisterInfo()->isSuperOrSubRegisterEq(
3308 AArch64::X0, LiveIn.PhysReg);
3309 }))
3310 X0Scratch = Reg1;
3311
3312 if (X0Scratch != AArch64::NoRegister)
3313 BuildMI(MBB, MI, DL, TII.get(AArch64::ORRXrr), Reg1)
3314 .addReg(AArch64::XZR)
3315 .addReg(AArch64::X0, RegState::Undef)
3316 .addReg(AArch64::X0, RegState::Implicit)
3318
3319 const uint32_t *RegMask = TRI->getCallPreservedMask(
3320 MF,
3322 BuildMI(MBB, MI, DL, TII.get(AArch64::BL))
3323 .addExternalSymbol("__arm_get_current_vg")
3324 .addRegMask(RegMask)
3325 .addReg(AArch64::X0, RegState::ImplicitDefine)
3327 Reg1 = AArch64::X0;
3328 AFI->setVGIdx(RPI.FrameIdx);
3329 }
3330 }
3331
3332 LLVM_DEBUG(dbgs() << "CSR spill: (" << printReg(Reg1, TRI);
3333 if (RPI.isPaired()) dbgs() << ", " << printReg(Reg2, TRI);
3334 dbgs() << ") -> fi#(" << RPI.FrameIdx;
3335 if (RPI.isPaired()) dbgs() << ", " << RPI.FrameIdx + 1;
3336 dbgs() << ")\n");
3337
3338 assert((!NeedsWinCFI || !(Reg1 == AArch64::LR && Reg2 == AArch64::FP)) &&
3339 "Windows unwdinding requires a consecutive (FP,LR) pair");
3340 // Windows unwind codes require consecutive registers if registers are
3341 // paired. Make the switch here, so that the code below will save (x,x+1)
3342 // and not (x+1,x).
3343 unsigned FrameIdxReg1 = RPI.FrameIdx;
3344 unsigned FrameIdxReg2 = RPI.FrameIdx + 1;
3345 if (NeedsWinCFI && RPI.isPaired()) {
3346 std::swap(Reg1, Reg2);
3347 std::swap(FrameIdxReg1, FrameIdxReg2);
3348 }
3349
3350 if (RPI.isPaired() && RPI.isScalable()) {
3351 [[maybe_unused]] const AArch64Subtarget &Subtarget =
3354 unsigned PnReg = AFI->getPredicateRegForFillSpill();
3355 assert((PnReg != 0 && enableMultiVectorSpillFill(Subtarget, MF)) &&
3356 "Expects SVE2.1 or SME2 target and a predicate register");
3357#ifdef EXPENSIVE_CHECKS
3358 auto IsPPR = [](const RegPairInfo &c) {
3359 return c.Reg1 == RegPairInfo::PPR;
3360 };
3361 auto PPRBegin = std::find_if(RegPairs.begin(), RegPairs.end(), IsPPR);
3362 auto IsZPR = [](const RegPairInfo &c) {
3363 return c.Type == RegPairInfo::ZPR;
3364 };
3365 auto ZPRBegin = std::find_if(RegPairs.begin(), RegPairs.end(), IsZPR);
3366 assert(!(PPRBegin < ZPRBegin) &&
3367 "Expected callee save predicate to be handled first");
3368#endif
3369 if (!PTrueCreated) {
3370 PTrueCreated = true;
3371 BuildMI(MBB, MI, DL, TII.get(AArch64::PTRUE_C_B), PnReg)
3373 }
3374 MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(StrOpc));
3375 if (!MRI.isReserved(Reg1))
3376 MBB.addLiveIn(Reg1);
3377 if (!MRI.isReserved(Reg2))
3378 MBB.addLiveIn(Reg2);
3379 MIB.addReg(/*PairRegs*/ AArch64::Z0_Z1 + (RPI.Reg1 - AArch64::Z0));
3381 MachinePointerInfo::getFixedStack(MF, FrameIdxReg2),
3382 MachineMemOperand::MOStore, Size, Alignment));
3383 MIB.addReg(PnReg);
3384 MIB.addReg(AArch64::SP)
3385 .addImm(RPI.Offset / 2) // [sp, #imm*2*vscale],
3386 // where 2*vscale is implicit
3389 MachinePointerInfo::getFixedStack(MF, FrameIdxReg1),
3390 MachineMemOperand::MOStore, Size, Alignment));
3391 if (NeedsWinCFI)
3393 } else { // The code when the pair of ZReg is not present
3394 MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(StrOpc));
3395 if (!MRI.isReserved(Reg1))
3396 MBB.addLiveIn(Reg1);
3397 if (RPI.isPaired()) {
3398 if (!MRI.isReserved(Reg2))
3399 MBB.addLiveIn(Reg2);
3400 MIB.addReg(Reg2, getPrologueDeath(MF, Reg2));
3402 MachinePointerInfo::getFixedStack(MF, FrameIdxReg2),
3403 MachineMemOperand::MOStore, Size, Alignment));
3404 }
3405 MIB.addReg(Reg1, getPrologueDeath(MF, Reg1))
3406 .addReg(AArch64::SP)
3407 .addImm(RPI.Offset) // [sp, #offset*vscale],
3408 // where factor*vscale is implicit
3411 MachinePointerInfo::getFixedStack(MF, FrameIdxReg1),
3412 MachineMemOperand::MOStore, Size, Alignment));
3413 if (NeedsWinCFI)
3415 }
3416 // Update the StackIDs of the SVE stack slots.
3417 MachineFrameInfo &MFI = MF.getFrameInfo();
3418 if (RPI.Type == RegPairInfo::ZPR || RPI.Type == RegPairInfo::PPR) {
3419 MFI.setStackID(FrameIdxReg1, TargetStackID::ScalableVector);
3420 if (RPI.isPaired())
3421 MFI.setStackID(FrameIdxReg2, TargetStackID::ScalableVector);
3422 }
3423
3424 if (X0Scratch != AArch64::NoRegister)
3425 BuildMI(MBB, MI, DL, TII.get(AArch64::ORRXrr), AArch64::X0)
3426 .addReg(AArch64::XZR)
3427 .addReg(X0Scratch, RegState::Undef)
3428 .addReg(X0Scratch, RegState::Implicit)
3430 }
3431 return true;
3432}
3433
3437 MachineFunction &MF = *MBB.getParent();
3439 DebugLoc DL;
3441 bool NeedsWinCFI = needsWinCFI(MF);
3442
3443 if (MBBI != MBB.end())
3444 DL = MBBI->getDebugLoc();
3445
3446 computeCalleeSaveRegisterPairs(MF, CSI, TRI, RegPairs, hasFP(MF));
3447 if (homogeneousPrologEpilog(MF, &MBB)) {
3448 auto MIB = BuildMI(MBB, MBBI, DL, TII.get(AArch64::HOM_Epilog))
3450 for (auto &RPI : RegPairs) {
3451 MIB.addReg(RPI.Reg1, RegState::Define);
3452 MIB.addReg(RPI.Reg2, RegState::Define);
3453 }
3454 return true;
3455 }
3456
3457 // For performance reasons restore SVE register in increasing order
3458 auto IsPPR = [](const RegPairInfo &c) { return c.Type == RegPairInfo::PPR; };
3459 auto PPRBegin = std::find_if(RegPairs.begin(), RegPairs.end(), IsPPR);
3460 auto PPREnd = std::find_if_not(PPRBegin, RegPairs.end(), IsPPR);
3461 std::reverse(PPRBegin, PPREnd);
3462 auto IsZPR = [](const RegPairInfo &c) { return c.Type == RegPairInfo::ZPR; };
3463 auto ZPRBegin = std::find_if(RegPairs.begin(), RegPairs.end(), IsZPR);
3464 auto ZPREnd = std::find_if_not(ZPRBegin, RegPairs.end(), IsZPR);
3465 std::reverse(ZPRBegin, ZPREnd);
3466
3467 bool PTrueCreated = false;
3468 for (const RegPairInfo &RPI : RegPairs) {
3469 unsigned Reg1 = RPI.Reg1;
3470 unsigned Reg2 = RPI.Reg2;
3471
3472 // Issue sequence of restores for cs regs. The last restore may be converted
3473 // to a post-increment load later by emitEpilogue if the callee-save stack
3474 // area allocation can't be combined with the local stack area allocation.
3475 // For example:
3476 // ldp fp, lr, [sp, #32] // addImm(+4)
3477 // ldp x20, x19, [sp, #16] // addImm(+2)
3478 // ldp x22, x21, [sp, #0] // addImm(+0)
3479 // Note: see comment in spillCalleeSavedRegisters()
3480 unsigned LdrOpc;
3481 unsigned Size = TRI->getSpillSize(*RPI.RC);
3482 Align Alignment = TRI->getSpillAlign(*RPI.RC);
3483 switch (RPI.Type) {
3484 case RegPairInfo::GPR:
3485 LdrOpc = RPI.isPaired() ? AArch64::LDPXi : AArch64::LDRXui;
3486 break;
3487 case RegPairInfo::FPR64:
3488 LdrOpc = RPI.isPaired() ? AArch64::LDPDi : AArch64::LDRDui;
3489 break;
3490 case RegPairInfo::FPR128:
3491 LdrOpc = RPI.isPaired() ? AArch64::LDPQi : AArch64::LDRQui;
3492 break;
3493 case RegPairInfo::ZPR:
3494 LdrOpc = RPI.isPaired() ? AArch64::LD1B_2Z_IMM : AArch64::LDR_ZXI;
3495 break;
3496 case RegPairInfo::PPR:
3497 LdrOpc = AArch64::LDR_PXI;
3498 break;
3499 case RegPairInfo::VG:
3500 continue;
3501 }
3502 LLVM_DEBUG(dbgs() << "CSR restore: (" << printReg(Reg1, TRI);
3503 if (RPI.isPaired()) dbgs() << ", " << printReg(Reg2, TRI);
3504 dbgs() << ") -> fi#(" << RPI.FrameIdx;
3505 if (RPI.isPaired()) dbgs() << ", " << RPI.FrameIdx + 1;
3506 dbgs() << ")\n");
3507
3508 // Windows unwind codes require consecutive registers if registers are
3509 // paired. Make the switch here, so that the code below will save (x,x+1)
3510 // and not (x+1,x).
3511 unsigned FrameIdxReg1 = RPI.FrameIdx;
3512 unsigned FrameIdxReg2 = RPI.FrameIdx + 1;
3513 if (NeedsWinCFI && RPI.isPaired()) {
3514 std::swap(Reg1, Reg2);
3515 std::swap(FrameIdxReg1, FrameIdxReg2);
3516 }
3517
3519 if (RPI.isPaired() && RPI.isScalable()) {
3520 [[maybe_unused]] const AArch64Subtarget &Subtarget =
3522 unsigned PnReg = AFI->getPredicateRegForFillSpill();
3523 assert((PnReg != 0 && enableMultiVectorSpillFill(Subtarget, MF)) &&
3524 "Expects SVE2.1 or SME2 target and a predicate register");
3525#ifdef EXPENSIVE_CHECKS
3526 assert(!(PPRBegin < ZPRBegin) &&
3527 "Expected callee save predicate to be handled first");
3528#endif
3529 if (!PTrueCreated) {
3530 PTrueCreated = true;
3531 BuildMI(MBB, MBBI, DL, TII.get(AArch64::PTRUE_C_B), PnReg)
3533 }
3534 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII.get(LdrOpc));
3535 MIB.addReg(/*PairRegs*/ AArch64::Z0_Z1 + (RPI.Reg1 - AArch64::Z0),
3536 getDefRegState(true));
3538 MachinePointerInfo::getFixedStack(MF, FrameIdxReg2),
3539 MachineMemOperand::MOLoad, Size, Alignment));
3540 MIB.addReg(PnReg);
3541 MIB.addReg(AArch64::SP)
3542 .addImm(RPI.Offset / 2) // [sp, #imm*2*vscale]
3543 // where 2*vscale is implicit
3546 MachinePointerInfo::getFixedStack(MF, FrameIdxReg1),
3547 MachineMemOperand::MOLoad, Size, Alignment));
3548 if (NeedsWinCFI)
3550 } else {
3551 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII.get(LdrOpc));
3552 if (RPI.isPaired()) {
3553 MIB.addReg(Reg2, getDefRegState(true));
3555 MachinePointerInfo::getFixedStack(MF, FrameIdxReg2),
3556 MachineMemOperand::MOLoad, Size, Alignment));
3557 }
3558 MIB.addReg(Reg1, getDefRegState(true));
3559 MIB.addReg(AArch64::SP)
3560 .addImm(RPI.Offset) // [sp, #offset*vscale]
3561 // where factor*vscale is implicit
3564 MachinePointerInfo::getFixedStack(MF, FrameIdxReg1),
3565 MachineMemOperand::MOLoad, Size, Alignment));
3566 if (NeedsWinCFI)
3568 }
3569 }
3570 return true;
3571}
3572
3573// Return the FrameID for a MMO.
3574static std::optional<int> getMMOFrameID(MachineMemOperand *MMO,
3575 const MachineFrameInfo &MFI) {
3576 auto *PSV =
3577 dyn_cast_or_null<FixedStackPseudoSourceValue>(MMO->getPseudoValue());
3578 if (PSV)
3579 return std::optional<int>(PSV->getFrameIndex());
3580
3581 if (MMO->getValue()) {
3582 if (auto *Al = dyn_cast<AllocaInst>(getUnderlyingObject(MMO->getValue()))) {
3583 for (int FI = MFI.getObjectIndexBegin(); FI < MFI.getObjectIndexEnd();
3584 FI++)
3585 if (MFI.getObjectAllocation(FI) == Al)
3586 return FI;
3587 }
3588 }
3589
3590 return std::nullopt;
3591}
3592
3593// Return the FrameID for a Load/Store instruction by looking at the first MMO.
3594static std::optional<int> getLdStFrameID(const MachineInstr &MI,
3595 const MachineFrameInfo &MFI) {
3596 if (!MI.mayLoadOrStore() || MI.getNumMemOperands() < 1)
3597 return std::nullopt;
3598
3599 return getMMOFrameID(*MI.memoperands_begin(), MFI);
3600}
3601
3602// Check if a Hazard slot is needed for the current function, and if so create
3603// one for it. The index is stored in AArch64FunctionInfo->StackHazardSlotIndex,
3604// which can be used to determine if any hazard padding is needed.
3605void AArch64FrameLowering::determineStackHazardSlot(
3606 MachineFunction &MF, BitVector &SavedRegs) const {
3607 unsigned StackHazardSize = getStackHazardSize(MF);
3608 if (StackHazardSize == 0 || StackHazardSize % 16 != 0 ||
3610 return;
3611
3612 // Stack hazards are only needed in streaming functions.
3614 if (!StackHazardInNonStreaming && Attrs.hasNonStreamingInterfaceAndBody())
3615 return;
3616
3617 MachineFrameInfo &MFI = MF.getFrameInfo();
3618
3619 // Add a hazard slot if there are any CSR FPR registers, or are any fp-only
3620 // stack objects.
3621 bool HasFPRCSRs = any_of(SavedRegs.set_bits(), [](unsigned Reg) {
3622 return AArch64::FPR64RegClass.contains(Reg) ||
3623 AArch64::FPR128RegClass.contains(Reg) ||
3624 AArch64::ZPRRegClass.contains(Reg) ||
3625 AArch64::PPRRegClass.contains(Reg);
3626 });
3627 bool HasFPRStackObjects = false;
3628 if (!HasFPRCSRs) {
3629 std::vector<unsigned> FrameObjects(MFI.getObjectIndexEnd());
3630 for (auto &MBB : MF) {
3631 for (auto &MI : MBB) {
3632 std::optional<int> FI = getLdStFrameID(MI, MFI);
3633 if (FI && *FI >= 0 && *FI < (int)FrameObjects.size()) {
3634 if (MFI.getStackID(*FI) == TargetStackID::ScalableVector ||
3636 FrameObjects[*FI] |= 2;
3637 else
3638 FrameObjects[*FI] |= 1;
3639 }
3640 }
3641 }
3642 HasFPRStackObjects =
3643 any_of(FrameObjects, [](unsigned B) { return (B & 3) == 2; });
3644 }
3645
3646 if (HasFPRCSRs || HasFPRStackObjects) {
3647 int ID = MFI.CreateStackObject(StackHazardSize, Align(16), false);
3648 LLVM_DEBUG(dbgs() << "Created Hazard slot at " << ID << " size "
3649 << StackHazardSize << "\n");
3650 MF.getInfo<AArch64FunctionInfo>()->setStackHazardSlotIndex(ID);
3651 }
3652}
3653
3655 BitVector &SavedRegs,
3656 RegScavenger *RS) const {
3657 // All calls are tail calls in GHC calling conv, and functions have no
3658 // prologue/epilogue.
3660 return;
3661
3663 const AArch64RegisterInfo *RegInfo = static_cast<const AArch64RegisterInfo *>(
3665 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
3667 unsigned UnspilledCSGPR = AArch64::NoRegister;
3668 unsigned UnspilledCSGPRPaired = AArch64::NoRegister;
3669
3670 MachineFrameInfo &MFI = MF.getFrameInfo();
3671 const MCPhysReg *CSRegs = MF.getRegInfo().getCalleeSavedRegs();
3672
3673 unsigned BasePointerReg = RegInfo->hasBasePointer(MF)
3674 ? RegInfo->getBaseRegister()
3675 : (unsigned)AArch64::NoRegister;
3676
3677 unsigned ExtraCSSpill = 0;
3678 bool HasUnpairedGPR64 = false;
3679 bool HasPairZReg = false;
3680 // Figure out which callee-saved registers to save/restore.
3681 for (unsigned i = 0; CSRegs[i]; ++i) {
3682 const unsigned Reg = CSRegs[i];
3683
3684 // Add the base pointer register to SavedRegs if it is callee-save.
3685 if (Reg == BasePointerReg)
3686 SavedRegs.set(Reg);
3687
3688 bool RegUsed = SavedRegs.test(Reg);
3689 unsigned PairedReg = AArch64::NoRegister;
3690 const bool RegIsGPR64 = AArch64::GPR64RegClass.contains(Reg);
3691 if (RegIsGPR64 || AArch64::FPR64RegClass.contains(Reg) ||
3692 AArch64::FPR128RegClass.contains(Reg)) {
3693 // Compensate for odd numbers of GP CSRs.
3694 // For now, all the known cases of odd number of CSRs are of GPRs.
3695 if (HasUnpairedGPR64)
3696 PairedReg = CSRegs[i % 2 == 0 ? i - 1 : i + 1];
3697 else
3698 PairedReg = CSRegs[i ^ 1];
3699 }
3700
3701 // If the function requires all the GP registers to save (SavedRegs),
3702 // and there are an odd number of GP CSRs at the same time (CSRegs),
3703 // PairedReg could be in a different register class from Reg, which would
3704 // lead to a FPR (usually D8) accidentally being marked saved.
3705 if (RegIsGPR64 && !AArch64::GPR64RegClass.contains(PairedReg)) {
3706 PairedReg = AArch64::NoRegister;
3707 HasUnpairedGPR64 = true;
3708 }
3709 assert(PairedReg == AArch64::NoRegister ||
3710 AArch64::GPR64RegClass.contains(Reg, PairedReg) ||
3711 AArch64::FPR64RegClass.contains(Reg, PairedReg) ||
3712 AArch64::FPR128RegClass.contains(Reg, PairedReg));
3713
3714 if (!RegUsed) {
3715 if (AArch64::GPR64RegClass.contains(Reg) &&
3716 !RegInfo->isReservedReg(MF, Reg)) {
3717 UnspilledCSGPR = Reg;
3718 UnspilledCSGPRPaired = PairedReg;
3719 }
3720 continue;
3721 }
3722
3723 // MachO's compact unwind format relies on all registers being stored in
3724 // pairs.
3725 // FIXME: the usual format is actually better if unwinding isn't needed.
3726 if (producePairRegisters(MF) && PairedReg != AArch64::NoRegister &&
3727 !SavedRegs.test(PairedReg)) {
3728 SavedRegs.set(PairedReg);
3729 if (AArch64::GPR64RegClass.contains(PairedReg) &&
3730 !RegInfo->isReservedReg(MF, PairedReg))
3731 ExtraCSSpill = PairedReg;
3732 }
3733 // Check if there is a pair of ZRegs, so it can select PReg for spill/fill
3734 HasPairZReg |= (AArch64::ZPRRegClass.contains(Reg, CSRegs[i ^ 1]) &&
3735 SavedRegs.test(CSRegs[i ^ 1]));
3736 }
3737
3738 if (HasPairZReg && enableMultiVectorSpillFill(Subtarget, MF)) {
3740 // Find a suitable predicate register for the multi-vector spill/fill
3741 // instructions.
3742 unsigned PnReg = findFreePredicateReg(SavedRegs);
3743 if (PnReg != AArch64::NoRegister)
3744 AFI->setPredicateRegForFillSpill(PnReg);
3745 // If no free callee-save has been found assign one.
3746 if (!AFI->getPredicateRegForFillSpill() &&
3747 MF.getFunction().getCallingConv() ==
3749 SavedRegs.set(AArch64::P8);
3750 AFI->setPredicateRegForFillSpill(AArch64::PN8);
3751 }
3752
3753 assert(!RegInfo->isReservedReg(MF, AFI->getPredicateRegForFillSpill()) &&
3754 "Predicate cannot be a reserved register");
3755 }
3756
3758 !Subtarget.isTargetWindows()) {
3759 // For Windows calling convention on a non-windows OS, where X18 is treated
3760 // as reserved, back up X18 when entering non-windows code (marked with the
3761 // Windows calling convention) and restore when returning regardless of
3762 // whether the individual function uses it - it might call other functions
3763 // that clobber it.
3764 SavedRegs.set(AArch64::X18);
3765 }
3766
3767 // Calculates the callee saved stack size.
3768 unsigned CSStackSize = 0;
3769 unsigned SVECSStackSize = 0;
3771 for (unsigned Reg : SavedRegs.set_bits()) {
3772 auto *RC = TRI->getMinimalPhysRegClass(Reg);
3773 assert(RC && "expected register class!");
3774 auto SpillSize = TRI->getSpillSize(*RC);
3775 if (AArch64::PPRRegClass.contains(Reg) ||
3776 AArch64::ZPRRegClass.contains(Reg))
3777 SVECSStackSize += SpillSize;
3778 else
3779 CSStackSize += SpillSize;
3780 }
3781
3782 // Increase the callee-saved stack size if the function has streaming mode
3783 // changes, as we will need to spill the value of the VG register.
3784 // For locally streaming functions, we spill both the streaming and
3785 // non-streaming VG value.
3786 const Function &F = MF.getFunction();
3787 SMEAttrs Attrs(F);
3788 if (requiresSaveVG(MF)) {
3789 if (Attrs.hasStreamingBody() && !Attrs.hasStreamingInterface())
3790 CSStackSize += 16;
3791 else
3792 CSStackSize += 8;
3793 }
3794
3795 // Determine if a Hazard slot should be used, and increase the CSStackSize by
3796 // StackHazardSize if so.
3797 determineStackHazardSlot(MF, SavedRegs);
3798 if (AFI->hasStackHazardSlotIndex())
3799 CSStackSize += getStackHazardSize(MF);
3800
3801 // Save number of saved regs, so we can easily update CSStackSize later.
3802 unsigned NumSavedRegs = SavedRegs.count();
3803
3804 // The frame record needs to be created by saving the appropriate registers
3805 uint64_t EstimatedStackSize = MFI.estimateStackSize(MF);
3806 if (hasFP(MF) ||
3807 windowsRequiresStackProbe(MF, EstimatedStackSize + CSStackSize + 16)) {
3808 SavedRegs.set(AArch64::FP);
3809 SavedRegs.set(AArch64::LR);
3810 }
3811
3812 LLVM_DEBUG({
3813 dbgs() << "*** determineCalleeSaves\nSaved CSRs:";
3814 for (unsigned Reg : SavedRegs.set_bits())
3815 dbgs() << ' ' << printReg(Reg, RegInfo);
3816 dbgs() << "\n";
3817 });
3818
3819 // If any callee-saved registers are used, the frame cannot be eliminated.
3820 int64_t SVEStackSize =
3821 alignTo(SVECSStackSize + estimateSVEStackObjectOffsets(MFI), 16);
3822 bool CanEliminateFrame = (SavedRegs.count() == 0) && !SVEStackSize;
3823
3824 // The CSR spill slots have not been allocated yet, so estimateStackSize
3825 // won't include them.
3826 unsigned EstimatedStackSizeLimit = estimateRSStackSizeLimit(MF);
3827
3828 // We may address some of the stack above the canonical frame address, either
3829 // for our own arguments or during a call. Include that in calculating whether
3830 // we have complicated addressing concerns.
3831 int64_t CalleeStackUsed = 0;
3832 for (int I = MFI.getObjectIndexBegin(); I != 0; ++I) {
3833 int64_t FixedOff = MFI.getObjectOffset(I);
3834 if (FixedOff > CalleeStackUsed)
3835 CalleeStackUsed = FixedOff;
3836 }
3837
3838 // Conservatively always assume BigStack when there are SVE spills.
3839 bool BigStack = SVEStackSize || (EstimatedStackSize + CSStackSize +
3840 CalleeStackUsed) > EstimatedStackSizeLimit;
3841 if (BigStack || !CanEliminateFrame || RegInfo->cannotEliminateFrame(MF))
3842 AFI->setHasStackFrame(true);
3843
3844 // Estimate if we might need to scavenge a register at some point in order
3845 // to materialize a stack offset. If so, either spill one additional
3846 // callee-saved register or reserve a special spill slot to facilitate
3847 // register scavenging. If we already spilled an extra callee-saved register
3848 // above to keep the number of spills even, we don't need to do anything else
3849 // here.
3850 if (BigStack) {
3851 if (!ExtraCSSpill && UnspilledCSGPR != AArch64::NoRegister) {
3852 LLVM_DEBUG(dbgs() << "Spilling " << printReg(UnspilledCSGPR, RegInfo)
3853 << " to get a scratch register.\n");
3854 SavedRegs.set(UnspilledCSGPR);
3855 ExtraCSSpill = UnspilledCSGPR;
3856
3857 // MachO's compact unwind format relies on all registers being stored in
3858 // pairs, so if we need to spill one extra for BigStack, then we need to
3859 // store the pair.
3860 if (producePairRegisters(MF)) {
3861 if (UnspilledCSGPRPaired == AArch64::NoRegister) {
3862 // Failed to make a pair for compact unwind format, revert spilling.
3863 if (produceCompactUnwindFrame(MF)) {
3864 SavedRegs.reset(UnspilledCSGPR);
3865 ExtraCSSpill = AArch64::NoRegister;
3866 }
3867 } else
3868 SavedRegs.set(UnspilledCSGPRPaired);
3869 }
3870 }
3871
3872 // If we didn't find an extra callee-saved register to spill, create
3873 // an emergency spill slot.
3874 if (!ExtraCSSpill || MF.getRegInfo().isPhysRegUsed(ExtraCSSpill)) {
3876 const TargetRegisterClass &RC = AArch64::GPR64RegClass;
3877 unsigned Size = TRI->getSpillSize(RC);
3878 Align Alignment = TRI->getSpillAlign(RC);
3879 int FI = MFI.CreateSpillStackObject(Size, Alignment);
3881 LLVM_DEBUG(dbgs() << "No available CS registers, allocated fi#" << FI
3882 << " as the emergency spill slot.\n");
3883 }
3884 }
3885
3886 // Adding the size of additional 64bit GPR saves.
3887 CSStackSize += 8 * (SavedRegs.count() - NumSavedRegs);
3888
3889 // A Swift asynchronous context extends the frame record with a pointer
3890 // directly before FP.
3891 if (hasFP(MF) && AFI->hasSwiftAsyncContext())
3892 CSStackSize += 8;
3893
3894 uint64_t AlignedCSStackSize = alignTo(CSStackSize, 16);
3895 LLVM_DEBUG(dbgs() << "Estimated stack frame size: "
3896 << EstimatedStackSize + AlignedCSStackSize << " bytes.\n");
3897
3899 AFI->getCalleeSavedStackSize() == AlignedCSStackSize) &&
3900 "Should not invalidate callee saved info");
3901
3902 // Round up to register pair alignment to avoid additional SP adjustment
3903 // instructions.
3904 AFI->setCalleeSavedStackSize(AlignedCSStackSize);
3905 AFI->setCalleeSaveStackHasFreeSpace(AlignedCSStackSize != CSStackSize);
3906 AFI->setSVECalleeSavedStackSize(alignTo(SVECSStackSize, 16));
3907}
3908
3910 MachineFunction &MF, const TargetRegisterInfo *RegInfo,
3911 std::vector<CalleeSavedInfo> &CSI, unsigned &MinCSFrameIndex,
3912 unsigned &MaxCSFrameIndex) const {
3913 bool NeedsWinCFI = needsWinCFI(MF);
3914 unsigned StackHazardSize = getStackHazardSize(MF);
3915 // To match the canonical windows frame layout, reverse the list of
3916 // callee saved registers to get them laid out by PrologEpilogInserter
3917 // in the right order. (PrologEpilogInserter allocates stack objects top
3918 // down. Windows canonical prologs store higher numbered registers at
3919 // the top, thus have the CSI array start from the highest registers.)
3920 if (NeedsWinCFI)
3921 std::reverse(CSI.begin(), CSI.end());
3922
3923 if (CSI.empty())
3924 return true; // Early exit if no callee saved registers are modified!
3925
3926 // Now that we know which registers need to be saved and restored, allocate
3927 // stack slots for them.
3928 MachineFrameInfo &MFI = MF.getFrameInfo();
3929 auto *AFI = MF.getInfo<AArch64FunctionInfo>();
3930
3931 bool UsesWinAAPCS = isTargetWindows(MF);
3932 if (UsesWinAAPCS && hasFP(MF) && AFI->hasSwiftAsyncContext()) {
3933 int FrameIdx = MFI.CreateStackObject(8, Align(16), true);
3934 AFI->setSwiftAsyncContextFrameIdx(FrameIdx);
3935 if ((unsigned)FrameIdx < MinCSFrameIndex)
3936 MinCSFrameIndex = FrameIdx;
3937 if ((unsigned)FrameIdx > MaxCSFrameIndex)
3938 MaxCSFrameIndex = FrameIdx;
3939 }
3940
3941 // Insert VG into the list of CSRs, immediately before LR if saved.
3942 if (requiresSaveVG(MF)) {
3943 std::vector<CalleeSavedInfo> VGSaves;
3944 SMEAttrs Attrs(MF.getFunction());
3945
3946 auto VGInfo = CalleeSavedInfo(AArch64::VG);
3947 VGInfo.setRestored(false);
3948 VGSaves.push_back(VGInfo);
3949
3950 // Add VG again if the function is locally-streaming, as we will spill two
3951 // values.
3952 if (Attrs.hasStreamingBody() && !Attrs.hasStreamingInterface())
3953 VGSaves.push_back(VGInfo);
3954
3955 bool InsertBeforeLR = false;
3956
3957 for (unsigned I = 0; I < CSI.size(); I++)
3958 if (CSI[I].getReg() == AArch64::LR) {
3959 InsertBeforeLR = true;
3960 CSI.insert(CSI.begin() + I, VGSaves.begin(), VGSaves.end());
3961 break;
3962 }
3963
3964 if (!InsertBeforeLR)
3965 CSI.insert(CSI.end(), VGSaves.begin(), VGSaves.end());
3966 }
3967
3968 Register LastReg = 0;
3969 int HazardSlotIndex = std::numeric_limits<int>::max();
3970 for (auto &CS : CSI) {
3971 Register Reg = CS.getReg();
3972 const TargetRegisterClass *RC = RegInfo->getMinimalPhysRegClass(Reg);
3973
3974 // Create a hazard slot as we switch between GPR and FPR CSRs.
3975 if (AFI->hasStackHazardSlotIndex() &&
3976 (!LastReg || !AArch64InstrInfo::isFpOrNEON(LastReg)) &&
3978 assert(HazardSlotIndex == std::numeric_limits<int>::max() &&
3979 "Unexpected register order for hazard slot");
3980 HazardSlotIndex = MFI.CreateStackObject(StackHazardSize, Align(8), true);
3981 LLVM_DEBUG(dbgs() << "Created CSR Hazard at slot " << HazardSlotIndex
3982 << "\n");
3983 AFI->setStackHazardCSRSlotIndex(HazardSlotIndex);
3984 if ((unsigned)HazardSlotIndex < MinCSFrameIndex)
3985 MinCSFrameIndex = HazardSlotIndex;
3986 if ((unsigned)HazardSlotIndex > MaxCSFrameIndex)
3987 MaxCSFrameIndex = HazardSlotIndex;
3988 }
3989
3990 unsigned Size = RegInfo->getSpillSize(*RC);
3991 Align Alignment(RegInfo->getSpillAlign(*RC));
3992 int FrameIdx = MFI.CreateStackObject(Size, Alignment, true);
3993 CS.setFrameIdx(FrameIdx);
3994
3995 if ((unsigned)FrameIdx < MinCSFrameIndex)
3996 MinCSFrameIndex = FrameIdx;
3997 if ((unsigned)FrameIdx > MaxCSFrameIndex)
3998 MaxCSFrameIndex = FrameIdx;
3999
4000 // Grab 8 bytes below FP for the extended asynchronous frame info.
4001 if (hasFP(MF) && AFI->hasSwiftAsyncContext() && !UsesWinAAPCS &&
4002 Reg == AArch64::FP) {
4003 FrameIdx = MFI.CreateStackObject(8, Alignment, true);
4004 AFI->setSwiftAsyncContextFrameIdx(FrameIdx);
4005 if ((unsigned)FrameIdx < MinCSFrameIndex)
4006 MinCSFrameIndex = FrameIdx;
4007 if ((unsigned)FrameIdx > MaxCSFrameIndex)
4008 MaxCSFrameIndex = FrameIdx;
4009 }
4010 LastReg = Reg;
4011 }
4012
4013 // Add hazard slot in the case where no FPR CSRs are present.
4014 if (AFI->hasStackHazardSlotIndex() &&
4015 HazardSlotIndex == std::numeric_limits<int>::max()) {
4016 HazardSlotIndex = MFI.CreateStackObject(StackHazardSize, Align(8), true);
4017 LLVM_DEBUG(dbgs() << "Created CSR Hazard at slot " << HazardSlotIndex
4018 << "\n");
4019 AFI->setStackHazardCSRSlotIndex(HazardSlotIndex);
4020 if ((unsigned)HazardSlotIndex < MinCSFrameIndex)
4021 MinCSFrameIndex = HazardSlotIndex;
4022 if ((unsigned)HazardSlotIndex > MaxCSFrameIndex)
4023 MaxCSFrameIndex = HazardSlotIndex;
4024 }
4025
4026 return true;
4027}
4028
4030 const MachineFunction &MF) const {
4032 // If the function has streaming-mode changes, don't scavenge a
4033 // spillslot in the callee-save area, as that might require an
4034 // 'addvl' in the streaming-mode-changing call-sequence when the
4035 // function doesn't use a FP.
4036 if (AFI->hasStreamingModeChanges() && !hasFP(MF))
4037 return false;
4038 // Don't allow register salvaging with hazard slots, in case it moves objects
4039 // into the wrong place.
4040 if (AFI->hasStackHazardSlotIndex())
4041 return false;
4042 return AFI->hasCalleeSaveStackFreeSpace();
4043}
4044
4045/// returns true if there are any SVE callee saves.
4047 int &Min, int &Max) {
4048 Min = std::numeric_limits<int>::max();
4049 Max = std::numeric_limits<int>::min();
4050
4051 if (!MFI.isCalleeSavedInfoValid())
4052 return false;
4053
4054 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
4055 for (auto &CS : CSI) {
4056 if (AArch64::ZPRRegClass.contains(CS.getReg()) ||
4057 AArch64::PPRRegClass.contains(CS.getReg())) {
4058 assert((Max == std::numeric_limits<int>::min() ||
4059 Max + 1 == CS.getFrameIdx()) &&
4060 "SVE CalleeSaves are not consecutive");
4061
4062 Min = std::min(Min, CS.getFrameIdx());
4063 Max = std::max(Max, CS.getFrameIdx());
4064 }
4065 }
4066 return Min != std::numeric_limits<int>::max();
4067}
4068
4069// Process all the SVE stack objects and determine offsets for each
4070// object. If AssignOffsets is true, the offsets get assigned.
4071// Fills in the first and last callee-saved frame indices into
4072// Min/MaxCSFrameIndex, respectively.
4073// Returns the size of the stack.
4075 int &MinCSFrameIndex,
4076 int &MaxCSFrameIndex,
4077 bool AssignOffsets) {
4078#ifndef NDEBUG
4079 // First process all fixed stack objects.
4080 for (int I = MFI.getObjectIndexBegin(); I != 0; ++I)
4082 "SVE vectors should never be passed on the stack by value, only by "
4083 "reference.");
4084#endif
4085
4086 auto Assign = [&MFI](int FI, int64_t Offset) {
4087 LLVM_DEBUG(dbgs() << "alloc FI(" << FI << ") at SP[" << Offset << "]\n");
4088 MFI.setObjectOffset(FI, Offset);
4089 };
4090
4091 int64_t Offset = 0;
4092
4093 // Then process all callee saved slots.
4094 if (getSVECalleeSaveSlotRange(MFI, MinCSFrameIndex, MaxCSFrameIndex)) {
4095 // Assign offsets to the callee save slots.
4096 for (int I = MinCSFrameIndex; I <= MaxCSFrameIndex; ++I) {
4097 Offset += MFI.getObjectSize(I);
4099 if (AssignOffsets)
4100 Assign(I, -Offset);
4101 }
4102 }
4103
4104 // Ensure that the Callee-save area is aligned to 16bytes.
4105 Offset = alignTo(Offset, Align(16U));
4106
4107 // Create a buffer of SVE objects to allocate and sort it.
4108 SmallVector<int, 8> ObjectsToAllocate;
4109 // If we have a stack protector, and we've previously decided that we have SVE
4110 // objects on the stack and thus need it to go in the SVE stack area, then it
4111 // needs to go first.
4112 int StackProtectorFI = -1;
4113 if (MFI.hasStackProtectorIndex()) {
4114 StackProtectorFI = MFI.getStackProtectorIndex();
4115 if (MFI.getStackID(StackProtectorFI) == TargetStackID::ScalableVector)
4116 ObjectsToAllocate.push_back(StackProtectorFI);
4117 }
4118 for (int I = 0, E = MFI.getObjectIndexEnd(); I != E; ++I) {
4119 unsigned StackID = MFI.getStackID(I);
4120 if (StackID != TargetStackID::ScalableVector)
4121 continue;
4122 if (I == StackProtectorFI)
4123 continue;
4124 if (MaxCSFrameIndex >= I && I >= MinCSFrameIndex)
4125 continue;
4126 if (MFI.isDeadObjectIndex(I))
4127 continue;
4128
4129 ObjectsToAllocate.push_back(I);
4130 }
4131
4132 // Allocate all SVE locals and spills
4133 for (unsigned FI : ObjectsToAllocate) {
4134 Align Alignment = MFI.getObjectAlign(FI);
4135 // FIXME: Given that the length of SVE vectors is not necessarily a power of
4136 // two, we'd need to align every object dynamically at runtime if the
4137 // alignment is larger than 16. This is not yet supported.
4138 if (Alignment > Align(16))
4140 "Alignment of scalable vectors > 16 bytes is not yet supported");
4141
4142 Offset = alignTo(Offset + MFI.getObjectSize(FI), Alignment);
4143 if (AssignOffsets)
4144 Assign(FI, -Offset);
4145 }
4146
4147 return Offset;
4148}
4149
4150int64_t AArch64FrameLowering::estimateSVEStackObjectOffsets(
4151 MachineFrameInfo &MFI) const {
4152 int MinCSFrameIndex, MaxCSFrameIndex;
4153 return determineSVEStackObjectOffsets(MFI, MinCSFrameIndex, MaxCSFrameIndex, false);
4154}
4155
4156int64_t AArch64FrameLowering::assignSVEStackObjectOffsets(
4157 MachineFrameInfo &MFI, int &MinCSFrameIndex, int &MaxCSFrameIndex) const {
4158 return determineSVEStackObjectOffsets(MFI, MinCSFrameIndex, MaxCSFrameIndex,
4159 true);
4160}
4161
4163 MachineFunction &MF, RegScavenger *RS) const {
4164 MachineFrameInfo &MFI = MF.getFrameInfo();
4165
4167 "Upwards growing stack unsupported");
4168
4169 int MinCSFrameIndex, MaxCSFrameIndex;
4170 int64_t SVEStackSize =
4171 assignSVEStackObjectOffsets(MFI, MinCSFrameIndex, MaxCSFrameIndex);
4172
4174 AFI->setStackSizeSVE(alignTo(SVEStackSize, 16U));
4175 AFI->setMinMaxSVECSFrameIndex(MinCSFrameIndex, MaxCSFrameIndex);
4176
4177 // If this function isn't doing Win64-style C++ EH, we don't need to do
4178 // anything.
4179 if (!MF.hasEHFunclets())
4180 return;
4182 WinEHFuncInfo &EHInfo = *MF.getWinEHFuncInfo();
4183
4184 MachineBasicBlock &MBB = MF.front();
4185 auto MBBI = MBB.begin();
4186 while (MBBI != MBB.end() && MBBI->getFlag(MachineInstr::FrameSetup))
4187 ++MBBI;
4188
4189 // Create an UnwindHelp object.
4190 // The UnwindHelp object is allocated at the start of the fixed object area
4191 int64_t FixedObject =
4192 getFixedObjectSize(MF, AFI, /*IsWin64*/ true, /*IsFunclet*/ false);
4193 int UnwindHelpFI = MFI.CreateFixedObject(/*Size*/ 8,
4194 /*SPOffset*/ -FixedObject,
4195 /*IsImmutable=*/false);
4196 EHInfo.UnwindHelpFrameIdx = UnwindHelpFI;
4197
4198 // We need to store -2 into the UnwindHelp object at the start of the
4199 // function.
4200 DebugLoc DL;
4202 RS->backward(MBBI);
4203 Register DstReg = RS->FindUnusedReg(&AArch64::GPR64commonRegClass);
4204 assert(DstReg && "There must be a free register after frame setup");
4205 BuildMI(MBB, MBBI, DL, TII.get(AArch64::MOVi64imm), DstReg).addImm(-2);
4206 BuildMI(MBB, MBBI, DL, TII.get(AArch64::STURXi))
4207 .addReg(DstReg, getKillRegState(true))
4208 .addFrameIndex(UnwindHelpFI)
4209 .addImm(0);
4210}
4211
4212namespace {
4213struct TagStoreInstr {
4215 int64_t Offset, Size;
4216 explicit TagStoreInstr(MachineInstr *MI, int64_t Offset, int64_t Size)
4217 : MI(MI), Offset(Offset), Size(Size) {}
4218};
4219
4220class TagStoreEdit {
4221 MachineFunction *MF;
4224 // Tag store instructions that are being replaced.
4226 // Combined memref arguments of the above instructions.
4228
4229 // Replace allocation tags in [FrameReg + FrameRegOffset, FrameReg +
4230 // FrameRegOffset + Size) with the address tag of SP.
4231 Register FrameReg;
4232 StackOffset FrameRegOffset;
4233 int64_t Size;
4234 // If not std::nullopt, move FrameReg to (FrameReg + FrameRegUpdate) at the
4235 // end.
4236 std::optional<int64_t> FrameRegUpdate;
4237 // MIFlags for any FrameReg updating instructions.
4238 unsigned FrameRegUpdateFlags;
4239
4240 // Use zeroing instruction variants.
4241 bool ZeroData;
4242 DebugLoc DL;
4243
4244 void emitUnrolled(MachineBasicBlock::iterator InsertI);
4245 void emitLoop(MachineBasicBlock::iterator InsertI);
4246
4247public:
4248 TagStoreEdit(MachineBasicBlock *MBB, bool ZeroData)
4249 : MBB(MBB), ZeroData(ZeroData) {
4250 MF = MBB->getParent();
4251 MRI = &MF->getRegInfo();
4252 }
4253 // Add an instruction to be replaced. Instructions must be added in the
4254 // ascending order of Offset, and have to be adjacent.
4255 void addInstruction(TagStoreInstr I) {
4256 assert((TagStores.empty() ||
4257 TagStores.back().Offset + TagStores.back().Size == I.Offset) &&
4258 "Non-adjacent tag store instructions.");
4259 TagStores.push_back(I);
4260 }
4261 void clear() { TagStores.clear(); }
4262 // Emit equivalent code at the given location, and erase the current set of
4263 // instructions. May skip if the replacement is not profitable. May invalidate
4264 // the input iterator and replace it with a valid one.
4265 void emitCode(MachineBasicBlock::iterator &InsertI,
4266 const AArch64FrameLowering *TFI, bool TryMergeSPUpdate);
4267};
4268
4269void TagStoreEdit::emitUnrolled(MachineBasicBlock::iterator InsertI) {
4270 const AArch64InstrInfo *TII =
4271 MF->getSubtarget<AArch64Subtarget>().getInstrInfo();
4272
4273 const int64_t kMinOffset = -256 * 16;
4274 const int64_t kMaxOffset = 255 * 16;
4275
4276 Register BaseReg = FrameReg;
4277 int64_t BaseRegOffsetBytes = FrameRegOffset.getFixed();
4278 if (BaseRegOffsetBytes < kMinOffset ||
4279 BaseRegOffsetBytes + (Size - Size % 32) > kMaxOffset ||
4280 // BaseReg can be FP, which is not necessarily aligned to 16-bytes. In
4281 // that case, BaseRegOffsetBytes will not be aligned to 16 bytes, which
4282 // is required for the offset of ST2G.
4283 BaseRegOffsetBytes % 16 != 0) {
4284 Register ScratchReg = MRI->createVirtualRegister(&AArch64::GPR64RegClass);
4285 emitFrameOffset(*MBB, InsertI, DL, ScratchReg, BaseReg,
4286 StackOffset::getFixed(BaseRegOffsetBytes), TII);
4287 BaseReg = ScratchReg;
4288 BaseRegOffsetBytes = 0;
4289 }
4290
4291 MachineInstr *LastI = nullptr;
4292 while (Size) {
4293 int64_t InstrSize = (Size > 16) ? 32 : 16;
4294 unsigned Opcode =
4295 InstrSize == 16
4296 ? (ZeroData ? AArch64::STZGi : AArch64::STGi)
4297 : (ZeroData ? AArch64::STZ2Gi : AArch64::ST2Gi);
4298 assert(BaseRegOffsetBytes % 16 == 0);
4299 MachineInstr *I = BuildMI(*MBB, InsertI, DL, TII->get(Opcode))
4300 .addReg(AArch64::SP)
4301 .addReg(BaseReg)
4302 .addImm(BaseRegOffsetBytes / 16)
4303 .setMemRefs(CombinedMemRefs);
4304 // A store to [BaseReg, #0] should go last for an opportunity to fold the
4305 // final SP adjustment in the epilogue.
4306 if (BaseRegOffsetBytes == 0)
4307 LastI = I;
4308 BaseRegOffsetBytes += InstrSize;
4309 Size -= InstrSize;
4310 }
4311
4312 if (LastI)
4313 MBB->splice(InsertI, MBB, LastI);
4314}
4315
4316void TagStoreEdit::emitLoop(MachineBasicBlock::iterator InsertI) {
4317 const AArch64InstrInfo *TII =
4318 MF->getSubtarget<AArch64Subtarget>().getInstrInfo();
4319
4320 Register BaseReg = FrameRegUpdate
4321 ? FrameReg
4322 : MRI->createVirtualRegister(&AArch64::GPR64RegClass);
4323 Register SizeReg = MRI->createVirtualRegister(&AArch64::GPR64RegClass);
4324
4325 emitFrameOffset(*MBB, InsertI, DL, BaseReg, FrameReg, FrameRegOffset, TII);
4326
4327 int64_t LoopSize = Size;
4328 // If the loop size is not a multiple of 32, split off one 16-byte store at
4329 // the end to fold BaseReg update into.
4330 if (FrameRegUpdate && *FrameRegUpdate)
4331 LoopSize -= LoopSize % 32;
4332 MachineInstr *LoopI = BuildMI(*MBB, InsertI, DL,
4333 TII->get(ZeroData ? AArch64::STZGloop_wback
4334 : AArch64::STGloop_wback))
4335 .addDef(SizeReg)
4336 .addDef(BaseReg)
4337 .addImm(LoopSize)
4338 .addReg(BaseReg)
4339 .setMemRefs(CombinedMemRefs);
4340 if (FrameRegUpdate)
4341 LoopI->setFlags(FrameRegUpdateFlags);
4342
4343 int64_t ExtraBaseRegUpdate =
4344 FrameRegUpdate ? (*FrameRegUpdate - FrameRegOffset.getFixed() - Size) : 0;
4345 LLVM_DEBUG(dbgs() << "TagStoreEdit::emitLoop: LoopSize=" << LoopSize
4346 << ", Size=" << Size
4347 << ", ExtraBaseRegUpdate=" << ExtraBaseRegUpdate
4348 << ", FrameRegUpdate=" << FrameRegUpdate
4349 << ", FrameRegOffset.getFixed()="
4350 << FrameRegOffset.getFixed() << "\n");
4351 if (LoopSize < Size) {
4352 assert(FrameRegUpdate);
4353 assert(Size - LoopSize == 16);
4354 // Tag 16 more bytes at BaseReg and update BaseReg.
4355 int64_t STGOffset = ExtraBaseRegUpdate + 16;
4356 assert(STGOffset % 16 == 0 && STGOffset >= -4096 && STGOffset <= 4080 &&
4357 "STG immediate out of range");
4358 BuildMI(*MBB, InsertI, DL,
4359 TII->get(ZeroData ? AArch64::STZGPostIndex : AArch64::STGPostIndex))
4360 .addDef(BaseReg)
4361 .addReg(BaseReg)
4362 .addReg(BaseReg)
4363 .addImm(STGOffset / 16)
4364 .setMemRefs(CombinedMemRefs)
4365 .setMIFlags(FrameRegUpdateFlags);
4366 } else if (ExtraBaseRegUpdate) {
4367 // Update BaseReg.
4368 int64_t AddSubOffset = std::abs(ExtraBaseRegUpdate);
4369 assert(AddSubOffset <= 4095 && "ADD/SUB immediate out of range");
4370 BuildMI(
4371 *MBB, InsertI, DL,
4372 TII->get(ExtraBaseRegUpdate > 0 ? AArch64::ADDXri : AArch64::SUBXri))
4373 .addDef(BaseReg)
4374 .addReg(BaseReg)
4375 .addImm(AddSubOffset)
4376 .addImm(0)
4377 .setMIFlags(FrameRegUpdateFlags);
4378 }
4379}
4380
4381// Check if *II is a register update that can be merged into STGloop that ends
4382// at (Reg + Size). RemainingOffset is the required adjustment to Reg after the
4383// end of the loop.
4384bool canMergeRegUpdate(MachineBasicBlock::iterator II, unsigned Reg,
4385 int64_t Size, int64_t *TotalOffset) {
4386 MachineInstr &MI = *II;
4387 if ((MI.getOpcode() == AArch64::ADDXri ||
4388 MI.getOpcode() == AArch64::SUBXri) &&
4389 MI.getOperand(0).getReg() == Reg && MI.getOperand(1).getReg() == Reg) {
4390 unsigned Shift = AArch64_AM::getShiftValue(MI.getOperand(3).getImm());
4391 int64_t Offset = MI.getOperand(2).getImm() << Shift;
4392 if (MI.getOpcode() == AArch64::SUBXri)
4393 Offset = -Offset;
4394 int64_t PostOffset = Offset - Size;
4395 // TagStoreEdit::emitLoop might emit either an ADD/SUB after the loop, or
4396 // an STGPostIndex which does the last 16 bytes of tag write. Which one is
4397 // chosen depends on the alignment of the loop size, but the difference
4398 // between the valid ranges for the two instructions is small, so we
4399 // conservatively assume that it could be either case here.
4400 //
4401 // Max offset of STGPostIndex, minus the 16 byte tag write folded into that
4402 // instruction.
4403 const int64_t kMaxOffset = 4080 - 16;
4404 // Max offset of SUBXri.
4405 const int64_t kMinOffset = -4095;
4406 if (PostOffset <= kMaxOffset && PostOffset >= kMinOffset &&
4407 PostOffset % 16 == 0) {
4408 *TotalOffset = Offset;
4409 return true;
4410 }
4411 }
4412 return false;
4413}
4414
4415void mergeMemRefs(const SmallVectorImpl<TagStoreInstr> &TSE,
4417 MemRefs.clear();
4418 for (auto &TS : TSE) {
4419 MachineInstr *MI = TS.MI;
4420 // An instruction without memory operands may access anything. Be
4421 // conservative and return an empty list.
4422 if (MI->memoperands_empty()) {
4423 MemRefs.clear();
4424 return;
4425 }
4426 MemRefs.append(MI->memoperands_begin(), MI->memoperands_end());
4427 }
4428}
4429
4430void TagStoreEdit::emitCode(MachineBasicBlock::iterator &InsertI,
4431 const AArch64FrameLowering *TFI,
4432 bool TryMergeSPUpdate) {
4433 if (TagStores.empty())
4434 return;
4435 TagStoreInstr &FirstTagStore = TagStores[0];
4436 TagStoreInstr &LastTagStore = TagStores[TagStores.size() - 1];
4437 Size = LastTagStore.Offset - FirstTagStore.Offset + LastTagStore.Size;
4438 DL = TagStores[0].MI->getDebugLoc();
4439
4440 Register Reg;
4441 FrameRegOffset = TFI->resolveFrameOffsetReference(
4442 *MF, FirstTagStore.Offset, false /*isFixed*/, false /*isSVE*/, Reg,
4443 /*PreferFP=*/false, /*ForSimm=*/true);
4444 FrameReg = Reg;
4445 FrameRegUpdate = std::nullopt;
4446
4447 mergeMemRefs(TagStores, CombinedMemRefs);
4448
4449 LLVM_DEBUG({
4450 dbgs() << "Replacing adjacent STG instructions:\n";
4451 for (const auto &Instr : TagStores) {
4452 dbgs() << " " << *Instr.MI;
4453 }
4454 });
4455
4456 // Size threshold where a loop becomes shorter than a linear sequence of
4457 // tagging instructions.
4458 const int kSetTagLoopThreshold = 176;
4459 if (Size < kSetTagLoopThreshold) {
4460 if (TagStores.size() < 2)
4461 return;
4462 emitUnrolled(InsertI);
4463 } else {
4464 MachineInstr *UpdateInstr = nullptr;
4465 int64_t TotalOffset = 0;
4466 if (TryMergeSPUpdate) {
4467 // See if we can merge base register update into the STGloop.
4468 // This is done in AArch64LoadStoreOptimizer for "normal" stores,
4469 // but STGloop is way too unusual for that, and also it only
4470 // realistically happens in function epilogue. Also, STGloop is expanded
4471 // before that pass.
4472 if (InsertI != MBB->end() &&
4473 canMergeRegUpdate(InsertI, FrameReg, FrameRegOffset.getFixed() + Size,
4474 &TotalOffset)) {
4475 UpdateInstr = &*InsertI++;
4476 LLVM_DEBUG(dbgs() << "Folding SP update into loop:\n "
4477 << *UpdateInstr);
4478 }
4479 }
4480
4481 if (!UpdateInstr && TagStores.size() < 2)
4482 return;
4483
4484 if (UpdateInstr) {
4485 FrameRegUpdate = TotalOffset;
4486 FrameRegUpdateFlags = UpdateInstr->getFlags();
4487 }
4488 emitLoop(InsertI);
4489 if (UpdateInstr)
4490 UpdateInstr->eraseFromParent();
4491 }
4492
4493 for (auto &TS : TagStores)
4494 TS.MI->eraseFromParent();
4495}
4496
4497bool isMergeableStackTaggingInstruction(MachineInstr &MI, int64_t &Offset,
4498 int64_t &Size, bool &ZeroData) {
4499 MachineFunction &MF = *MI.getParent()->getParent();
4500 const MachineFrameInfo &MFI = MF.getFrameInfo();
4501
4502 unsigned Opcode = MI.getOpcode();
4503 ZeroData = (Opcode == AArch64::STZGloop || Opcode == AArch64::STZGi ||
4504 Opcode == AArch64::STZ2Gi);
4505
4506 if (Opcode == AArch64::STGloop || Opcode == AArch64::STZGloop) {
4507 if (!MI.getOperand(0).isDead() || !MI.getOperand(1).isDead())
4508 return false;
4509 if (!MI.getOperand(2).isImm() || !MI.getOperand(3).isFI())
4510 return false;
4511 Offset = MFI.getObjectOffset(MI.getOperand(3).getIndex());
4512 Size = MI.getOperand(2).getImm();
4513 return true;
4514 }
4515
4516 if (Opcode == AArch64::STGi || Opcode == AArch64::STZGi)
4517 Size = 16;
4518 else if (Opcode == AArch64::ST2Gi || Opcode == AArch64::STZ2Gi)
4519 Size = 32;
4520 else
4521 return false;
4522
4523 if (MI.getOperand(0).getReg() != AArch64::SP || !MI.getOperand(1).isFI())
4524 return false;
4525
4526 Offset = MFI.getObjectOffset(MI.getOperand(1).getIndex()) +
4527 16 * MI.getOperand(2).getImm();
4528 return true;
4529}
4530
4531// Detect a run of memory tagging instructions for adjacent stack frame slots,
4532// and replace them with a shorter instruction sequence:
4533// * replace STG + STG with ST2G
4534// * replace STGloop + STGloop with STGloop
4535// This code needs to run when stack slot offsets are already known, but before
4536// FrameIndex operands in STG instructions are eliminated.
4538 const AArch64FrameLowering *TFI,
4539 RegScavenger *RS) {
4540 bool FirstZeroData;
4541 int64_t Size, Offset;
4542 MachineInstr &MI = *II;
4543 MachineBasicBlock *MBB = MI.getParent();
4545 if (&MI == &MBB->instr_back())
4546 return II;
4547 if (!isMergeableStackTaggingInstruction(MI, Offset, Size, FirstZeroData))
4548 return II;
4549
4551 Instrs.emplace_back(&MI, Offset, Size);
4552
4553 constexpr int kScanLimit = 10;
4554 int Count = 0;
4556 NextI != E && Count < kScanLimit; ++NextI) {
4557 MachineInstr &MI = *NextI;
4558 bool ZeroData;
4559 int64_t Size, Offset;
4560 // Collect instructions that update memory tags with a FrameIndex operand
4561 // and (when applicable) constant size, and whose output registers are dead
4562 // (the latter is almost always the case in practice). Since these
4563 // instructions effectively have no inputs or outputs, we are free to skip
4564 // any non-aliasing instructions in between without tracking used registers.
4565 if (isMergeableStackTaggingInstruction(MI, Offset, Size, ZeroData)) {
4566 if (ZeroData != FirstZeroData)
4567 break;
4568 Instrs.emplace_back(&MI, Offset, Size);
4569 continue;
4570 }
4571
4572 // Only count non-transient, non-tagging instructions toward the scan
4573 // limit.
4574 if (!MI.isTransient())
4575 ++Count;
4576
4577 // Just in case, stop before the epilogue code starts.
4578 if (MI.getFlag(MachineInstr::FrameSetup) ||
4580 break;
4581
4582 // Reject anything that may alias the collected instructions.
4583 if (MI.mayLoadOrStore() || MI.hasUnmodeledSideEffects() || MI.isCall())
4584 break;
4585 }
4586
4587 // New code will be inserted after the last tagging instruction we've found.
4588 MachineBasicBlock::iterator InsertI = Instrs.back().MI;
4589
4590 // All the gathered stack tag instructions are merged and placed after
4591 // last tag store in the list. The check should be made if the nzcv
4592 // flag is live at the point where we are trying to insert. Otherwise
4593 // the nzcv flag might get clobbered if any stg loops are present.
4594
4595 // FIXME : This approach of bailing out from merge is conservative in
4596 // some ways like even if stg loops are not present after merge the
4597 // insert list, this liveness check is done (which is not needed).
4599 LiveRegs.addLiveOuts(*MBB);
4600 for (auto I = MBB->rbegin();; ++I) {
4601 MachineInstr &MI = *I;
4602 if (MI == InsertI)
4603 break;
4604 LiveRegs.stepBackward(*I);
4605 }
4606 InsertI++;
4607 if (LiveRegs.contains(AArch64::NZCV))
4608 return InsertI;
4609
4610 llvm::stable_sort(Instrs,
4611 [](const TagStoreInstr &Left, const TagStoreInstr &Right) {
4612 return Left.Offset < Right.Offset;
4613 });
4614
4615 // Make sure that we don't have any overlapping stores.
4616 int64_t CurOffset = Instrs[0].Offset;
4617 for (auto &Instr : Instrs) {
4618 if (CurOffset > Instr.Offset)
4619 return NextI;
4620 CurOffset = Instr.Offset + Instr.Size;
4621 }
4622
4623 // Find contiguous runs of tagged memory and emit shorter instruction
4624 // sequencies for them when possible.
4625 TagStoreEdit TSE(MBB, FirstZeroData);
4626 std::optional<int64_t> EndOffset;
4627 for (auto &Instr : Instrs) {
4628 if (EndOffset && *EndOffset != Instr.Offset) {
4629 // Found a gap.
4630 TSE.emitCode(InsertI, TFI, /*TryMergeSPUpdate = */ false);
4631 TSE.clear();
4632 }
4633
4634 TSE.addInstruction(Instr);
4635 EndOffset = Instr.Offset + Instr.Size;
4636 }
4637
4638 const MachineFunction *MF = MBB->getParent();
4639 // Multiple FP/SP updates in a loop cannot be described by CFI instructions.
4640 TSE.emitCode(
4641 InsertI, TFI, /*TryMergeSPUpdate = */
4643
4644 return InsertI;
4645}
4646} // namespace
4647
4649 const AArch64FrameLowering *TFI) {
4650 MachineInstr &MI = *II;
4651 MachineBasicBlock *MBB = MI.getParent();
4652 MachineFunction *MF = MBB->getParent();
4653
4654 if (MI.getOpcode() != AArch64::VGSavePseudo &&
4655 MI.getOpcode() != AArch64::VGRestorePseudo)
4656 return II;
4657
4658 SMEAttrs FuncAttrs(MF->getFunction());
4659 bool LocallyStreaming =
4660 FuncAttrs.hasStreamingBody() && !FuncAttrs.hasStreamingInterface();
4663 const AArch64InstrInfo *TII =
4664 MF->getSubtarget<AArch64Subtarget>().getInstrInfo();
4665
4666 int64_t VGFrameIdx =
4667 LocallyStreaming ? AFI->getStreamingVGIdx() : AFI->getVGIdx();
4668 assert(VGFrameIdx != std::numeric_limits<int>::max() &&
4669 "Expected FrameIdx for VG");
4670
4671 unsigned CFIIndex;
4672 if (MI.getOpcode() == AArch64::VGSavePseudo) {
4673 const MachineFrameInfo &MFI = MF->getFrameInfo();
4674 int64_t Offset =
4675 MFI.getObjectOffset(VGFrameIdx) - TFI->getOffsetOfLocalArea();
4677 nullptr, TRI->getDwarfRegNum(AArch64::VG, true), Offset));
4678 } else
4680 nullptr, TRI->getDwarfRegNum(AArch64::VG, true)));
4681
4682 MachineInstr *UnwindInst = BuildMI(*MBB, II, II->getDebugLoc(),
4683 TII->get(TargetOpcode::CFI_INSTRUCTION))
4684 .addCFIIndex(CFIIndex);
4685
4686 MI.eraseFromParent();
4687 return UnwindInst->getIterator();
4688}
4689
4691 MachineFunction &MF, RegScavenger *RS = nullptr) const {
4692 for (auto &BB : MF)
4693 for (MachineBasicBlock::iterator II = BB.begin(); II != BB.end();) {
4694 if (requiresSaveVG(MF))
4695 II = emitVGSaveRestore(II, this);
4697 II = tryMergeAdjacentSTG(II, this, RS);
4698 }
4699}
4700
4701/// For Win64 AArch64 EH, the offset to the Unwind object is from the SP
4702/// before the update. This is easily retrieved as it is exactly the offset
4703/// that is set in processFunctionBeforeFrameFinalized.
4705 const MachineFunction &MF, int FI, Register &FrameReg,
4706 bool IgnoreSPUpdates) const {
4707 const MachineFrameInfo &MFI = MF.getFrameInfo();
4708 if (IgnoreSPUpdates) {
4709 LLVM_DEBUG(dbgs() << "Offset from the SP for " << FI << " is "
4710 << MFI.getObjectOffset(FI) << "\n");
4711 FrameReg = AArch64::SP;
4712 return StackOffset::getFixed(MFI.getObjectOffset(FI));
4713 }
4714
4715 // Go to common code if we cannot provide sp + offset.
4716 if (MFI.hasVarSizedObjects() ||
4719 return getFrameIndexReference(MF, FI, FrameReg);
4720
4721 FrameReg = AArch64::SP;
4722 return getStackOffset(MF, MFI.getObjectOffset(FI));
4723}
4724
4725/// The parent frame offset (aka dispFrame) is only used on X86_64 to retrieve
4726/// the parent's frame pointer
4728 const MachineFunction &MF) const {
4729 return 0;
4730}
4731
4732/// Funclets only need to account for space for the callee saved registers,
4733/// as the locals are accounted for in the parent's stack frame.
4735 const MachineFunction &MF) const {
4736 // This is the size of the pushed CSRs.
4737 unsigned CSSize =
4738 MF.getInfo<AArch64FunctionInfo>()->getCalleeSavedStackSize();
4739 // This is the amount of stack a funclet needs to allocate.
4740 return alignTo(CSSize + MF.getFrameInfo().getMaxCallFrameSize(),
4741 getStackAlign());
4742}
4743
4744namespace {
4745struct FrameObject {
4746 bool IsValid = false;
4747 // Index of the object in MFI.
4748 int ObjectIndex = 0;
4749 // Group ID this object belongs to.
4750 int GroupIndex = -1;
4751 // This object should be placed first (closest to SP).
4752 bool ObjectFirst = false;
4753 // This object's group (which always contains the object with
4754 // ObjectFirst==true) should be placed first.
4755 bool GroupFirst = false;
4756
4757 // Used to distinguish between FP and GPR accesses. The values are decided so
4758 // that they sort FPR < Hazard < GPR and they can be or'd together.
4759 unsigned Accesses = 0;
4760 enum { AccessFPR = 1, AccessHazard = 2, AccessGPR = 4 };
4761};
4762
4763class GroupBuilder {
4764 SmallVector<int, 8> CurrentMembers;
4765 int NextGroupIndex = 0;
4766 std::vector<FrameObject> &Objects;
4767
4768public:
4769 GroupBuilder(std::vector<FrameObject> &Objects) : Objects(Objects) {}
4770 void AddMember(int Index) { CurrentMembers.push_back(Index); }
4771 void EndCurrentGroup() {
4772 if (CurrentMembers.size() > 1) {
4773 // Create a new group with the current member list. This might remove them
4774 // from their pre-existing groups. That's OK, dealing with overlapping
4775 // groups is too hard and unlikely to make a difference.
4776 LLVM_DEBUG(dbgs() << "group:");
4777 for (int Index : CurrentMembers) {
4778 Objects[Index].GroupIndex = NextGroupIndex;
4779 LLVM_DEBUG(dbgs() << " " << Index);
4780 }
4781 LLVM_DEBUG(dbgs() << "\n");
4782 NextGroupIndex++;
4783 }
4784 CurrentMembers.clear();
4785 }
4786};
4787
4788bool FrameObjectCompare(const FrameObject &A, const FrameObject &B) {
4789 // Objects at a lower index are closer to FP; objects at a higher index are
4790 // closer to SP.
4791 //
4792 // For consistency in our comparison, all invalid objects are placed
4793 // at the end. This also allows us to stop walking when we hit the
4794 // first invalid item after it's all sorted.
4795 //
4796 // If we want to include a stack hazard region, order FPR accesses < the
4797 // hazard object < GPRs accesses in order to create a separation between the
4798 // two. For the Accesses field 1 = FPR, 2 = Hazard Object, 4 = GPR.
4799 //
4800 // Otherwise the "first" object goes first (closest to SP), followed by the
4801 // members of the "first" group.
4802 //
4803 // The rest are sorted by the group index to keep the groups together.
4804 // Higher numbered groups are more likely to be around longer (i.e. untagged
4805 // in the function epilogue and not at some earlier point). Place them closer
4806 // to SP.
4807 //
4808 // If all else equal, sort by the object index to keep the objects in the
4809 // original order.
4810 return std::make_tuple(!A.IsValid, A.Accesses, A.ObjectFirst, A.GroupFirst,
4811 A.GroupIndex, A.ObjectIndex) <
4812 std::make_tuple(!B.IsValid, B.Accesses, B.ObjectFirst, B.GroupFirst,
4813 B.GroupIndex, B.ObjectIndex);
4814}
4815} // namespace
4816
4818 const MachineFunction &MF, SmallVectorImpl<int> &ObjectsToAllocate) const {
4819 if (!OrderFrameObjects || ObjectsToAllocate.empty())
4820 return;
4821
4823 const MachineFrameInfo &MFI = MF.getFrameInfo();
4824 std::vector<FrameObject> FrameObjects(MFI.getObjectIndexEnd());
4825 for (auto &Obj : ObjectsToAllocate) {
4826 FrameObjects[Obj].IsValid = true;
4827 FrameObjects[Obj].ObjectIndex = Obj;
4828 }
4829
4830 // Identify FPR vs GPR slots for hazards, and stack slots that are tagged at
4831 // the same time.
4832 GroupBuilder GB(FrameObjects);
4833 for (auto &MBB : MF) {
4834 for (auto &MI : MBB) {
4835 if (MI.isDebugInstr())
4836 continue;
4837
4838 if (AFI.hasStackHazardSlotIndex()) {
4839 std::optional<int> FI = getLdStFrameID(MI, MFI);
4840 if (FI && *FI >= 0 && *FI < (int)FrameObjects.size()) {
4841 if (MFI.getStackID(*FI) == TargetStackID::ScalableVector ||
4843 FrameObjects[*FI].Accesses |= FrameObject::AccessFPR;
4844 else
4845 FrameObjects[*FI].Accesses |= FrameObject::AccessGPR;
4846 }
4847 }
4848
4849 int OpIndex;
4850 switch (MI.getOpcode()) {
4851 case AArch64::STGloop:
4852 case AArch64::STZGloop:
4853 OpIndex = 3;
4854 break;
4855 case AArch64::STGi:
4856 case AArch64::STZGi:
4857 case AArch64::ST2Gi:
4858 case AArch64::STZ2Gi:
4859 OpIndex = 1;
4860 break;
4861 default:
4862 OpIndex = -1;
4863 }
4864
4865 int TaggedFI = -1;
4866 if (OpIndex >= 0) {
4867 const MachineOperand &MO = MI.getOperand(OpIndex);
4868 if (MO.isFI()) {
4869 int FI = MO.getIndex();
4870 if (FI >= 0 && FI < MFI.getObjectIndexEnd() &&
4871 FrameObjects[FI].IsValid)
4872 TaggedFI = FI;
4873 }
4874 }
4875
4876 // If this is a stack tagging instruction for a slot that is not part of a
4877 // group yet, either start a new group or add it to the current one.
4878 if (TaggedFI >= 0)
4879 GB.AddMember(TaggedFI);
4880 else
4881 GB.EndCurrentGroup();
4882 }
4883 // Groups should never span multiple basic blocks.
4884 GB.EndCurrentGroup();
4885 }
4886
4887 if (AFI.hasStackHazardSlotIndex()) {
4888 FrameObjects[AFI.getStackHazardSlotIndex()].Accesses =
4889 FrameObject::AccessHazard;
4890 // If a stack object is unknown or both GPR and FPR, sort it into GPR.
4891 for (auto &Obj : FrameObjects)
4892 if (!Obj.Accesses ||
4893 Obj.Accesses == (FrameObject::AccessGPR | FrameObject::AccessFPR))
4894 Obj.Accesses = FrameObject::AccessGPR;
4895 }
4896
4897 // If the function's tagged base pointer is pinned to a stack slot, we want to
4898 // put that slot first when possible. This will likely place it at SP + 0,
4899 // and save one instruction when generating the base pointer because IRG does
4900 // not allow an immediate offset.
4901 std::optional<int> TBPI = AFI.getTaggedBasePointerIndex();
4902 if (TBPI) {
4903 FrameObjects[*TBPI].ObjectFirst = true;
4904 FrameObjects[*TBPI].GroupFirst = true;
4905 int FirstGroupIndex = FrameObjects[*TBPI].GroupIndex;
4906 if (FirstGroupIndex >= 0)
4907 for (FrameObject &Object : FrameObjects)
4908 if (Object.GroupIndex == FirstGroupIndex)
4909 Object.GroupFirst = true;
4910 }
4911
4912 llvm::stable_sort(FrameObjects, FrameObjectCompare);
4913
4914 int i = 0;
4915 for (auto &Obj : FrameObjects) {
4916 // All invalid items are sorted at the end, so it's safe to stop.
4917 if (!Obj.IsValid)
4918 break;
4919 ObjectsToAllocate[i++] = Obj.ObjectIndex;
4920 }
4921
4922 LLVM_DEBUG({
4923 dbgs() << "Final frame order:\n";
4924 for (auto &Obj : FrameObjects) {
4925 if (!Obj.IsValid)
4926 break;
4927 dbgs() << " " << Obj.ObjectIndex << ": group " << Obj.GroupIndex;
4928 if (Obj.ObjectFirst)
4929 dbgs() << ", first";
4930 if (Obj.GroupFirst)
4931 dbgs() << ", group-first";
4932 dbgs() << "\n";
4933 }
4934 });
4935}
4936
4937/// Emit a loop to decrement SP until it is equal to TargetReg, with probes at
4938/// least every ProbeSize bytes. Returns an iterator of the first instruction
4939/// after the loop. The difference between SP and TargetReg must be an exact
4940/// multiple of ProbeSize.
4942AArch64FrameLowering::inlineStackProbeLoopExactMultiple(
4943 MachineBasicBlock::iterator MBBI, int64_t ProbeSize,
4944 Register TargetReg) const {
4946 MachineFunction &MF = *MBB.getParent();
4947 const AArch64InstrInfo *TII =
4948 MF.getSubtarget<AArch64Subtarget>().getInstrInfo();
4950
4951 MachineFunction::iterator MBBInsertPoint = std::next(MBB.getIterator());
4953 MF.insert(MBBInsertPoint, LoopMBB);
4955 MF.insert(MBBInsertPoint, ExitMBB);
4956
4957 // SUB SP, SP, #ProbeSize (or equivalent if ProbeSize is not encodable
4958 // in SUB).
4959 emitFrameOffset(*LoopMBB, LoopMBB->end(), DL, AArch64::SP, AArch64::SP,
4960 StackOffset::getFixed(-ProbeSize), TII,
4962 // STR XZR, [SP]
4963 BuildMI(*LoopMBB, LoopMBB->end(), DL, TII->get(AArch64::STRXui))
4964 .addReg(AArch64::XZR)
4965 .addReg(AArch64::SP)
4966 .addImm(0)
4968 // CMP SP, TargetReg
4969 BuildMI(*LoopMBB, LoopMBB->end(), DL, TII->get(AArch64::SUBSXrx64),
4970 AArch64::XZR)
4971 .addReg(AArch64::SP)
4972 .addReg(TargetReg)
4975 // B.CC Loop
4976 BuildMI(*LoopMBB, LoopMBB->end(), DL, TII->get(AArch64::Bcc))
4978 .addMBB(LoopMBB)
4980
4981 LoopMBB->addSuccessor(ExitMBB);
4982 LoopMBB->addSuccessor(LoopMBB);
4983 // Synthesize the exit MBB.
4984 ExitMBB->splice(ExitMBB->end(), &MBB, MBBI, MBB.end());
4986 MBB.addSuccessor(LoopMBB);
4987 // Update liveins.
4988 fullyRecomputeLiveIns({ExitMBB, LoopMBB});
4989
4990 return ExitMBB->begin();
4991}
4992
4993void AArch64FrameLowering::inlineStackProbeFixed(
4994 MachineBasicBlock::iterator MBBI, Register ScratchReg, int64_t FrameSize,
4995 StackOffset CFAOffset) const {
4997 MachineFunction &MF = *MBB->getParent();
4998 const AArch64InstrInfo *TII =
4999 MF.getSubtarget<AArch64Subtarget>().getInstrInfo();
5001 bool EmitAsyncCFI = AFI->needsAsyncDwarfUnwindInfo(MF);
5002 bool HasFP = hasFP(MF);
5003
5004 DebugLoc DL;
5005 int64_t ProbeSize = MF.getInfo<AArch64FunctionInfo>()->getStackProbeSize();
5006 int64_t NumBlocks = FrameSize / ProbeSize;
5007 int64_t ResidualSize = FrameSize % ProbeSize;
5008
5009 LLVM_DEBUG(dbgs() << "Stack probing: total " << FrameSize << " bytes, "
5010 << NumBlocks << " blocks of " << ProbeSize
5011 << " bytes, plus " << ResidualSize << " bytes\n");
5012
5013 // Decrement SP by NumBlock * ProbeSize bytes, with either unrolled or
5014 // ordinary loop.
5015 if (NumBlocks <= AArch64::StackProbeMaxLoopUnroll) {
5016 for (int i = 0; i < NumBlocks; ++i) {
5017 // SUB SP, SP, #ProbeSize (or equivalent if ProbeSize is not
5018 // encodable in a SUB).
5019 emitFrameOffset(*MBB, MBBI, DL, AArch64::SP, AArch64::SP,
5020 StackOffset::getFixed(-ProbeSize), TII,
5021 MachineInstr::FrameSetup, false, false, nullptr,
5022 EmitAsyncCFI && !HasFP, CFAOffset);
5023 CFAOffset += StackOffset::getFixed(ProbeSize);
5024 // STR XZR, [SP]
5025 BuildMI(*MBB, MBBI, DL, TII->get(AArch64::STRXui))
5026 .addReg(AArch64::XZR)
5027 .addReg(AArch64::SP)
5028 .addImm(0)
5030 }
5031 } else if (NumBlocks != 0) {
5032 // SUB ScratchReg, SP, #FrameSize (or equivalent if FrameSize is not
5033 // encodable in ADD). ScrathReg may temporarily become the CFA register.
5034 emitFrameOffset(*MBB, MBBI, DL, ScratchReg, AArch64::SP,
5035 StackOffset::getFixed(-ProbeSize * NumBlocks), TII,
5036 MachineInstr::FrameSetup, false, false, nullptr,
5037 EmitAsyncCFI && !HasFP, CFAOffset);
5038 CFAOffset += StackOffset::getFixed(ProbeSize * NumBlocks);
5039 MBBI = inlineStackProbeLoopExactMultiple(MBBI, ProbeSize, ScratchReg);
5040 MBB = MBBI->getParent();
5041 if (EmitAsyncCFI && !HasFP) {
5042 // Set the CFA register back to SP.
5044 *MF.getSubtarget<AArch64Subtarget>().getRegisterInfo();
5045 unsigned Reg = RegInfo.getDwarfRegNum(AArch64::SP, true);
5046 unsigned CFIIndex =
5048 BuildMI(*MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
5049 .addCFIIndex(CFIIndex)
5051 }
5052 }
5053
5054 if (ResidualSize != 0) {
5055 // SUB SP, SP, #ResidualSize (or equivalent if ResidualSize is not encodable
5056 // in SUB).
5057 emitFrameOffset(*MBB, MBBI, DL, AArch64::SP, AArch64::SP,
5058 StackOffset::getFixed(-ResidualSize), TII,
5059 MachineInstr::FrameSetup, false, false, nullptr,
5060 EmitAsyncCFI && !HasFP, CFAOffset);
5061 if (ResidualSize > AArch64::StackProbeMaxUnprobedStack) {
5062 // STR XZR, [SP]
5063 BuildMI(*MBB, MBBI, DL, TII->get(AArch64::STRXui))
5064 .addReg(AArch64::XZR)
5065 .addReg(AArch64::SP)
5066 .addImm(0)
5068 }
5069 }
5070}
5071
5072void AArch64FrameLowering::inlineStackProbe(MachineFunction &MF,
5073 MachineBasicBlock &MBB) const {
5074 // Get the instructions that need to be replaced. We emit at most two of
5075 // these. Remember them in order to avoid complications coming from the need
5076 // to traverse the block while potentially creating more blocks.
5078 for (MachineInstr &MI : MBB)
5079 if (MI.getOpcode() == AArch64::PROBED_STACKALLOC ||
5080 MI.getOpcode() == AArch64::PROBED_STACKALLOC_VAR)
5081 ToReplace.push_back(&MI);
5082
5083 for (MachineInstr *MI : ToReplace) {
5084 if (MI->getOpcode() == AArch64::PROBED_STACKALLOC) {
5085 Register ScratchReg = MI->getOperand(0).getReg();
5086 int64_t FrameSize = MI->getOperand(1).getImm();
5087 StackOffset CFAOffset = StackOffset::get(MI->getOperand(2).getImm(),
5088 MI->getOperand(3).getImm());
5089 inlineStackProbeFixed(MI->getIterator(), ScratchReg, FrameSize,
5090 CFAOffset);
5091 } else {
5092 assert(MI->getOpcode() == AArch64::PROBED_STACKALLOC_VAR &&
5093 "Stack probe pseudo-instruction expected");
5094 const AArch64InstrInfo *TII =
5095 MI->getMF()->getSubtarget<AArch64Subtarget>().getInstrInfo();
5096 Register TargetReg = MI->getOperand(0).getReg();
5097 (void)TII->probedStackAlloc(MI->getIterator(), TargetReg, true);
5098 }
5099 MI->eraseFromParent();
5100 }
5101}
5102
5105 NotAccessed = 0, // Stack object not accessed by load/store instructions.
5106 GPR = 1 << 0, // A general purpose register.
5107 PPR = 1 << 1, // A predicate register.
5108 FPR = 1 << 2, // A floating point/Neon/SVE register.
5109 };
5110
5111 int Idx;
5113 int64_t Size;
5114 unsigned AccessTypes;
5115
5116 StackAccess() : Idx(0), Offset(), Size(0), AccessTypes(NotAccessed) {}
5117
5118 bool operator<(const StackAccess &Rhs) const {
5119 return std::make_tuple(start(), Idx) <
5120 std::make_tuple(Rhs.start(), Rhs.Idx);
5121 }
5122
5123 bool isCPU() const {
5124 // Predicate register load and store instructions execute on the CPU.
5125 return AccessTypes & (AccessType::GPR | AccessType::PPR);
5126 }
5127 bool isSME() const { return AccessTypes & AccessType::FPR; }
5128 bool isMixed() const { return isCPU() && isSME(); }
5129
5130 int64_t start() const { return Offset.getFixed() + Offset.getScalable(); }
5131 int64_t end() const { return start() + Size; }
5132
5133 std::string getTypeString() const {
5134 switch (AccessTypes) {
5135 case AccessType::FPR:
5136 return "FPR";
5137 case AccessType::PPR:
5138 return "PPR";
5139 case AccessType::GPR:
5140 return "GPR";
5141 case AccessType::NotAccessed:
5142 return "NA";
5143 default:
5144 return "Mixed";
5145 }
5146 }
5147
5148 void print(raw_ostream &OS) const {
5149 OS << getTypeString() << " stack object at [SP"
5150 << (Offset.getFixed() < 0 ? "" : "+") << Offset.getFixed();
5151 if (Offset.getScalable())
5152 OS << (Offset.getScalable() < 0 ? "" : "+") << Offset.getScalable()
5153 << " * vscale";
5154 OS << "]";
5155 }
5156};
5157
5158static inline raw_ostream &operator<<(raw_ostream &OS, const StackAccess &SA) {
5159 SA.print(OS);
5160 return OS;
5161}
5162
5163void AArch64FrameLowering::emitRemarks(
5164 const MachineFunction &MF, MachineOptimizationRemarkEmitter *ORE) const {
5165
5167 if (Attrs.hasNonStreamingInterfaceAndBody())
5168 return;
5169
5170 unsigned StackHazardSize = getStackHazardSize(MF);
5171 const uint64_t HazardSize =
5172 (StackHazardSize) ? StackHazardSize : StackHazardRemarkSize;
5173
5174 if (HazardSize == 0)
5175 return;
5176
5177 const MachineFrameInfo &MFI = MF.getFrameInfo();
5178 // Bail if function has no stack objects.
5179 if (!MFI.hasStackObjects())
5180 return;
5181
5182 std::vector<StackAccess> StackAccesses(MFI.getNumObjects());
5183
5184 size_t NumFPLdSt = 0;
5185 size_t NumNonFPLdSt = 0;
5186
5187 // Collect stack accesses via Load/Store instructions.
5188 for (const MachineBasicBlock &MBB : MF) {
5189 for (const MachineInstr &MI : MBB) {
5190 if (!MI.mayLoadOrStore() || MI.getNumMemOperands() < 1)
5191 continue;
5192 for (MachineMemOperand *MMO : MI.memoperands()) {
5193 std::optional<int> FI = getMMOFrameID(MMO, MFI);
5194 if (FI && !MFI.isDeadObjectIndex(*FI)) {
5195 int FrameIdx = *FI;
5196
5197 size_t ArrIdx = FrameIdx + MFI.getNumFixedObjects();
5198 if (StackAccesses[ArrIdx].AccessTypes == StackAccess::NotAccessed) {
5199 StackAccesses[ArrIdx].Idx = FrameIdx;
5200 StackAccesses[ArrIdx].Offset =
5201 getFrameIndexReferenceFromSP(MF, FrameIdx);
5202 StackAccesses[ArrIdx].Size = MFI.getObjectSize(FrameIdx);
5203 }
5204
5205 unsigned RegTy = StackAccess::AccessType::GPR;
5206 if (MFI.getStackID(FrameIdx) == TargetStackID::ScalableVector) {
5207 if (AArch64::PPRRegClass.contains(MI.getOperand(0).getReg()))
5208 RegTy = StackAccess::PPR;
5209 else
5210 RegTy = StackAccess::FPR;
5211 } else if (AArch64InstrInfo::isFpOrNEON(MI)) {
5212 RegTy = StackAccess::FPR;
5213 }
5214
5215 StackAccesses[ArrIdx].AccessTypes |= RegTy;
5216
5217 if (RegTy == StackAccess::FPR)
5218 ++NumFPLdSt;
5219 else
5220 ++NumNonFPLdSt;
5221 }
5222 }
5223 }
5224 }
5225
5226 if (NumFPLdSt == 0 || NumNonFPLdSt == 0)
5227 return;
5228
5229 llvm::sort(StackAccesses);
5230 StackAccesses.erase(llvm::remove_if(StackAccesses,
5231 [](const StackAccess &S) {
5232 return S.AccessTypes ==
5234 }),
5235 StackAccesses.end());
5236
5239
5240 if (StackAccesses.front().isMixed())
5241 MixedObjects.push_back(&StackAccesses.front());
5242
5243 for (auto It = StackAccesses.begin(), End = std::prev(StackAccesses.end());
5244 It != End; ++It) {
5245 const auto &First = *It;
5246 const auto &Second = *(It + 1);
5247
5248 if (Second.isMixed())
5249 MixedObjects.push_back(&Second);
5250
5251 if ((First.isSME() && Second.isCPU()) ||
5252 (First.isCPU() && Second.isSME())) {
5253 uint64_t Distance = static_cast<uint64_t>(Second.start() - First.end());
5254 if (Distance < HazardSize)
5255 HazardPairs.emplace_back(&First, &Second);
5256 }
5257 }
5258
5259 auto EmitRemark = [&](llvm::StringRef Str) {
5260 ORE->emit([&]() {
5262 "sme", "StackHazard", MF.getFunction().getSubprogram(), &MF.front());
5263 return R << formatv("stack hazard in '{0}': ", MF.getName()).str() << Str;
5264 });
5265 };
5266
5267 for (const auto &P : HazardPairs)
5268 EmitRemark(formatv("{0} is too close to {1}", *P.first, *P.second).str());
5269
5270 for (const auto *Obj : MixedObjects)
5271 EmitRemark(
5272 formatv("{0} accessed by both GP and FP instructions", *Obj).str());
5273}
unsigned const MachineRegisterInfo * MRI
#define Success
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
static int64_t getArgumentStackToRestore(MachineFunction &MF, MachineBasicBlock &MBB)
Returns how much of the incoming argument stack area (in bytes) we should clean up in an epilogue.
static void emitShadowCallStackEpilogue(const TargetInstrInfo &TII, MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL)
static void getLiveRegsForEntryMBB(LivePhysRegs &LiveRegs, const MachineBasicBlock &MBB)
static void emitCalleeSavedRestores(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, bool SVE)
static void computeCalleeSaveRegisterPairs(MachineFunction &MF, ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI, SmallVectorImpl< RegPairInfo > &RegPairs, bool NeedsFrameRecord)
static const unsigned DefaultSafeSPDisplacement
This is the biggest offset to the stack pointer we can encode in aarch64 instructions (without using ...
static void emitDefineCFAWithFP(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, unsigned FixedObject)
static bool needsWinCFI(const MachineFunction &MF)
static void insertCFISameValue(const MCInstrDesc &Desc, MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertPt, unsigned DwarfReg)
static cl::opt< bool > StackTaggingMergeSetTag("stack-tagging-merge-settag", cl::desc("merge settag instruction in function epilog"), cl::init(true), cl::Hidden)
bool requiresGetVGCall(MachineFunction &MF)
bool enableMultiVectorSpillFill(const AArch64Subtarget &Subtarget, MachineFunction &MF)
bool isVGInstruction(MachineBasicBlock::iterator MBBI)
static std::optional< int > getLdStFrameID(const MachineInstr &MI, const MachineFrameInfo &MFI)
static bool produceCompactUnwindFrame(MachineFunction &MF)
static cl::opt< bool > StackHazardInNonStreaming("aarch64-stack-hazard-in-non-streaming", cl::init(false), cl::Hidden)
static int64_t determineSVEStackObjectOffsets(MachineFrameInfo &MFI, int &MinCSFrameIndex, int &MaxCSFrameIndex, bool AssignOffsets)
static cl::opt< bool > OrderFrameObjects("aarch64-order-frame-objects", cl::desc("sort stack allocations"), cl::init(true), cl::Hidden)
static bool windowsRequiresStackProbe(MachineFunction &MF, uint64_t StackSizeInBytes)
static void fixupCalleeSaveRestoreStackOffset(MachineInstr &MI, uint64_t LocalStackSize, bool NeedsWinCFI, bool *HasWinCFI)
static bool invalidateWindowsRegisterPairing(unsigned Reg1, unsigned Reg2, bool NeedsWinCFI, bool IsFirst, const TargetRegisterInfo *TRI)
static MachineBasicBlock::iterator convertCalleeSaveRestoreToSPPrePostIncDec(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, const TargetInstrInfo *TII, int CSStackSizeInc, bool NeedsWinCFI, bool *HasWinCFI, bool EmitCFI, MachineInstr::MIFlag FrameFlag=MachineInstr::FrameSetup, int CFAOffset=0)
static void fixupSEHOpcode(MachineBasicBlock::iterator MBBI, unsigned LocalStackSize)
static StackOffset getSVEStackSize(const MachineFunction &MF)
Returns the size of the entire SVE stackframe (calleesaves + spills).
static cl::opt< bool > DisableMultiVectorSpillFill("aarch64-disable-multivector-spill-fill", cl::desc("Disable use of LD/ST pairs for SME2 or SVE2p1"), cl::init(false), cl::Hidden)
static cl::opt< bool > EnableRedZone("aarch64-redzone", cl::desc("enable use of redzone on AArch64"), cl::init(false), cl::Hidden)
static MachineBasicBlock::iterator InsertSEH(MachineBasicBlock::iterator MBBI, const TargetInstrInfo &TII, MachineInstr::MIFlag Flag)
static Register findScratchNonCalleeSaveRegister(MachineBasicBlock *MBB)
static void getLivePhysRegsUpTo(MachineInstr &MI, const TargetRegisterInfo &TRI, LivePhysRegs &LiveRegs)
Collect live registers from the end of MI's parent up to (including) MI in LiveRegs.
cl::opt< bool > EnableHomogeneousPrologEpilog("homogeneous-prolog-epilog", cl::Hidden, cl::desc("Emit homogeneous prologue and epilogue for the size " "optimization (default = off)"))
MachineBasicBlock::iterator emitVGSaveRestore(MachineBasicBlock::iterator II, const AArch64FrameLowering *TFI)
static bool IsSVECalleeSave(MachineBasicBlock::iterator I)
static bool invalidateRegisterPairing(unsigned Reg1, unsigned Reg2, bool UsesWinAAPCS, bool NeedsWinCFI, bool NeedsFrameRecord, bool IsFirst, const TargetRegisterInfo *TRI)
Returns true if Reg1 and Reg2 cannot be paired using a ldp/stp instruction.
unsigned findFreePredicateReg(BitVector &SavedRegs)
static unsigned getPrologueDeath(MachineFunction &MF, unsigned Reg)
static StackOffset getFPOffset(const MachineFunction &MF, int64_t ObjectOffset)
static bool isTargetWindows(const MachineFunction &MF)
static StackOffset getStackOffset(const MachineFunction &MF, int64_t ObjectOffset)
static int64_t upperBound(StackOffset Size)
static unsigned estimateRSStackSizeLimit(MachineFunction &MF)
Look at each instruction that references stack frames and return the stack size limit beyond which so...
static bool getSVECalleeSaveSlotRange(const MachineFrameInfo &MFI, int &Min, int &Max)
returns true if there are any SVE callee saves.
static cl::opt< unsigned > StackHazardRemarkSize("aarch64-stack-hazard-remark-size", cl::init(0), cl::Hidden)
static MCRegister getRegisterOrZero(MCRegister Reg, bool HasSVE)
static bool isFuncletReturnInstr(const MachineInstr &MI)
static unsigned getStackHazardSize(const MachineFunction &MF)
static void emitShadowCallStackPrologue(const TargetInstrInfo &TII, MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, bool NeedsWinCFI, bool NeedsUnwindInfo)
static std::optional< int > getMMOFrameID(MachineMemOperand *MMO, const MachineFrameInfo &MFI)
static bool requiresSaveVG(MachineFunction &MF)
static unsigned getFixedObjectSize(const MachineFunction &MF, const AArch64FunctionInfo *AFI, bool IsWin64, bool IsFunclet)
Returns the size of the fixed object area (allocated next to sp on entry) On Win64 this may include a...
static const int kSetTagLoopThreshold
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
This file contains the simple types necessary to represent the attributes associated with functions a...
#define CASE(ATTRNAME, AANAME,...)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
#define LLVM_DEBUG(...)
Definition: Debug.h:106
uint32_t Index
uint64_t Size
bool End
Definition: ELF_riscv.cpp:480
static const HTTPClientCleanup Cleanup
Definition: HTTPClient.cpp:42
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
static std::string getTypeString(Type *T)
Definition: LLParser.cpp:71
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
unsigned const TargetRegisterInfo * TRI
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
uint64_t IntrinsicInst * II
#define P(N)
static const MCPhysReg FPR[]
FPR - The set of FP registers that should be allocated for arguments on Darwin and AIX.
if(PassOpts->AAPipeline)
This file declares the machine register scavenger class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
unsigned OpIndex
raw_pwrite_stream & OS
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition: Value.cpp:469
This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition: Statistic.h:166
static const unsigned FramePtr
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 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...
StackOffset getFrameIndexReferenceFromSP(const MachineFunction &MF, int FI) const override
getFrameIndexReferenceFromSP - This method returns the offset from the stack pointer to the slot of t...
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.
bool enableCFIFixup(MachineFunction &MF) const override
Returns true if we may need to fix the unwind information for the function.
void resetCFIToInitialState(MachineBasicBlock &MBB) const override
Emit CFI instructions that recreate the state of the unwind information upon fucntion entry.
bool hasReservedCallFrame(const MachineFunction &MF) const override
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
bool canUseRedZone(const MachineFunction &MF) const
Can this function use the red zone for local allocations.
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
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 resolveFrameOffsetReference(const MachineFunction &MF, int64_t ObjectOffset, bool isFixed, bool isSVE, Register &FrameReg, bool PreferFP, bool ForSimm) const
bool assignCalleeSavedSpillSlots(MachineFunction &MF, const TargetRegisterInfo *TRI, std::vector< CalleeSavedInfo > &CSI, unsigned &MinCSFrameIndex, unsigned &MaxCSFrameIndex) const override
assignCalleeSavedSpillSlots - Allows target to override spill slot assignment logic.
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...
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
bool needsShadowCallStackPrologueEpilogue(MachineFunction &MF) const
unsigned getCalleeSavedStackSize(const MachineFrameInfo &MFI) const
void setCalleeSaveBaseToFrameRecordOffset(int Offset)
bool shouldSignReturnAddress(const MachineFunction &MF) const
void setPredicateRegForFillSpill(unsigned Reg)
void setStreamingVGIdx(unsigned FrameIdx)
std::optional< int > getTaggedBasePointerIndex() const
bool needsDwarfUnwindInfo(const MachineFunction &MF) const
void setTaggedBasePointerOffset(unsigned Offset)
bool needsAsyncDwarfUnwindInfo(const MachineFunction &MF) const
void setMinMaxSVECSFrameIndex(int Min, int Max)
static bool isTailCallReturnInst(const MachineInstr &MI)
Returns true if MI is one of the TCRETURN* instructions.
static bool isSEHInstruction(const MachineInstr &MI)
Return true if the instructions is a SEH instruciton used for unwinding on Windows.
static bool isFpOrNEON(Register Reg)
Returns whether the physical register is FP or NEON.
bool isReservedReg(const MachineFunction &MF, MCRegister Reg) const
bool hasBasePointer(const MachineFunction &MF) const
bool cannotEliminateFrame(const MachineFunction &MF) const
const AArch64RegisterInfo * getRegisterInfo() const override
bool isNeonAvailable() const
Returns true if the target has NEON and the function at runtime is known to have NEON enabled (e....
const AArch64InstrInfo * getInstrInfo() const override
const AArch64TargetLowering * getTargetLowering() const override
const Triple & getTargetTriple() const
const char * getChkStkName() const
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 isCallingConvWin64(CallingConv::ID CC, bool IsVarArg) const
bool swiftAsyncContextIsDynamicallySet() const
Return whether FrameLowering should always set the "extended frame present" bit in FP,...
bool hasInlineStackProbe(const MachineFunction &MF) const override
True if stack clash protection is enabled for this functions.
unsigned getRedZoneSize(const Function &F) const
bool supportSwiftError() const override
Return true if the target supports swifterror attribute.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:168
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:163
bool hasAttrSomewhere(Attribute::AttrKind Kind, unsigned *Index=nullptr) const
Return true if the specified attribute is set for at least one parameter or for the return value.
bool test(unsigned Idx) const
Definition: BitVector.h:461
BitVector & reset()
Definition: BitVector.h:392
size_type count() const
count - Returns the number of bits which are set.
Definition: BitVector.h:162
BitVector & set()
Definition: BitVector.h:351
iterator_range< const_set_bits_iterator > set_bits() const
Definition: BitVector.h:140
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
A debug info location.
Definition: DebugLoc.h:33
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
Definition: Function.h:707
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
Definition: Function.h:704
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition: Function.h:277
AttributeList getAttributes() const
Return the attribute list for this Function.
Definition: Function.h:353
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition: Function.h:234
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.cpp:731
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
Emit instructions to copy a pair of physical registers.
A set of physical registers with utility functions to track liveness when walking backward/forward th...
Definition: LivePhysRegs.h:52
bool available(const MachineRegisterInfo &MRI, MCPhysReg Reg) const
Returns true if register Reg and no aliasing register is in the set.
void stepBackward(const MachineInstr &MI)
Simulates liveness when stepping backwards over an instruction(bundle).
void removeReg(MCPhysReg Reg)
Removes a physical register, all its sub-registers, and all its super-registers from the set.
Definition: LivePhysRegs.h:92
void addLiveIns(const MachineBasicBlock &MBB)
Adds all live-in registers of basic block MBB.
void addLiveOuts(const MachineBasicBlock &MBB)
Adds all live-out registers of basic block MBB.
void addReg(MCPhysReg Reg)
Adds a physical register and all its sub-registers to the set.
Definition: LivePhysRegs.h:83
bool usesWindowsCFI() const
Definition: MCAsmInfo.h:661
static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register, SMLoc Loc={})
.cfi_def_cfa_register modifies a rule for computing CFA.
Definition: MCDwarf.h:582
static MCCFIInstruction createRestore(MCSymbol *L, unsigned Register, SMLoc Loc={})
.cfi_restore says that the rule for Register is now the same as it was at the beginning of the functi...
Definition: MCDwarf.h:656
static MCCFIInstruction cfiDefCfa(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})
.cfi_def_cfa defines a rule for computing CFA as: take address from Register and add Offset to it.
Definition: MCDwarf.h:575
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
Definition: MCDwarf.h:617
static MCCFIInstruction createNegateRAStateWithPC(MCSymbol *L, SMLoc Loc={})
.cfi_negate_ra_state_with_pc AArch64 negate RA state with PC.
Definition: MCDwarf.h:648
static MCCFIInstruction createNegateRAState(MCSymbol *L, SMLoc Loc={})
.cfi_negate_ra_state AArch64 negate RA state.
Definition: MCDwarf.h:643
static MCCFIInstruction cfiDefCfaOffset(MCSymbol *L, int64_t Offset, SMLoc Loc={})
.cfi_def_cfa_offset modifies a rule for computing CFA.
Definition: MCDwarf.h:590
static MCCFIInstruction createEscape(MCSymbol *L, StringRef Vals, SMLoc Loc={}, StringRef Comment="")
.cfi_escape Allows the user to add arbitrary bytes to the unwind info.
Definition: MCDwarf.h:687
static MCCFIInstruction createSameValue(MCSymbol *L, unsigned Register, SMLoc Loc={})
.cfi_same_value Current value of Register is the same as in the previous frame.
Definition: MCDwarf.h:670
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
Definition: MCContext.cpp:345
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:198
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
instr_iterator instr_begin()
iterator_range< livein_iterator > liveins() const
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
bool isEHFuncletEntry() const
Returns true if this is the entry block of an EH funclet.
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
MachineInstr & instr_back()
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.
iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
instr_iterator instr_end()
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
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 '...
bool isLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
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 ...
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
const AllocaInst * getObjectAllocation(int ObjectIdx) const
Return the underlying Alloca of the specified stack object if it exists.
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...
Align getMaxAlign() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
void setObjectOffset(int ObjectIdx, int64_t SPOffset)
Set the stack frame offset of the specified object.
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...
int getStackProtectorIndex() const
Return the index for the stack protector object.
int CreateSpillStackObject(uint64_t Size, Align Alignment)
Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...
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...
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.
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.
unsigned addFrameInst(const MCCFIInstruction &Inst)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MCContext & getContext() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineBasicBlock & front() const
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
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 & addCFIIndex(unsigned CFIIndex) const
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
Definition: MachineInstr.h:71
void setFlags(unsigned flags)
Definition: MachineInstr.h:412
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
uint32_t getFlags() const
Return the MI flags bitvector.
Definition: MachineInstr.h:394
A description of a memory reference used in the backend.
const PseudoSourceValue * getPseudoValue() const
@ 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.
void setImm(int64_t immVal)
int64_t getImm() const
static MachineOperand CreateImm(int64_t Val)
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
Diagnostic information for optimization analysis remarks.
void emit(DiagnosticInfoOptimizationBase &OptDiag)
Emit an optimization remark.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
bool isLiveIn(Register Reg) const
const MCPhysReg * getCalleeSavedRegs() const
Returns list of callee saved registers.
bool isPhysRegUsed(MCRegister PhysReg, bool SkipRegMaskTest=false) const
Return true if the specified register is modified or read in this function.
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition: ArrayRef.h:310
void enterBasicBlockEnd(MachineBasicBlock &MBB)
Start tracking liveness from the end of basic block MBB.
Register FindUnusedReg(const TargetRegisterClass *RC) const
Find an unused register of the specified register class.
void backward()
Update internal register state and move MBB iterator backwards.
void addScavengingFrameIndex(int FI)
Add a scavenging frame index.
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
SMEAttrs is a utility class to parse the SME ACLE attributes on functions.
bool hasStreamingInterface() const
bool hasStreamingBody() const
bool empty() const
Definition: SmallVector.h:81
size_t size() const
Definition: SmallVector.h:78
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:937
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:683
void push_back(const T &Elt)
Definition: SmallVector.h:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
StackOffset holds a fixed and a scalable offset in bytes.
Definition: TypeSize.h:33
int64_t getFixed() const
Returns the fixed component of the stack.
Definition: TypeSize.h:49
int64_t getScalable() const
Returns the scalable component of the stack.
Definition: TypeSize.h:52
static StackOffset get(int64_t Fixed, int64_t Scalable)
Definition: TypeSize.h:44
static StackOffset getScalable(int64_t Scalable)
Definition: TypeSize.h:43
static StackOffset getFixed(int64_t Fixed)
Definition: TypeSize.h:42
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
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(MachineFunction &MF) const
Returns true if we may need to fix the unwind information for the function.
TargetInstrInfo - Interface to description of machine instruction set.
TargetOptions Options
CodeModel::Model getCodeModel() const
Returns the code model.
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
SwiftAsyncFramePointerMode SwiftAsyncFramePointer
Control when and how the Swift async frame pointer bit should be set.
bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
const TargetRegisterClass * getMinimalPhysRegClass(MCRegister Reg, MVT VT=MVT::Other) const
Returns the Register Class of a physical register of the given type, picking the most sub register cl...
Align getSpillAlign(const TargetRegisterClass &RC) const
Return the minimum required alignment in bytes for a spill slot for a register of this class.
bool hasStackRealignment(const MachineFunction &MF) const
True if stack realignment is required and still possible.
unsigned getSpillSize(const TargetRegisterClass &RC) const
Return the size in bytes of the stack slot allocated to hold a spilled copy of a register from class ...
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual const TargetInstrInfo * getInstrInfo() const
StringRef getArchName() const
Get the architecture (first) component of the triple.
Definition: Triple.cpp:1354
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition: TypeSize.h:345
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
constexpr ScalarTy getFixedValue() const
Definition: TypeSize.h:202
self_iterator getIterator()
Definition: ilist_node.h:132
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ MO_GOT
MO_GOT - This flag indicates that a symbol operand represents the address of the GOT entry for the sy...
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...
static uint64_t encodeLogicalImmediate(uint64_t imm, unsigned regSize)
encodeLogicalImmediate - Return the encoded immediate value for a logical immediate instruction of th...
static unsigned getShifterImm(AArch64_AM::ShiftExtendType ST, unsigned Imm)
getShifterImm - Encode the shift type and amount: imm: 6-bit shift amount shifter: 000 ==> lsl 001 ==...
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 Attrs[]
Key for Kernel::Metadata::mAttrs.
@ AArch64_SVE_VectorCall
Used between AArch64 SVE functions.
Definition: CallingConv.h:224
@ 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
@ AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1
Preserve X1-X15, X19-X29, SP, Z0-Z31, P0-P15.
Definition: CallingConv.h:271
@ PreserveAll
Used for runtime calls that preserves (almost) all registers.
Definition: CallingConv.h:66
@ 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.
Definition: CallingConv.h:159
@ SwiftTail
This follows the Swift calling convention in how arguments are passed but guarantees tail calls will ...
Definition: CallingConv.h:87
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Dead
Unused definition.
@ Define
Register definition.
@ Kill
The last use of a register.
@ Undef
Value of the register doesn't matter.
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
NodeAddr< InstrNode * > Instr
Definition: RDFGraph.h:389
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
void stable_sort(R &&Range)
Definition: STLExtras.h:2037
MCCFIInstruction createDefCFA(const TargetRegisterInfo &TRI, unsigned FrameReg, unsigned Reg, const StackOffset &Offset, bool LastAdjustmentWasScalable=true)
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.
detail::scope_exit< std::decay_t< Callable > > make_scope_exit(Callable &&F)
Definition: ScopeExit.h:59
MCCFIInstruction createCFAOffset(const TargetRegisterInfo &MRI, unsigned Reg, const StackOffset &OffsetFromDefCFA)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
unsigned getBLRCallOpcode(const MachineFunction &MF)
Return opcode to be used for indirect calls.
const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=6)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
@ AArch64FrameOffsetCannotUpdate
Offset cannot apply.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1746
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
auto reverse(ContainerTy &&C)
Definition: STLExtras.h:420
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1664
@ Always
Always set the bit.
@ DeploymentBased
Determine whether to set the bit statically or dynamically based on the deployment target.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
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.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167
EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
auto remove_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1778
unsigned getDefRegState(bool B)
unsigned getKillRegState(bool B)
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
Definition: APFixedPoint.h:303
bool isAsynchronousEHPersonality(EHPersonality Pers)
Returns true if this personality function catches asynchronous exceptions.
void fullyRecomputeLiveIns(ArrayRef< MachineBasicBlock * > MBBs)
Convenience function for recomputing live-in's for a set of MBBs until the computation converges.
Definition: LivePhysRegs.h:215
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.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:860
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
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85
Description of the encoding of one expression Op.
Pair of physical register and lane mask.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.