LLVM 24.0.0git
AArch64FrameLowering.cpp File Reference
#include "AArch64FrameLowering.h"
#include "AArch64InstrInfo.h"
#include "AArch64MachineFunctionInfo.h"
#include "AArch64PrologueEpilogue.h"
#include "AArch64RegisterInfo.h"
#include "AArch64SMEAttributes.h"
#include "AArch64Subtarget.h"
#include "MCTargetDesc/AArch64AddressingModes.h"
#include "MCTargetDesc/AArch64MCTargetDesc.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/CodeGen/CFIInstBuilder.h"
#include "llvm/CodeGen/LivePhysRegs.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterScavenging.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/CodeGen/WinEHFuncInfo.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include <cassert>
#include <cstdint>
#include <iterator>
#include <optional>
#include <vector>

Go to the source code of this file.

Classes

struct  StackAccess

Macros

#define DEBUG_TYPE   "frame-info"
#define CASE(n)
#define CASE(n)

Enumerations

enum class  AssignObjectOffsets { No , Yes }

Functions

static bool produceCompactUnwindFrame (const AArch64FrameLowering &, MachineFunction &MF)
static SVEStackSizes determineSVEStackSizes (MachineFunction &MF, AssignObjectOffsets AssignOffsets)
 Process all the SVE stack objects and the SVE stack size and offsets for each object.
static unsigned getStackHazardSize (const MachineFunction &MF)
static bool isLikelyToHaveSVEStack (const AArch64FrameLowering &AFL, const MachineFunction &MF)
static bool isTargetWindows (const MachineFunction &MF)
static unsigned estimateRSStackSizeLimit (MachineFunction &MF)
 Look at each instruction that references stack frames and return the stack size limit beyond which some of these instructions will require a scratch register during their expansion later.
static MCRegister getRegisterOrZero (MCRegister Reg, bool HasSVE)
static void getLiveRegsForEntryMBB (LivePhysRegs &LiveRegs, const MachineBasicBlock &MBB)
static RegState getPrologueDeath (MachineFunction &MF, unsigned Reg)
static bool invalidateWindowsRegisterPairing (bool SpillExtendedVolatile, unsigned SpillCount, unsigned Reg1, unsigned Reg2, bool NeedsWinCFI, const TargetRegisterInfo *TRI)
static bool invalidateRegisterPairing (bool SpillExtendedVolatile, unsigned SpillCount, unsigned Reg1, unsigned Reg2, bool UsesWinAAPCS, bool NeedsWinCFI, bool NeedsFrameRecord, const TargetRegisterInfo *TRI)
 Returns true if Reg1 and Reg2 cannot be paired using a ldp/stp instruction.
static bool isValidMemOpOffset (const AArch64InstrInfo *TII, unsigned Opcode, int Offset)
MCRegister findFreePredicateReg (BitVector &SavedRegs)
bool enableMultiVectorSpillFill (const AArch64Subtarget &Subtarget, MachineFunction &MF)
void computeCalleeSaveRegisterPairs (const AArch64FrameLowering &AFL, MachineFunction &MF, ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI, SmallVectorImpl< RegPairInfo > &RegPairs, bool NeedsFrameRecord)
static std::optional< int > getMMOFrameID (MachineMemOperand *MMO, const MachineFrameInfo &MFI)
static std::optional< int > getLdStFrameID (const MachineInstr &MI, const MachineFrameInfo &MFI)
static bool isPPRAccess (const MachineInstr &MI)
static void orderZPRCalleeSavesForPairs (MachineFunction &MF, const TargetRegisterInfo *RegInfo, std::vector< CalleeSavedInfo > &CSI)
static bool getSVECalleeSaveSlotRange (const MachineFrameInfo &MFI, int &Min, int &Max)
 returns true if there are any SVE callee saves.
static raw_ostream & operator<< (raw_ostream &OS, const StackAccess &SA)

Variables

static const unsigned DefaultSafeSPDisplacement = 255
 This is the biggest offset to the stack pointer we can encode in aarch64 instructions (without using a separate calculation and a temp register).

Macro Definition Documentation

◆ CASE [1/2]

