LLVM 22.0.0git
ARMFrameLowering.cpp File Reference
#include "ARMFrameLowering.h"
#include "ARMBaseInstrInfo.h"
#include "ARMBaseRegisterInfo.h"
#include "ARMConstantPoolValue.h"
#include "ARMMachineFunctionInfo.h"
#include "ARMSubtarget.h"
#include "MCTargetDesc/ARMAddressingModes.h"
#include "MCTargetDesc/ARMBaseInfo.h"
#include "Utils/ARMBaseInfo.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/CFIInstBuilder.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineJumpTableInfo.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/IR/Attributes.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Function.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <iterator>
#include <utility>
#include <vector>

Go to the source code of this file.

Macros

#define DEBUG_TYPE   "arm-frame-lowering"

Enumerations

enum class  SpillArea {
  GPRCS1 , GPRCS2 , FPStatus , DPRCS1 ,
  DPRCS2 , GPRCS3 , FPCXT
}

Functions

static MachineBasicBlock::iterator skipAlignedDPRCS2Spills (MachineBasicBlock::iterator MI, unsigned NumAlignedDPRCS2Regs)
 Skip past the code inserted by emitAlignedDPRCS2Spills, and return an iterator to the following instruction.
SpillArea getSpillArea (Register Reg, ARMSubtarget::PushPopSplitVariation Variation, unsigned NumAlignedDPRCS2Regs, const ARMBaseRegisterInfo *RegInfo)
 Get the spill area that Reg should be saved into in the prologue.
static int getArgumentStackToRestore (MachineFunction &MF, MachineBasicBlock &MBB)
static bool needsWinCFI (const MachineFunction &MF)
static MachineBasicBlock::iterator insertSEH (MachineBasicBlock::iterator MBBI, const TargetInstrInfo &TII, unsigned Flags)
static MachineBasicBlock::iterator initMBBRange (MachineBasicBlock &MBB, const MachineBasicBlock::iterator &MBBI)
static void insertSEHRange (MachineBasicBlock &MBB, MachineBasicBlock::iterator Start, const MachineBasicBlock::iterator &End, const ARMBaseInstrInfo &TII, unsigned MIFlags)
static void emitRegPlusImmediate (bool isARM, MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &dl, const ARMBaseInstrInfo &TII, unsigned DestReg, unsigned SrcReg, int NumBytes, unsigned MIFlags=MachineInstr::NoFlags, ARMCC::CondCodes Pred=ARMCC::AL, unsigned PredReg=0)
static void emitSPUpdate (bool isARM, MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &dl, const ARMBaseInstrInfo &TII, int NumBytes, unsigned MIFlags=MachineInstr::NoFlags, ARMCC::CondCodes Pred=ARMCC::AL, unsigned PredReg=0)
static int sizeOfSPAdjustment (const MachineInstr &MI)
static bool WindowsRequiresStackProbe (const MachineFunction &MF, size_t StackSizeInBytes)
static void emitAligningInstructions (MachineFunction &MF, ARMFunctionInfo *AFI, const TargetInstrInfo &TII, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, const unsigned Reg, const Align Alignment, const bool MustBeSingleInstruction)
 Emit an instruction sequence that will align the address in register Reg by zero-ing out the lower bits.
static int getMaxFPOffset (const ARMSubtarget &STI, const ARMFunctionInfo &AFI, const MachineFunction &MF)
 We need the offset of the frame pointer relative to other MachineFrameInfo offsets which are encoded relative to SP at function begin.
static void emitAlignedDPRCS2Spills (MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned NumAlignedDPRCS2Regs, ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI)
 Emit aligned spill instructions for NumAlignedDPRCS2Regs D-registers starting from d8.
static void emitAlignedDPRCS2Restores (MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned NumAlignedDPRCS2Regs, ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI)
 Emit aligned reload instructions for NumAlignedDPRCS2Regs D-registers starting from d8.
static unsigned EstimateFunctionSizeInBytes (const MachineFunction &MF, const ARMBaseInstrInfo &TII)
static unsigned estimateRSStackSizeLimit (MachineFunction &MF, const TargetFrameLowering *TFI, bool &HasNonSPFrameIndex)
 estimateRSStackSizeLimit - 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 void checkNumAlignedDPRCS2Regs (MachineFunction &MF, BitVector &SavedRegs)
static bool canSpillOnFrameIndexAccess (const MachineFunction &MF, const TargetFrameLowering &TFI)
static uint32_t alignToARMConstant (uint32_t Value)
 Get the minimum constant for ARM that is greater than or equal to the argument.

Variables

static cl::opt< boolSpillAlignedNEONRegs ("align-neon-spills", cl::Hidden, cl::init(true), cl::desc("Align ARM NEON spills in prolog and epilog"))
static const uint64_t kSplitStackAvailable = 256

Macro Definition Documentation

◆ DEBUG_TYPE

#define DEBUG_TYPE   "arm-frame-lowering"

Definition at line 160 of file ARMFrameLowering.cpp.

Enumeration Type Documentation

◆ SpillArea

enum class SpillArea
strong
Enumerator
GPRCS1 
GPRCS2 
FPStatus 
DPRCS1 
DPRCS2 
GPRCS3 
FPCXT 

Definition at line 172 of file ARMFrameLowering.cpp.

Function Documentation

◆ alignToARMConstant()

uint32_t alignToARMConstant ( uint32_t Value)
static

Get the minimum constant for ARM that is greater than or equal to the argument.

In ARM, constants can have any value that can be produced by rotating an 8-bit value to the right by an even number of bits within a 32-bit word.

