36 cl::desc(
"Align ARM NEON spills in prolog and epilog"));
40 unsigned NumAlignedDPRCS2Regs);
85 if (CFSize >= ((1 << 12) - 1) / 2)
112 if ((MI->
getOpcode() == ARM::LDR_POST_IMM ||
125 unsigned SrcReg,
int NumBytes,
128 unsigned PredReg = 0) {
131 Pred, PredReg, TII, MIFlags);
134 Pred, PredReg, TII, MIFlags);
142 unsigned PredReg = 0) {
144 MIFlags, Pred, PredReg);
150 case ARM::VSTMDDB_UPD:
154 case ARM::t2STMDB_UPD:
158 case ARM::STR_PRE_IMM:
173 size_t StackSizeInBytes) {
181 return StackSizeInBytes >= StackProbeSize;
185 struct StackAdjustingInsts {
195 bool BeforeFPSet =
false) {
196 InstInfo Info = {
I, SPAdjust, BeforeFPSet};
197 Insts.push_back(Info);
201 auto Info = std::find_if(Insts.begin(), Insts.end(),
202 [&](InstInfo &Info) {
return Info.I ==
I; });
203 assert(Info != Insts.end() &&
"invalid sp adjusting instruction");
204 Info->SPAdjust += ExtraBytes;
209 unsigned CFAOffset = 0;
210 for (
auto &Info : Insts) {
211 if (HasFP && !Info.BeforeFPSet)
214 CFAOffset -= Info.SPAdjust;
217 BuildMI(MBB, std::next(Info.I), dl,
219 .addCFIIndex(CFIIndex)
238 const unsigned Alignment,
239 const bool MustBeSingleInstruction) {
243 const unsigned AlignMask = Alignment - 1;
260 }
else if (AlignMask <= 255) {
266 assert(!MustBeSingleInstruction &&
267 "Shouldn't call emitAligningInstructions demanding a single "
268 "instruction to be emitted for large stack alignment for a target "
291 assert(&MBB == &MF.
front() &&
"Shrink-wrapping not yet implemented");
302 "This emitPrologue does not support Thumb1!");
313 unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
314 int FramePtrSpillFI = 0;
322 StackAdjustingInsts DefCFAOffsetCandidates;
323 bool HasFP =
hasFP(MF);
326 if (ArgRegsSaveSize) {
327 emitSPUpdate(isARM, MBB, MBBI, dl, TII, -ArgRegsSaveSize,
329 DefCFAOffsetCandidates.addInst(std::prev(MBBI), ArgRegsSaveSize,
true);
334 if (NumBytes - ArgRegsSaveSize != 0) {
335 emitSPUpdate(isARM, MBB, MBBI, dl, TII, -(NumBytes - ArgRegsSaveSize),
337 DefCFAOffsetCandidates.addInst(std::prev(MBBI),
338 NumBytes - ArgRegsSaveSize,
true);
340 DefCFAOffsetCandidates.emitDefCFAOffsets(MMI, MBB, dl, TII, HasFP);
345 for (
unsigned i = 0, e = CSI.size(); i != e; ++i) {
346 unsigned Reg = CSI[i].getReg();
347 int FI = CSI[i].getFrameIdx();
369 FramePtrSpillFI = FI;
383 if (GPRCS1Size > 0) {
384 GPRCS1Push = LastPush = MBBI++;
385 DefCFAOffsetCandidates.addInst(LastPush, GPRCS1Size,
true);
389 unsigned GPRCS1Offset = NumBytes - ArgRegsSaveSize - GPRCS1Size;
390 unsigned GPRCS2Offset = GPRCS1Offset - GPRCS2Size;
391 unsigned DPRAlign = DPRCSSize ?
std::min(8U, Align) : 4U;
392 unsigned DPRGapSize = (GPRCS1Size + GPRCS2Size + ArgRegsSaveSize) % DPRAlign;
393 unsigned DPRCSOffset = GPRCS2Offset - DPRGapSize - DPRCSSize;
394 int FramePtrOffsetInPush = 0;
396 FramePtrOffsetInPush =
406 if (GPRCS2Size > 0) {
407 GPRCS2Push = LastPush = MBBI++;
408 DefCFAOffsetCandidates.addInst(LastPush, GPRCS2Size);
414 assert(DPRGapSize == 4 &&
"unexpected alignment requirements for DPRs");
416 DefCFAOffsetCandidates.addExtraBytes(LastPush, DPRGapSize);
420 DefCFAOffsetCandidates.addInst(std::prev(MBBI), DPRGapSize);
428 while (MBBI->getOpcode() == ARM::VSTMDDB_UPD) {
443 NumBytes = DPRCSOffset;
446 uint32_t NumWords = NumBytes >> 2;
448 if (NumWords < 65536)
462 BuildMI(MBB, MBBI, dl, TII.get(ARM::tBL))
470 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi32imm), ARM::R12)
471 .addExternalSymbol(
"__chkstk")
474 BuildMI(MBB, MBBI, dl, TII.get(ARM::tBLXr))
493 DefCFAOffsetCandidates.addExtraBytes(LastPush, NumBytes);
497 DefCFAOffsetCandidates.addInst(std::prev(MBBI), NumBytes);
523 PushSize + FramePtrOffsetInPush,
525 if (FramePtrOffsetInPush + PushSize != 0) {
528 -(ArgRegsSaveSize - FramePtrOffsetInPush)));
530 .addCFIIndex(CFIIndex)
537 .addCFIIndex(CFIIndex)
545 if (GPRCS1Size > 0) {
548 for (
const auto &Entry : CSI) {
549 unsigned Reg = Entry.getReg();
550 int FI = Entry.getFrameIdx();
572 .addCFIIndex(CFIIndex)
579 if (GPRCS2Size > 0) {
581 for (
const auto &Entry : CSI) {
582 unsigned Reg = Entry.getReg();
583 int FI = Entry.getFrameIdx();
593 unsigned CFIIndex = MMI.addFrameInst(
596 .addCFIIndex(CFIIndex)
608 for (
const auto &Entry : CSI) {
609 unsigned Reg = Entry.getReg();
610 int FI = Entry.getFrameIdx();
611 if ((Reg >= ARM::D0 && Reg <= ARM::D31) &&
615 unsigned CFIIndex = MMI.addFrameInst(
618 .addCFIIndex(CFIIndex)
628 DefCFAOffsetCandidates.emitDefCFAOffsets(MMI, MBB, dl, TII, HasFP);
696 assert(MBBI->isReturn() &&
"Can only insert epilog into returning blocks");
697 unsigned RetOpcode = MBBI->getOpcode();
702 if (!(RetOpcode == ARM::TCRETURNdi || RetOpcode == ARM::TCRETURNri))
710 if (RetOpcode == ARM::TCRETURNdi) {
726 }
else if (RetOpcode == ARM::TCRETURNri) {
728 TII.get(
STI.
isThumb() ? ARM::tTAILJMPr : ARM::TAILJMPr)).
733 for (
unsigned i = 1, e = MBBI->getNumOperands(); i != e; ++i)
744 assert(MBBI->isReturn() &&
"Can only insert epilog into returning blocks");
752 "This emitEpilogue does not support Thumb1!");
757 unsigned FramePtr = RegInfo->getFrameRegister(MF);
767 if (NumBytes - ArgRegsSaveSize != 0)
768 emitSPUpdate(isARM, MBB, MBBI, dl, TII, NumBytes - ArgRegsSaveSize);
771 const MCPhysReg *CSRegs = RegInfo->getCalleeSavedRegs(&MF);
772 if (MBBI != MBB.
begin()) {
781 NumBytes -= (ArgRegsSaveSize +
804 "No scratch register to restore SP from FP!");
814 BuildMI(MBB, MBBI, dl, TII.get(ARM::MOVr), ARM::SP)
821 }
else if (NumBytes &&
830 while (MBBI->getOpcode() == ARM::VLDMDIA_UPD)
835 "unexpected DPR alignment gap");
846 emitSPUpdate(isARM, MBB, MBBI, dl, TII, ArgRegsSaveSize);
855 unsigned &FrameReg)
const {
861 int FI,
unsigned &FrameReg,
881 assert (
hasFP(MF) &&
"dynamic stack realignment without a FP!");
885 }
else if (hasMovingSP) {
887 "VLAs and dynamic stack alignment, but missing base pointer!");
900 }
else if (hasMovingSP) {
906 if (FPOffset >= -255 && FPOffset < 0) {
915 if (Offset >= 0 && (Offset & 3) == 0 && Offset <= 1020)
919 if (FPOffset >= -255 && FPOffset < 0) {
923 }
else if (Offset > (FPOffset < 0 ? -FPOffset : FPOffset)) {
943 const std::vector<CalleeSavedInfo> &CSI,
944 unsigned StmOpc,
unsigned StrOpc,
946 bool(*
Func)(
unsigned,
bool),
947 unsigned NumAlignedDPRCS2Regs,
948 unsigned MIFlags)
const {
953 if (MI != MBB.
end()) DL = MI->getDebugLoc();
956 unsigned i = CSI.
size();
958 unsigned LastReg = 0;
959 for (; i != 0; --i) {
960 unsigned Reg = CSI[i-1].getReg();
964 if (Reg >= ARM::D8 && Reg < ARM::D8 + NumAlignedDPRCS2Regs)
972 if (Reg == ARM::LR) {
984 if (NoGap && LastReg && LastReg != Reg-1)
987 Regs.
push_back(std::make_pair(Reg, isKill));
992 if (Regs.
size() > 1 || StrOpc== 0) {
996 for (
unsigned i = 0, e = Regs.
size(); i < e; ++i)
998 }
else if (Regs.
size() == 1) {
1017 const std::vector<CalleeSavedInfo> &CSI,
1018 unsigned LdmOpc,
unsigned LdrOpc,
1019 bool isVarArg,
bool NoGap,
1020 bool(*
Func)(
unsigned,
bool),
1021 unsigned NumAlignedDPRCS2Regs)
const {
1026 unsigned RetOpcode = MI->getOpcode();
1027 bool isTailCall = (RetOpcode == ARM::TCRETURNdi ||
1028 RetOpcode == ARM::TCRETURNri);
1030 RetOpcode == ARM::SUBS_PC_LR || RetOpcode == ARM::t2SUBS_PC_LR;
1033 unsigned i = CSI.
size();
1035 unsigned LastReg = 0;
1036 bool DeleteRet =
false;
1037 for (; i != 0; --i) {
1038 unsigned Reg = CSI[i-1].getReg();
1042 if (Reg >= ARM::D8 && Reg < ARM::D8 + NumAlignedDPRCS2Regs)
1045 if (Reg == ARM::LR && !isTailCall && !isVarArg && !isInterrupt &&
1056 if (NoGap && LastReg && LastReg != Reg-1)
1065 if (Regs.
size() > 1 || LdrOpc == 0) {
1069 for (
unsigned i = 0, e = Regs.
size(); i < e; ++i)
1076 }
else if (Regs.
size() == 1) {
1079 if (Regs[0] == ARM::PC)
1082 BuildMI(MBB, MI, DL, TII.
get(LdrOpc), Regs[0])
1087 if (LdrOpc == ARM::LDR_POST_REG || LdrOpc == ARM::LDR_POST_IMM) {
1107 unsigned NumAlignedDPRCS2Regs,
1108 const std::vector<CalleeSavedInfo> &CSI,
1119 for (
unsigned i = 0, e = CSI.size(); i != e; ++i) {
1120 unsigned DNum = CSI[i].getReg() - ARM::D8;
1123 int FI = CSI[i].getFrameIdx();
1151 unsigned Opc = isThumb ? ARM::t2SUBri : ARM::SUBri;
1154 .
addImm(8 * NumAlignedDPRCS2Regs)));
1168 Opc = isThumb ? ARM::tMOVr : ARM::MOVr;
1177 unsigned NextReg = ARM::D8;
1181 if (NumAlignedDPRCS2Regs >= 6) {
1183 &ARM::QQPRRegClass);
1191 NumAlignedDPRCS2Regs -= 4;
1196 unsigned R4BaseReg = NextReg;
1199 if (NumAlignedDPRCS2Regs >= 4) {
1201 &ARM::QQPRRegClass);
1207 NumAlignedDPRCS2Regs -= 4;
1211 if (NumAlignedDPRCS2Regs >= 2) {
1218 NumAlignedDPRCS2Regs -= 2;
1222 if (NumAlignedDPRCS2Regs) {
1238 unsigned NumAlignedDPRCS2Regs) {
1243 assert(MI->mayStore() &&
"Expecting spill instruction");
1246 switch(NumAlignedDPRCS2Regs) {
1249 assert(MI->mayStore() &&
"Expecting spill instruction");
1252 assert(MI->mayStore() &&
"Expecting spill instruction");
1256 assert(MI->killsRegister(
ARM::R4) &&
"Missed kill flag");
1267 unsigned NumAlignedDPRCS2Regs,
1268 const std::vector<CalleeSavedInfo> &CSI,
1277 for (
unsigned i = 0, e = CSI.size(); i != e; ++i)
1278 if (CSI[i].
getReg() == ARM::D8) {
1279 D8SpillFI = CSI[i].getFrameIdx();
1291 unsigned Opc = isThumb ? ARM::t2ADDri : ARM::ADDri;
1293 .addFrameIndex(D8SpillFI).
addImm(0)));
1296 unsigned NextReg = ARM::D8;
1299 if (NumAlignedDPRCS2Regs >= 6) {
1301 &ARM::QQPRRegClass);
1307 NumAlignedDPRCS2Regs -= 4;
1312 unsigned R4BaseReg = NextReg;
1315 if (NumAlignedDPRCS2Regs >= 4) {
1317 &ARM::QQPRRegClass);
1322 NumAlignedDPRCS2Regs -= 4;
1326 if (NumAlignedDPRCS2Regs >= 2) {
1332 NumAlignedDPRCS2Regs -= 2;
1336 if (NumAlignedDPRCS2Regs)
1346 const std::vector<CalleeSavedInfo> &CSI,
1354 unsigned PushOpc = AFI->
isThumbFunction() ? ARM::t2STMDB_UPD : ARM::STMDB_UPD;
1356 ARM::t2STR_PRE : ARM::STR_PRE_IMM;
1357 unsigned FltOpc = ARM::VSTMDDB_UPD;
1369 if (NumAlignedDPRCS2Regs)
1377 const std::vector<CalleeSavedInfo> &CSI,
1389 if (NumAlignedDPRCS2Regs)
1392 unsigned PopOpc = AFI->
isThumbFunction() ? ARM::t2LDMIA_UPD : ARM::LDMIA_UPD;
1393 unsigned LdrOpc = AFI->
isThumbFunction() ? ARM::t2LDR_POST :ARM::LDR_POST_IMM;
1394 unsigned FltOpc = ARM::VLDMDIA_UPD;
1396 NumAlignedDPRCS2Regs);
1397 emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg,
false,
1399 emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg,
false,
1408 unsigned FnSize = 0;
1409 for (
auto &MBB : MF) {
1410 for (
auto &MI : MBB)
1423 unsigned Limit = (1 << 12) - 1;
1424 for (
auto &MBB : MF) {
1425 for (
auto &MI : MBB) {
1426 for (
unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
1427 if (!MI.getOperand(i).isFI())
1432 if (MI.getOpcode() == ARM::ADDri) {
1433 Limit =
std::min(Limit, (1U << 8) - 1);
1441 Limit =
std::min(Limit, (1U << 8) - 1);
1445 Limit =
std::min(Limit, ((1U << 8) - 1) * 4);
1451 Limit =
std::min(Limit, (1U << 8) - 1);
1484 if (!static_cast<const ARMSubtarget &>(MF.
getSubtarget()).hasNEON())
1492 if (!static_cast<const ARMBaseRegisterInfo *>(
1501 unsigned NumSpills = 0;
1502 for (; NumSpills < 8; ++NumSpills)
1503 if (!SavedRegs.
test(ARM::D8 + NumSpills))
1525 bool CanEliminateFrame =
true;
1526 bool CS1Spilled =
false;
1527 bool LRSpilled =
false;
1528 unsigned NumGPRSpills = 0;
1552 SavedRegs.
set(ARM::LR);
1560 unsigned StackSize = MFI->estimateStackSize(MF);
1561 if (MFI->hasVarSizedObjects() || StackSize > 508)
1575 for (
unsigned i = 0; CSRegs[i]; ++i) {
1576 unsigned Reg = CSRegs[i];
1577 bool Spilled =
false;
1578 if (SavedRegs.
test(Reg)) {
1580 CanEliminateFrame =
false;
1583 if (!ARM::GPRRegClass.
contains(Reg))
1601 case ARM::R0:
case ARM::R1:
1617 case ARM::R0:
case ARM::R1:
1631 bool ForceLRSpill =
false;
1637 if (FnSize >= (1 << 11)) {
1638 CanEliminateFrame =
false;
1639 ForceLRSpill =
true;
1659 (MFI->estimateStackSize(MF) +
1662 || MFI->hasVarSizedObjects()
1665 bool ExtraCSSpill =
false;
1671 if (!LRSpilled && CS1Spilled) {
1672 SavedRegs.
set(ARM::LR);
1675 LRPos = std::find(UnspilledCS1GPRs.
begin(), UnspilledCS1GPRs.
end(),
1677 if (LRPos != UnspilledCS1GPRs.
end())
1678 UnspilledCS1GPRs.
erase(LRPos);
1680 ForceLRSpill =
false;
1681 ExtraCSSpill =
true;
1685 SavedRegs.
set(FramePtr);
1686 auto FPPos = std::find(UnspilledCS1GPRs.
begin(), UnspilledCS1GPRs.
end(),
1688 if (
FPPos != UnspilledCS1GPRs.
end())
1697 if (TargetAlign >= 8 && (NumGPRSpills & 1)) {
1698 if (CS1Spilled && !UnspilledCS1GPRs.
empty()) {
1699 for (
unsigned i = 0, e = UnspilledCS1GPRs.
size(); i != e; ++i) {
1700 unsigned Reg = UnspilledCS1GPRs[i];
1706 ExtraCSSpill =
true;
1711 unsigned Reg = UnspilledCS2GPRs.
front();
1714 ExtraCSSpill =
true;
1723 if (BigStack && !ExtraCSSpill) {
1726 unsigned NumExtras = TargetAlign / 4;
1728 while (NumExtras && !UnspilledCS1GPRs.
empty()) {
1729 unsigned Reg = UnspilledCS1GPRs.
back();
1740 while (NumExtras && !UnspilledCS2GPRs.
empty()) {
1741 unsigned Reg = UnspilledCS2GPRs.
back();
1749 if (Extras.
size() && NumExtras == 0) {
1750 for (
unsigned i = 0, e = Extras.
size(); i != e; ++i) {
1751 SavedRegs.
set(Extras[i]);
1765 SavedRegs.
set(ARM::LR);
1771 void ARMFrameLowering::
1788 Amount = (Amount+Align-1)/Align*Align;
1792 "This eliminateCallFramePseudoInstr does not support Thumb1!");
1800 if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
1808 assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP);
1822 unsigned Shifted = 0;
1827 while (!(Value & 0xC0000000)) {
1832 bool Carry = (Value & 0x00FFFFFF);
1833 Value = ((Value & 0xFF000000) >> 24) + Carry;
1835 if (Value & 0x0000100)
1836 Value = Value & 0x000001FC;
1839 Value = Value >> (Shifted - 24);
1841 Value = Value << (24 - Shifted);
1888 assert(&PrologueMBB == &MF.
front() &&
"Shrink-wrapping not yet implemented");
1898 uint64_t StackSize = MFI->getStackSize();
1906 unsigned ScratchReg0 =
ARM::R4;
1907 unsigned ScratchReg1 = ARM::R5;
1908 uint64_t AlignedStackSize;
1952 .addReg(ScratchReg0).
addReg(ScratchReg1);
1960 .addCFIIndex(CFIIndex);
1964 .addCFIIndex(CFIIndex);
1968 .addCFIIndex(CFIIndex);
1974 }
else if (CompareStackPointer) {
1976 .addReg(ARM::SP)).addReg(0);
1980 if (!CompareStackPointer && Thumb) {
1984 }
else if (!CompareStackPointer) {
1986 .addReg(ARM::SP).
addImm(AlignedStackSize)).addReg(0);
1998 .addConstantPoolIndex(CPI));
2002 .addReg(ScratchReg0).
addImm(0));
2020 .addReg(ScratchReg0).
addImm(4 * TlsOffset));
2025 Opcode = Thumb ? ARM::tCMPr : ARM::CMPrr;
2027 .addReg(ScratchReg0)
2031 Opcode = Thumb ? ARM::tBcc : ARM::Bcc;
2032 BuildMI(GetMBB, DL, TII.get(Opcode)).addMBB(PostStackMBB)
2045 ScratchReg0)).
addImm(AlignedStackSize));
2048 .addImm(AlignedStackSize)).addReg(0);
2078 .addCFIIndex(CFIIndex);
2082 .addCFIIndex(CFIIndex);
2089 BuildMI(AllocMBB, DL, TII.get(ARM::BL))
2090 .addExternalSymbol(
"__morestack");
2099 .addReg(ScratchReg0));
2126 .addReg(ScratchReg0)
2133 .addCFIIndex(CFIIndex);
2136 Opcode = Thumb ? ARM::tBX_RET : ARM::BX_RET;
2149 .addReg(ScratchReg0)
2156 .addCFIIndex(CFIIndex);
2163 .addCFIIndex(CFIIndex);
2167 .addCFIIndex(CFIIndex);
void push_front(MachineBasicBlock *MBB)
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
std::enable_if< std::numeric_limits< T >::is_signed, bool >::type getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
void push_back(const T &Elt)
const MachineFunction * getParent() const
getParent - Return the MachineFunction containing this basic block.
The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...
unsigned getAlignment() const
getAlignment - Return the alignment (log2, not bytes) of the function.
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
int getDwarfRegNum(unsigned RegNum, bool isEH) const
Map a target register to an equivalent dwarf register number.
const GlobalValue * getGlobal() const
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
BitVector getPristineRegs(const MachineFunction &MF) const
Return a set of physical registers that are pristine.
static unsigned getSORegOpc(ShiftOpc ShOp, unsigned Imm)
static cl::opt< bool > SpillAlignedNEONRegs("align-neon-spills", cl::Hidden, cl::init(true), cl::desc("Align ARM NEON spills in prolog and epilog"))
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register...
ARMConstantPoolValue - ARM specific constantpool value.
std::vector< unsigned >::const_iterator livein_iterator
unsigned getBaseRegister() const
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int Offset)
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
void emitT2RegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, DebugLoc dl, unsigned DestReg, unsigned BaseReg, int NumBytes, ARMCC::CondCodes Pred, unsigned PredReg, const ARMBaseInstrInfo &TII, unsigned MIFlags=0)
void adjustForSegmentedStacks(MachineFunction &MF, MachineBasicBlock &MBB) const override
Adjust the prologue to have the function use segmented stacks.
void verify(Pass *p=nullptr, const char *Banner=nullptr) const
verify - Run the current MachineFunction through the machine code verifier, useful for debugger use...
int ResolveFrameIndexReference(const MachineFunction &MF, int FI, unsigned &FrameReg, int SPAdj) const
void addLiveIn(unsigned Reg)
Adds the specified register as a live in.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
bool isReturnAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
virtual unsigned GetInstSizeInBytes(const MachineInstr *MI) const
GetInstSize - Returns the size of the specified MachineInstr.
const char * getSymbolName() const
bool isThumbFunction() const
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
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...
void setGPRCalleeSavedArea2Offset(unsigned o)
static uint32_t alignToARMConstant(uint32_t Value)
Get the minimum constant for ARM that is greater than or equal to the argument.
bool isThumb1Only() const
static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset)
.cfi_def_cfa_offset modifies a rule for computing CFA.
unsigned createPICLabelUId()
static bool isThumb(const MCSubtargetInfo &STI)
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
unsigned getDPRCalleeSavedAreaSize() const
unsigned getMaxAlignment() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
const ARMBaseInstrInfo * getInstrInfo() const override
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...
static const uint64_t kSplitStackAvailable
livein_iterator livein_begin() const
unsigned getSize() const
getSize - Return the size of the register in bytes, which is also the size of a stack slot allocated ...
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
Code Generation virtual methods...
unsigned getNumAlignedDPRCS2Regs() const
static const MachineInstrBuilder & AddDefaultPred(const MachineInstrBuilder &MIB)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
const HexagonInstrInfo * TII
bool isTargetDarwin() const
virtual bool hasFP(const MachineFunction &MF) const =0
hasFP - Return true if the specified function should have a dedicated frame pointer register...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned getFrameRegister(const MachineFunction &MF) const override
bool hasReservedCallFrame(const MachineFunction &MF) const override
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required, we reserve argument space for call sites in the function immediately on entry to the current function.
bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
unsigned getArgRegsSaveSize() const
Reg
All possible values of the reg field in the ModR/M byte.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
Number of individual test Apply this number of consecutive mutations to each input exit after the first new interesting input is found the minimized corpus is saved into the first input directory Number of jobs to run If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
bool isFrameAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
void setDPRCalleeSavedAreaOffset(unsigned o)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
const MachineInstrBuilder & addImm(int64_t Val) const
addImm - Add a new immediate operand.
unsigned getNumOperands() const
Access to explicit operands of the instruction.
void setFramePtrSpillOffset(unsigned o)
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
Context object for machine code objects.
const MachineBasicBlock & front() const
unsigned getArgumentStackSize() const
bool isLiveIn(unsigned Reg) const
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
void setDPRCalleeSavedGapSize(unsigned s)
int getOffsetAdjustment() const
Return the correction for frame offsets.
void setShouldRestoreSPFromFP(bool s)
bool isTargetMachO() const
unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx, const TargetRegisterClass *RC) const
getMatchingSuperReg - Return a super-register of the specified register Reg so its sub-register of in...
unsigned LLVM_ATTRIBUTE_UNUSED_RESULT addFrameInst(const MCCFIInstruction &Inst)
void setLRIsSpilledForFarJump(bool s)
iterator getLastNonDebugInstr()
getLastNonDebugInstr - returns an iterator to the last non-debug instruction in the basic block...
static bool isARMArea1Register(unsigned Reg, bool isIOS)
isARMArea1Register - Returns true if the register is a low register (r0-r7) or a stack/pc register th...
bool isThumb1OnlyFunction() const
int getFrameIndexOffset(const MachineFunction &MF, int FI) const override
getFrameIndexOffset - Returns the displacement from the frame register to the stack frame of the spec...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
unsigned getKillRegState(bool B)
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
TargetInstrInfo - Interface to description of machine instruction set.
unsigned getDefRegState(bool B)
bundle_iterator< MachineInstr, instr_iterator > iterator
static MachineBasicBlock::iterator skipAlignedDPRCS2Spills(MachineBasicBlock::iterator MI, unsigned NumAlignedDPRCS2Regs)
Skip past the code inserted by emitAlignedDPRCS2Spills, and return an iterator to the following instr...
static MCCFIInstruction createSameValue(MCSymbol *L, unsigned Register)
.cfi_same_value Current value of Register is the same as in the previous frame.
static bool isCalleeSavedRegister(unsigned Reg, const MCPhysReg *CSRegs)
initializer< Ty > init(const Ty &Val)
unsigned getTargetFlags() const
static unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO, unsigned IdxMode=0)
static bool isCSRestore(MachineInstr *MI, const ARMBaseInstrInfo &TII, const MCPhysReg *CSRegs)
bool hasStackFrame() const
std::size_t countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the least significant bit to the most stopping at the first 1...
static MCCFIInstruction createDefCfa(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...
CodeModel::Model getCodeModel() const
Returns the code model.
virtual bool needsStackRealignment(const MachineFunction &MF) const
needsStackRealignment - true if storage within the function requires the stack pointer to be aligned ...
static void emitSPUpdate(bool isARM, MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, DebugLoc dl, const ARMBaseInstrInfo &TII, int NumBytes, unsigned MIFlags=MachineInstr::NoFlags, ARMCC::CondCodes Pred=ARMCC::AL, unsigned PredReg=0)
unsigned getAlignment() const
getAlignment - Return the minimum required alignment for a register of this class.
static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register)
.cfi_def_cfa_register modifies a rule for computing CFA.
bool isReserved(unsigned PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
livein_iterator livein_end() const
const MachineOperand & getOperand(unsigned i) const
static int sizeOfSPAdjustment(const MachineInstr *MI)
unsigned getFramePtrSpillOffset() const
bool isSymbol() const
isSymbol - Tests if this is a MO_ExternalSymbol operand.
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
void setGPRCalleeSavedArea2Size(unsigned s)
int64_t getOffset() const
Return the offset from the symbol in this operand.
static void emitAlignedDPRCS2Restores(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned NumAlignedDPRCS2Regs, const std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI)
Emit aligned reload instructions for NumAlignedDPRCS2Regs D-registers starting from d8...
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
const ARMFrameLowering * getFrameLowering() const override
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
BuildMI - Builder interface.
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
iterator erase(iterator I)
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
void emitARMRegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, DebugLoc dl, unsigned DestReg, unsigned BaseReg, int NumBytes, ARMCC::CondCodes Pred, unsigned PredReg, const ARMBaseInstrInfo &TII, unsigned MIFlags=0)
emitARMRegPlusImmediate / emitT2RegPlusImmediate - Emits a series of instructions to materializea des...
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
static void emitRegPlusImmediate(bool isARM, MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, DebugLoc dl, const ARMBaseInstrInfo &TII, unsigned DestReg, unsigned SrcReg, int NumBytes, unsigned MIFlags=MachineInstr::NoFlags, ARMCC::CondCodes Pred=ARMCC::AL, unsigned PredReg=0)
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
int getFrameIndexReference(const MachineFunction &MF, int FI, unsigned &FrameReg) const override
getFrameIndexReference - Provide a base+offset reference to an FI slot for debug info.
bool hasCalls() const
Return true if the current function has any function calls.
virtual const TargetFrameLowering * getFrameLowering() const
static const MachineInstrBuilder & AddDefaultCC(const MachineInstrBuilder &MIB)
virtual bool noFramePointerElim(const MachineFunction &MF) const
Return true if the target needs to disable frame pointer elimination.
static void emitAlignedDPRCS2Spills(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned NumAlignedDPRCS2Regs, const std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI)
Emit aligned spill instructions for NumAlignedDPRCS2Regs D-registers starting from d8...
void setGPRCalleeSavedArea1Size(unsigned s)
void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
const MCContext & getContext() const
void addScavengingFrameIndex(int FI)
Add a scavenging frame index.
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
bool test(unsigned Idx) const
static bool isARMArea2Register(unsigned Reg, bool isIOS)
unsigned getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call...
Information about stack frame layout on the target.
bool isTargetAndroid() const
void setOffsetAdjustment(int Adj)
Set the correction for frame offsets.
MachineFrameInfo * getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI) const override
restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee saved registers and returns...
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(NoStrictAlign), cl::values(clEnumValN(StrictAlign,"aarch64-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"aarch64-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
void fixTCReturn(MachineFunction &MF, MachineBasicBlock &MBB) const
bool hasBasePointer(const MachineFunction &MF) const
static ARMConstantPoolSymbol * Create(LLVMContext &C, const char *s, unsigned ID, unsigned char PCAdj)
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
ARMFrameLowering(const ARMSubtarget &sti)
int findFirstPredOperandIdx() const
Find the index of the first operand in the operand list that is used to represent the predicate...
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
int getStackProtectorIndex() const
Return the index for the stack protector object.
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned char TargetFlags=0) const
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
static unsigned estimateRSStackSizeLimit(MachineFunction &MF, const TargetFrameLowering *TFI)
estimateRSStackSizeLimit - Look at each instruction that references stack frames and return the stack...
const MCRegisterInfo * getRegisterInfo() const
bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override
canSimplifyCallFramePseudos - If there is a reserved call frame, the call frame pseudos can be simpli...
static bool isPopOpcode(int Opc)
bool noFramePointerElim(const MachineFunction &MF) const override
Return true if the target needs to disable frame pointer elimination.
static bool isARMLowRegister(unsigned Reg)
isARMLowRegister - Returns true if the register is a low register (r0-r7).
Representation of each machine instruction.
static void emitAligningInstructions(MachineFunction &MF, ARMFunctionInfo *AFI, const TargetInstrInfo &TII, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc DL, const unsigned Reg, const unsigned Alignment, const bool MustBeSingleInstruction)
Emit an instruction sequence that will align the address in register Reg by zero-ing out the lower bi...
void setHasStackFrame(bool s)
void setGPRCalleeSavedArea1Offset(unsigned o)
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
bool isTargetLinux() const
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned char TargetFlags=0) const
ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...
const ARMBaseRegisterInfo * getRegisterInfo() const override
unsigned getDPRCalleeSavedGapSize() const
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
void setDPRCalleeSavedAreaSize(unsigned s)
const MachineInstrBuilder & copyImplicitOps(const MachineInstr *OtherMI)
Copy all the implicit operands from OtherMI onto this one.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
static bool isARMArea3Register(unsigned Reg, bool isIOS)
unsigned getReg() const
getReg - Returns the register number.
StringRef getValueAsString() const
Return the attribute's value as a string.
static bool WindowsRequiresStackProbe(const MachineFunction &MF, size_t StackSizeInBytes)
bool cannotEliminateFrame(const MachineFunction &MF) const
virtual const TargetInstrInfo * getInstrInfo() const
LLVM Value Representation.
static unsigned GetFunctionSizeInBytes(const MachineFunction &MF, const ARMBaseInstrInfo &TII)
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI) const override
spillCalleeSavedRegisters - Issues instruction(s) to spill all callee saved registers and returns tru...
unsigned getGPRCalleeSavedArea1Size() const
static const unsigned FramePtr
Primary interface to the complete machine description for the target machine.
bool addRegisterKilled(unsigned IncomingReg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
We have determined MI kills a register.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
MachineModuleInfo & getMMI() const
unsigned getGPRCalleeSavedArea2Size() const
bool isThumb2Function() const
static void checkNumAlignedDPRCS2Regs(MachineFunction &MF, BitVector &SavedRegs)
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
addReg - Add a new virtual register operand...
void setObjectAlignment(int ObjectIdx, unsigned Align)
setObjectAlignment - Change the alignment of the specified stack object.
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
bool needsStackRealignment(const MachineFunction &MF) const override
void addSuccessor(MachineBasicBlock *succ, uint32_t weight=0)
addSuccessor - Add succ as a successor of this MachineBasicBlock.
bool isTargetWindows() const
unsigned getConstantPoolIndex(const Constant *C, unsigned Alignment)
getConstantPoolIndex - Create a new entry in the constant pool or return an existing one...
MachineModuleInfo - This class contains meta information specific to a module.
bool shouldRestoreSPFromFP() const