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;
208 for (
unsigned i = 0,
e = CSI.size();
i !=
e; ++
i) {
209 unsigned Reg = CSI[
i].getReg();
210 int FI = CSI[
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;
269 for (std::vector<CalleeSavedInfo>::const_iterator
I = CSI.begin(),
270 E = CSI.end();
I !=
E; ++
I) {
271 unsigned Reg =
I->getReg();
272 int FI =
I->getFrameIdx();
302 FramePtrOffsetInBlock +=
306 .
addImm(FramePtrOffsetInBlock / 4)
309 if(FramePtrOffsetInBlock) {
310 CFAOffset -= FramePtrOffsetInBlock;
312 nullptr,
MRI->getDwarfRegNum(
FramePtr,
true), CFAOffset));
351 for (
auto &
I : CSI) {
352 unsigned Reg =
I.getReg();
353 int FI =
I.getFrameIdx();
378 unsigned ScratchRegister = ARM::NoRegister;
379 for (
auto &
I : CSI) {
380 unsigned Reg =
I.getReg();
382 ScratchRegister =
Reg;
389 CFAOffset += NumBytes;
406 if (RegInfo->hasStackRealignment(MF)) {
458 if (
MI.getOpcode() == ARM::tLDRspi &&
MI.getOperand(1).isFI() &&
461 else if (
MI.getOpcode() == ARM::tPOP) {
463 }
else if (
MI.getOpcode() == ARM::tMOVr) {
466 return ((ARM::tGPRRegClass.
contains(Src) || Src == ARM::LR) &&
485 assert((
unsigned)NumBytes >= ArgRegsSaveSize &&
486 "ArgRegsSaveSize is included in NumBytes");
487 const MCPhysReg *CSRegs = RegInfo->getCalleeSavedRegs(&MF);
491 if (NumBytes - ArgRegsSaveSize != 0)
493 NumBytes - ArgRegsSaveSize, ARM::NoRegister,
518 "No scratch register to restore SP from FP!");
532 unsigned ScratchRegister = ARM::NoRegister;
533 bool HasFP =
hasFP(MF);
535 unsigned Reg =
I.getReg();
537 ScratchRegister =
Reg;
553 if (needPopSpecialFixUp(MF)) {
554 bool Done = emitPopSpecialFixUp(
MBB,
true);
556 assert(Done &&
"Emission of the special fixup failed!?");
565 return emitPopSpecialFixUp(*TmpMBB,
false);
568 bool Thumb1FrameLowering::needPopSpecialFixUp(
const MachineFunction &MF)
const {
576 if (CSI.getReg() == ARM::LR)
619 bool CanRestoreDirectly =
STI.
hasV5TOps() && !ArgRegsSaveSize;
620 if (CanRestoreDirectly) {
622 CanRestoreDirectly = (
MBBI->getOpcode() == ARM::tBX_RET ||
623 MBBI->getOpcode() == ARM::tPOP_RET);
625 auto MBBI_prev =
MBBI;
627 assert(MBBI_prev->getOpcode() == ARM::tPOP);
629 if ((*
MBB.
succ_begin())->begin()->getOpcode() == ARM::tBX_RET)
632 CanRestoreDirectly =
false;
636 if (CanRestoreDirectly) {
637 if (!DoIt ||
MBBI->getOpcode() == ARM::tPOP_RET)
643 for (
auto MO:
MBBI->operands())
644 if (MO.isReg() && (MO.isImplicit() || MO.isDef()))
656 UsedRegs.addLiveOuts(
MBB);
662 for (
unsigned i = 0; CSRegs[
i]; ++
i)
663 UsedRegs.addReg(CSRegs[
i]);
667 dl =
MBBI->getDebugLoc();
668 auto InstUpToMBBI =
MBB.
end();
669 while (InstUpToMBBI !=
MBBI)
672 UsedRegs.stepBackward(*--InstUpToMBBI);
678 unsigned TemporaryReg = 0;
685 PopFriendly.
set(ARM::R7);
687 assert(PopFriendly.
any() &&
"No allocatable pop-friendly register?!");
692 GPRsNoLRSP |= PopFriendly;
693 GPRsNoLRSP.
reset(ARM::LR);
694 GPRsNoLRSP.
reset(ARM::SP);
695 GPRsNoLRSP.
reset(ARM::PC);
701 bool UseLDRSP =
false;
703 auto PrevMBBI =
MBBI;
705 if (PrevMBBI->getOpcode() == ARM::tPOP) {
706 UsedRegs.stepBackward(*PrevMBBI);
715 if (!DoIt && !PopReg && !TemporaryReg)
718 assert((PopReg || TemporaryReg) &&
"Cannot get LR");
721 assert(PopReg &&
"Do not know how to get LR");
737 ArgRegsSaveSize + 4, ARM::NoRegister,
743 assert(!PopReg &&
"Unnecessary MOV is about to be inserted");
758 for (
auto MO:
MBBI->operands())
759 if (MO.isReg() && (MO.isImplicit() || MO.isDef()) &&
760 MO.getReg() != ARM::PC) {
762 if (!MO.isImplicit())
774 assert(PopReg &&
"Do not know how to get LR");
803 const unsigned *OrderEnd) {
804 while (CurrentReg != OrderEnd && !EnabledRegs[*CurrentReg])
826 for (
unsigned i = CSI.
size();
i != 0; --
i) {
827 unsigned Reg = CSI[
i-1].getReg();
830 LoRegsToSave[
Reg] =
true;
832 HiRegsToSave[
Reg] =
true;
840 CopyRegs[
Reg] =
true;
844 for (
unsigned ArgReg : {ARM::R0, ARM::R1,
ARM::R2, ARM::R3})
846 CopyRegs[ArgReg] =
true;
850 if (!LoRegsToSave.none()) {
854 if (LoRegsToSave[
Reg]) {
874 static const unsigned AllCopyRegs[] = {ARM::LR, ARM::R7,
ARM::R6,
877 static const unsigned AllHighRegs[] = {ARM::R11, ARM::R10, ARM::R9, ARM::R8};
879 const unsigned *AllCopyRegsEnd =
std::end(AllCopyRegs);
880 const unsigned *AllHighRegsEnd =
std::end(AllHighRegs);
884 std::begin(AllHighRegs), HiRegsToSave, AllHighRegsEnd);
886 while (HiRegToSave != AllHighRegsEnd) {
888 const unsigned *CopyReg =
897 while (HiRegToSave != AllHighRegsEnd && CopyReg != AllCopyRegsEnd) {
898 if (HiRegsToSave[*HiRegToSave]) {
911 RegsToPush.push_back(*CopyReg);
951 unsigned Reg =
I.getReg();
954 LoRegsToRestore[
Reg] =
true;
956 HiRegsToRestore[
Reg] =
true;
965 CopyRegs[
Reg] =
true;
972 CopyRegs[ARM::R0] =
true;
973 CopyRegs[ARM::R1] =
true;
975 CopyRegs[ARM::R3] =
true;
978 CopyRegs[
Op.getReg()] =
false;
982 static const unsigned AllCopyRegs[] = {ARM::R0, ARM::R1,
ARM::R2, ARM::R3,
984 static const unsigned AllHighRegs[] = {ARM::R8, ARM::R9, ARM::R10, ARM::R11};
986 const unsigned *AllCopyRegsEnd =
std::end(AllCopyRegs);
987 const unsigned *AllHighRegsEnd =
std::end(AllHighRegs);
991 HiRegsToRestore, AllHighRegsEnd);
993 while (HiRegToRestore != AllHighRegsEnd) {
1003 while (HiRegToRestore != AllHighRegsEnd && CopyReg != AllCopyRegsEnd) {
1022 bool NeedsPop =
false;
1023 for (
unsigned i = CSI.size();
i != 0; --
i) {
1031 if (
Reg == ARM::LR) {
1032 Info.setRestored(
false);
1034 MI->getOpcode() == ARM::TCRETURNdi ||
1035 MI->getOpcode() == ARM::TCRETURNri)
1056 (*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.
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)
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
static void findTemporariesForLR(const BitVector &GPRsNoLRSP, const BitVector &PopFriendly, const LivePhysRegs &UsedRegs, unsigned &PopReg, unsigned &TmpReg)
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.
bool contains(MCPhysReg Reg) const
Returns true if register Reg is contained in the set.
const ARMBaseInstrInfo * getInstrInfo() const override
bool useR7AsFramePointer() const
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.
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...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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
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.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
@ Define
Register definition.
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
@ Kill
The last use of a register.
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 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.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
static bool isCalleeSavedRegister(unsigned Reg, const MCPhysReg *CSRegs)
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)
bool hasReservedCallFrame(const MachineFunction &MF) const override
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
static bool isCSRestore(MachineInstr &MI, const MCPhysReg *CSRegs)
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...
size_t size() const
size - Get the array size.
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)