Definition at line 3218 of file ARMFrameLowering.cpp.

Referenced by llvm::ARMFrameLowering::adjustForSegmentedStacks().

◆ canSpillOnFrameIndexAccess()

◆ checkNumAlignedDPRCS2Regs()

◆ emitAlignedDPRCS2Restores()

◆ emitAlignedDPRCS2Spills()

◆ emitAligningInstructions()

void emitAligningInstructions ( MachineFunction & MF,
ARMFunctionInfo * AFI,
const TargetInstrInfo & TII,
MachineBasicBlock & MBB,
MachineBasicBlock::iterator MBBI,
const DebugLoc & DL,
const unsigned Reg,
const Align Alignment,
const bool MustBeSingleInstruction )
static

Emit an instruction sequence that will align the address in register Reg by zero-ing out the lower bits.

For versions of the architecture that support Neon, this must be done in a single instruction, since skipAlignedDPRCS2Spills assumes it is done in a single instruction. That function only gets called when optimizing spilling of D registers on a core with the Neon instruction set present.

Definition at line 796 of file ARMFrameLowering.cpp.

References llvm::MachineInstrBuilder::add(), llvm::MachineInstrBuilder::addImm(), llvm::MachineInstrBuilder::addReg(), llvm::ARMCC::AL, assert(), llvm::BuildMI(), llvm::condCodeOp(), DL, llvm::ARM_AM::getSORegOpc(), llvm::MachineFunction::getSubtarget(), llvm::ARMFunctionInfo::isThumb1OnlyFunction(), llvm::ARMFunctionInfo::isThumbFunction(), llvm::RegState::Kill, llvm::Log2(), llvm::ARM_AM::lsl, llvm::ARM_AM::lsr, MBB, MBBI, llvm::predOps(), Reg, TII, and llvm::Align::value().

Referenced by emitAlignedDPRCS2Spills(), and llvm::ARMFrameLowering::emitPrologue().

◆ emitRegPlusImmediate()

void emitRegPlusImmediate ( bool isARM,
MachineBasicBlock & MBB,
MachineBasicBlock::iterator & MBBI,
const DebugLoc & dl,
const ARMBaseInstrInfo & TII,
unsigned DestReg,
unsigned SrcReg,
int NumBytes,
unsigned MIFlags = MachineInstr::NoFlags,
ARMCC::CondCodes Pred = ARMCC::AL,
unsigned PredReg = 0 )
static

◆ emitSPUpdate()

void emitSPUpdate ( bool isARM,
MachineBasicBlock & MBB,
MachineBasicBlock::iterator & MBBI,
const DebugLoc & dl,
const ARMBaseInstrInfo & TII,
int NumBytes,
unsigned MIFlags = MachineInstr::NoFlags,
ARMCC::CondCodes Pred = ARMCC::AL,
unsigned PredReg = 0 )
static

◆ EstimateFunctionSizeInBytes()

◆ estimateRSStackSizeLimit()

◆ getArgumentStackToRestore()

◆ getMaxFPOffset()

int getMaxFPOffset ( const ARMSubtarget & STI,
const ARMFunctionInfo & AFI,
const MachineFunction & MF )
static

We need the offset of the frame pointer relative to other MachineFrameInfo offsets which are encoded relative to SP at function begin.

See also emitPrologue() for how the FP is set up. Unfortunately we cannot determine this value in determineCalleeSaves() yet as assignCalleeSavedSpillSlots() hasn't run at this point. Instead we use this to produce a conservative estimate that we check in an assert() later.

Definition at line 862 of file ARMFrameLowering.cpp.

References llvm::ARMFunctionInfo::getArgRegsSaveSize(), llvm::ARMSubtarget::getPushPopSplitVariation(), llvm::ARMFunctionInfo::isCmseNSEntryFunction(), llvm::ARMFunctionInfo::isThumb1OnlyFunction(), llvm::ARMSubtarget::SplitR11AAPCSSignRA, and llvm::ARMSubtarget::SplitR11WindowsSEH.

Referenced by llvm::ARMFrameLowering::determineCalleeSaves(), and llvm::ARMFrameLowering::emitPrologue().

◆ getSpillArea()

◆ initMBBRange()

Definition at line 643 of file ARMFrameLowering.cpp.

References MBB, and MBBI.

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

◆ insertSEH()

◆ insertSEHRange()

◆ needsWinCFI()

◆ sizeOfSPAdjustment()

int sizeOfSPAdjustment ( const MachineInstr & MI)
static

Definition at line 696 of file ARMFrameLowering.cpp.

References llvm::count(), llvm_unreachable, MI, and RegSize.

Referenced by llvm::ARMFrameLowering::emitPrologue().

◆ skipAlignedDPRCS2Spills()

MachineBasicBlock::iterator skipAlignedDPRCS2Spills ( MachineBasicBlock::iterator MI,
unsigned NumAlignedDPRCS2Regs )
static

Skip past the code inserted by emitAlignedDPRCS2Spills, and return an iterator to the following instruction.

Definition at line 2082 of file ARMFrameLowering.cpp.

References assert(), and MI.

Referenced by llvm::ARMFrameLowering::emitPrologue().

◆ WindowsRequiresStackProbe()

Variable Documentation

◆ kSplitStackAvailable

◆ SpillAlignedNEONRegs

cl::opt< bool > SpillAlignedNEONRegs("align-neon-spills", cl::Hidden, cl::init(true), cl::desc("Align ARM NEON spills in prolog and epilog")) ( "align-neon-spills" ,
cl::Hidden ,
cl::init(true) ,
cl::desc("Align ARM NEON spills in prolog and epilog")  )
static