164#define DEBUG_TYPE "arm-frame-lowering"
170 cl::desc(
"Align ARM NEON spills in prolog and epilog"));
174 unsigned NumAlignedDPRCS2Regs);
233 if (CFSize >= ((1 << 12) - 1) / 2)
256 bool IsTailCallReturn =
false;
258 unsigned RetOpcode =
MBBI->getOpcode();
259 IsTailCallReturn = RetOpcode == ARM::TCRETURNdi ||
260 RetOpcode == ARM::TCRETURNri;
264 int ArgumentPopSize = 0;
265 if (IsTailCallReturn) {
271 ArgumentPopSize = StackAdjust.
getImm();
280 return ArgumentPopSize;
286 F.needsUnwindTableEntry();
294 unsigned Opc =
MBBI->getOpcode();
320 case ARM::t2MOVi16: {
321 bool Wide =
MBBI->getOperand(1).getImm() >= 256;
325 NewInstr.
add(
MBBI->getOperand(0));
343 case ARM::t2MOVi32imm:
361 if (
MBBI->getOperand(0).getReg() == ARM::SP &&
362 MBBI->getOperand(2).getReg() == ARM::SP &&
363 MBBI->getOperand(3).getImm() == -4) {
364 unsigned Reg =
RegInfo->getSEHRegNum(
MBBI->getOperand(1).getReg());
374 case ARM::t2LDR_POST:
375 if (
MBBI->getOperand(1).getReg() == ARM::SP &&
376 MBBI->getOperand(2).getReg() == ARM::SP &&
377 MBBI->getOperand(3).getImm() == 4) {
378 unsigned Reg =
RegInfo->getSEHRegNum(
MBBI->getOperand(0).getReg());
388 case ARM::t2LDMIA_RET:
389 case ARM::t2LDMIA_UPD:
390 case ARM::t2STMDB_UPD: {
393 for (
unsigned i = 4, NumOps =
MBBI->getNumOperands(); i != NumOps; ++i) {
400 if (Reg >= 8 && Reg <= 13)
402 else if (Opc == ARM::t2LDMIA_UPD && Reg == 14)
409 case ARM::t2LDMIA_RET:
410 NewOpc = ARM::tPOP_RET;
412 case ARM::t2LDMIA_UPD:
415 case ARM::t2STMDB_UPD:
423 for (
unsigned i = 2, NumOps =
MBBI->getNumOperands(); i != NumOps; ++i)
424 NewInstr.
add(
MBBI->getOperand(i));
430 (Opc == ARM::t2LDMIA_RET) ? ARM::SEH_SaveRegs_Ret : ARM::SEH_SaveRegs;
437 case ARM::VSTMDDB_UPD:
438 case ARM::VLDMDIA_UPD: {
441 unsigned Reg =
RegInfo->getSEHRegNum(MO.getReg());
459 case ARM::t2SUBspImm:
460 case ARM::t2SUBspImm12:
461 case ARM::t2ADDspImm:
462 case ARM::t2ADDspImm12:
470 if (
MBBI->getOperand(1).getReg() == ARM::SP &&
472 unsigned Reg =
RegInfo->getSEHRegNum(
MBBI->getOperand(0).getReg());
476 }
else if (
MBBI->getOperand(0).getReg() == ARM::SP &&
478 unsigned Reg =
RegInfo->getSEHRegNum(
MBBI->getOperand(1).getReg());
488 case ARM::TCRETURNri:
494 case ARM::TCRETURNdi:
507 return std::prev(
MBBI);
515 Start = std::next(Start);
519 for (
auto MI = Start;
MI !=
End;) {
520 auto Next = std::next(
MI);
524 MI = std::next(Next);
541 Pred, PredReg,
TII, MIFlags);
544 Pred, PredReg,
TII, MIFlags);
552 unsigned PredReg = 0) {
554 MIFlags, Pred, PredReg);
559 switch (
MI.getOpcode()) {
560 case ARM::VSTMDDB_UPD:
564 case ARM::t2STMDB_UPD:
568 case ARM::STR_PRE_IMM:
577 for (
int i =
MI.getNumOperands() - 1; i >= 4; --i)
583 size_t StackSizeInBytes) {
589 F.getFnAttributeAsParsedInteger(
"stack-probe-size", StackProbeSize);
590 return (StackSizeInBytes >= StackProbeSize) &&
591 !
F.hasFnAttribute(
"no-stack-arg-probe");
596struct StackAdjustingInsts {
606 bool BeforeFPSet =
false) {
607 InstInfo
Info = {
I, SPAdjust, BeforeFPSet};
614 assert(
Info != Insts.
end() &&
"invalid sp adjusting instruction");
615 Info->SPAdjust += ExtraBytes;
621 unsigned CFAOffset = 0;
622 for (
auto &
Info : Insts) {
623 if (HasFP && !
Info.BeforeFPSet)
626 CFAOffset +=
Info.SPAdjust;
630 TII.get(TargetOpcode::CFI_INSTRUCTION))
651 const Align Alignment,
652 const bool MustBeSingleInstruction) {
654 const bool CanUseBFC = AST.hasV6T2Ops() || AST.hasV7Ops();
655 const unsigned AlignMask = Alignment.
value() - 1U;
656 const unsigned NrBitsToZero =
Log2(Alignment);
673 }
else if (AlignMask <= 255) {
680 assert(!MustBeSingleInstruction &&
681 "Shouldn't call emitAligningInstructions demanding a single "
682 "instruction to be emitted for large stack alignment for a target "
720 int MaxRegBytes = 8 * 4;
724 MaxRegBytes = 11 * 4 + 8 * 8;
743 "This emitPrologue does not support Thumb1!");
749 int FPCXTSaveSize = 0;
760 unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
761 int FramePtrSpillFI = 0;
769 StackAdjustingInsts DefCFAOffsetCandidates;
770 bool HasFP =
hasFP(MF);
777 DefCFAOffsetCandidates.addInst(std::prev(
MBBI), NumBytes,
true);
780 DefCFAOffsetCandidates.emitDefCFAOffsets(
MBB, dl,
TII, HasFP);
794 int FI =
I.getFrameIdx();
799 FramePtrSpillFI = FI;
830 int FI =
I.getFrameIdx();
852 FramePtrSpillFI = FI;
875 if (FPCXTSaveSize > 0) {
877 DefCFAOffsetCandidates.addInst(LastPush, FPCXTSaveSize,
true);
881 if (ArgRegsSaveSize) {
884 LastPush = std::prev(
MBBI);
885 DefCFAOffsetCandidates.addInst(LastPush, ArgRegsSaveSize,
true);
889 if (GPRCS1Size > 0) {
890 GPRCS1Push = LastPush =
MBBI++;
891 DefCFAOffsetCandidates.addInst(LastPush, GPRCS1Size,
true);
895 unsigned FPCXTOffset = NumBytes - ArgRegsSaveSize - FPCXTSaveSize;
896 unsigned GPRCS1Offset = FPCXTOffset - GPRCS1Size;
897 unsigned GPRCS2Offset = GPRCS1Offset - GPRCS2Size;
899 unsigned DPRGapSize = GPRCS1Size + FPCXTSaveSize + ArgRegsSaveSize;
901 DPRGapSize += GPRCS2Size;
903 DPRGapSize %= DPRAlign.
value();
905 unsigned DPRCSOffset;
907 DPRCSOffset = GPRCS1Offset - DPRGapSize - DPRCSSize;
908 GPRCS2Offset = DPRCSOffset - GPRCS2Size;
910 DPRCSOffset = GPRCS2Offset - DPRGapSize - DPRCSSize;
912 int FramePtrOffsetInPush = 0;
916 "Max FP estimation is wrong");
917 FramePtrOffsetInPush = FPOffset + ArgRegsSaveSize + FPCXTSaveSize;
927 GPRCS2Push = LastPush =
MBBI++;
928 DefCFAOffsetCandidates.addInst(LastPush, GPRCS2Size);
934 assert(DPRGapSize == 4 &&
"unexpected alignment requirements for DPRs");
935 if (LastPush !=
MBB.
end() &&
937 DefCFAOffsetCandidates.addExtraBytes(LastPush, DPRGapSize);
941 DefCFAOffsetCandidates.addInst(std::prev(
MBBI), DPRGapSize);
949 while (
MBBI !=
MBB.
end() &&
MBBI->getOpcode() == ARM::VSTMDDB_UPD) {
964 NumBytes = DPRCSOffset;
967 GPRCS2Push = LastPush =
MBBI++;
968 DefCFAOffsetCandidates.addInst(LastPush, GPRCS2Size);
971 bool NeedsWinCFIStackAlloc = NeedsWinCFI;
973 NeedsWinCFIStackAlloc =
false;
978 if (NumWords < 65536) {
988 .
addImm(NumWords & 0xffff)
998 switch (
TM.getCodeModel()) {
1030 if (NeedsWinCFIStackAlloc) {
1031 SEH =
BuildMI(MF, dl,
TII.get(ARM::SEH_StackAlloc))
1044 DefCFAOffsetCandidates.addExtraBytes(LastPush, NumBytes);
1048 DefCFAOffsetCandidates.addInst(std::prev(
MBBI), NumBytes);
1074 AfterPush = std::next(GPRCS1Push);
1076 int FPOffset = PushSize + FramePtrOffsetInPush;
1078 AfterPush = std::next(GPRCS2Push);
1087 if (FramePtrOffsetInPush + PushSize != 0) {
1090 FPCXTSaveSize + ArgRegsSaveSize - FramePtrOffsetInPush));
1091 BuildMI(
MBB, AfterPush, dl,
TII.get(TargetOpcode::CFI_INSTRUCTION))
1098 BuildMI(
MBB, AfterPush, dl,
TII.get(TargetOpcode::CFI_INSTRUCTION))
1120 if (GPRCS1Size > 0 && !NeedsWinCFI) {
1123 for (
const auto &Entry : CSI) {
1125 int FI = Entry.getFrameIdx();
1146 BuildMI(
MBB, Pos, dl,
TII.get(TargetOpcode::CFI_INSTRUCTION))
1154 if (GPRCS2Size > 0 && !NeedsWinCFI) {
1156 for (
const auto &Entry : CSI) {
1158 int FI = Entry.getFrameIdx();
1166 unsigned DwarfReg =
MRI->getDwarfRegNum(
1167 Reg == ARM::R12 ? ARM::RA_AUTH_CODE : Reg,
true);
1171 BuildMI(
MBB, Pos, dl,
TII.get(TargetOpcode::CFI_INSTRUCTION))
1180 if (DPRCSSize > 0 && !NeedsWinCFI) {
1184 for (
const auto &Entry : CSI) {
1186 int FI = Entry.getFrameIdx();
1187 if ((Reg >= ARM::D0 && Reg <= ARM::D31) &&
1189 unsigned DwarfReg =
MRI->getDwarfRegNum(Reg,
true);
1193 BuildMI(
MBB, Pos, dl,
TII.get(TargetOpcode::CFI_INSTRUCTION))
1205 DefCFAOffsetCandidates.emitDefCFAOffsets(
MBB, dl,
TII, HasFP);
1280 "This emitEpilogue does not support Thumb1!");
1310 if (NumBytes + IncomingArgStackToRestore != 0)
1312 NumBytes + IncomingArgStackToRestore,
1332 NumBytes -= (ReservedArgStack +
1357 "No scratch register to restore SP from FP!");
1379 }
else if (NumBytes &&
1392 while (
MBBI !=
MBB.
end() &&
MBBI->getOpcode() == ARM::VLDMDIA_UPD)
1397 "unexpected DPR alignment gap");
1406 if (ReservedArgStack || IncomingArgStackToRestore) {
1407 assert((
int)ReservedArgStack + IncomingArgStackToRestore >= 0 &&
1408 "attempting to restore negative stack amount");
1410 ReservedArgStack + IncomingArgStackToRestore,
1459 if (RegInfo->hasStackRealignment(MF)) {
1460 assert(
hasFP(MF) &&
"dynamic stack realignment without a FP!");
1464 }
else if (hasMovingSP) {
1466 "VLAs and dynamic stack alignment, but missing base pointer!");
1480 }
else if (hasMovingSP) {
1486 if (FPOffset >= -255 && FPOffset < 0) {
1505 }
else if (
Offset > (FPOffset < 0 ? -FPOffset : FPOffset)) {
1524 unsigned StmOpc,
unsigned StrOpc,
1525 bool NoGap,
bool (*Func)(
unsigned,
bool),
1526 unsigned NumAlignedDPRCS2Regs,
1527 unsigned MIFlags)
const {
1534 using RegAndKill = std::pair<unsigned, bool>;
1537 unsigned i = CSI.
size();
1539 unsigned LastReg = 0;
1540 for (; i != 0; --i) {
1545 if (Reg >= ARM::D8 && Reg < ARM::D8 + NumAlignedDPRCS2Regs)
1549 bool isLiveIn =
MRI.isLiveIn(Reg);
1550 if (!isLiveIn && !
MRI.isReserved(Reg))
1555 if (NoGap && LastReg && LastReg != Reg-1)
1563 Regs.
push_back(std::make_pair(Reg, !isLiveIn));
1569 llvm::sort(Regs, [&](
const RegAndKill &LHS,
const RegAndKill &RHS) {
1570 return TRI.getEncodingValue(
LHS.first) <
TRI.getEncodingValue(
RHS.first);
1573 if (Regs.
size() > 1 || StrOpc== 0) {
1578 for (
unsigned i = 0, e = Regs.
size(); i < e; ++i)
1580 }
else if (Regs.
size() == 1) {
1601 unsigned LdmOpc,
unsigned LdrOpc,
1602 bool isVarArg,
bool NoGap,
1603 bool (*Func)(
unsigned,
bool),
1604 unsigned NumAlignedDPRCS2Regs)
const {
1611 bool isTailCall =
false;
1612 bool isInterrupt =
false;
1613 bool isTrap =
false;
1614 bool isCmseEntry =
false;
1616 DL =
MI->getDebugLoc();
1617 unsigned RetOpcode =
MI->getOpcode();
1618 isTailCall = (RetOpcode == ARM::TCRETURNdi || RetOpcode == ARM::TCRETURNri);
1620 RetOpcode == ARM::SUBS_PC_LR || RetOpcode == ARM::t2SUBS_PC_LR;
1622 RetOpcode == ARM::TRAP || RetOpcode == ARM::TRAPNaCl ||
1623 RetOpcode == ARM::tTRAP;
1624 isCmseEntry = (RetOpcode == ARM::tBXNS || RetOpcode == ARM::tBXNS_RET);
1628 unsigned i = CSI.
size();
1630 unsigned LastReg = 0;
1631 bool DeleteRet =
false;
1632 for (; i != 0; --i) {
1638 if (Reg >= ARM::D8 && Reg < ARM::D8 + NumAlignedDPRCS2Regs)
1640 if (Reg == ARM::LR && !isTailCall && !isVarArg && !isInterrupt &&
1653 if (NoGap && LastReg && LastReg != Reg-1)
1663 llvm::sort(Regs, [&](
unsigned LHS,
unsigned RHS) {
1664 return TRI.getEncodingValue(LHS) <
TRI.getEncodingValue(RHS);
1667 if (Regs.
size() > 1 || LdrOpc == 0) {
1672 for (
unsigned i = 0, e = Regs.
size(); i < e; ++i)
1677 MI->eraseFromParent();
1681 }
else if (Regs.
size() == 1) {
1684 if (Regs[0] == ARM::PC)
1693 if (LdrOpc == ARM::LDR_POST_REG || LdrOpc == ARM::LDR_POST_IMM) {
1714 unsigned NumAlignedDPRCS2Regs,
1727 unsigned DNum =
I.getReg() - ARM::D8;
1728 if (DNum > NumAlignedDPRCS2Regs - 1)
1730 int FI =
I.getFrameIdx();
1758 unsigned Opc =
isThumb ? ARM::t2SUBri : ARM::SUBri;
1761 .
addImm(8 * NumAlignedDPRCS2Regs)
1777 Opc =
isThumb ? ARM::tMOVr : ARM::MOVr;
1786 unsigned NextReg = ARM::D8;
1790 if (NumAlignedDPRCS2Regs >= 6) {
1791 unsigned SupReg =
TRI->getMatchingSuperReg(NextReg, ARM::dsub_0,
1792 &ARM::QQPRRegClass);
1801 NumAlignedDPRCS2Regs -= 4;
1806 unsigned R4BaseReg = NextReg;
1809 if (NumAlignedDPRCS2Regs >= 4) {
1810 unsigned SupReg =
TRI->getMatchingSuperReg(NextReg, ARM::dsub_0,
1811 &ARM::QQPRRegClass);
1820 NumAlignedDPRCS2Regs -= 4;
1824 if (NumAlignedDPRCS2Regs >= 2) {
1825 unsigned SupReg =
TRI->getMatchingSuperReg(NextReg, ARM::dsub_0,
1834 NumAlignedDPRCS2Regs -= 2;
1838 if (NumAlignedDPRCS2Regs) {
1844 .
addImm((NextReg - R4BaseReg) * 2)
1856 unsigned NumAlignedDPRCS2Regs) {
1861 assert(
MI->mayStore() &&
"Expecting spill instruction");
1864 switch(NumAlignedDPRCS2Regs) {
1867 assert(
MI->mayStore() &&
"Expecting spill instruction");
1871 assert(
MI->mayStore() &&
"Expecting spill instruction");
1876 assert(
MI->killsRegister(ARM::R4) &&
"Missed kill flag");
1887 unsigned NumAlignedDPRCS2Regs,
1898 if (
I.getReg() == ARM::D8) {
1899 D8SpillFI =
I.getFrameIdx();
1911 unsigned Opc =
isThumb ? ARM::t2ADDri : ARM::ADDri;
1919 unsigned NextReg = ARM::D8;
1922 if (NumAlignedDPRCS2Regs >= 6) {
1923 unsigned SupReg =
TRI->getMatchingSuperReg(NextReg, ARM::dsub_0,
1924 &ARM::QQPRRegClass);
1932 NumAlignedDPRCS2Regs -= 4;
1937 unsigned R4BaseReg = NextReg;
1940 if (NumAlignedDPRCS2Regs >= 4) {
1941 unsigned SupReg =
TRI->getMatchingSuperReg(NextReg, ARM::dsub_0,
1942 &ARM::QQPRRegClass);
1949 NumAlignedDPRCS2Regs -= 4;
1953 if (NumAlignedDPRCS2Regs >= 2) {
1954 unsigned SupReg =
TRI->getMatchingSuperReg(NextReg, ARM::dsub_0,
1961 NumAlignedDPRCS2Regs -= 2;
1965 if (NumAlignedDPRCS2Regs)
1968 .
addImm(2 * (NextReg - R4BaseReg))
1984 unsigned PushOpc = AFI->
isThumbFunction() ? ARM::t2STMDB_UPD : ARM::STMDB_UPD;
1986 ARM::t2STR_PRE : ARM::STR_PRE_IMM;
1987 unsigned FltOpc = ARM::VSTMDDB_UPD;
1996 return C.getReg() == ARM::FPCXTNS;
2005 emitPushInst(
MBB,
MI, CSI, PushOpc, PushOneOpc,
false,
2009 emitPushInst(
MBB,
MI, CSI, PushOpc, PushOneOpc,
false,
2023 if (NumAlignedDPRCS2Regs)
2042 if (NumAlignedDPRCS2Regs)
2045 unsigned PopOpc = AFI->
isThumbFunction() ? ARM::t2LDMIA_UPD : ARM::LDMIA_UPD;
2048 unsigned FltOpc = ARM::VLDMDIA_UPD;
2050 emitPopInst(
MBB,
MI, CSI, PopOpc, LdrOpc, isVarArg,
false,
2053 NumAlignedDPRCS2Regs);
2054 emitPopInst(
MBB,
MI, CSI, PopOpc, LdrOpc, isVarArg,
false,
2058 NumAlignedDPRCS2Regs);
2059 emitPopInst(
MBB,
MI, CSI, PopOpc, LdrOpc, isVarArg,
false,
2061 emitPopInst(
MBB,
MI, CSI, PopOpc, LdrOpc, isVarArg,
false,
2071 unsigned FnSize = 0;
2072 for (
auto &
MBB : MF) {
2073 for (
auto &
MI :
MBB)
2074 FnSize +=
TII.getInstSizeInBytes(
MI);
2078 FnSize += Table.MBBs.size() * 4;
2089 bool &HasNonSPFrameIndex) {
2094 unsigned Limit = (1 << 12) - 1;
2095 for (
auto &
MBB : MF) {
2096 for (
auto &
MI :
MBB) {
2097 if (
MI.isDebugInstr())
2099 for (
unsigned i = 0, e =
MI.getNumOperands(); i != e; ++i) {
2100 if (!
MI.getOperand(i).isFI())
2105 if (
MI.getOpcode() == ARM::ADDri) {
2106 Limit = std::min(Limit, (1U << 8) - 1);
2111 if (
MI.getOpcode() == ARM::t2ADDri ||
MI.getOpcode() == ARM::t2ADDri12)
2116 if (RegClass && !RegClass->
contains(ARM::SP))
2117 HasNonSPFrameIndex =
true;
2127 Limit = std::min(Limit, (1U << 8) - 1);
2130 Limit = std::min(Limit, ((1U << 8) - 1) * 2);
2135 Limit = std::min(Limit, ((1U << 8) - 1) * 4);
2141 Limit = std::min(Limit, (1U << 8) - 1);
2149 Limit = std::min(Limit, ((1U << 7) - 1) * 1);
2152 Limit = std::min(Limit, ((1U << 7) - 1) * 2);
2155 Limit = std::min(Limit, ((1U << 7) - 1) * 4);
2158 llvm_unreachable(
"Unhandled addressing mode in stack size limit calculation");
2199 unsigned NumSpills = 0;
2200 for (; NumSpills < 8; ++NumSpills)
2201 if (!SavedRegs.
test(ARM::D8 + NumSpills))
2212 SavedRegs.
set(ARM::R4);
2218 if (
STI.hasV8_1MMainlineOps() &&
2234 return Subtarget.createAAPCSFrameChainLeaf() ||
2248 for (
const auto &
MBB : MF)
2249 for (
const auto &
MI :
MBB)
2250 if (
MI.getOpcode() == ARM::tSTRspi ||
MI.getOpcode() == ARM::tSTRi ||
2251 STI.genExecuteOnly())
2252 for (
const auto &
Op :
MI.operands())
2256 if (ARM::hGPRRegClass.
contains(Reg) && Reg != ARM::SP)
2271 bool CS1Spilled =
false;
2272 bool LRSpilled =
false;
2273 unsigned NumGPRSpills = 0;
2274 unsigned NumFPRSpills = 0;
2294 (MFI.hasVarSizedObjects() || RegInfo->hasStackRealignment(MF)))
2295 SavedRegs.
set(ARM::R4);
2304 SavedRegs.
set(ARM::R4);
2305 SavedRegs.
set(ARM::LR);
2311 SavedRegs.
set(ARM::LR);
2319 if (MFI.hasVarSizedObjects() || RegInfo->hasStackRealignment(MF) ||
2320 MFI.estimateStackSize(MF) > 508)
2321 SavedRegs.
set(ARM::R4);
2333 CanEliminateFrame =
false;
2337 CanEliminateFrame =
false;
2342 for (
unsigned i = 0; CSRegs[i]; ++i) {
2343 unsigned Reg = CSRegs[i];
2344 bool Spilled =
false;
2345 if (SavedRegs.
test(Reg)) {
2347 CanEliminateFrame =
false;
2350 if (!ARM::GPRRegClass.
contains(Reg)) {
2352 if (ARM::SPRRegClass.
contains(Reg))
2354 else if (ARM::DPRRegClass.
contains(Reg))
2356 else if (ARM::QPRRegClass.
contains(Reg))
2377 case ARM::R0:
case ARM::R1:
2378 case ARM::R2:
case ARM::R3:
2379 case ARM::R4:
case ARM::R5:
2380 case ARM::R6:
case ARM::R7:
2393 case ARM::R0:
case ARM::R1:
2394 case ARM::R2:
case ARM::R3:
2395 case ARM::R4:
case ARM::R5:
2396 case ARM::R6:
case ARM::R7:
2407 bool ForceLRSpill =
false;
2412 if (FnSize >= (1 << 11)) {
2413 CanEliminateFrame =
false;
2414 ForceLRSpill =
true;
2432 unsigned EstimatedStackSize =
2433 MFI.estimateStackSize(MF) + 4 * (NumGPRSpills + NumFPRSpills);
2436 int MaxFixedOffset = 0;
2437 for (
int I = MFI.getObjectIndexBegin();
I < 0; ++
I) {
2438 int MaxObjectOffset = MFI.getObjectOffset(
I) + MFI.getObjectSize(
I);
2439 MaxFixedOffset = std::max(MaxFixedOffset, MaxObjectOffset);
2442 bool HasFP =
hasFP(MF);
2445 EstimatedStackSize += 4;
2449 EstimatedStackSize += MaxFixedOffset;
2451 EstimatedStackSize += 16;
2453 unsigned EstimatedRSStackSizeLimit, EstimatedRSFixedSizeLimit;
2454 bool HasNonSPFrameIndex =
false;
2475 EstimatedRSStackSizeLimit = (1U << 5) * 4;
2477 EstimatedRSStackSizeLimit = (1U << 8) * 4;
2478 EstimatedRSFixedSizeLimit = (1U << 5) * 4;
2480 EstimatedRSStackSizeLimit =
2482 EstimatedRSFixedSizeLimit = EstimatedRSStackSizeLimit;
2486 bool HasLargeStack = EstimatedStackSize > EstimatedRSStackSizeLimit;
2492 bool HasMovingSP = MFI.hasVarSizedObjects() ||
2494 bool HasBPOrFixedSP = RegInfo->
hasBasePointer(MF) || !HasMovingSP;
2503 bool HasLargeArgumentList =
2504 HasFP && (MaxFixedOffset - MaxFPOffset) > (
int)EstimatedRSFixedSizeLimit;
2506 bool BigFrameOffsets = HasLargeStack || !HasBPOrFixedSP ||
2507 HasLargeArgumentList || HasNonSPFrameIndex;
2508 LLVM_DEBUG(
dbgs() <<
"EstimatedLimit: " << EstimatedRSStackSizeLimit
2509 <<
"; EstimatedStack: " << EstimatedStackSize
2510 <<
"; EstimatedFPStack: " << MaxFixedOffset - MaxFPOffset
2511 <<
"; BigFrameOffsets: " << BigFrameOffsets <<
"\n");
2512 if (BigFrameOffsets ||
2523 SavedRegs.
set(ARM::LR);
2526 auto LRPos =
llvm::find(UnspilledCS1GPRs, ARM::LR);
2527 if (LRPos != UnspilledCS1GPRs.
end())
2528 UnspilledCS1GPRs.
erase(LRPos);
2531 if (FPPos != UnspilledCS1GPRs.
end())
2532 UnspilledCS1GPRs.
erase(FPPos);
2550 unsigned NumExtraCSSpill = 0;
2567 int EntryRegDeficit = 0;
2568 for (
unsigned Reg : {ARM::R0, ARM::R1, ARM::R2, ARM::R3}) {
2573 <<
" is unused argument register, EntryRegDeficit = "
2574 << EntryRegDeficit <<
"\n");
2581 <<
" return regs used, ExitRegDeficit = "
2582 << ExitRegDeficit <<
"\n");
2584 int RegDeficit = std::max(EntryRegDeficit, ExitRegDeficit);
2589 for (
unsigned Reg : {ARM::R4, ARM::R5, ARM::R6}) {
2590 if (SavedRegs.
test(Reg)) {
2593 <<
" is saved low register, RegDeficit = "
2594 << RegDeficit <<
"\n");
2600 <<
" is non-saved low register, adding to AvailableRegs\n");
2605 if (!HasFP ||
FramePtr != ARM::R7) {
2606 if (SavedRegs.
test(ARM::R7)) {
2609 << RegDeficit <<
"\n");
2614 <<
"%r7 is non-saved low register, adding to AvailableRegs\n");
2619 for (
unsigned Reg : {ARM::R8, ARM::R9, ARM::R10, ARM::R11}) {
2620 if (SavedRegs.
test(Reg)) {
2623 <<
" is saved high register, RegDeficit = "
2624 << RegDeficit <<
"\n");
2631 if ((EntryRegDeficit > ExitRegDeficit) &&
2634 if (SavedRegs.
test(ARM::LR)) {
2637 << RegDeficit <<
"\n");
2640 LLVM_DEBUG(
dbgs() <<
"%lr is not saved, adding to AvailableRegs\n");
2649 LLVM_DEBUG(
dbgs() <<
"Final RegDeficit = " << RegDeficit <<
"\n");
2650 for (; RegDeficit > 0 && !AvailableRegs.
empty(); --RegDeficit) {
2653 <<
" to make up reg deficit\n");
2657 assert(!
MRI.isReserved(Reg) &&
"Should not be reserved");
2658 if (Reg != ARM::LR && !
MRI.isPhysRegUsed(Reg))
2664 LLVM_DEBUG(
dbgs() <<
"After adding spills, RegDeficit = " << RegDeficit
2674 if (!LRSpilled && CS1Spilled && !ExpensiveLRRestore) {
2675 SavedRegs.
set(ARM::LR);
2678 LRPos =
llvm::find(UnspilledCS1GPRs, (
unsigned)ARM::LR);
2679 if (LRPos != UnspilledCS1GPRs.
end())
2680 UnspilledCS1GPRs.
erase(LRPos);
2682 ForceLRSpill =
false;
2683 if (!
MRI.isReserved(ARM::LR) && !
MRI.isPhysRegUsed(ARM::LR) &&
2693 if (TargetAlign >=
Align(8) && (NumGPRSpills & 1)) {
2694 if (CS1Spilled && !UnspilledCS1GPRs.
empty()) {
2695 for (
unsigned Reg : UnspilledCS1GPRs) {
2701 (Reg == ARM::LR && !ExpensiveLRRestore)) {
2704 <<
" to make up alignment\n");
2705 if (!
MRI.isReserved(Reg) && !
MRI.isPhysRegUsed(Reg) &&
2712 unsigned Reg = UnspilledCS2GPRs.
front();
2715 <<
" to make up alignment\n");
2716 if (!
MRI.isReserved(Reg) && !
MRI.isPhysRegUsed(Reg))
2727 unsigned RegsNeeded = 0;
2736 if (RegsNeeded > NumExtraCSSpill) {
2739 unsigned NumExtras = TargetAlign.
value() / 4;
2741 while (NumExtras && !UnspilledCS1GPRs.
empty()) {
2743 if (!
MRI.isReserved(Reg) &&
2751 while (NumExtras && !UnspilledCS2GPRs.
empty()) {
2753 if (!
MRI.isReserved(Reg)) {
2759 if (NumExtras == 0) {
2760 for (
unsigned Reg : Extras) {
2762 if (!
MRI.isPhysRegUsed(Reg))
2766 while ((RegsNeeded > NumExtraCSSpill) && RS) {
2770 unsigned Size =
TRI->getSpillSize(RC);
2771 Align Alignment =
TRI->getSpillAlign(RC);
2773 MFI.CreateStackObject(
Size, Alignment,
false));
2780 SavedRegs.
set(ARM::LR);
2793 if (
Info.getReg() != ARM::LR)
2797 return !Term.isReturn() || Term.getOpcode() == ARM::LDMIA_RET ||
2798 Term.getOpcode() == ARM::t2LDMIA_RET ||
2799 Term.getOpcode() == ARM::tPOP_RET;
2802 Info.setRestored(
false);
2823 SavedRegs.
set(ARM::R0);
2828 std::vector<CalleeSavedInfo> &CSI)
const {
2831 if (
STI.hasV8_1MMainlineOps() &&
2833 CSI.emplace_back(ARM::FPCXTNS);
2834 CSI.back().setRestored(
false);
2848 [=](
const auto &CS) {
2850 return Reg == ARM::R10 || Reg == ARM::R11 ||
2851 Reg == ARM::R8 || Reg == ARM::R9 ||
2852 ARM::DPRRegClass.contains(Reg);
2862 static const SpillSlot FixedSpillOffsets[] = {{ARM::FPCXTNS, -4}};
2863 NumEntries = std::size(FixedSpillOffsets);
2864 return FixedSpillOffsets;
2875 unsigned Opc =
I->getOpcode();
2876 bool IsDestroy = Opc ==
TII.getCallFrameDestroyOpcode();
2877 unsigned CalleePopAmount = IsDestroy ?
I->getOperand(1).getImm() : 0;
2880 "This eliminateCallFramePseudoInstr does not support Thumb1!");
2882 int PIdx =
I->findFirstPredOperandIdx();
2886 unsigned PredReg =
TII.getFramePred(*
I);
2890 if (IsDestroy && CalleePopAmount != -1U)
2896 unsigned Amount =
TII.getFrameSize(*
I);
2903 if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
2907 assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP);
2912 }
else if (CalleePopAmount != -1U) {
2926 unsigned Shifted = 0;
2931 while (!(
Value & 0xC0000000)) {
2936 bool Carry = (
Value & 0x00FFFFFF);
2937 Value = ((
Value & 0xFF000000) >> 24) + Carry;
2939 if (
Value & 0x0000100)
2983 bool Thumb = ST->isThumb();
2984 bool Thumb2 = ST->isThumb2();
2990 if (!ST->isTargetAndroid() && !ST->isTargetLinux())
3009 unsigned ScratchReg0 = ARM::R4;
3010 unsigned ScratchReg1 = ARM::R5;
3011 unsigned MovOp = ST->useMovt() ? ARM::t2MOVi32imm : ARM::tMOVi32imm;
3028 if (BeforePrologueRegion.
insert(PredBB).second)
3031 }
while (!WalkList.
empty());
3041 BeforePrologueRegion.
insert(
B);
3043 for (
const auto &LI : PrologueMBB.
liveins()) {
3045 PredBB->addLiveIn(LI);
3051 BeforePrologueRegion.
erase(
B);
3096 BuildMI(PrevStackMBB,
DL,
TII.get(TargetOpcode::CFI_INSTRUCTION))
3099 nullptr,
MRI->getDwarfRegNum(ScratchReg1,
true), -4));
3100 BuildMI(PrevStackMBB,
DL,
TII.get(TargetOpcode::CFI_INSTRUCTION))
3103 nullptr,
MRI->getDwarfRegNum(ScratchReg0,
true), -8));
3104 BuildMI(PrevStackMBB,
DL,
TII.get(TargetOpcode::CFI_INSTRUCTION))
3113 }
else if (CompareStackPointer) {
3121 if (!CompareStackPointer && Thumb) {
3122 if (AlignedStackSize < 256) {
3126 .
addImm(AlignedStackSize)
3129 if (Thumb2 || ST->genExecuteOnly()) {
3131 .
addImm(AlignedStackSize);
3144 }
else if (!CompareStackPointer) {
3145 if (AlignedStackSize < 256) {
3148 .
addImm(AlignedStackSize)
3164 if (Thumb && ST->isThumb1Only()) {
3165 if (ST->genExecuteOnly()) {
3176 BuildMI(GetMBB,
DL,
TII.get(ARM::tLDRpci), ScratchReg0)
3189 BuildMI(McrMBB,
DL,
TII.get(Thumb ? ARM::t2MRC : ARM::MRC),
3199 assert(ST->isTargetAndroid() || ST->isTargetLinux());
3200 unsigned TlsOffset = ST->isTargetAndroid() ? 63 : 1;
3204 BuildMI(GetMBB,
DL,
TII.get(Thumb ? ARM::t2LDRi12 : ARM::LDRi12),
3213 Opcode = Thumb ? ARM::tCMPr : ARM::CMPrr;
3220 Opcode = Thumb ? ARM::tBcc : ARM::Bcc;
3233 if (AlignedStackSize < 256) {
3234 BuildMI(AllocMBB,
DL,
TII.get(ARM::tMOVi8), ScratchReg0)
3236 .
addImm(AlignedStackSize)
3239 if (Thumb2 || ST->genExecuteOnly()) {
3241 .
addImm(AlignedStackSize);
3250 if (AlignedStackSize < 256) {
3252 .
addImm(AlignedStackSize)
3267 BuildMI(AllocMBB,
DL,
TII.get(ARM::tMOVi8), ScratchReg1)
3272 if (Thumb2 || ST->genExecuteOnly()) {
3279 *AllocMBB,
MBBI,
DL, ScratchReg1, 0,
3293 *AllocMBB,
MBBI,
DL, ScratchReg1, 0,
3315 BuildMI(AllocMBB,
DL,
TII.get(TargetOpcode::CFI_INSTRUCTION))
3318 nullptr,
MRI->getDwarfRegNum(ARM::LR,
true), -12));
3319 BuildMI(AllocMBB,
DL,
TII.get(TargetOpcode::CFI_INSTRUCTION))
3335 if (ST->isThumb1Only()) {
3379 BuildMI(AllocMBB,
DL,
TII.get(TargetOpcode::CFI_INSTRUCTION))
3405 BuildMI(PostStackMBB,
DL,
TII.get(TargetOpcode::CFI_INSTRUCTION))
3411 nullptr,
MRI->getDwarfRegNum(ScratchReg0,
true)));
3412 BuildMI(PostStackMBB,
DL,
TII.get(TargetOpcode::CFI_INSTRUCTION))
3415 nullptr,
MRI->getDwarfRegNum(ScratchReg1,
true)));
3416 BuildMI(PostStackMBB,
DL,
TII.get(TargetOpcode::CFI_INSTRUCTION))
3432#ifdef EXPENSIVE_CHECKS
unsigned const MachineRegisterInfo * MRI
static int64_t getArgumentStackToRestore(MachineFunction &MF, MachineBasicBlock &MBB)
Returns how much of the incoming argument stack area (in bytes) we should clean up in an epilogue.
static bool needsWinCFI(const MachineFunction &MF)
static unsigned estimateRSStackSizeLimit(MachineFunction &MF)
Look at each instruction that references stack frames and return the stack size limit beyond which so...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static bool isThumb(const MCSubtargetInfo &STI)
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 void emitAligningInstructions(MachineFunction &MF, ARMFunctionInfo *AFI, const TargetInstrInfo &TII, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, const unsigned Reg, const Align Alignment, const bool MustBeSingleInstruction)
Emit an instruction sequence that will align the address in register Reg by zero-ing out the lower bi...
static uint32_t alignToARMConstant(uint32_t Value)
Get the minimum constant for ARM that is greater than or equal to the argument.
static void checkNumAlignedDPRCS2Regs(MachineFunction &MF, BitVector &SavedRegs)
static void insertSEHRange(MachineBasicBlock &MBB, MachineBasicBlock::iterator Start, const MachineBasicBlock::iterator &End, const ARMBaseInstrInfo &TII, unsigned MIFlags)
static void emitAlignedDPRCS2Restores(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned NumAlignedDPRCS2Regs, ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI)
Emit aligned reload instructions for NumAlignedDPRCS2Regs D-registers starting from d8.
static void emitAlignedDPRCS2Spills(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned NumAlignedDPRCS2Regs, ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI)
Emit aligned spill instructions for NumAlignedDPRCS2Regs D-registers starting from d8.
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)
static unsigned EstimateFunctionSizeInBytes(const MachineFunction &MF, const ARMBaseInstrInfo &TII)
static MachineBasicBlock::iterator insertSEH(MachineBasicBlock::iterator MBBI, const TargetInstrInfo &TII, unsigned Flags)
static bool canSpillOnFrameIndexAccess(const MachineFunction &MF, const TargetFrameLowering &TFI)
static bool requiresAAPCSFrameRecord(const MachineFunction &MF)
static bool WindowsRequiresStackProbe(const MachineFunction &MF, size_t StackSizeInBytes)
static int getMaxFPOffset(const ARMSubtarget &STI, const ARMFunctionInfo &AFI, const MachineFunction &MF)
We need the offset of the frame pointer relative to other MachineFrameInfo offsets which are encoded ...
static MachineBasicBlock::iterator initMBBRange(MachineBasicBlock &MBB, const MachineBasicBlock::iterator &MBBI)
static int sizeOfSPAdjustment(const MachineInstr &MI)
static const uint64_t kSplitStackAvailable
static cl::opt< bool > SpillAlignedNEONRegs("align-neon-spills", cl::Hidden, cl::init(true), cl::desc("Align ARM NEON spills in prolog and epilog"))
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)
This file contains the simple types necessary to represent the attributes associated with functions a...
This file implements the BitVector class.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Analysis containing CSE Info
const HexagonInstrInfo * TII
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
unsigned const TargetRegisterInfo * TRI
const char LLVMTargetMachineRef TM
This file declares the machine register scavenger class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
static const unsigned FramePtr
bool hasBasePointer(const MachineFunction &MF) const
virtual void emitLoadConstPool(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &dl, Register DestReg, unsigned SubIdx, int Val, ARMCC::CondCodes Pred=ARMCC::AL, Register PredReg=Register(), unsigned MIFlags=MachineInstr::NoFlags) const
emitLoadConstPool - Emits a load from constpool to materialize the specified immediate.
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
Code Generation virtual methods...
bool cannotEliminateFrame(const MachineFunction &MF) const
Register getFrameRegister(const MachineFunction &MF) const override
bool canRealignStack(const MachineFunction &MF) const override
Register getBaseRegister() const
static ARMConstantPoolSymbol * Create(LLVMContext &C, StringRef s, unsigned ID, unsigned char PCAdj)
ARMConstantPoolValue - ARM specific constantpool value.
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 hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register.
StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const override
getFrameIndexReference - Provide a base+offset reference to an FI slot for debug info.
static void updateLRRestored(MachineFunction &MF)
Update the IsRestored flag on LR if it is spilled, based on the return instructions.
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
ARMFrameLowering(const ARMSubtarget &sti)
bool enableShrinkWrapping(const MachineFunction &MF) const override
Returns true if the target will correctly handle shrink wrapping.
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 emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
bool isFPReserved(const MachineFunction &MF) const
isFPReserved - Return true if the frame pointer register should be considered a reserved register on ...
bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override
canSimplifyCallFramePseudos - If there is a reserved call frame, the call frame pseudos can be simpli...
void adjustForSegmentedStacks(MachineFunction &MF, MachineBasicBlock &MBB) const override
Adjust the prologue to have the function use segmented stacks.
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...
bool hasReservedCallFrame(const MachineFunction &MF) const override
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
const SpillSlot * getCalleeSavedSpillSlots(unsigned &NumEntries) const override
getCalleeSavedSpillSlots - This method returns a pointer to an array of pairs, that contains an entry...
void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS=nullptr) const override
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
int ResolveFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg, int SPAdj) const
void getCalleeSaves(const MachineFunction &MF, BitVector &SavedRegs) const override
Returns the callee-saved registers as computed by determineCalleeSaves in the BitVector SavedRegs.
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
bool enableCalleeSaveSkip(const MachineFunction &MF) const override
Returns true if the target can safely skip saving callee-saved registers for noreturn nounwind functi...
bool assignCalleeSavedSpillSlots(MachineFunction &MF, const TargetRegisterInfo *TRI, std::vector< CalleeSavedInfo > &CSI) const override
ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...
void setDPRCalleeSavedAreaSize(unsigned s)
bool hasStackFrame() const
bool isThumb2Function() const
unsigned getFPCXTSaveAreaSize() const
unsigned getGPRCalleeSavedArea1Size() const
unsigned getDPRCalleeSavedGapSize() const
unsigned createPICLabelUId()
void setLRIsSpilled(bool s)
void setGPRCalleeSavedArea2Size(unsigned s)
bool isThumb1OnlyFunction() const
void setHasStackFrame(bool s)
void setDPRCalleeSavedAreaOffset(unsigned o)
bool isThumbFunction() const
void setFramePtrSpillOffset(unsigned o)
unsigned getGPRCalleeSavedArea2Size() const
unsigned getNumAlignedDPRCS2Regs() const
bool shouldSignReturnAddress() const
void setGPRCalleeSavedArea1Size(unsigned s)
unsigned getArgumentStackToRestore() const
void setFPCXTSaveAreaSize(unsigned s)
bool isCmseNSEntryFunction() const
unsigned getDPRCalleeSavedAreaSize() const
unsigned getFramePtrSpillOffset() const
bool shouldRestoreSPFromFP() const
unsigned getArgRegsSaveSize() const
void setGPRCalleeSavedArea2Offset(unsigned o)
void setGPRCalleeSavedArea1Offset(unsigned o)
void setDPRCalleeSavedGapSize(unsigned s)
unsigned getArgumentStackSize() const
void setShouldRestoreSPFromFP(bool s)
unsigned getReturnRegsCount() const
bool getPreservesR0() const
const ARMBaseInstrInfo * getInstrInfo() const override
bool isTargetWindows() const
const ARMBaseRegisterInfo * getRegisterInfo() const override
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),...
bool splitFramePointerPush(const MachineFunction &MF) const
const ARMFrameLowering * getFrameLowering() const override
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
bool test(unsigned Idx) 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.
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
bool usesWindowsCFI() const
static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register, SMLoc Loc={})
.cfi_def_cfa_register modifies a rule for computing CFA.
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int Offset, SMLoc Loc={})
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
static MCCFIInstruction cfiDefCfaOffset(MCSymbol *L, int Offset, SMLoc Loc={})
.cfi_def_cfa_offset modifies a rule for computing CFA.
static MCCFIInstruction cfiDefCfa(MCSymbol *L, unsigned Register, int Offset, SMLoc Loc={})
.cfi_def_cfa defines a rule for computing CFA as: take address from Register and add Offset to it.
static MCCFIInstruction createSameValue(MCSymbol *L, unsigned Register, SMLoc Loc={})
.cfi_same_value Current value of Register is the same as in the previous frame.
Context object for machine code objects.
Describe properties that are true of each instruction in the target description file.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
iterator_range< livein_iterator > liveins() const
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
void sortUniqueLiveIns()
Sorts and uniques the LiveIns vector.
iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
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...
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.
iterator_range< iterator > terminators()
iterator insertAfter(iterator I, MachineInstr *MI)
Insert MI into the instruction list after I.
bool isSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a successor of this block.
iterator_range< pred_iterator > predecessors()
MachineInstrBundleIterator< MachineInstr > iterator
The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...
const std::vector< MachineConstantPoolEntry > & getConstants() const
unsigned getConstantPoolIndex(const Constant *C, Align Alignment)
getConstantPoolIndex - Create a new entry in the constant pool or return an existing one.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool needsSplitStackProlog() const
Return true if this function requires a split stack prolog, even if it uses no stack space.
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.
bool isReturnAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
bool hasCalls() const
Return true if the current function has any function calls.
bool isFrameAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
Align getMaxAlign() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
int getStackProtectorIndex() const
Return the index for the stack protector object.
int getOffsetAdjustment() const
Return the correction for frame offsets.
bool isCalleeSavedInfoValid() const
Has the callee saved info been calculated yet?
void setOffsetAdjustment(int Adj)
Set the correction for frame offsets.
BitVector getPristineRegs(const MachineFunction &MF) const
Return a set of physical registers that are pristine.
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
unsigned getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
void setObjectAlignment(int ObjectIdx, Align Alignment)
setObjectAlignment - Change the alignment of the specified stack object.
unsigned addFrameInst(const MCCFIInstruction &Inst)
void setHasWinCFI(bool v)
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.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
MachineModuleInfo & getMMI() const
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
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.
const MachineJumpTableInfo * getJumpTableInfo() const
getJumpTableInfo - Return the jump table info object for the current function.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
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 & addFrameIndex(int Idx) const
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & copyImplicitOps(const MachineInstr &OtherMI) const
Copy all the implicit operands from OtherMI onto this one.
Representation of each machine instruction.
bool addRegisterKilled(Register IncomingReg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
We have determined MI kills a register.
const std::vector< MachineJumpTableEntry > & getJumpTables() const
This class contains meta information specific to a module.
const MCContext & getContext() const
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
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...
void addScavengingFrameIndex(int FI)
Add a scavenging frame index.
Wrapper class representing virtual and physical registers.
bool erase(PtrType Ptr)
erase - If the set contains the specified pointer, remove it and return true, otherwise return false.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
iterator erase(const_iterator CI)
typename SuperClass::iterator iterator
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset holds a fixed and a scalable offset in bytes.
int64_t getFixed() const
Returns the fixed component of the stack.
Information about stack frame layout on the target.
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
virtual void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS=nullptr) const
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
virtual bool hasFP(const MachineFunction &MF) const =0
hasFP - Return true if the specified function should have a dedicated frame pointer register.
virtual void getCalleeSaves(const MachineFunction &MF, BitVector &SavedRegs) const
Returns the callee-saved registers as computed by determineCalleeSaves in the BitVector SavedRegs.
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
int alignSPAdjust(int SPAdj) const
alignSPAdjust - This method aligns the stack adjustment to the correct alignment.
virtual StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const
getFrameIndexReference - This method should return the base register and offset used to reference a f...
TargetInstrInfo - Interface to description of machine instruction set.
Primary interface to the complete machine description for the target machine.
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
bool contains(Register Reg) const
Return true if the specified register is included in this register class.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
bool hasStackRealignment(const MachineFunction &MF) const
True if stack realignment is required and still possible.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual const TargetFrameLowering * getFrameLowering() const
virtual const TargetInstrInfo * getInstrInfo() const
LLVM Value Representation.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO, unsigned IdxMode=0)
unsigned getSORegOpc(ShiftOpc ShOp, unsigned Imm)
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
@ C
The default llvm calling convention, compatible with C.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Define
Register definition.
@ Kill
The last use of a register.
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static bool isSplitFPArea1Register(unsigned Reg, bool SplitFramePushPop)
static bool isARMArea2Register(unsigned Reg, bool SplitFramePushPop)
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
static bool isSEHInstruction(const MachineInstr &MI)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
static bool isARMArea3Register(unsigned Reg, bool SplitFramePushPop)
bool tryFoldSPUpdateIntoPushPop(const ARMSubtarget &Subtarget, MachineFunction &MF, MachineInstr *MI, unsigned NumBytes)
Tries to add registers to the reglist of a given base-updating push/pop instruction to adjust the sta...
static bool isARMLowRegister(unsigned Reg)
isARMLowRegister - Returns true if the register is a low register (r0-r7).
void sort(IteratorTy Start, IteratorTy End)
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.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
unsigned getDefRegState(bool B)
unsigned getKillRegState(bool B)
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
static MachineOperand t1CondCodeOp(bool isDead=false)
Get the operand corresponding to the conditional code result for Thumb1.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
static bool isARMArea1Register(unsigned Reg, bool SplitFramePushPop)
isARMArea1Register - Returns true if the register is a low register (r0-r7) or a stack/pc register th...
static MachineOperand condCodeOp(unsigned CCReg=0)
Get the operand corresponding to the conditional code result.
unsigned Log2(Align A)
Returns the log2 of the alignment.
void emitARMRegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &dl, Register DestReg, Register BaseReg, int NumBytes, ARMCC::CondCodes Pred, Register PredReg, const ARMBaseInstrInfo &TII, unsigned MIFlags=0)
emitARMRegPlusImmediate / emitT2RegPlusImmediate - Emits a series of instructions to materializea des...
static bool isSplitFPArea2Register(unsigned Reg, bool SplitFramePushPop)
Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
void emitT2RegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &dl, Register DestReg, Register BaseReg, int NumBytes, ARMCC::CondCodes Pred, Register PredReg, const ARMBaseInstrInfo &TII, unsigned MIFlags=0)
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t value() const
This is a hole in the type system and should not be abused.