LLVM  16.0.0git
Macros | Functions | Variables
AArch64FrameLowering.cpp File Reference
#include "AArch64FrameLowering.h"
#include "AArch64InstrInfo.h"
#include "AArch64MachineFunctionInfo.h"
#include "AArch64RegisterInfo.h"
#include "AArch64Subtarget.h"
#include "AArch64TargetMachine.h"
#include "MCTargetDesc/AArch64AddressingModes.h"
#include "MCTargetDesc/AArch64MCTargetDesc.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.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/MC/MCAsmInfo.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include <cassert>
#include <cstdint>
#include <iterator>
#include <optional>
#include <vector>
Include dependency graph for AArch64FrameLowering.cpp:

Go to the source code of this file.

Macros

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

Functions

 STATISTIC (NumRedZoneFunctions, "Number of functions using red zone")
 
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. More...
 
static bool produceCompactUnwindFrame (MachineFunction &MF)
 
static bool needsWinCFI (const MachineFunction &MF)
 
static StackOffset getSVEStackSize (const MachineFunction &MF)
 Returns the size of the entire SVE stackframe (calleesaves + spills). More...
 
static bool needsShadowCallStackPrologueEpilogue (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. More...
 
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 var args area and an UnwindHelp object for EH. More...
 
static void insertCFISameValue (const MCInstrDesc &Desc, MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertPt, unsigned DwarfReg)
 
static void emitCalleeSavedRestores (MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, bool SVE)
 
static MCRegister getRegisterOrZero (MCRegister Reg, bool HasSVE)
 
static unsigned findScratchNonCalleeSaveRegister (MachineBasicBlock *MBB)
 
static bool windowsRequiresStackProbe (MachineFunction &MF, uint64_t StackSizeInBytes)
 
static MachineBasicBlock::iterator InsertSEH (MachineBasicBlock::iterator MBBI, const TargetInstrInfo &TII, MachineInstr::MIFlag Flag)
 
static void fixupSEHOpcode (MachineBasicBlock::iterator MBBI, unsigned LocalStackSize)
 
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 fixupCalleeSaveRestoreStackOffset (MachineInstr &MI, uint64_t LocalStackSize, bool NeedsWinCFI, bool *HasWinCFI)
 
static bool isTargetWindows (const MachineFunction &MF)
 
static bool IsSVECalleeSave (MachineBasicBlock::iterator I)
 
static void emitShadowCallStackPrologue (const TargetInstrInfo &TII, MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, bool NeedsWinCFI, bool NeedsUnwindInfo)
 
static void emitShadowCallStackEpilogue (const TargetInstrInfo &TII, MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL)
 
static void InsertReturnAddressAuth (MachineFunction &MF, MachineBasicBlock &MBB, bool NeedsWinCFI, bool *HasWinCFI)
 
static bool isFuncletReturnInstr (const MachineInstr &MI)
 
static StackOffset getFPOffset (const MachineFunction &MF, int64_t ObjectOffset)
 
static StackOffset getStackOffset (const MachineFunction &MF, int64_t ObjectOffset)
 
static unsigned getPrologueDeath (MachineFunction &MF, unsigned Reg)
 
static bool invalidateWindowsRegisterPairing (unsigned Reg1, unsigned Reg2, bool NeedsWinCFI, bool IsFirst, const TargetRegisterInfo *TRI)
 
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. More...
 
static void computeCalleeSaveRegisterPairs (MachineFunction &MF, ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI, SmallVectorImpl< RegPairInfo > &RegPairs, bool NeedsFrameRecord)
 
static bool getSVECalleeSaveSlotRange (const MachineFrameInfo &MFI, int &Min, int &Max)
 returns true if there are any SVE callee saves. More...
 
static int64_t determineSVEStackObjectOffsets (MachineFrameInfo &MFI, int &MinCSFrameIndex, int &MaxCSFrameIndex, bool AssignOffsets)
 

Variables

static cl::opt< bool > EnableRedZone ("aarch64-redzone", cl::desc("enable use of redzone on AArch64"), cl::init(false), cl::Hidden)
 
static cl::opt< bool > ReverseCSRRestoreSeq ("reverse-csr-restore-seq", cl::desc("reverse the CSR restore sequence"), cl::init(false), cl::Hidden)
 
static cl::opt< bool > StackTaggingMergeSetTag ("stack-tagging-merge-settag", cl::desc("merge settag instruction in function epilog"), cl::init(true), cl::Hidden)
 
static cl::opt< bool > OrderFrameObjects ("aarch64-order-frame-objects", cl::desc("sort stack allocations"), cl::init(true), cl::Hidden)
 
cl::opt< bool > EnableHomogeneousPrologEpilog ("homogeneous-prolog-epilog", cl::Hidden, cl::desc("Emit homogeneous prologue and epilogue for the size " "optimization (default = off)"))
 
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). More...
 

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 236 of file AArch64FrameLowering.cpp.

