66 #define DEBUG_TYPE "arm-frame-lowering" 72 cl::desc(
"Align ARM NEON spills in prolog and epilog"));
76 unsigned NumAlignedDPRCS2Regs);
130 if (CFSize >= ((1 << 12) - 1) / 2)
156 if ((MI.
getOpcode() == ARM::LDR_POST_IMM ||
173 Pred, PredReg, TII, MIFlags);
176 Pred, PredReg, TII, MIFlags);
184 unsigned PredReg = 0) {
186 MIFlags, Pred, PredReg);
192 case ARM::VSTMDDB_UPD:
196 case ARM::t2STMDB_UPD:
200 case ARM::STR_PRE_IMM:
215 size_t StackSizeInBytes) {
223 return (StackSizeInBytes >= StackProbeSize) &&
229 struct StackAdjustingInsts {
239 bool BeforeFPSet =
false) {
240 InstInfo
Info = {
I, SPAdjust, BeforeFPSet};
247 assert(Info != Insts.
end() &&
"invalid sp adjusting instruction");
248 Info->SPAdjust += ExtraBytes;
254 unsigned CFAOffset = 0;
255 for (
auto &
Info : Insts) {
256 if (HasFP && !
Info.BeforeFPSet)
259 CFAOffset -=
Info.SPAdjust;
263 TII.get(TargetOpcode::CFI_INSTRUCTION))
264 .addCFIIndex(CFIIndex)
284 const unsigned Alignment,
285 const bool MustBeSingleInstruction) {
289 const unsigned AlignMask = Alignment - 1;
307 }
else if (AlignMask <= 255) {
314 assert(!MustBeSingleInstruction &&
315 "Shouldn't call emitAligningInstructions demanding a single " 316 "instruction to be emitted for large stack alignment for a target " 364 "This emitPrologue does not support Thumb1!");
379 unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
380 int FramePtrSpillFI = 0;
388 StackAdjustingInsts DefCFAOffsetCandidates;
389 bool HasFP =
hasFP(MF);
392 if (ArgRegsSaveSize) {
393 emitSPUpdate(isARM, MBB, MBBI, dl, TII, -ArgRegsSaveSize,
395 DefCFAOffsetCandidates.addInst(std::prev(MBBI), ArgRegsSaveSize,
true);
400 if (NumBytes - ArgRegsSaveSize != 0) {
401 emitSPUpdate(isARM, MBB, MBBI, dl, TII, -(NumBytes - ArgRegsSaveSize),
403 DefCFAOffsetCandidates.addInst(std::prev(MBBI),
404 NumBytes - ArgRegsSaveSize,
true);
406 DefCFAOffsetCandidates.emitDefCFAOffsets(MBB, dl, TII, HasFP);
411 for (
unsigned i = 0, e = CSI.size(); i != e; ++i) {
412 unsigned Reg = CSI[i].getReg();
413 int FI = CSI[i].getFrameIdx();
435 FramePtrSpillFI = FI;
449 if (GPRCS1Size > 0) {
450 GPRCS1Push = LastPush = MBBI++;
451 DefCFAOffsetCandidates.addInst(LastPush, GPRCS1Size,
true);
455 unsigned GPRCS1Offset = NumBytes - ArgRegsSaveSize - GPRCS1Size;
456 unsigned GPRCS2Offset = GPRCS1Offset - GPRCS2Size;
457 unsigned DPRAlign = DPRCSSize ? std::min(8U, Align) : 4U;
458 unsigned DPRGapSize = (GPRCS1Size + GPRCS2Size + ArgRegsSaveSize) % DPRAlign;
459 unsigned DPRCSOffset = GPRCS2Offset - DPRGapSize - DPRCSSize;
460 int FramePtrOffsetInPush = 0;
464 "Max FP estimation is wrong");
465 FramePtrOffsetInPush = FPOffset + ArgRegsSaveSize;
474 if (GPRCS2Size > 0) {
475 GPRCS2Push = LastPush = MBBI++;
476 DefCFAOffsetCandidates.addInst(LastPush, GPRCS2Size);
482 assert(DPRGapSize == 4 &&
"unexpected alignment requirements for DPRs");
483 if (LastPush != MBB.
end() &&
485 DefCFAOffsetCandidates.addExtraBytes(LastPush, DPRGapSize);
489 DefCFAOffsetCandidates.addInst(std::prev(MBBI), DPRGapSize);
497 while (MBBI != MBB.
end() && MBBI->getOpcode() == ARM::VSTMDDB_UPD) {
512 NumBytes = DPRCSOffset;
517 if (NumWords < 65536)
533 BuildMI(MBB, MBBI, dl, TII.get(ARM::tBL))
535 .addExternalSymbol(
"__chkstk")
540 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi32imm), ARM::R12)
541 .addExternalSymbol(
"__chkstk")
544 BuildMI(MBB, MBBI, dl, TII.get(ARM::tBLXr))
552 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2SUBrr), ARM::SP)
565 DefCFAOffsetCandidates.addExtraBytes(LastPush, NumBytes);
569 DefCFAOffsetCandidates.addInst(std::prev(MBBI), NumBytes);
594 dl,
TII, FramePtr, ARM::SP,
595 PushSize + FramePtrOffsetInPush,
597 if (FramePtrOffsetInPush + PushSize != 0) {
600 -(ArgRegsSaveSize - FramePtrOffsetInPush)));
601 BuildMI(MBB, AfterPush, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
602 .addCFIIndex(CFIIndex)
608 BuildMI(MBB, AfterPush, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
609 .addCFIIndex(CFIIndex)
617 if (GPRCS1Size > 0) {
620 for (
const auto &Entry : CSI) {
621 unsigned Reg = Entry.getReg();
622 int FI = Entry.getFrameIdx();
643 BuildMI(MBB, Pos, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
644 .addCFIIndex(CFIIndex)
651 if (GPRCS2Size > 0) {
653 for (
const auto &Entry : CSI) {
654 unsigned Reg = Entry.getReg();
655 int FI = Entry.getFrameIdx();
667 BuildMI(MBB, Pos, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
668 .addCFIIndex(CFIIndex)
680 for (
const auto &Entry : CSI) {
681 unsigned Reg = Entry.getReg();
682 int FI = Entry.getFrameIdx();
683 if ((Reg >= ARM::D0 && Reg <= ARM::D31) &&
689 BuildMI(MBB, Pos, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
690 .addCFIIndex(CFIIndex)
700 DefCFAOffsetCandidates.emitDefCFAOffsets(MBB, dl, TII, HasFP);
734 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), ARM::SP)
774 "This emitEpilogue does not support Thumb1!");
779 unsigned FramePtr = RegInfo->getFrameRegister(MF);
791 if (NumBytes - ArgRegsSaveSize != 0)
792 emitSPUpdate(isARM, MBB, MBBI, dl, TII, NumBytes - ArgRegsSaveSize);
795 const MCPhysReg *CSRegs = RegInfo->getCalleeSavedRegs(&MF);
796 if (MBBI != MBB.
begin()) {
805 NumBytes -= (ArgRegsSaveSize +
828 "No scratch register to restore SP from FP!");
831 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), ARM::SP)
838 BuildMI(MBB, MBBI, dl, TII.get(ARM::MOVr), ARM::SP)
843 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), ARM::SP)
847 }
else if (NumBytes &&
856 while (MBBI != MBB.
end() && MBBI->getOpcode() == ARM::VLDMDIA_UPD)
861 "unexpected DPR alignment gap");
870 emitSPUpdate(isARM, MBB, MBBI, dl, TII, ArgRegsSaveSize);
879 unsigned &FrameReg)
const {
885 int FI,
unsigned &FrameReg,
904 if (RegInfo->needsStackRealignment(MF)) {
905 assert(
hasFP(MF) &&
"dynamic stack realignment without a FP!");
909 }
else if (hasMovingSP) {
911 "VLAs and dynamic stack alignment, but missing base pointer!");
925 }
else if (hasMovingSP) {
931 if (FPOffset >= -255 && FPOffset < 0) {
942 if (Offset >= 0 && (Offset & 3) == 0 && Offset <= 1020)
950 }
else if (Offset > (FPOffset < 0 ? -FPOffset : FPOffset)) {
964 const std::vector<CalleeSavedInfo> &CSI,
965 unsigned StmOpc,
unsigned StrOpc,
967 bool(*Func)(
unsigned,
bool),
968 unsigned NumAlignedDPRCS2Regs,
969 unsigned MIFlags)
const {
976 using RegAndKill = std::pair<unsigned, bool>;
979 unsigned i = CSI.
size();
981 unsigned LastReg = 0;
982 for (; i != 0; --i) {
983 unsigned Reg = CSI[i-1].getReg();
987 if (Reg >= ARM::D8 && Reg < ARM::D8 + NumAlignedDPRCS2Regs)
997 if (NoGap && LastReg && LastReg != Reg-1)
1005 Regs.
push_back(std::make_pair(Reg, !isLiveIn));
1011 llvm::sort(Regs, [&](
const RegAndKill &LHS,
const RegAndKill &RHS) {
1015 if (Regs.
size() > 1 || StrOpc== 0) {
1020 for (
unsigned i = 0, e = Regs.
size(); i < e; ++i)
1022 }
else if (Regs.
size() == 1) {
1023 BuildMI(MBB, MI, DL, TII.
get(StrOpc), ARM::SP)
1035 if (MI != MBB.
begin())
1042 std::vector<CalleeSavedInfo> &CSI,
1043 unsigned LdmOpc,
unsigned LdrOpc,
1044 bool isVarArg,
bool NoGap,
1045 bool(*Func)(
unsigned,
bool),
1046 unsigned NumAlignedDPRCS2Regs)
const {
1052 bool isTailCall =
false;
1053 bool isInterrupt =
false;
1054 bool isTrap =
false;
1055 if (MBB.
end() !=
MI) {
1056 DL = MI->getDebugLoc();
1057 unsigned RetOpcode = MI->getOpcode();
1058 isTailCall = (RetOpcode == ARM::TCRETURNdi || RetOpcode == ARM::TCRETURNri);
1060 RetOpcode == ARM::SUBS_PC_LR || RetOpcode == ARM::t2SUBS_PC_LR;
1062 RetOpcode ==
ARM::TRAP || RetOpcode == ARM::TRAPNaCl ||
1063 RetOpcode == ARM::tTRAP;
1067 unsigned i = CSI.
size();
1069 unsigned LastReg = 0;
1070 bool DeleteRet =
false;
1071 for (; i != 0; --i) {
1077 if (Reg >= ARM::D8 && Reg < ARM::D8 + NumAlignedDPRCS2Regs)
1080 if (Reg == ARM::LR && !isTailCall && !isVarArg && !isInterrupt &&
1097 if (NoGap && LastReg && LastReg != Reg-1)
1107 llvm::sort(Regs, [&](
unsigned LHS,
unsigned RHS) {
1111 if (Regs.
size() > 1 || LdrOpc == 0) {
1115 for (
unsigned i = 0, e = Regs.
size(); i < e; ++i)
1118 if (MI != MBB.
end()) {
1120 MI->eraseFromParent();
1124 }
else if (Regs.
size() == 1) {
1127 if (Regs[0] == ARM::PC)
1130 BuildMI(MBB, MI, DL, TII.
get(LdrOpc), Regs[0])
1135 if (LdrOpc == ARM::LDR_POST_REG || LdrOpc == ARM::LDR_POST_IMM) {
1146 if (MI != MBB.
end())
1156 unsigned NumAlignedDPRCS2Regs,
1157 const std::vector<CalleeSavedInfo> &CSI,
1168 for (
unsigned i = 0, e = CSI.size(); i != e; ++i) {
1169 unsigned DNum = CSI[i].getReg() - ARM::D8;
1170 if (DNum > NumAlignedDPRCS2Regs - 1)
1172 int FI = CSI[i].getFrameIdx();
1200 unsigned Opc = isThumb ? ARM::t2SUBri : ARM::SUBri;
1203 .
addImm(8 * NumAlignedDPRCS2Regs)
1219 Opc = isThumb ? ARM::tMOVr : ARM::MOVr;
1228 unsigned NextReg = ARM::D8;
1232 if (NumAlignedDPRCS2Regs >= 6) {
1234 &ARM::QQPRRegClass);
1243 NumAlignedDPRCS2Regs -= 4;
1248 unsigned R4BaseReg = NextReg;
1251 if (NumAlignedDPRCS2Regs >= 4) {
1253 &ARM::QQPRRegClass);
1262 NumAlignedDPRCS2Regs -= 4;
1266 if (NumAlignedDPRCS2Regs >= 2) {
1276 NumAlignedDPRCS2Regs -= 2;
1280 if (NumAlignedDPRCS2Regs) {
1286 .
addImm((NextReg - R4BaseReg) * 2)
1298 unsigned NumAlignedDPRCS2Regs) {
1303 assert(MI->mayStore() &&
"Expecting spill instruction");
1306 switch(NumAlignedDPRCS2Regs) {
1309 assert(MI->mayStore() &&
"Expecting spill instruction");
1313 assert(MI->mayStore() &&
"Expecting spill instruction");
1329 unsigned NumAlignedDPRCS2Regs,
1330 const std::vector<CalleeSavedInfo> &CSI,
1339 for (
unsigned i = 0, e = CSI.size(); i != e; ++i)
1340 if (CSI[i].
getReg() == ARM::D8) {
1341 D8SpillFI = CSI[i].getFrameIdx();
1353 unsigned Opc = isThumb ? ARM::t2ADDri : ARM::ADDri;
1355 .addFrameIndex(D8SpillFI)
1361 unsigned NextReg = ARM::D8;
1364 if (NumAlignedDPRCS2Regs >= 6) {
1366 &ARM::QQPRRegClass);
1367 BuildMI(MBB, MI, DL, TII.
get(ARM::VLD1d64Qwb_fixed), NextReg)
1374 NumAlignedDPRCS2Regs -= 4;
1379 unsigned R4BaseReg = NextReg;
1382 if (NumAlignedDPRCS2Regs >= 4) {
1384 &ARM::QQPRRegClass);
1385 BuildMI(MBB, MI, DL, TII.
get(ARM::VLD1d64Q), NextReg)
1391 NumAlignedDPRCS2Regs -= 4;
1395 if (NumAlignedDPRCS2Regs >= 2) {
1398 BuildMI(MBB, MI, DL, TII.
get(ARM::VLD1q64), SupReg)
1403 NumAlignedDPRCS2Regs -= 2;
1407 if (NumAlignedDPRCS2Regs)
1408 BuildMI(MBB, MI, DL, TII.
get(ARM::VLDRD), NextReg)
1410 .
addImm(2 * (NextReg - R4BaseReg))
1419 const std::vector<CalleeSavedInfo> &CSI,
1427 unsigned PushOpc = AFI->
isThumbFunction() ? ARM::t2STMDB_UPD : ARM::STMDB_UPD;
1429 ARM::t2STR_PRE : ARM::STR_PRE_IMM;
1430 unsigned FltOpc = ARM::VSTMDDB_UPD;
1442 if (NumAlignedDPRCS2Regs)
1450 std::vector<CalleeSavedInfo> &CSI,
1462 if (NumAlignedDPRCS2Regs)
1465 unsigned PopOpc = AFI->
isThumbFunction() ? ARM::t2LDMIA_UPD : ARM::LDMIA_UPD;
1466 unsigned LdrOpc = AFI->
isThumbFunction() ? ARM::t2LDR_POST :ARM::LDR_POST_IMM;
1467 unsigned FltOpc = ARM::VLDMDIA_UPD;
1469 NumAlignedDPRCS2Regs);
1470 emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg,
false,
1472 emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg,
false,
1481 unsigned FnSize = 0;
1482 for (
auto &MBB : MF) {
1483 for (
auto &MI : MBB)
1496 unsigned Limit = (1 << 12) - 1;
1497 for (
auto &MBB : MF) {
1498 for (
auto &MI : MBB) {
1499 for (
unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
1500 if (!MI.getOperand(i).isFI())
1505 if (MI.getOpcode() == ARM::ADDri) {
1506 Limit = std::min(Limit, (1U << 8) - 1);
1514 Limit = std::min(Limit, (1U << 8) - 1);
1519 Limit = std::min(Limit, ((1U << 8) - 1) * 4);
1525 Limit = std::min(Limit, (1U << 8) - 1);
1557 if (!static_cast<const ARMSubtarget &>(MF.
getSubtarget()).hasNEON())
1565 if (!static_cast<const ARMBaseRegisterInfo *>(
1574 unsigned NumSpills = 0;
1575 for (; NumSpills < 8; ++NumSpills)
1576 if (!SavedRegs.
test(ARM::D8 + NumSpills))
1598 bool CanEliminateFrame =
true;
1599 bool CS1Spilled =
false;
1600 bool LRSpilled =
false;
1601 unsigned NumGPRSpills = 0;
1602 unsigned NumFPRSpills = 0;
1622 (MFI.hasVarSizedObjects() || RegInfo->needsStackRealignment(MF)))
1633 SavedRegs.
set(ARM::LR);
1639 SavedRegs.
set(ARM::LR);
1647 if (MFI.hasVarSizedObjects() || RegInfo->needsStackRealignment(MF) ||
1648 MFI.estimateStackSize(MF) > 508)
1662 for (
unsigned i = 0; CSRegs[i]; ++i) {
1663 unsigned Reg = CSRegs[i];
1664 bool Spilled =
false;
1665 if (SavedRegs.
test(Reg)) {
1667 CanEliminateFrame =
false;
1670 if (!ARM::GPRRegClass.
contains(Reg)) {
1672 if (ARM::SPRRegClass.
contains(Reg))
1674 else if (ARM::DPRRegClass.
contains(Reg))
1676 else if (ARM::QPRRegClass.
contains(Reg))
1697 case ARM::R0:
case ARM::R1:
1713 case ARM::R0:
case ARM::R1:
1727 bool ForceLRSpill =
false;
1733 if (FnSize >= (1 << 11)) {
1734 CanEliminateFrame =
false;
1735 ForceLRSpill =
true;
1753 unsigned EstimatedStackSize =
1754 MFI.estimateStackSize(MF) + 4 * (NumGPRSpills + NumFPRSpills);
1757 int MaxFixedOffset = 0;
1758 for (
int I = MFI.getObjectIndexBegin();
I < 0; ++
I) {
1759 int MaxObjectOffset = MFI.getObjectOffset(
I) + MFI.getObjectSize(
I);
1760 MaxFixedOffset =
std::max(MaxFixedOffset, MaxObjectOffset);
1763 bool HasFP =
hasFP(MF);
1766 EstimatedStackSize += 4;
1770 EstimatedStackSize += MaxFixedOffset;
1772 EstimatedStackSize += 16;
1776 bool BigFrameOffsets = EstimatedStackSize >= EstimatedRSStackSizeLimit ||
1777 MFI.hasVarSizedObjects() ||
1780 (HasFP && (MaxFixedOffset - MaxFPOffset) >= (int)EstimatedRSStackSizeLimit);
1781 if (BigFrameOffsets ||
1786 SavedRegs.
set(FramePtr);
1790 SavedRegs.
set(ARM::LR);
1793 auto LRPos =
llvm::find(UnspilledCS1GPRs, ARM::LR);
1794 if (LRPos != UnspilledCS1GPRs.
end())
1795 UnspilledCS1GPRs.
erase(LRPos);
1798 if (
FPPos != UnspilledCS1GPRs.
end())
1801 if (FramePtr == ARM::R7)
1807 bool ExtraCSSpill =
false;
1824 int EntryRegDeficit = 0;
1825 for (
unsigned Reg : {ARM::R0, ARM::R1,
ARM::R2, ARM::R3}) {
1830 <<
" is unused argument register, EntryRegDeficit = " 1831 << EntryRegDeficit <<
"\n");
1838 <<
" return regs used, ExitRegDeficit = " 1839 << ExitRegDeficit <<
"\n");
1841 int RegDeficit =
std::max(EntryRegDeficit, ExitRegDeficit);
1850 <<
" is saved low register, RegDeficit = " 1851 << RegDeficit <<
"\n");
1857 <<
" is non-saved low register, adding to AvailableRegs\n");
1863 if (SavedRegs.
test(ARM::R7)) {
1866 << RegDeficit <<
"\n");
1871 <<
"%r7 is non-saved low register, adding to AvailableRegs\n");
1876 for (
unsigned Reg : {ARM::R8, ARM::R9, ARM::R10, ARM::R11}) {
1880 <<
" is saved high register, RegDeficit = " 1881 << RegDeficit <<
"\n");
1888 if ((EntryRegDeficit > ExitRegDeficit) &&
1891 if (SavedRegs.
test(ARM::LR)) {
1894 << RegDeficit <<
"\n");
1897 LLVM_DEBUG(
dbgs() <<
"%lr is not saved, adding to AvailableRegs\n");
1906 LLVM_DEBUG(
dbgs() <<
"Final RegDeficit = " << RegDeficit <<
"\n");
1907 for (; RegDeficit > 0 && !AvailableRegs.
empty(); --RegDeficit) {
1910 <<
" to make up reg deficit\n");
1916 ExtraCSSpill =
true;
1921 LLVM_DEBUG(
dbgs() <<
"After adding spills, RegDeficit = " << RegDeficit
1931 if (!LRSpilled && CS1Spilled && !ExpensiveLRRestore) {
1932 SavedRegs.
set(ARM::LR);
1935 LRPos =
llvm::find(UnspilledCS1GPRs, (
unsigned)ARM::LR);
1936 if (LRPos != UnspilledCS1GPRs.
end())
1937 UnspilledCS1GPRs.
erase(LRPos);
1939 ForceLRSpill =
false;
1941 ExtraCSSpill =
true;
1949 if (TargetAlign >= 8 && (NumGPRSpills & 1)) {
1950 if (CS1Spilled && !UnspilledCS1GPRs.
empty()) {
1951 for (
unsigned i = 0, e = UnspilledCS1GPRs.
size(); i != e; ++i) {
1952 unsigned Reg = UnspilledCS1GPRs[i];
1958 (Reg == ARM::LR && !ExpensiveLRRestore)) {
1961 <<
" to make up alignment\n");
1963 ExtraCSSpill =
true;
1968 unsigned Reg = UnspilledCS2GPRs.
front();
1971 <<
" to make up alignment\n");
1973 ExtraCSSpill =
true;
1982 if (BigFrameOffsets && !ExtraCSSpill) {
1985 unsigned NumExtras = TargetAlign / 4;
1987 while (NumExtras && !UnspilledCS1GPRs.
empty()) {
1988 unsigned Reg = UnspilledCS1GPRs.
back();
1999 while (NumExtras && !UnspilledCS2GPRs.
empty()) {
2000 unsigned Reg = UnspilledCS2GPRs.
back();
2008 if (NumExtras == 0) {
2009 for (
unsigned Reg : Extras) {
2012 ExtraCSSpill =
true;
2018 assert(RS &&
"Register scavenging not provided");
2028 SavedRegs.
set(ARM::LR);
2044 unsigned Amount = TII.getFrameSize(Old);
2053 "This eliminateCallFramePseudoInstr does not support Thumb1!");
2063 if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
2067 assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP);
2073 return MBB.
erase(I);
2081 unsigned Shifted = 0;
2086 while (!(Value & 0xC0000000)) {
2091 bool Carry = (Value & 0x00FFFFFF);
2092 Value = ((Value & 0xFF000000) >> 24) + Carry;
2094 if (Value & 0x0000100)
2095 Value = Value & 0x000001FC;
2098 Value = Value >> (Shifted - 24);
2100 Value = Value << (24 - Shifted);
2172 unsigned ScratchReg0 =
ARM::R4;
2173 unsigned ScratchReg1 = ARM::R5;
2174 uint64_t AlignedStackSize;
2190 if (BeforePrologueRegion.
insert(PredBB).second)
2193 }
while (!WalkList.
empty());
2203 BeforePrologueRegion.
insert(
B);
2205 for (
const auto &LI : PrologueMBB.
liveins()) {
2207 PredBB->addLiveIn(LI);
2213 BeforePrologueRegion.
erase(
B);
2240 BuildMI(PrevStackMBB, DL, TII.get(ARM::tPUSH))
2242 .addReg(ScratchReg0)
2243 .addReg(ScratchReg1);
2245 BuildMI(PrevStackMBB, DL, TII.get(ARM::STMDB_UPD))
2257 BuildMI(PrevStackMBB, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
2258 .addCFIIndex(CFIIndex);
2261 BuildMI(PrevStackMBB, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
2262 .addCFIIndex(CFIIndex);
2265 BuildMI(PrevStackMBB, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
2266 .addCFIIndex(CFIIndex);
2270 BuildMI(McrMBB, DL, TII.get(ARM::tMOVr), ScratchReg1)
2273 }
else if (CompareStackPointer) {
2274 BuildMI(McrMBB, DL, TII.get(ARM::MOVr), ScratchReg1)
2281 if (!CompareStackPointer && Thumb) {
2282 BuildMI(McrMBB, DL, TII.get(ARM::tSUBi8), ScratchReg1)
2284 .addReg(ScratchReg1)
2285 .addImm(AlignedStackSize)
2287 }
else if (!CompareStackPointer) {
2288 BuildMI(McrMBB, DL, TII.get(ARM::SUBri), ScratchReg1)
2290 .
addImm(AlignedStackSize)
2303 BuildMI(GetMBB, DL, TII.get(ARM::tLDRpci), ScratchReg0)
2304 .addConstantPoolIndex(CPI)
2308 BuildMI(GetMBB, DL, TII.get(ARM::tLDRi), ScratchReg0)
2309 .addReg(ScratchReg0)
2315 BuildMI(McrMBB, DL, TII.get(ARM::MRC), ScratchReg0)
2329 BuildMI(GetMBB, DL, TII.get(ARM::LDRi12), ScratchReg0)
2330 .addReg(ScratchReg0)
2337 Opcode = Thumb ? ARM::tCMPr : ARM::CMPrr;
2338 BuildMI(GetMBB, DL, TII.get(Opcode))
2339 .addReg(ScratchReg0)
2344 Opcode = Thumb ? ARM::tBcc : ARM::Bcc;
2345 BuildMI(GetMBB, DL, TII.get(Opcode)).addMBB(PostStackMBB)
2357 BuildMI(AllocMBB, DL, TII.get(ARM::tMOVi8), ScratchReg0)
2359 .addImm(AlignedStackSize)
2362 BuildMI(AllocMBB, DL, TII.get(ARM::MOVi), ScratchReg0)
2363 .addImm(AlignedStackSize)
2370 BuildMI(AllocMBB, DL, TII.get(ARM::tMOVi8), ScratchReg1)
2375 BuildMI(AllocMBB, DL, TII.get(ARM::MOVi), ScratchReg1)
2383 BuildMI(AllocMBB, DL, TII.get(ARM::tPUSH))
2387 BuildMI(AllocMBB, DL, TII.get(ARM::STMDB_UPD))
2398 BuildMI(AllocMBB, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
2399 .addCFIIndex(CFIIndex);
2402 BuildMI(AllocMBB, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
2403 .addCFIIndex(CFIIndex);
2407 BuildMI(AllocMBB, DL, TII.get(ARM::tBL))
2409 .addExternalSymbol(
"__morestack");
2412 .addExternalSymbol(
"__morestack");
2418 BuildMI(AllocMBB, DL, TII.get(ARM::tPOP))
2420 .addReg(ScratchReg0);
2421 BuildMI(AllocMBB, DL, TII.get(ARM::tMOVr), ARM::LR)
2422 .addReg(ScratchReg0)
2425 BuildMI(AllocMBB, DL, TII.get(ARM::t2LDR_POST))
2433 BuildMI(AllocMBB, DL, TII.get(ARM::LDMIA_UPD))
2445 BuildMI(AllocMBB, DL, TII.get(ARM::tPOP))
2447 .addReg(ScratchReg0)
2448 .addReg(ScratchReg1);
2450 BuildMI(AllocMBB, DL, TII.get(ARM::LDMIA_UPD))
2460 BuildMI(AllocMBB, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
2461 .addCFIIndex(CFIIndex);
2469 BuildMI(PostStackMBB, DL, TII.get(ARM::tPOP))
2471 .addReg(ScratchReg0)
2472 .addReg(ScratchReg1);
2474 BuildMI(PostStackMBB, DL, TII.get(ARM::LDMIA_UPD))
2484 BuildMI(PostStackMBB, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
2485 .addCFIIndex(CFIIndex);
2491 BuildMI(PostStackMBB, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
2492 .addCFIIndex(CFIIndex);
2495 BuildMI(PostStackMBB, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
2496 .addCFIIndex(CFIIndex);
2499 PostStackMBB->addSuccessor(&PrologueMBB);
2510 #ifdef EXPENSIVE_CHECKS bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
const MachineInstrBuilder & add(const MachineOperand &MO) const
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
int findFirstPredOperandIdx() const
Find the index of the first operand in the operand list that is used to represent the predicate...
static ARMConstantPoolSymbol * Create(LLVMContext &C, StringRef s, unsigned ID, unsigned char PCAdj)
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class represents lattice values for constants.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
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...
void push_back(const T &Elt)
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
ARMConstantPoolValue - ARM specific constantpool value.
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
unsigned getReg() const
getReg - Returns the register number.
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int Offset)
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
void adjustForSegmentedStacks(MachineFunction &MF, MachineBasicBlock &MBB) const override
Adjust the prologue to have the function use segmented stacks.
bool test(unsigned Idx) const
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
unsigned const TargetRegisterInfo * TRI
MachineModuleInfo & getMMI() const
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...
bool isThumb1Only() const
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.
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)
unsigned getSpillSize(const TargetRegisterClass &RC) const
Return the size in bytes of the stack slot allocated to hold a spilled copy of a register from class ...
return AArch64::GPR64RegClass contains(Reg)
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
const ARMBaseInstrInfo * getInstrInfo() const override
static const uint64_t kSplitStackAvailable
unsigned getSpillAlignment(const TargetRegisterClass &RC) const
Return the minimum required alignment in bytes for a spill slot for a register of this class...
void ReplaceUsesOfBlockWith(MachineBasicBlock *Old, MachineBasicBlock *New)
Given a machine basic block that branched to 'Old', change the code and CFG so that it branches to 'N...
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
Code Generation virtual methods...
bool isFrameAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
unsigned getFramePred(const MachineInstr &MI) const
Returns predicate register associated with the given frame instruction.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
const HexagonInstrInfo * TII
unsigned getNumOperands() const
Retuns the total number of operands.
Printable printReg(unsigned Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
virtual bool hasFP(const MachineFunction &MF) const =0
hasFP - Return true if the specified function should have a dedicated frame pointer register...
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.
MachineBasicBlock iterator that automatically skips over MIs that are inside bundles (i...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void emitT2RegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &dl, unsigned DestReg, unsigned BaseReg, int NumBytes, ARMCC::CondCodes Pred, unsigned PredReg, const ARMBaseInstrInfo &TII, unsigned MIFlags=0)
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
This file contains the simple types necessary to represent the attributes associated with functions a...
static int sizeOfSPAdjustment(const MachineInstr &MI)
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 ...
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
int getDwarfRegNum(unsigned RegNum, bool isEH) const
Map a target register to an equivalent dwarf register number.
bool keepFramePointer(const MachineFunction &MF) const override
Return true if the target wants to keep the frame pointer regardless of the function attribute "frame...
void setDPRCalleeSavedAreaOffset(unsigned o)
LLVM_NODISCARD unsigned addFrameInst(const MCCFIInstruction &Inst)
bool enableCalleeSaveSkip(const MachineFunction &MF) const override
Returns true if the target can safely skip saving callee-saved registers for noreturn nounwind functi...
unsigned getArgRegsSaveSize() const
void setFramePtrSpillOffset(unsigned o)
Context object for machine code objects.
static void emitRegPlusImmediate(bool isARM, MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &dl, const ARMBaseInstrInfo &TII, unsigned DestReg, unsigned SrcReg, int NumBytes, unsigned MIFlags=MachineInstr::NoFlags, ARMCC::CondCodes Pred=ARMCC::AL, unsigned PredReg=0)
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
unsigned getDPRCalleeSavedAreaSize() const
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)...
void setDPRCalleeSavedGapSize(unsigned s)
void setShouldRestoreSPFromFP(bool s)
unsigned getNumAlignedDPRCS2Regs() const
bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
const MCContext & getContext() const
int alignSPAdjust(int SPAdj) const
alignSPAdjust - This method aligns the stack adjustment to the correct alignment. ...
void setLRIsSpilledForFarJump(bool s)
bool isThumb2Function() const
virtual const TargetInstrInfo * getInstrInfo() const
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 shouldRestoreSPFromFP() const
void setHasNosplitStack(bool b)
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
Analysis containing CSE Info
auto count(R &&Range, const E &Element) -> typename std::iterator_traits< decltype(adl_begin(Range))>::difference_type
Wrapper function around std::count to count the number of times an element Element occurs in the give...
unsigned getKillRegState(bool B)
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
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)
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
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)
int ResolveFrameIndexReference(const MachineFunction &MF, int FI, unsigned &FrameReg, int SPAdj) const
initializer< Ty > init(const Ty &Val)
void addLiveIn(MCPhysReg PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
This file declares the machine register scavenger class.
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI) const override
restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee saved registers and returns...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
unsigned const MachineRegisterInfo * MRI
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...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
bool cannotEliminateFrame(const MachineFunction &MF) const
static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register)
.cfi_def_cfa_register modifies a rule for computing CFA.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
GetInstSize - Returns the size of the specified MachineInstr.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
unsigned getGPRCalleeSavedArea1Size() const
int getStackProtectorIndex() const
Return the index for the stack protector object.
unsigned getMaxAlignment() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
bool hasBasePointer(const MachineFunction &MF) const
void setGPRCalleeSavedArea2Size(unsigned s)
static int getMaxFPOffset(const Function &F, const ARMFunctionInfo &AFI)
We need the offset of the frame pointer relative to other MachineFrameInfo offsets which are encoded ...
TRAP - Trapping instruction.
unsigned getReturnRegsCount() const
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...
self_iterator getIterator()
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
iterator_range< pred_iterator > predecessors()
auto find_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range))
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly...
const ARMFrameLowering * getFrameLowering() const override
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
bool isThumb1OnlyFunction() const
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
void emitARMRegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const 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...
iterator erase(const_iterator CI)
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
auto find(R &&Range, const T &Val) -> decltype(adl_begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void sort(IteratorTy Start, IteratorTy End)
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.
int getFrameIndexReference(const MachineFunction &MF, int FI, unsigned &FrameReg) const override
getFrameIndexReference - Provide a base+offset reference to an FI slot for debug info.
unsigned getDPRCalleeSavedGapSize() const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
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)
unsigned getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call...
bool erase(PtrType Ptr)
erase - If the set contains the specified pointer, remove it and return true, otherwise return false...
unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO, unsigned IdxMode=0)
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
bool isTargetLinux() const
void addScavengingFrameIndex(int FI)
Add a scavenging frame index.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
static bool isARMArea2Register(unsigned Reg, bool isIOS)
bool isTargetAndroid() const
Information about stack frame layout on the target.
static void emitAligningInstructions(MachineFunction &MF, ARMFunctionInfo *AFI, const TargetInstrInfo &TII, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const 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...
LLVM_NODISCARD T pop_back_val()
unsigned getSORegOpc(ShiftOpc ShOp, unsigned Imm)
void setOffsetAdjustment(int Adj)
Set the correction for frame offsets.
void sortUniqueLiveIns()
Sorts and uniques the LiveIns vector.
unsigned getBaseRegister() const
const Function & getFunction() const
Return the LLVM function that this machine code represents.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
bool isPhysRegUsed(unsigned PhysReg) const
Return true if the specified register is modified or read in this function.
CodeModel::Model getCodeModel() const
Returns the code model.
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
ARMFrameLowering(const ARMSubtarget &sti)
const MachineInstrBuilder & copyImplicitOps(const MachineInstr &OtherMI) const
Copy all the implicit operands from OtherMI onto this one.
unsigned getReturnOpcode() const
Returns the correct return opcode for the current feature set.
unsigned getArgumentStackSize() 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...
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 isLiveIn(unsigned Reg) const
static bool isARMLowRegister(unsigned Reg)
isARMLowRegister - Returns true if the register is a low register (r0-r7).
Representation of each machine instruction.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
uint16_t getEncodingValue(unsigned RegNo) const
Returns the encoding for RegNo.
void setHasStackFrame(bool s)
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
unsigned getGPRCalleeSavedArea2Size() const
void setGPRCalleeSavedArea1Offset(unsigned o)
static MachineOperand condCodeOp(unsigned CCReg=0)
Get the operand corresponding to the conditional code result.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
bool verify(Pass *p=nullptr, const char *Banner=nullptr, bool AbortOnError=true) const
Run the current MachineFunction through the machine code verifier, useful for debugger use...
LLVM_NODISCARD bool empty() const
unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx, const TargetRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg...
StringRef getValueAsString() const
Return the attribute's value as a string.
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
bool isReturnAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
const ARMBaseRegisterInfo * getRegisterInfo() const override
virtual const TargetFrameLowering * getFrameLowering() const
void setDPRCalleeSavedAreaSize(unsigned s)
bool hasStackFrame() const
int getOffsetAdjustment() const
Return the correction for frame offsets.
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
iterator_range< livein_iterator > liveins() const
static bool isARMArea3Register(unsigned Reg, bool isIOS)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void insert(iterator MBBI, MachineBasicBlock *MBB)
static bool WindowsRequiresStackProbe(const MachineFunction &MF, size_t StackSizeInBytes)
const MCRegisterInfo * getRegisterInfo() const
bool needsStackRealignment(const MachineFunction &MF) const
True if storage within the function requires the stack pointer to be aligned more than the normal cal...
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 getFramePtrSpillOffset() const
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
bool isTargetWindows() const
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.
static bool isCSRestore(MachineInstr &MI, const ARMBaseInstrInfo &TII, const MCPhysReg *CSRegs)
BitVector getPristineRegs(const MachineFunction &MF) const
Return a set of physical registers that are pristine.
static void checkNumAlignedDPRCS2Regs(MachineFunction &MF, BitVector &SavedRegs)
const MachineOperand & getOperand(unsigned i) const
bool hasTailCall() const
Returns true if the function contains a tail call.
void setObjectAlignment(int ObjectIdx, unsigned Align)
setObjectAlignment - Change the alignment of the specified stack object.
bool isThumbFunction() const
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...
unsigned getConstantPoolIndex(const Constant *C, unsigned Alignment)
getConstantPoolIndex - Create a new entry in the constant pool or return an existing one...
static void emitSPUpdate(bool isARM, MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &dl, const ARMBaseInstrInfo &TII, int NumBytes, unsigned MIFlags=MachineInstr::NoFlags, ARMCC::CondCodes Pred=ARMCC::AL, unsigned PredReg=0)
bool isReserved(unsigned PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
This class contains meta information specific to a module.