#define CASE ( n)
Value:
case AArch64::W##n: \
case AArch64::X##n: \
return AArch64::X##n

◆ CASE [2/2]

#define CASE ( n)
Value:
case AArch64::B##n: \
case AArch64::H##n: \
case AArch64::S##n: \
case AArch64::D##n: \
case AArch64::Q##n: \
return HasSVE ? AArch64::Z##n : AArch64::Q##n

◆ DEBUG_TYPE

#define DEBUG_TYPE   "frame-info"

Definition at line 266 of file AArch64FrameLowering.cpp.

Enumeration Type Documentation

◆ AssignObjectOffsets

enum class AssignObjectOffsets
strong
Enumerator
No 
Yes 

Definition at line 299 of file AArch64FrameLowering.cpp.

Function Documentation

◆ computeCalleeSaveRegisterPairs()

void computeCalleeSaveRegisterPairs ( const AArch64FrameLowering & AFL,
MachineFunction & MF,
ArrayRef< CalleeSavedInfo > CSI,
const TargetRegisterInfo * TRI,
SmallVectorImpl< RegPairInfo > & RegPairs,
bool NeedsFrameRecord )

Definition at line 1674 of file AArch64FrameLowering.cpp.

References llvm::alignDown(), llvm::Aligned, llvm::alignTo(), llvm::any_of(), assert(), llvm::SmallVectorTemplateCommon< T, typename >::begin(), contains(), llvm::Count, llvm::CallingConv::CXX_FAST_TLS, llvm::ArrayRef< T >::empty(), llvm::SmallVectorTemplateCommon< T, typename >::end(), llvm::AArch64FunctionInfo::getCalleeSavedStackSize(), llvm::Function::getCallingConv(), llvm::MachineFunction::getFrameInfo(), llvm::MachineFunction::getFunction(), llvm::MachineFunction::getInfo(), llvm::MachineFrameInfo::getObjectAlign(), llvm::AArch64FunctionInfo::getPPRCalleeSavedStackSize(), llvm::AArch64FunctionInfo::getPredicateRegForFillSpill(), getStackHazardSize(), llvm::MachineFunction::getSubtarget(), llvm::AArch64FunctionInfo::getZPRCalleeSavedStackSize(), llvm::AArch64FunctionInfo::hasCalleeSaveStackFreeSpace(), llvm::AArch64FunctionInfo::hasSplitSVEObjects(), llvm::AArch64FunctionInfo::hasStackHazardSlotIndex(), llvm::AArch64FrameLowering::hasSVECalleeSavesAboveFrameRecord(), llvm::AArch64FunctionInfo::hasSwiftAsyncContext(), invalidateRegisterPairing(), llvm::AArch64InstrInfo::isFpOrNEON(), isTargetWindows(), isValidMemOpOffset(), llvm_unreachable, llvm::AArch64FrameLowering::needsWinCFI(), llvm::Offset, llvm::CallingConv::PreserveAll, llvm::CallingConv::PreserveMost, produceCompactUnwindFrame(), llvm::SmallVectorTemplateBase< T, bool >::push_back(), Reg, llvm::AArch64FunctionInfo::setCalleeSaveBaseToFrameRecordOffset(), llvm::MachineFrameInfo::setObjectAlignment(), llvm::ArrayRef< T >::size(), TII, TRI, and llvm::CallingConv::Win64.

Referenced by llvm::AArch64FrameLowering::restoreCalleeSavedRegisters(), and llvm::AArch64FrameLowering::spillCalleeSavedRegisters().

◆ determineSVEStackSizes()

◆ enableMultiVectorSpillFill()

◆ estimateRSStackSizeLimit()

unsigned estimateRSStackSizeLimit ( MachineFunction & MF)
static

Look at each instruction that references stack frames and return the stack size limit beyond which some of these instructions will require a scratch register during their expansion later.

Definition at line 431 of file AArch64FrameLowering.cpp.

References llvm::AArch64FrameOffsetCannotUpdate, DefaultSafeSPDisplacement, llvm::isAArch64FrameOffsetLegal(), MBB, MI, and llvm::Offset.