Function Documentation

◆ computeCalleeSaveRegisterPairs()

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

◆ convertCalleeSaveRestoreToSPPrePostIncDec()

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

◆ determineSVEStackObjectOffsets()

static int64_t determineSVEStackObjectOffsets ( MachineFrameInfo MFI,
int MinCSFrameIndex,
int MaxCSFrameIndex,
bool  AssignOffsets 
)
static

◆ emitCalleeSavedRestores()

static void emitCalleeSavedRestores ( MachineBasicBlock MBB,
MachineBasicBlock::iterator  MBBI,
bool  SVE 
)
static

◆ emitShadowCallStackEpilogue()

static void emitShadowCallStackEpilogue ( const TargetInstrInfo TII,
MachineFunction MF,
MachineBasicBlock MBB,
MachineBasicBlock::iterator  MBBI,
const DebugLoc DL 
)
static

◆ emitShadowCallStackPrologue()

static void emitShadowCallStackPrologue ( const TargetInstrInfo TII,
MachineFunction MF,
MachineBasicBlock MBB,
MachineBasicBlock::iterator  MBBI,
const DebugLoc DL,
bool  NeedsWinCFI,
bool  NeedsUnwindInfo 
)
static

◆ estimateRSStackSizeLimit()

static 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 351 of file AArch64FrameLowering.cpp.

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

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

◆ findScratchNonCalleeSaveRegister()

static unsigned findScratchNonCalleeSaveRegister ( MachineBasicBlock MBB)
static

◆ fixupCalleeSaveRestoreStackOffset()

static void fixupCalleeSaveRestoreStackOffset ( MachineInstr MI,
uint64_t  LocalStackSize,
bool  NeedsWinCFI,
bool *  HasWinCFI 
)
static

◆ fixupSEHOpcode()

static void fixupSEHOpcode ( MachineBasicBlock::iterator  MBBI,
unsigned  LocalStackSize 
)
static

◆ getArgumentStackToRestore()

static int64_t getArgumentStackToRestore ( MachineFunction MF,
MachineBasicBlock MBB 
)
static

Returns how much of the incoming argument stack area (in bytes) we should clean up in an epilogue.

For the C calling convention this will be 0, for guaranteed tail call conventions it can be positive (a normal return or a tail call to a function that uses less stack space for arguments) or negative (for a tail call to a function that needs more stack space than us for arguments).

Definition at line 269 of file AArch64FrameLowering.cpp.

References llvm::MachineBasicBlock::end(), llvm::AArch64FunctionInfo::getArgumentStackToRestore(), llvm::MachineOperand::getImm(), llvm::MachineFunction::getInfo(), llvm::MachineBasicBlock::getLastNonDebugInstr(), MBB, and MBBI.

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

◆ getFixedObjectSize()

static unsigned getFixedObjectSize ( const MachineFunction MF,
const AArch64FunctionInfo AFI,
bool  IsWin64,
bool  IsFunclet 
)
static

◆ getFPOffset()

static StackOffset getFPOffset ( const MachineFunction MF,
int64_t  ObjectOffset 
)
static

◆ getPrologueDeath()

static unsigned getPrologueDeath ( MachineFunction MF,
unsigned  Reg 
)
static

◆ getRegisterOrZero()

static MCRegister getRegisterOrZero ( MCRegister  Reg,
bool  HasSVE 
)
static

Definition at line 674 of file AArch64FrameLowering.cpp.

