Go to the documentation of this file.
60 if (CFSize >= ((1 << 8) - 1) * 4 / 2)
71 unsigned ScratchReg,
unsigned MIFlags) {
79 if (ScratchReg == ARM::NoRegister)
83 if (
ST.genExecuteOnly()) {
127 unsigned Amount =
TII.getFrameSize(Old);
136 if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
139 assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP);
161 assert(NumBytes >= ArgRegsSaveSize &&
162 "ArgRegsSaveSize is included in NumBytes");
174 NumBytes = (NumBytes + 3) & ~3;
179 unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
180 int FramePtrSpillFI = 0;
182 if (ArgRegsSaveSize) {
185 CFAOffset += ArgRegsSaveSize;
194 if (NumBytes - ArgRegsSaveSize != 0) {
196 -(NumBytes - ArgRegsSaveSize),
198 CFAOffset += NumBytes - ArgRegsSaveSize;
210 int FI =
I.getFrameIdx();
227 FramePtrSpillFI = FI;
240 unsigned DPRCSOffset = NumBytes - ArgRegsSaveSize - (GPRCS1Size + GPRCS2Size + DPRCSSize);
241 unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize;
242 unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size;
243 bool HasFP =
hasFP(MF);
250 NumBytes = DPRCSOffset;
252 int FramePtrOffsetInBlock = 0;
253 unsigned adjustedGPRCS1Size = GPRCS1Size;
254 if (GPRCS1Size > 0 && GPRCS2Size == 0 &&
256 FramePtrOffsetInBlock = NumBytes;
257 adjustedGPRCS1Size += NumBytes;
261 if (adjustedGPRCS1Size) {
262 CFAOffset += adjustedGPRCS1Size;
271 int FI =
I.getFrameIdx();
301 FramePtrOffsetInBlock +=
305 .
addImm(FramePtrOffsetInBlock / 4)
308 if(FramePtrOffsetInBlock) {
309 CFAOffset -= FramePtrOffsetInBlock;
311 nullptr,
MRI->getDwarfRegNum(
FramePtr,
true), CFAOffset));
350 for (
auto &
I : CSI) {
352 int FI =
I.getFrameIdx();
377 unsigned ScratchRegister = ARM::NoRegister;
378 for (
auto &
I : CSI) {
381 ScratchRegister =
Reg;
388 CFAOffset += NumBytes;
405 if (RegInfo->hasStackRealignment(MF)) {
469 assert((
unsigned)NumBytes >= ArgRegsSaveSize &&
470 "ArgRegsSaveSize is included in NumBytes");
474 if (NumBytes - ArgRegsSaveSize != 0)
476 NumBytes - ArgRegsSaveSize, ARM::NoRegister,
501 "No scratch register to restore SP from FP!");
517 unsigned ScratchRegister = ARM::NoRegister;
518 bool HasFP =
hasFP(MF);
522 ScratchRegister =
Reg;
538 if (needPopSpecialFixUp(MF)) {
539 bool Done = emitPopSpecialFixUp(
MBB,
true);
541 assert(Done &&
"Emission of the special fixup failed!?");
550 return emitPopSpecialFixUp(*TmpMBB,
false);
553 bool Thumb1FrameLowering::needPopSpecialFixUp(
const MachineFunction &MF)
const {
561 if (CSI.getReg() == ARM::LR)
604 bool CanRestoreDirectly =
STI.hasV5TOps() && !ArgRegsSaveSize;
605 if (CanRestoreDirectly) {
607 CanRestoreDirectly = (
MBBI->getOpcode() == ARM::tBX_RET ||
608 MBBI->getOpcode() == ARM::tPOP_RET);
610 auto MBBI_prev =
MBBI;
612 assert(MBBI_prev->getOpcode() == ARM::tPOP);
614 if ((*
MBB.
succ_begin())->begin()->getOpcode() == ARM::tBX_RET)
617 CanRestoreDirectly =
false;
621 if (CanRestoreDirectly) {
622 if (!DoIt ||
MBBI->getOpcode() == ARM::tPOP_RET)
629 for (
auto MO:
MBBI->operands())
630 if (MO.isReg() && (MO.isImplicit() || MO.isDef()))
642 UsedRegs.addLiveOuts(
MBB);
648 for (
unsigned i = 0; CSRegs[
i]; ++
i)
649 UsedRegs.addReg(CSRegs[
i]);
653 dl =
MBBI->getDebugLoc();
654 auto InstUpToMBBI =
MBB.
end();
655 while (InstUpToMBBI !=
MBBI)
658 UsedRegs.stepBackward(*--InstUpToMBBI);
664 unsigned TemporaryReg = 0;
671 PopFriendly.
set(ARM::R7);
673 assert(PopFriendly.
any() &&
"No allocatable pop-friendly register?!");
678 GPRsNoLRSP |= PopFriendly;
679 GPRsNoLRSP.
reset(ARM::LR);
680 GPRsNoLRSP.
reset(ARM::SP);
681 GPRsNoLRSP.
reset(ARM::PC);
688 bool UseLDRSP =
false;
690 auto PrevMBBI =
MBBI;
692 if (PrevMBBI->getOpcode() == ARM::tPOP) {
693 UsedRegs.stepBackward(*PrevMBBI);
703 if (!DoIt && !PopReg && !TemporaryReg)
706 assert((PopReg || TemporaryReg) &&
"Cannot get LR");
709 assert(PopReg &&
"Do not know how to get LR");
727 ArgRegsSaveSize + 4, ARM::NoRegister,
733 assert(!PopReg &&
"Unnecessary MOV is about to be inserted");
750 for (
auto MO:
MBBI->operands())
751 if (MO.isReg() && (MO.isImplicit() || MO.isDef()) &&
752 MO.getReg() != ARM::PC) {
754 if (!MO.isImplicit())
767 assert(PopReg &&
"Do not know how to get LR");
799 const unsigned *OrderEnd) {
800 while (CurrentReg != OrderEnd && !EnabledRegs[*CurrentReg])
826 LoRegsToSave[
Reg] =
true;
828 HiRegsToSave[
Reg] =
true;
836 CopyRegs[
Reg] =
true;
840 for (
unsigned ArgReg : {ARM::R0, ARM::R1,
ARM::R2, ARM::R3})
842 CopyRegs[ArgReg] =
true;
846 if (!LoRegsToSave.none()) {
850 if (LoRegsToSave[
Reg]) {
870 static const unsigned AllCopyRegs[] = {ARM::LR, ARM::R7,
ARM::R6,
873 static const unsigned AllHighRegs[] = {ARM::R11, ARM::R10, ARM::R9, ARM::R8};
875 const unsigned *AllCopyRegsEnd =
std::end(AllCopyRegs);
876 const unsigned *AllHighRegsEnd =
std::end(AllHighRegs);
880 std::begin(AllHighRegs), HiRegsToSave, AllHighRegsEnd);
882 while (HiRegToSave != AllHighRegsEnd) {
884 const unsigned *CopyReg =
893 while (HiRegToSave != AllHighRegsEnd && CopyReg != AllCopyRegsEnd) {
894 if (HiRegsToSave[*HiRegToSave]) {
907 RegsToPush.push_back(*CopyReg);
950 LoRegsToRestore[
Reg] =
true;
952 HiRegsToRestore[
Reg] =
true;
961 CopyRegs[
Reg] =
true;
968 CopyRegs[ARM::R0] =
true;
969 CopyRegs[ARM::R1] =
true;
971 CopyRegs[ARM::R3] =
true;
974 CopyRegs[
Op.getReg()] =
false;
978 static const unsigned AllCopyRegs[] = {ARM::R0, ARM::R1,
ARM::R2, ARM::R3,
980 static const unsigned AllHighRegs[] = {ARM::R8, ARM::R9, ARM::R10, ARM::R11};
982 const unsigned *AllCopyRegsEnd =
std::end(AllCopyRegs);
983 const unsigned *AllHighRegsEnd =
std::end(AllHighRegs);
987 HiRegsToRestore, AllHighRegsEnd);
989 while (HiRegToRestore != AllHighRegsEnd) {
1000 while (HiRegToRestore != AllHighRegsEnd && CopyReg != AllCopyRegsEnd) {
1021 bool NeedsPop =
false;
1029 if (
Reg == ARM::LR) {
1030 Info.setRestored(
false);
1032 MI->getOpcode() == ARM::TCRETURNdi ||
1033 MI->getOpcode() == ARM::TCRETURNri)
1045 if (!
STI.hasV5TOps())
1054 (*MIB).setDesc(
TII.get(ARM::tPOP_RET));
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...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
unsigned succ_size() const
ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
This is an optimization pass for GlobalISel generic memory operations.
const MachineInstrBuilder & copyImplicitOps(const MachineInstr &OtherMI) const
Copy all the implicit operands from OtherMI onto this one.
void setGPRCalleeSavedArea2Size(unsigned s)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const MachineInstrBuilder & add(const MachineOperand &MO) const
bool shouldRestoreSPFromFP() const
void setGPRCalleeSavedArea1Size(unsigned s)
Thumb1FrameLowering(const ARMSubtarget &sti)
const MachineInstrBuilder & addCFIIndex(unsigned CFIIndex) const
return AArch64::GPR64RegClass contains(Reg)
Reg
All possible values of the reg field in the ModR/M byte.
BitVector getAllocatableSet(const MachineFunction &MF, const TargetRegisterClass *RC=nullptr) const
Returns a bitset indexed by register number indicating if a register is allocatable or not.
unsigned getGPRCalleeSavedArea1Size() const
static void emitPrologueEpilogueSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const TargetInstrInfo &TII, const DebugLoc &dl, const ThumbRegisterInfo &MRI, int NumBytes, unsigned ScratchReg, unsigned MIFlags)
iterator_range< const_set_bits_iterator > set_bits() const
int getOffsetAdjustment() const
Return the correction for frame offsets.
unsigned getGPRCalleeSavedArea2Size() const
A set of physical registers with utility functions to track liveness when walking backward/forward th...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
bool canUseAsEpilogue(const MachineBasicBlock &MBB) const override
Check whether or not the given MBB can be used as a epilogue for the target.
void setStackSize(uint64_t Size)
Set the size of the stack.
auto reverse(ContainerTy &&C, std::enable_if_t< has_rbegin< ContainerTy >::value > *=nullptr)
const_iterator end(StringRef path)
Get end iterator over path.
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
const ARMBaseInstrInfo * getInstrInfo() const override
unsigned const TargetRegisterInfo * TRI
unsigned getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
bool empty() const
empty - Check if the array is empty.
static MCCFIInstruction cfiDefCfaOffset(MCSymbol *L, int Offset)
.cfi_def_cfa_offset modifies a rule for computing CFA.
Register getBaseRegister() const
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
unsigned getDPRCalleeSavedAreaSize() const
bool isCmseNSEntryFunction() const
virtual const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const =0
Return a null-terminated list of all of the callee-saved registers on this target.
static void findTemporariesForLR(const BitVector &GPRsNoLRSP, const BitVector &PopFriendly, const LivePhysRegs &UsedRegs, unsigned &PopReg, unsigned &TmpReg, MachineRegisterInfo &MRI)
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
bool splitFramePushPop(const MachineFunction &MF) const
Returns true if the frame setup is split into two separate pushes (first r0-r7,lr then r8-r11),...
unsigned getDefRegState(bool B)
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
TargetInstrInfo - Interface to description of machine instruction set.
void setShouldRestoreSPFromFP(bool s)
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
Register getFrameRegister(const MachineFunction &MF) const override
bool isReserved(MCRegister PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
void setDPRCalleeSavedAreaSize(unsigned s)
unsigned Log2(Align A)
Returns the log2 of the alignment.
Clang compiles this i1 i64 store i64 i64 store i64 i64 store i64 i64 store i64 align Which gets codegen d xmm0 movaps rbp movaps rbp movaps rbp movaps rbp rbp rbp rbp rbp It would be better to have movq s of instead of the movaps s LLVM produces ret int
@ Kill
The last use of a register.
void deleteMachineInstr(MachineInstr *MI)
DeleteMachineInstr - Delete the given MachineInstr.
const MachineFunctionProperties & getProperties() const
Get the function properties.
static void emitCallSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const TargetInstrInfo &TII, const DebugLoc &dl, const ThumbRegisterInfo &MRI, int NumBytes, unsigned MIFlags=MachineInstr::NoFlags)
static const unsigned FramePtr
const HexagonInstrInfo * TII
unsigned getFramePtrSpillOffset() const
This class contains meta information specific to a module.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
Analysis containing CSE Info
static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register)
.cfi_def_cfa_register modifies a rule for computing CFA.
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register.
MachineModuleInfo & getMMI() const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
const TargetRegisterClass * getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
Representation of each machine instruction.
bool any() const
any - Returns true if any bit is set.
bool available(const MachineRegisterInfo &MRI, MCPhysReg Reg) const
Returns true if register Reg and no aliasing register is in the set.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
MCPhysReg getFramePointerReg() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
succ_iterator succ_begin()
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
bool tryFoldSPUpdateIntoPushPop(const ARMSubtarget &Subtarget, MachineFunction &MF, MachineInstr *MI, unsigned NumBytes)
Tries to add registers to the reglist of a given base-updating push/pop instruction to adjust the sta...
static MCCFIInstruction cfiDefCfa(MCSymbol *L, unsigned Register, int Offset)
.cfi_def_cfa defines a rule for computing CFA as: take address from Register and add Offset to it.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
void setFramePtrSpillOffset(unsigned o)
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
const ARMBaseRegisterInfo * getRegisterInfo() const override
MachineBasicBlock MachineBasicBlock::iterator MBBI
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
void setGPRCalleeSavedArea2Offset(unsigned o)
BitVector getPristineRegs(const MachineFunction &MF) const
Return a set of physical registers that are pristine.
MachineFunctionProperties & reset(Property P)
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
unsigned const MachineRegisterInfo * MRI
void setGPRCalleeSavedArea1Offset(unsigned o)
Align getMaxAlign() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
Wrapper class representing virtual and physical registers.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
bool test(unsigned Idx) const
bool isLiveIn(Register Reg) const
std::bitset< ARM::NUM_TARGET_REGS > ARMRegSet
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
void setDPRCalleeSavedAreaOffset(unsigned o)
@ Define
Register definition.
bool hasReservedCallFrame(const MachineFunction &MF) const override
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
unsigned getKillRegState(bool B)
LLVM_NODISCARD unsigned addFrameInst(const MCCFIInstruction &Inst)
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const override
This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy p...
bool hasStackFrame() const
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
int find_first() const
find_first - Returns the index of the first set bit, -1 if none of the bits are set.
void emitThumbRegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &dl, Register DestReg, Register BaseReg, int NumBytes, const TargetInstrInfo &TII, const ARMBaseRegisterInfo &MRI, unsigned MIFlags=0)
emitThumbRegPlusImmediate - Emits a series of instructions to materialize a destreg = basereg + immed...
unsigned getArgRegsSaveSize() const
bool hasBasePointer(const MachineFunction &MF) const
static bool isARMLowRegister(unsigned Reg)
isARMLowRegister - Returns true if the register is a low register (r0-r7).
void setOffsetAdjustment(int Adj)
Set the correction for frame offsets.
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int Offset)
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
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...
APFloat abs(APFloat X)
Returns the absolute value of the argument.
static const unsigned * findNextOrderedReg(const unsigned *CurrentReg, const ARMRegSet &EnabledRegs, const unsigned *OrderEnd)