Referenced by llvm::AArch64FrameLowering::determineCalleeSaves(), llvm::ARMFrameLowering::determineCalleeSaves(), and llvm::CSKYFrameLowering::determineCalleeSaves().

◆ findFreePredicateReg()

MCRegister findFreePredicateReg ( BitVector & SavedRegs)

◆ getLdStFrameID()

std::optional< int > getLdStFrameID ( const MachineInstr & MI,
const MachineFrameInfo & MFI )
static

Definition at line 2361 of file AArch64FrameLowering.cpp.

References getMMOFrameID(), and MI.

Referenced by llvm::AArch64FrameLowering::orderFrameObjects().

◆ getLiveRegsForEntryMBB()

◆ getMMOFrameID()

◆ getPrologueDeath()

◆ getRegisterOrZero()

MCRegister getRegisterOrZero ( MCRegister Reg,
bool HasSVE )
static

Definition at line 732 of file AArch64FrameLowering.cpp.

References CASE, and Reg.

◆ getStackHazardSize()

◆ getSVECalleeSaveSlotRange()

bool getSVECalleeSaveSlotRange ( const MachineFrameInfo & MFI,
int & Min,
int & Max )
static

returns true if there are any SVE callee saves.

Definition at line 2996 of file AArch64FrameLowering.cpp.

References assert(), contains(), llvm::MachineFrameInfo::getCalleeSavedInfo(), and llvm::MachineFrameInfo::isCalleeSavedInfoValid().

Referenced by determineSVEStackSizes().

◆ invalidateRegisterPairing()

bool invalidateRegisterPairing ( bool SpillExtendedVolatile,
unsigned SpillCount,
unsigned Reg1,
unsigned Reg2,
bool UsesWinAAPCS,
bool NeedsWinCFI,
bool NeedsFrameRecord,
const TargetRegisterInfo * TRI )
static

Returns true if Reg1 and Reg2 cannot be paired using a ldp/stp instruction.

WindowsCFI requires that only consecutive registers can be paired. LR and FP need to be allocated together when the frame needs to save the frame-record. This means any other register pairing with LR is invalid.

Definition at line 1594 of file AArch64FrameLowering.cpp.

References invalidateWindowsRegisterPairing(), and TRI.

Referenced by computeCalleeSaveRegisterPairs().

◆ invalidateWindowsRegisterPairing()

bool invalidateWindowsRegisterPairing ( bool SpillExtendedVolatile,
unsigned SpillCount,
unsigned Reg1,
unsigned Reg2,
bool NeedsWinCFI,
const TargetRegisterInfo * TRI )
static

Definition at line 1555 of file AArch64FrameLowering.cpp.

References TRI.

Referenced by invalidateRegisterPairing().

◆ isLikelyToHaveSVEStack()

◆ isPPRAccess()

bool isPPRAccess ( const MachineInstr & MI)
static

Definition at line 2370 of file AArch64FrameLowering.cpp.

References MI.

◆ isTargetWindows()

◆ isValidMemOpOffset()

bool isValidMemOpOffset ( const AArch64InstrInfo * TII,
unsigned Opcode,
int Offset )
static

Definition at line 1613 of file AArch64FrameLowering.cpp.

References llvm::Offset, and TII.

Referenced by computeCalleeSaveRegisterPairs().

◆ operator<<()

raw_ostream & operator<< ( raw_ostream & OS,
const StackAccess & SA )
inlinestatic

Definition at line 4127 of file AArch64FrameLowering.cpp.

References StackAccess::print().

◆ orderZPRCalleeSavesForPairs()

◆ produceCompactUnwindFrame()

Variable Documentation

◆ DefaultSafeSPDisplacement

const unsigned DefaultSafeSPDisplacement = 255
static

This is the biggest offset to the stack pointer we can encode in aarch64 instructions (without using a separate calculation and a temp register).

Note that the exception here are vector stores/loads which cannot encode any displacements (see estimateRSStackSizeLimit(), isAArch64FrameOffsetLegal()).

Definition at line 426 of file AArch64FrameLowering.cpp.

Referenced by estimateRSStackSizeLimit(), and llvm::AArch64FrameLowering::hasFPImpl().