References CASE.

◆ getStackOffset()

static StackOffset getStackOffset ( const MachineFunction MF,
int64_t  ObjectOffset 
)
static

◆ getSVECalleeSaveSlotRange()

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

◆ getSVEStackSize()

static StackOffset getSVEStackSize ( const MachineFunction MF)
static

◆ insertCFISameValue()

static void insertCFISameValue ( const MCInstrDesc Desc,
MachineFunction MF,
MachineBasicBlock MBB,
MachineBasicBlock::iterator  InsertPt,
unsigned  DwarfReg 
)
static

◆ InsertReturnAddressAuth()

static void InsertReturnAddressAuth ( MachineFunction MF,
MachineBasicBlock MBB,
bool  NeedsWinCFI,
bool *  HasWinCFI 
)
static

◆ InsertSEH()

◆ invalidateRegisterPairing()

static bool invalidateRegisterPairing ( unsigned  Reg1,
unsigned  Reg2,
bool  UsesWinAAPCS,
bool  NeedsWinCFI,
bool  NeedsFrameRecord,
bool  IsFirst,
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 2485 of file AArch64FrameLowering.cpp.

References invalidateWindowsRegisterPairing(), and TRI.

Referenced by computeCalleeSaveRegisterPairs().

◆ invalidateWindowsRegisterPairing()

static bool invalidateWindowsRegisterPairing ( unsigned  Reg1,
unsigned  Reg2,
bool  NeedsWinCFI,
bool  IsFirst,
const TargetRegisterInfo TRI 
)
static

◆ isFuncletReturnInstr()

static bool isFuncletReturnInstr ( const MachineInstr MI)
static

◆ IsSVECalleeSave()

static bool IsSVECalleeSave ( MachineBasicBlock::iterator  I)
static

◆ isTargetWindows()

static bool isTargetWindows ( const MachineFunction MF)
static

◆ needsShadowCallStackPrologueEpilogue()

static bool needsShadowCallStackPrologueEpilogue ( MachineFunction MF)
static

◆ needsWinCFI()

static bool needsWinCFI ( const MachineFunction MF)
static

◆ produceCompactUnwindFrame()

static bool produceCompactUnwindFrame ( MachineFunction MF)
static

◆ STATISTIC()

STATISTIC ( NumRedZoneFunctions  ,
"Number of functions using red zone"   
)

◆ windowsRequiresStackProbe()

static bool windowsRequiresStackProbe ( MachineFunction MF,
uint64_t  StackSizeInBytes 
)
static

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 346 of file AArch64FrameLowering.cpp.

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

◆ EnableHomogeneousPrologEpilog

cl::opt<bool> EnableHomogeneousPrologEpilog("homogeneous-prolog-epilog", cl::Hidden, cl::desc("Emit homogeneous prologue and epilogue for the size " "optimization (default = off)"))

◆ EnableRedZone

cl::opt<bool> EnableRedZone("aarch64-redzone", cl::desc("enable use of redzone on AArch64"), cl::init(false), cl::Hidden)
static

◆ OrderFrameObjects

cl::opt<bool> OrderFrameObjects("aarch64-order-frame-objects", cl::desc("sort stack allocations"), cl::init(true), cl::Hidden)
static

◆ ReverseCSRRestoreSeq

cl::opt<bool> ReverseCSRRestoreSeq("reverse-csr-restore-seq", cl::desc("reverse the CSR restore sequence"), cl::init(false), cl::Hidden)
static

◆ StackTaggingMergeSetTag

cl::opt<bool> StackTaggingMergeSetTag("stack-tagging-merge-settag", cl::desc("merge settag instruction in function epilog"), cl::init(true), cl::Hidden)
static
llvm::RISCVFenceField::W
@ W
Definition: RISCVBaseInfo.h:266
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
X
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
D
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
H
#define H(x, y, z)
Definition: MD5.cpp:57
llvm::ARCCC::Z
@ Z
Definition: ARCInfo.h:41
n
The same transformation can work with an even modulo with the addition of a and shrink the compare RHS by the same amount Unless the target supports that transformation probably isn t worthwhile The transformation can also easily be made to work with non zero equality for n
Definition: README.txt:685