46#define DEBUG_TYPE "arm-frame-lowering"
60 if (CFSize >= ((1 << 8) - 1) * 4 / 2)
71 unsigned ScratchReg,
unsigned MIFlags) {
74 if (std::abs(NumBytes) > 508 * 3) {
79 if (ScratchReg == ARM::NoRegister)
83 if (ST.genExecuteOnly()) {
84 unsigned XOInstr = ST.useMovt() ? ARM::t2MOVi32imm : ARM::tMOVi32imm;
128 unsigned Amount =
TII.getFrameSize(Old);
137 if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
140 assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP);
161 assert(NumBytes >= ArgRegsSaveSize &&
162 "ArgRegsSaveSize is included in NumBytes");
165 "Must use R7 spilt for Thumb1");
176 NumBytes = (NumBytes + 3) & ~3;
181 unsigned FRSize = 0, GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
182 int FramePtrSpillFI = 0;
184 if (ArgRegsSaveSize) {
187 CFAOffset += ArgRegsSaveSize;
196 if (NumBytes - ArgRegsSaveSize != 0) {
198 -(NumBytes - ArgRegsSaveSize),
200 CFAOffset += NumBytes - ArgRegsSaveSize;
210 bool HasFrameRecordArea =
hasFP(MF) && ARM::hGPRRegClass.contains(
FramePtr);
214 int FI =
I.getFrameIdx();
216 FramePtrSpillFI = FI;
219 if (HasFrameRecordArea) {
230 if (HasFrameRecordArea) {
247 if (HasFrameRecordArea) {
252 std::advance(
MBBI, 2);
290 MBBI->getOperand(0).getReg() == ARM::LR &&
297 unsigned DPRCSOffset = NumBytes - ArgRegsSaveSize -
298 (FRSize + GPRCS1Size + GPRCS2Size + DPRCSSize);
299 unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize;
300 unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size;
301 bool HasFP =
hasFP(MF);
305 if (HasFrameRecordArea)
310 NumBytes = DPRCSOffset;
312 int FramePtrOffsetInBlock = 0;
313 unsigned adjustedGPRCS1Size = GPRCS1Size;
314 if (GPRCS1Size > 0 && GPRCS2Size == 0 &&
316 FramePtrOffsetInBlock = NumBytes;
317 adjustedGPRCS1Size += NumBytes;
320 CFAOffset += adjustedGPRCS1Size;
325 HasFrameRecordArea ? std::next(FRPush) : std::next(GPRCS1Push);
326 if (HasFrameRecordArea) {
334 FramePtrOffsetInBlock +=
338 .
addImm(FramePtrOffsetInBlock / 4)
343 if(FramePtrOffsetInBlock) {
345 nullptr,
MRI->getDwarfRegNum(
FramePtr,
true), (CFAOffset - FramePtrOffsetInBlock)));
346 BuildMI(
MBB, AfterPush, dl,
TII.get(TargetOpcode::CFI_INSTRUCTION))
353 BuildMI(
MBB, AfterPush, dl,
TII.get(TargetOpcode::CFI_INSTRUCTION))
364 if (GPRCS1Size > 0) {
366 if (adjustedGPRCS1Size) {
369 BuildMI(
MBB, Pos, dl,
TII.get(TargetOpcode::CFI_INSTRUCTION))
375 int FI =
I.getFrameIdx();
394 BuildMI(
MBB, Pos, dl,
TII.get(TargetOpcode::CFI_INSTRUCTION))
403 if (GPRCS2Size > 0) {
405 for (
auto &
I : CSI) {
407 int FI =
I.getFrameIdx();
416 BuildMI(
MBB, Pos, dl,
TII.get(TargetOpcode::CFI_INSTRUCTION))
433 unsigned ScratchRegister = ARM::NoRegister;
434 for (
auto &
I : CSI) {
437 ScratchRegister = Reg;
444 CFAOffset += NumBytes;
461 if (RegInfo->hasStackRealignment(MF)) {
525 assert((
unsigned)NumBytes >= ArgRegsSaveSize &&
526 "ArgRegsSaveSize is included in NumBytes");
530 if (NumBytes - ArgRegsSaveSize != 0)
532 NumBytes - ArgRegsSaveSize, ARM::NoRegister,
552 unsigned ScratchRegister = ARM::NoRegister;
553 bool HasFP =
hasFP(MF);
557 ScratchRegister = Reg;
568 assert(ScratchRegister != ARM::NoRegister &&
569 "No scratch register to restore SP from FP!");
594 if (needPopSpecialFixUp(MF)) {
595 bool Done = emitPopSpecialFixUp(
MBB,
true);
597 assert(
Done &&
"Emission of the special fixup failed!?");
606 return emitPopSpecialFixUp(*TmpMBB,
false);
609bool Thumb1FrameLowering::needPopSpecialFixUp(
const MachineFunction &MF)
const {
617 if (CSI.getReg() == ARM::LR)
628 for (
auto Reg : GPRsNoLRSP.
set_bits()) {
631 if (PopFriendly.
test(Reg)) {
660 bool CanRestoreDirectly =
STI.hasV5TOps() && !ArgRegsSaveSize;
661 if (CanRestoreDirectly) {
663 CanRestoreDirectly = (
MBBI->getOpcode() == ARM::tBX_RET ||
664 MBBI->getOpcode() == ARM::tPOP_RET);
666 auto MBBI_prev =
MBBI;
668 assert(MBBI_prev->getOpcode() == ARM::tPOP);
670 if ((*
MBB.
succ_begin())->begin()->getOpcode() == ARM::tBX_RET)
673 CanRestoreDirectly =
false;
677 if (CanRestoreDirectly) {
678 if (!DoIt ||
MBBI->getOpcode() == ARM::tPOP_RET)
685 for (
auto MO:
MBBI->operands())
686 if (MO.isReg() && (MO.isImplicit() || MO.isDef()))
698 UsedRegs.addLiveOuts(
MBB);
704 for (
unsigned i = 0; CSRegs[i]; ++i)
705 UsedRegs.addReg(CSRegs[i]);
709 dl =
MBBI->getDebugLoc();
710 auto InstUpToMBBI =
MBB.
end();
711 while (InstUpToMBBI !=
MBBI)
714 UsedRegs.stepBackward(*--InstUpToMBBI);
720 unsigned TemporaryReg = 0;
722 TRI.getAllocatableSet(MF,
TRI.getRegClass(ARM::tGPRRegClassID));
724 assert(PopFriendly.
any() &&
"No allocatable pop-friendly register?!");
728 TRI.getAllocatableSet(MF,
TRI.getRegClass(ARM::hGPRRegClassID));
729 GPRsNoLRSP |= PopFriendly;
730 GPRsNoLRSP.
reset(ARM::LR);
731 GPRsNoLRSP.
reset(ARM::SP);
732 GPRsNoLRSP.
reset(ARM::PC);
739 bool UseLDRSP =
false;
741 auto PrevMBBI =
MBBI;
743 if (PrevMBBI->getOpcode() == ARM::tPOP) {
744 UsedRegs.stepBackward(*PrevMBBI);
754 if (!DoIt && !PopReg && !TemporaryReg)
757 assert((PopReg || TemporaryReg) &&
"Cannot get LR");
760 assert(PopReg &&
"Do not know how to get LR");
778 ArgRegsSaveSize + 4, ARM::NoRegister,
784 assert(!PopReg &&
"Unnecessary MOV is about to be inserted");
801 for (
auto MO:
MBBI->operands())
802 if (MO.isReg() && (MO.isImplicit() || MO.isDef()) &&
803 MO.getReg() != ARM::PC) {
805 if (!MO.isImplicit())
818 assert(PopReg &&
"Do not know how to get LR");
848 ARM::R0, ARM::R1, ARM::R2, ARM::R3, ARM::R4,
849 ARM::R5, ARM::R6, ARM::R7, ARM::LR};
852 std::set<Register> &LowRegs,
853 std::set<Register> &HighRegs) {
855 if (ARM::tGPRRegClass.
contains(Reg) || Reg == ARM::LR) {
857 }
else if (ARM::hGPRRegClass.
contains(Reg) && Reg != ARM::LR) {
858 HighRegs.insert(Reg);
865template <
typename It>
867 const std::set<Register> &RegSet) {
868 return std::find_if(OrderedStartIt, OrderedEndIt,
869 [&](
Register Reg) {
return RegSet.count(Reg); });
875 const std::set<Register> &RegsToSave,
876 const std::set<Register> &CopyRegs,
877 bool &UsedLRAsTemp) {
882 std::set<Register> LowRegs, HighRegs;
886 if (!LowRegs.empty()) {
890 if (LowRegs.count(Reg)) {
891 bool isKill = !
MRI.isLiveIn(Reg);
892 if (isKill && !
MRI.isReserved(Reg))
930 if (HighRegs.count(*HiRegToSave)) {
931 bool isKill = !
MRI.isLiveIn(*HiRegToSave);
932 if (isKill && !
MRI.isReserved(*HiRegToSave))
934 if (*CopyRegIt == ARM::LR)
968 const std::set<Register> &RegsToRestore,
969 const std::set<Register> &AvailableCopyRegs,
970 bool IsVarArg,
bool HasV5Ops) {
971 if (RegsToRestore.empty())
978 std::set<Register> LowRegs, HighRegs;
992 std::set<Register> CopyRegs = AvailableCopyRegs;
994 if (!HighRegs.empty() && CopyRegs.empty()) {
997 LowScratchReg = ARM::R0;
1003 CopyRegs.insert(LowScratchReg);
1007 assert(!CopyRegs.empty());
1040 if (LowScratchReg.
isValid()) {
1049 if (!LowRegs.empty()) {
1054 bool NeedsPop =
false;
1056 if (!LowRegs.count(Reg))
1059 if (Reg == ARM::LR) {
1061 MI->getOpcode() == ARM::TCRETURNri ||
1062 MI->getOpcode() == ARM::TCRETURNrinotr12)
1083 (*MIB).setDesc(
TII.get(ARM::tPOP_RET));
1114 bool NeedsFrameRecordPush =
hasFP(MF) && ARM::hGPRRegClass.contains(
FPReg);
1116 bool UsedLRAsTemp =
false;
1118 std::set<Register> FrameRecord;
1119 std::set<Register> SpilledGPRs;
1122 if (NeedsFrameRecordPush && (Reg ==
FPReg || Reg == ARM::LR))
1123 FrameRecord.insert(Reg);
1125 SpilledGPRs.insert(Reg);
1136 std::set<Register> FrameRecordCopyRegs;
1137 for (
unsigned ArgReg : {ARM::R0, ARM::R1, ARM::R2, ARM::R3})
1139 FrameRecordCopyRegs.insert(ArgReg);
1140 if (FrameRecordCopyRegs.empty())
1141 FrameRecordCopyRegs.insert(ARM::LR);
1148 std::set<Register> CopyRegs;
1150 if ((ARM::tGPRRegClass.
contains(Reg) || Reg == ARM::LR) &&
1152 CopyRegs.insert(Reg);
1153 for (
unsigned ArgReg : {ARM::R0, ARM::R1, ARM::R2, ARM::R3})
1155 CopyRegs.insert(ArgReg);
1164 if (LRLiveIn && UsedLRAsTemp) {
1168 unsigned NumRegsPushed = FrameRecord.size() + SpilledGPRs.size();
1170 dbgs() <<
"LR is live-in but clobbered in prologue, restoring via "
1171 << RegInfo->getName(*CopyRegIt) <<
"\n");
1175 .
addImm(NumRegsPushed - 1)
1204 bool NeedsFrameRecordPop =
hasFP(MF) && ARM::hGPRRegClass.contains(
FPReg);
1206 std::set<Register> FrameRecord;
1207 std::set<Register> SpilledGPRs;
1210 if (NeedsFrameRecordPop && (Reg ==
FPReg || Reg == ARM::LR))
1211 FrameRecord.insert(Reg);
1213 SpilledGPRs.insert(Reg);
1216 I.setRestored(
false);
1222 std::set<Register> CopyRegs;
1223 std::set<Register> UnusedReturnRegs;
1226 CopyRegs.insert(Reg);
1228 if (Terminator !=
MBB.
end() && Terminator->getOpcode() == ARM::tBX_RET) {
1229 UnusedReturnRegs.insert(ARM::R0);
1230 UnusedReturnRegs.insert(ARM::R1);
1231 UnusedReturnRegs.insert(ARM::R2);
1232 UnusedReturnRegs.insert(ARM::R3);
1233 for (
auto Op : Terminator->implicit_operands()) {
1235 UnusedReturnRegs.erase(
Op.getReg());
1238 CopyRegs.insert(UnusedReturnRegs.begin(), UnusedReturnRegs.end());
1246 assert((!SpilledGPRs.count(ARM::LR) || FrameRecord.empty()) &&
1247 "Can't insert pop after return sequence");
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
This file implements the BitVector class.
const HexagonInstrInfo * TII
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
unsigned const TargetRegisterInfo * TRI
static constexpr Register FPReg
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallVector class.
static void emitCallSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const TargetInstrInfo &TII, const DebugLoc &dl, const ThumbRegisterInfo &MRI, int NumBytes, unsigned MIFlags=MachineInstr::NoFlags)
static void pushRegsToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const TargetInstrInfo &TII, const std::set< Register > &RegsToSave, const std::set< Register > &CopyRegs, bool &UsedLRAsTemp)
static const SmallVector< Register > OrderedCopyRegs
static const SmallVector< Register > OrderedLowRegs
static void splitLowAndHighRegs(const std::set< Register > &Regs, std::set< Register > &LowRegs, std::set< Register > &HighRegs)
It getNextOrderedReg(It OrderedStartIt, It OrderedEndIt, const std::set< Register > &RegSet)
static void emitPrologueEpilogueSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const TargetInstrInfo &TII, const DebugLoc &dl, const ThumbRegisterInfo &MRI, int NumBytes, unsigned ScratchReg, unsigned MIFlags)
static const SmallVector< Register > OrderedHighRegs
static void popRegsFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MI, const TargetInstrInfo &TII, const std::set< Register > &RegsToRestore, const std::set< Register > &AvailableCopyRegs, bool IsVarArg, bool HasV5Ops)
static void findTemporariesForLR(const BitVector &GPRsNoLRSP, const BitVector &PopFriendly, const LiveRegUnits &UsedRegs, unsigned &PopReg, unsigned &TmpReg, MachineRegisterInfo &MRI)
static const unsigned FramePtr
bool hasBasePointer(const MachineFunction &MF) const
Register getFrameRegister(const MachineFunction &MF) const override
Register getBaseRegister() const
ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...
bool hasStackFrame() const
unsigned getGPRCalleeSavedArea1Size() const
unsigned getDPRCalleeSavedArea1Size() const
void setDPRCalleeSavedArea1Offset(unsigned o)
void setGPRCalleeSavedArea2Size(unsigned s)
void setFramePtrSpillOffset(unsigned o)
unsigned getGPRCalleeSavedArea2Size() const
void setGPRCalleeSavedArea1Size(unsigned s)
bool isCmseNSEntryFunction() const
unsigned getFramePtrSpillOffset() const
bool shouldRestoreSPFromFP() const
void setFrameRecordSavedAreaSize(unsigned s)
unsigned getArgRegsSaveSize() const
void setGPRCalleeSavedArea2Offset(unsigned o)
unsigned getFrameRecordSavedAreaSize() const
void setGPRCalleeSavedArea1Offset(unsigned o)
void setDPRCalleeSavedArea1Size(unsigned s)
void setShouldRestoreSPFromFP(bool s)
const ARMBaseInstrInfo * getInstrInfo() const override
const ARMBaseRegisterInfo * getRegisterInfo() const override
enum PushPopSplitVariation getPushPopSplitVariation(const MachineFunction &MF) const
@ SplitR7
R7 and LR must be adjacent, because R7 is the frame pointer, and must point to a frame record consist...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool empty() const
empty - Check if the array is empty.
bool test(unsigned Idx) const
int find_first() const
find_first - Returns the index of the first set bit, -1 if none of the bits are set.
bool any() const
any - Returns true if any bit is set.
iterator_range< const_set_bits_iterator > set_bits() const
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
This class represents an Operation in the Expression.
A set of register units used to track register liveness.
bool available(MCPhysReg Reg) const
Returns true if no part of physical register Reg is live.
static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register, SMLoc Loc={})
.cfi_def_cfa_register modifies a rule for computing CFA.
static MCCFIInstruction cfiDefCfa(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})
.cfi_def_cfa defines a rule for computing CFA as: take address from Register and add Offset to it.
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
static MCCFIInstruction cfiDefCfaOffset(MCSymbol *L, int64_t Offset, SMLoc Loc={})
.cfi_def_cfa_offset modifies a rule for computing CFA.
const MCRegisterInfo * getRegisterInfo() const
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
succ_iterator succ_begin()
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
unsigned succ_size() const
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
Align getMaxAlign() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
uint64_t getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
int64_t getOffsetAdjustment() const
Return the correction for frame offsets.
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
void setStackSize(uint64_t Size)
Set the size of the stack.
void setOffsetAdjustment(int64_t Adj)
Set the correction for frame offsets.
MachineFunctionProperties & reset(Property P)
unsigned addFrameInst(const MCCFIInstruction &Inst)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
void deleteMachineInstr(MachineInstr *MI)
DeleteMachineInstr - Delete the given MachineInstr.
MCContext & getContext() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineFunctionProperties & getProperties() const
Get the function properties.
const MachineInstrBuilder & addCFIIndex(unsigned CFIIndex) const
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & copyImplicitOps(const MachineInstr &OtherMI) const
Copy all the implicit operands from OtherMI onto this one.
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
bool isLiveIn(Register Reg) const
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Wrapper class representing virtual and physical registers.
constexpr bool isValid() const
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
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...
Thumb1FrameLowering(const ARMSubtarget &sti)
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
bool canUseAsEpilogue(const MachineBasicBlock &MBB) const override
Check whether or not the given MBB can be used as a epilogue for the target.
bool hasReservedCallFrame(const MachineFunction &MF) const override
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
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...
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...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ Define
Register definition.
@ Kill
The last use of a register.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static bool isARMLowRegister(MCRegister Reg)
isARMLowRegister - Returns true if the register is a low register (r0-r7).
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
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...
auto reverse(ContainerTy &&C)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
unsigned getDefRegState(bool B)
unsigned getKillRegState(bool B)
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...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
unsigned Log2(Align A)
Returns the log2 of the alignment.