138 using namespace llvm;
140 #define DEBUG_TYPE "frame-info" 143 cl::desc(
"enable use of redzone on AArch64"),
148 cl::desc(
"reverse the CSR restore sequence"),
151 STATISTIC(NumRedZoneFunctions,
"Number of functions using red zone");
168 if (
MI.isDebugInstr() ||
MI.isPseudo() ||
169 MI.getOpcode() == AArch64::ADDXri ||
170 MI.getOpcode() == AArch64::ADDSXri)
254 unsigned Opc = I->getOpcode();
255 bool IsDestroy = Opc == TII->getCallFrameDestroyOpcode();
256 uint64_t CalleePopAmount = IsDestroy ? I->getOperand(1).getImm() : 0;
262 int64_t Amount = I->getOperand(0).getImm();
263 Amount =
alignTo(Amount, Align);
270 if (CalleePopAmount == 0) {
281 assert(Amount > -0xffffff && Amount < 0xffffff &&
"call frame too large");
284 }
else if (CalleePopAmount != 0) {
287 assert(CalleePopAmount < 0xffffff &&
"call frame too large");
288 emitFrameOffset(MBB, I, DL, AArch64::SP, AArch64::SP, -CalleePopAmount,
310 assert(Scope.
equals(
"non-leaf") &&
"Expected all, none or non-leaf");
313 if (
Info.getReg() == AArch64::LR)
333 for (
const auto &
Info : CSI) {
340 BuildMI(MBB, MBBI, DL, TII->
get(TargetOpcode::CFI_INSTRUCTION))
341 .addCFIIndex(CFIIndex)
361 if (&MF->
front() == MBB)
371 for (
unsigned i = 0; CSRegs[i]; ++i)
372 LiveRegs.
addReg(CSRegs[i]);
376 if (LiveRegs.
available(MRI, AArch64::X9))
379 for (
unsigned Reg : AArch64::GPR64RegClass) {
383 return AArch64::NoRegister;
394 if (!RegInfo->needsStackRealignment(*MF))
402 unsigned StackSizeInBytes) {
409 unsigned StackProbeSize = 4096;
414 return (StackSizeInBytes >= StackProbeSize) &&
418 bool AArch64FrameLowering::shouldCombineCSRLocalStackBump(
433 if (MFI.hasVarSizedObjects())
436 if (RegInfo->needsStackRealignment(MF))
453 unsigned Opc = MBBI->getOpcode();
457 unsigned ImmIdx = MBBI->getNumOperands() - 1;
458 int Imm = MBBI->getOperand(ImmIdx).getImm();
466 case AArch64::LDPDpost:
469 case AArch64::STPDpre: {
470 unsigned Reg0 = RegInfo->getSEHRegNum(MBBI->getOperand(1).getReg());
471 unsigned Reg1 = RegInfo->getSEHRegNum(MBBI->getOperand(2).getReg());
472 MIB =
BuildMI(MF, DL, TII.
get(AArch64::SEH_SaveFRegP_X))
479 case AArch64::LDPXpost:
482 case AArch64::STPXpre: {
483 unsigned Reg0 = MBBI->getOperand(1).getReg();
484 unsigned Reg1 = MBBI->getOperand(2).getReg();
486 MIB =
BuildMI(MF, DL, TII.
get(AArch64::SEH_SaveFPLR_X))
490 MIB =
BuildMI(MF, DL, TII.
get(AArch64::SEH_SaveRegP_X))
491 .addImm(RegInfo->getSEHRegNum(Reg0))
492 .addImm(RegInfo->getSEHRegNum(Reg1))
497 case AArch64::LDRDpost:
500 case AArch64::STRDpre: {
501 unsigned Reg = RegInfo->getSEHRegNum(MBBI->getOperand(1).getReg());
502 MIB =
BuildMI(MF, DL, TII.
get(AArch64::SEH_SaveFReg_X))
508 case AArch64::LDRXpost:
511 case AArch64::STRXpre: {
512 unsigned Reg = RegInfo->getSEHRegNum(MBBI->getOperand(1).getReg());
513 MIB =
BuildMI(MF, DL, TII.
get(AArch64::SEH_SaveReg_X))
520 case AArch64::LDPDi: {
521 unsigned Reg0 = RegInfo->getSEHRegNum(MBBI->getOperand(0).getReg());
522 unsigned Reg1 = RegInfo->getSEHRegNum(MBBI->getOperand(1).getReg());
523 MIB =
BuildMI(MF, DL, TII.
get(AArch64::SEH_SaveFRegP))
531 case AArch64::LDPXi: {
532 unsigned Reg0 = MBBI->getOperand(0).getReg();
533 unsigned Reg1 = MBBI->getOperand(1).getReg();
535 MIB =
BuildMI(MF, DL, TII.
get(AArch64::SEH_SaveFPLR))
539 MIB =
BuildMI(MF, DL, TII.
get(AArch64::SEH_SaveRegP))
540 .addImm(RegInfo->getSEHRegNum(Reg0))
541 .addImm(RegInfo->getSEHRegNum(Reg1))
546 case AArch64::STRXui:
547 case AArch64::LDRXui: {
548 int Reg = RegInfo->getSEHRegNum(MBBI->getOperand(0).getReg());
549 MIB =
BuildMI(MF, DL, TII.
get(AArch64::SEH_SaveReg))
555 case AArch64::STRDui:
556 case AArch64::LDRDui: {
557 unsigned Reg = RegInfo->getSEHRegNum(MBBI->getOperand(0).getReg());
558 MIB =
BuildMI(MF, DL, TII.
get(AArch64::SEH_SaveFReg))
571 unsigned LocalStackSize) {
573 unsigned ImmIdx = MBBI->getNumOperands() - 1;
574 switch (MBBI->getOpcode()) {
577 case AArch64::SEH_SaveFPLR:
578 case AArch64::SEH_SaveRegP:
579 case AArch64::SEH_SaveReg:
580 case AArch64::SEH_SaveFRegP:
581 case AArch64::SEH_SaveFReg:
582 ImmOpnd = &MBBI->getOperand(ImmIdx);
595 bool NeedsWinCFI,
bool InProlog =
true) {
598 while (MBBI->getOpcode() == AArch64::STRXpost ||
599 MBBI->getOpcode() == AArch64::LDRXpre ||
600 MBBI->getOpcode() == AArch64::CFI_INSTRUCTION) {
601 if (MBBI->getOpcode() != AArch64::CFI_INSTRUCTION)
602 assert(MBBI->getOperand(0).getReg() != AArch64::SP);
607 switch (MBBI->getOpcode()) {
611 NewOpc = AArch64::STPXpre;
615 NewOpc = AArch64::STPDpre;
619 NewOpc = AArch64::STPQpre;
622 case AArch64::STRXui:
623 NewOpc = AArch64::STRXpre;
625 case AArch64::STRDui:
626 NewOpc = AArch64::STRDpre;
628 case AArch64::STRQui:
629 NewOpc = AArch64::STRQpre;
632 NewOpc = AArch64::LDPXpost;
636 NewOpc = AArch64::LDPDpost;
640 NewOpc = AArch64::LDPQpost;
643 case AArch64::LDRXui:
644 NewOpc = AArch64::LDRXpost;
646 case AArch64::LDRDui:
647 NewOpc = AArch64::LDRDpost;
649 case AArch64::LDRQui:
650 NewOpc = AArch64::LDRQpost;
655 auto SEH = std::next(MBBI);
657 SEH->eraseFromParent();
664 unsigned OpndIdx = 0;
665 for (
unsigned OpndEnd = MBBI->getNumOperands() - 1; OpndIdx < OpndEnd;
667 MIB.
add(MBBI->getOperand(OpndIdx));
669 assert(MBBI->getOperand(OpndIdx).getImm() == 0 &&
670 "Unexpected immediate offset in first/last callee-save save/restore " 672 assert(MBBI->getOperand(OpndIdx - 1).getReg() == AArch64::SP &&
673 "Unexpected base register in callee-save save/restore instruction!");
674 assert(CSStackSizeInc % Scale == 0);
675 MIB.
addImm(CSStackSizeInc / Scale);
685 return std::prev(MBB.
erase(MBBI));
691 unsigned LocalStackSize,
700 if (Opc == AArch64::STRXpost || Opc == AArch64::LDRXpre ||
701 Opc == AArch64::CFI_INSTRUCTION) {
702 if (Opc != AArch64::CFI_INSTRUCTION)
710 case AArch64::STRXui:
712 case AArch64::STRDui:
714 case AArch64::LDRXui:
716 case AArch64::LDRDui:
720 case AArch64::STRQui:
722 case AArch64::LDRQui:
731 "Unexpected base register in callee-save save/restore instruction!");
735 assert(LocalStackSize % Scale == 0);
736 OffsetOpnd.setImm(OffsetOpnd.getImm() + LocalStackSize / Scale);
742 "Expecting a SEH instruction");
764 MBB.
splice(FirstSPPopI, &MBB, LastPopI);
808 bool HasFP =
hasFP(MF);
824 BuildMI(MBB, MBBI, DL, TII->
get(AArch64::PACIASP))
827 BuildMI(MBB, MBBI, DL, TII->
get(AArch64::EMITBKEY))
829 BuildMI(MBB, MBBI, DL, TII->
get(AArch64::PACIBSP))
835 BuildMI(MBB, MBBI, DL, TII->
get(TargetOpcode::CFI_INSTRUCTION))
836 .addCFIIndex(CFIIndex)
854 assert(!HasFP &&
"unexpected function without stack frame but with FP");
863 ++NumRedZoneFunctions;
865 emitFrameOffset(MBB, MBBI, DL, AArch64::SP, AArch64::SP, -NumBytes, TII,
873 BuildMI(MBB, MBBI, DL, TII->
get(TargetOpcode::CFI_INSTRUCTION))
874 .addCFIIndex(CFIIndex)
880 BuildMI(MBB, MBBI, DL, TII->
get(AArch64::SEH_PrologEnd))
890 unsigned FixedObject = (IsWin64 && !IsFunclet) ?
896 bool CombineSPBump = shouldCombineCSRLocalStackBump(MF, NumBytes);
898 emitFrameOffset(MBB, MBBI, DL, AArch64::SP, AArch64::SP, -NumBytes, TII,
901 }
else if (PrologueSaveSize != 0) {
903 MBB, MBBI, DL, TII, -PrologueSaveSize, NeedsWinCFI);
904 NumBytes -= PrologueSaveSize;
906 assert(NumBytes >= 0 &&
"Negative stack allocation size!?");
924 BuildMI(MBB, MBBI, DL, TII->
get(AArch64::SEH_PrologEnd))
952 if (NumBytes >= (1 << 28))
954 "unwinding purposes");
956 uint32_t LowNumWords = NumWords & 0xFFFF;
957 BuildMI(MBB, MBBI, DL, TII->
get(AArch64::MOVZXi), AArch64::X15)
961 BuildMI(MBB, MBBI, DL, TII->
get(AArch64::SEH_Nop))
963 if ((NumWords & 0xFFFF0000) != 0) {
964 BuildMI(MBB, MBBI, DL, TII->
get(AArch64::MOVKXi), AArch64::X15)
965 .addReg(AArch64::X15)
966 .
addImm((NumWords & 0xFFFF0000) >> 16)
969 BuildMI(MBB, MBBI, DL, TII->
get(AArch64::SEH_Nop))
973 BuildMI(MBB, MBBI, DL, TII->
get(AArch64::MOVi64imm), AArch64::X15)
984 .addExternalSymbol(
"__chkstk")
991 BuildMI(MBB, MBBI, DL, TII->
get(AArch64::SEH_Nop))
995 BuildMI(MBB, MBBI, DL, TII->
get(AArch64::MOVaddrEXT))
1001 BuildMI(MBB, MBBI, DL, TII->
get(AArch64::SEH_Nop))
1004 BuildMI(MBB, MBBI, DL, TII->
get(AArch64::BLR))
1012 BuildMI(MBB, MBBI, DL, TII->
get(AArch64::SEH_Nop))
1017 BuildMI(MBB, MBBI, DL, TII->
get(AArch64::SUBXrx64), AArch64::SP)
1023 BuildMI(MBB, MBBI, DL, TII->
get(AArch64::SEH_StackAlloc))
1031 const bool NeedsRealignment = RegInfo->needsStackRealignment(MF);
1032 unsigned scratchSPReg = AArch64::SP;
1034 if (NeedsRealignment) {
1036 assert(scratchSPReg != AArch64::NoRegister);
1044 emitFrameOffset(MBB, MBBI, DL, scratchSPReg, AArch64::SP, -NumBytes, TII,
1047 if (NeedsRealignment) {
1050 assert(NrBitsToZero > 1);
1051 assert(scratchSPReg != AArch64::SP);
1060 uint32_t andMaskEncoded = (1 << 12)
1061 | ((64 - NrBitsToZero) << 6)
1062 | ((64 - NrBitsToZero - 1) << 0);
1064 BuildMI(MBB, MBBI, DL, TII->
get(AArch64::ANDXri), AArch64::SP)
1069 BuildMI(MBB, MBBI, DL, TII->
get(AArch64::SEH_StackAlloc))
1070 .addImm(NumBytes & andMaskEncoded)
1082 if (RegInfo->hasBasePointer(MF)) {
1083 TII->
copyPhysReg(MBB, MBBI, DL, RegInfo->getBaseRegister(), AArch64::SP,
1086 BuildMI(MBB, MBBI, DL, TII->
get(AArch64::SEH_Nop))
1093 BuildMI(MBB, MBBI, DL, TII->
get(AArch64::SEH_PrologEnd))
1096 if (needsFrameMoves) {
1099 unsigned FramePtr = RegInfo->getFrameRegister(MF);
1168 unsigned Reg = RegInfo->getDwarfRegNum(FramePtr,
true);
1170 nullptr, Reg, 2 * StackGrowth - FixedObject));
1171 BuildMI(MBB, MBBI, DL, TII->
get(TargetOpcode::CFI_INSTRUCTION))
1172 .addCFIIndex(CFIIndex)
1178 BuildMI(MBB, MBBI, DL, TII->
get(TargetOpcode::CFI_INSTRUCTION))
1179 .addCFIIndex(CFIIndex)
1198 if (MBBI != MBB.
end())
1199 DL = MBBI->getDebugLoc();
1206 MBBI->getOpcode() == AArch64::RET_ReallyLR) {
1209 .copyImplicitOps(*MBBI);
1236 bool IsTailCallReturn =
false;
1238 bool IsFunclet =
false;
1240 if (MBB.
end() != MBBI) {
1241 DL = MBBI->getDebugLoc();
1242 unsigned RetOpcode = MBBI->getOpcode();
1243 IsTailCallReturn = RetOpcode == AArch64::TCRETURNdi ||
1244 RetOpcode == AArch64::TCRETURNri ||
1245 RetOpcode == AArch64::TCRETURNriBTI;
1260 uint64_t ArgumentPopSize = 0;
1261 if (IsTailCallReturn) {
1267 ArgumentPopSize = StackAdjust.
getImm();
1309 unsigned FixedObject =
1312 uint64_t AfterCSRPopSize = ArgumentPopSize;
1320 bool CombineSPBump = shouldCombineCSRLocalStackBump(MF, NumBytes);
1323 if (!CombineSPBump && PrologueSaveSize != 0) {
1326 Pop = std::prev(Pop);
1329 const MachineOperand &OffsetOp = Pop->getOperand(Pop->getNumOperands() - 1);
1331 if (OffsetOp.
getImm() == 0)
1333 MBB, Pop, DL, TII, PrologueSaveSize, NeedsWinCFI,
false);
1339 AfterCSRPopSize += PrologueSaveSize;
1348 while (LastPopI != Begin) {
1353 }
else if (CombineSPBump)
1359 BuildMI(MBB, LastPopI, DL, TII->
get(AArch64::SEH_EpilogStart))
1363 if (CombineSPBump) {
1366 false, NeedsWinCFI);
1369 TII->
get(AArch64::SEH_EpilogEnd))
1370 .setMIFlag(MachineInstr::FrameDestroy);
1374 NumBytes -= PrologueSaveSize;
1375 assert(NumBytes >= 0 &&
"Negative stack allocation size!?");
1381 if (RedZone && AfterCSRPopSize == 0)
1384 bool NoCalleeSaveRestore = PrologueSaveSize == 0;
1385 int StackRestoreBytes = RedZone ? 0 : NumBytes;
1386 if (NoCalleeSaveRestore)
1387 StackRestoreBytes += AfterCSRPopSize;
1391 bool Done = NoCalleeSaveRestore || AfterCSRPopSize == 0;
1403 TII->
get(AArch64::SEH_EpilogEnd))
1420 emitFrameOffset(MBB, LastPopI, DL, AArch64::SP, AArch64::SP, NumBytes, TII,
1421 MachineInstr::FrameDestroy,
false, NeedsWinCFI);
1426 if (AfterCSRPopSize) {
1431 while (FirstSPPopI != Begin) {
1432 auto Prev = std::prev(FirstSPPopI);
1433 if (Prev->getOpcode() != AArch64::LDRXpre ||
1434 Prev->getOperand(0).getReg() == AArch64::SP)
1442 AfterCSRPopSize, TII, MachineInstr::FrameDestroy,
false,
1447 .setMIFlag(MachineInstr::FrameDestroy);
1456 unsigned &FrameReg)
const {
1461 int FI,
unsigned &FrameReg,
1462 bool PreferFP)
const {
1489 }
else if (isCSR && RegInfo->needsStackRealignment(MF)) {
1493 assert(
hasFP(MF) &&
"Re-aligned stack must have frame pointer");
1495 }
else if (
hasFP(MF) && !RegInfo->needsStackRealignment(MF)) {
1500 bool FPOffsetFits = FPOffset >= -256;
1501 PreferFP |= Offset > -FPOffset;
1508 if (FPOffsetFits && CanUseBP)
1515 }
else if (FPOffset >= 0) {
1526 "Funclets should only be present on Win64");
1530 if (FPOffsetFits && PreferFP)
1536 assert(((isFixed || isCSR) || !RegInfo->needsStackRealignment(MF) || !UseFP) &&
1537 "In the presence of dynamic stack pointer realignment, " 1538 "non-argument/CSR objects cannot be accessed through the frame pointer");
1550 "Can't use SP when we have var sized objects.");
1551 FrameReg = AArch64::SP;
1592 if (Reg2 == Reg1 + 1)
1599 struct RegPairInfo {
1600 unsigned Reg1 = AArch64::NoRegister;
1601 unsigned Reg2 = AArch64::NoRegister;
1604 enum RegType {
GPR, FPR64, FPR128 }
Type;
1606 RegPairInfo() =
default;
1608 bool isPaired()
const {
return Reg2 != AArch64::NoRegister; }
1616 bool &NeedShadowCallStackProlog) {
1625 unsigned Count = CSI.size();
1631 (Count & 1) == 0) &&
1632 "Odd number of callee-saved regs to spill!");
1638 bool FixupDone =
false;
1639 for (
unsigned i = 0; i < Count; ++i) {
1641 RPI.Reg1 = CSI[i].getReg();
1643 if (AArch64::GPR64RegClass.
contains(RPI.Reg1))
1645 else if (AArch64::FPR64RegClass.
contains(RPI.Reg1))
1646 RPI.Type = RegPairInfo::FPR64;
1647 else if (AArch64::FPR128RegClass.
contains(RPI.Reg1))
1648 RPI.Type = RegPairInfo::FPR128;
1653 if (i + 1 < Count) {
1654 unsigned NextReg = CSI[i + 1].getReg();
1657 if (AArch64::GPR64RegClass.
contains(NextReg) &&
1661 case RegPairInfo::FPR64:
1662 if (AArch64::FPR64RegClass.
contains(NextReg) &&
1666 case RegPairInfo::FPR128:
1667 if (AArch64::FPR128RegClass.
contains(NextReg))
1675 if ((RPI.Reg1 == AArch64::LR || RPI.Reg2 == AArch64::LR) &&
1679 NeedShadowCallStackProlog =
true;
1688 assert((!RPI.isPaired() ||
1689 (CSI[i].getFrameIdx() + 1 == CSI[i + 1].getFrameIdx())) &&
1690 "Out of order callee saved regs!");
1697 ((RPI.Reg1 == AArch64::LR && RPI.Reg2 ==
AArch64::FP) ||
1698 RPI.Reg1 + 1 == RPI.Reg2))) &&
1699 "Callee-save registers not saved as adjacent register pair!");
1701 RPI.FrameIdx = CSI[i].getFrameIdx();
1703 int Scale = RPI.Type == RegPairInfo::FPR128 ? 16 : 8;
1704 Offset -= RPI.isPaired() ? 2 * Scale : Scale;
1709 RPI.Type != RegPairInfo::FPR128 && !RPI.isPaired()) {
1712 assert(Offset % 16 == 0);
1713 assert(MFI.getObjectAlignment(RPI.FrameIdx) <= 16);
1714 MFI.setObjectAlignment(RPI.FrameIdx, 16);
1717 assert(Offset % Scale == 0);
1718 RPI.Offset = Offset / Scale;
1719 assert((RPI.Offset >= -64 && RPI.Offset <= 63) &&
1720 "Offset out of bounds for LDP/STP immediate");
1730 const std::vector<CalleeSavedInfo> &CSI,
1738 bool NeedShadowCallStackProlog =
false;
1740 NeedShadowCallStackProlog);
1743 if (NeedShadowCallStackProlog) {
1745 BuildMI(MBB, MI, DL, TII.
get(AArch64::STRXpost))
1753 BuildMI(MBB, MI, DL, TII.
get(AArch64::SEH_Nop))
1759 static const char CFIInst[] = {
1760 dwarf::DW_CFA_val_expression,
1763 static_cast<char>(
unsigned(dwarf::DW_OP_breg18)),
1764 static_cast<char>(-8) & 0x7f,
1768 BuildMI(MBB, MI, DL, TII.
get(AArch64::CFI_INSTRUCTION))
1769 .addCFIIndex(CFIIndex)
1777 for (
auto RPII = RegPairs.
rbegin(), RPIE = RegPairs.
rend(); RPII != RPIE;
1779 RegPairInfo
RPI = *RPII;
1780 unsigned Reg1 = RPI.Reg1;
1781 unsigned Reg2 = RPI.Reg2;
1797 StrOpc = RPI.isPaired() ? AArch64::STPXi : AArch64::STRXui;
1801 case RegPairInfo::FPR64:
1802 StrOpc = RPI.isPaired() ? AArch64::STPDi : AArch64::STRDui;
1806 case RegPairInfo::FPR128:
1807 StrOpc = RPI.isPaired() ? AArch64::STPQi : AArch64::STRQui;
1813 if (RPI.isPaired())
dbgs() <<
", " <<
printReg(Reg2, TRI);
1814 dbgs() <<
") -> fi#(" << RPI.FrameIdx;
1815 if (RPI.isPaired())
dbgs() <<
", " << RPI.FrameIdx + 1;
1819 "Windows unwdinding requires a consecutive (FP,LR) pair");
1823 unsigned FrameIdxReg1 = RPI.FrameIdx;
1824 unsigned FrameIdxReg2 = RPI.FrameIdx + 1;
1825 if (NeedsWinCFI && RPI.isPaired()) {
1832 if (RPI.isPaired()) {
1857 std::vector<CalleeSavedInfo> &CSI,
1865 if (MI != MBB.
end())
1866 DL = MI->getDebugLoc();
1868 bool NeedShadowCallStackProlog =
false;
1870 NeedShadowCallStackProlog);
1872 auto EmitMI = [&](
const RegPairInfo &
RPI) {
1873 unsigned Reg1 =
RPI.Reg1;
1874 unsigned Reg2 =
RPI.Reg2;
1888 LdrOpc =
RPI.isPaired() ? AArch64::LDPXi : AArch64::LDRXui;
1892 case RegPairInfo::FPR64:
1893 LdrOpc =
RPI.isPaired() ? AArch64::LDPDi : AArch64::LDRDui;
1897 case RegPairInfo::FPR128:
1898 LdrOpc =
RPI.isPaired() ? AArch64::LDPQi : AArch64::LDRQui;
1905 dbgs() <<
") -> fi#(" <<
RPI.FrameIdx;
1906 if (
RPI.isPaired())
dbgs() <<
", " <<
RPI.FrameIdx + 1;
1912 unsigned FrameIdxReg1 =
RPI.FrameIdx;
1913 unsigned FrameIdxReg2 =
RPI.FrameIdx + 1;
1914 if (NeedsWinCFI &&
RPI.isPaired()) {
1919 if (
RPI.isPaired()) {
1937 for (
const RegPairInfo &
RPI :
reverse(RegPairs))
1940 for (
const RegPairInfo &
RPI : RegPairs)
1943 if (NeedShadowCallStackProlog) {
1945 BuildMI(MBB, MI, DL, TII.
get(AArch64::LDRXpre))
1968 unsigned UnspilledCSGPR = AArch64::NoRegister;
1969 unsigned UnspilledCSGPRPaired = AArch64::NoRegister;
1978 unsigned ExtraCSSpill = 0;
1980 for (
unsigned i = 0; CSRegs[i]; ++i) {
1981 const unsigned Reg = CSRegs[i];
1984 if (Reg == BasePointerReg)
1987 bool RegUsed = SavedRegs.
test(Reg);
1988 unsigned PairedReg = CSRegs[i ^ 1];
1990 if (AArch64::GPR64RegClass.
contains(Reg) &&
1992 UnspilledCSGPR =
Reg;
1993 UnspilledCSGPRPaired = PairedReg;
2002 !SavedRegs.
test(PairedReg)) {
2003 SavedRegs.
set(PairedReg);
2004 if (AArch64::GPR64RegClass.
contains(PairedReg) &&
2006 ExtraCSSpill = PairedReg;
2011 unsigned CSStackSize = 0;
2018 unsigned NumSavedRegs = SavedRegs.
count();
2025 SavedRegs.
set(AArch64::LR);
2035 bool CanEliminateFrame = SavedRegs.
count() == 0;
2040 bool BigStack = (EstimatedStackSize + CSStackSize) > EstimatedStackSizeLimit;
2051 if (!ExtraCSSpill && UnspilledCSGPR != AArch64::NoRegister) {
2053 <<
" to get a scratch register.\n");
2054 SavedRegs.
set(UnspilledCSGPR);
2059 SavedRegs.
set(UnspilledCSGPRPaired);
2060 ExtraCSSpill = UnspilledCSGPRPaired;
2072 LLVM_DEBUG(
dbgs() <<
"No available CS registers, allocated fi#" << FI
2073 <<
" as the emergency spill slot.\n");
2078 CSStackSize += 8 * (SavedRegs.
count() - NumSavedRegs);
2079 unsigned AlignedCSStackSize =
alignTo(CSStackSize, 16);
2081 << EstimatedStackSize + AlignedCSStackSize
2107 auto MBBI = MBB.
begin();
2120 unsigned DstReg = RS->
FindUnusedReg(&AArch64::GPR64commonRegClass);
2121 assert(DstReg &&
"There must be a free register after frame setup");
2122 BuildMI(MBB, MBBI, DL, TII.
get(AArch64::MOVi64imm), DstReg).addImm(-2);
2123 BuildMI(MBB, MBBI, DL, TII.
get(AArch64::STURXi))
2125 .addFrameIndex(UnwindHelpFI)
2134 bool IgnoreSPUpdates)
const {
2138 FrameReg = AArch64::SP;
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 cl::opt< bool > ReverseCSRRestoreSeq("reverse-csr-restore-seq", cl::desc("reverse the CSR restore sequence"), cl::init(false), cl::Hidden)
const MachineInstrBuilder & setMemRefs(ArrayRef< MachineMemOperand *> MMOs) const
const MachineInstrBuilder & add(const MachineOperand &MO) const
A parsed version of the target data layout string in and methods for querying it. ...
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
bool usesWindowsCFI() const
bool hasStackMap() const
This method may be called any time after instruction selection is complete to determine if there is a...
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
bool hasDebugInfo() const
Returns true if valid debug info is present.
static bool ShouldSignWithAKey(MachineFunction &MF)
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.
void setHasWinCFI(bool v)
unsigned getLocalStackSize() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
LLVM_NODISCARD bool equals_lower(StringRef RHS) const
equals_lower - Check for string equality, ignoring case.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
class llvm::RegisterBankInfo GPR
static void computeCalleeSaveRegisterPairs(MachineFunction &MF, const std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI, SmallVectorImpl< RegPairInfo > &RegPairs, bool &NeedShadowCallStackProlog)
void push_back(const T &Elt)
bool cannotEliminateFrame(const MachineFunction &MF) const
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.
bool test(unsigned Idx) const
iterator insertAfter(iterator I, MachineInstr *MI)
Insert MI into the instruction list after I.
LLVM_NODISCARD detail::scope_exit< typename std::decay< Callable >::type > make_scope_exit(Callable &&F)
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
STATISTIC(NumFunctions, "Total number of functions")
unsigned const TargetRegisterInfo * TRI
MachineModuleInfo & getMMI() const
uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew=0)
Returns the next integer (mod 2**64) that is greater than or equal to Value and is a multiple of Alig...
bool canUseRedZone(const MachineFunction &MF) const
Can this function use the red zone for local allocations.
int getOffsetOfLocalArea() const
getOffsetOfLocalArea - This method returns the offset of the local area from the stack pointer on ent...
static bool invalidateWindowsRegisterPairing(unsigned Reg1, unsigned Reg2, bool NeedsWinCFI)
static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset)
.cfi_def_cfa_offset modifies a rule for computing CFA.
int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it...
bool isCallingConvWin64(CallingConv::ID CC) const
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 ...
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
return AArch64::GPR64RegClass contains(Reg)
static bool isFuncletReturnInstr(const MachineInstr &MI)
static unsigned findScratchNonCalleeSaveRegister(MachineBasicBlock *MBB)
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
bool supportSwiftError() const override
Return true if the target supports swifterror attribute.
unsigned getFrameRegister(const MachineFunction &MF) const override
static unsigned getPrologueDeath(MachineFunction &MF, unsigned Reg)
unsigned getSpillAlignment(const TargetRegisterClass &RC) const
Return the minimum required alignment in bytes for a spill slot for a register of this class...
CLEANUPRET - Represents a return from a cleanup block funclet.
bool isFrameAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
static bool isSEHInstruction(const MachineInstr &MI)
Return true if the instructions is a SEH instruciton used for unwinding on Windows.
bool isStackRealigned() const
const HexagonInstrInfo * TII
void emitFrameOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, int Offset, const TargetInstrInfo *TII, MachineInstr::MIFlag=MachineInstr::NoFlags, bool SetNZCV=false, bool NeedsWinCFI=false)
emitFrameOffset - Emit instructions as needed to set DestReg to SrcReg plus Offset.
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.
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.
void setHasRedZone(bool s)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
int getFrameIndexReference(const MachineFunction &MF, int FI, unsigned &FrameReg) const override
getFrameIndexReference - Provide a base+offset reference to an FI slot for debug info.
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 MachineBasicBlock::iterator convertCalleeSaveRestoreToSPPrePostIncDec(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, const TargetInstrInfo *TII, int CSStackSizeInc, bool NeedsWinCFI, bool InProlog=true)
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
void backward()
Update internal register state and move MBB iterator backwards.
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 isTargetMachO() const
LLVM_NODISCARD unsigned addFrameInst(const MCCFIInstruction &Inst)
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, unsigned base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
int getFrameIndexReferencePreferSP(const MachineFunction &MF, int FI, unsigned &FrameReg, bool IgnoreSPUpdates) const override
For Win64 AArch64 EH, the offset to the Unwind object is from the SP before the update.
bool canUseAsPrologue(const MachineBasicBlock &MBB) const override
Check whether or not the given MBB can be used as a prologue for the target.
unsigned getWinEHParentFrameOffset(const MachineFunction &MF) const override
The parent frame offset (aka dispFrame) is only used on X86_64 to retrieve the parent's frame pointer...
static unsigned estimateRSStackSizeLimit(MachineFunction &MF)
Look at each instruction that references stack frames and return the stack size limit beyond which so...
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
unsigned getArgumentStackToRestore() const
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
int isAArch64FrameOffsetLegal(const MachineInstr &MI, int &Offset, bool *OutUseUnscaledOp=nullptr, unsigned *OutUnscaledOp=nullptr, int *EmittableOffset=nullptr)
Check if the Offset is a valid frame offset for MI.
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
virtual void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const
Emit instructions to copy a pair of physical registers.
unsigned FindUnusedReg(const TargetRegisterClass *RC) const
Find an unused register of the specified register class.
const AArch64RegisterInfo * getRegisterInfo() const override
bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
const MCContext & getContext() const
iterator getLastNonDebugInstr()
Returns an iterator to the last non-debug instruction in the basic block, or end().
AttributeList getAttributes() const
Return the attribute list for this Function.
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
unsigned getWinEHFuncletFrameSize(const MachineFunction &MF) const
Funclets only need to account for space for the callee saved registers, as the locals are accounted f...
virtual const TargetInstrInfo * getInstrInfo() const
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
bool isXRegisterReserved(size_t i) const
Analysis containing CSE Info
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
unsigned getKillRegState(bool B)
static unsigned getShifterImm(AArch64_AM::ShiftExtendType ST, unsigned Imm)
getShifterImm - Encode the shift type and amount: imm: 6-bit shift amount shifter: 000 ==> lsl 001 ==...
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Flag
These should be considered private to the implementation of the MCInstrDesc class.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
TargetInstrInfo - Interface to description of machine instruction set.
bool isTargetWindows() const
unsigned getDefRegState(bool B)
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
const AArch64TargetLowering * getTargetLowering() const override
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata *> MDs)
initializer< Ty > init(const Ty &Val)
static MCCFIInstruction createNegateRAState(MCSymbol *L)
.cfi_negate_ra_state AArch64 negate RA state.
void addLiveIn(MCPhysReg PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
unsigned getCalleeSavedStackSize() const
This file declares the machine register scavenger class.
MCSymbol * createTempSymbol(bool CanBeUnnamed=true)
Create and return a new assembler temporary symbol with a unique but unspecified name.
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...
void setLocalStackSize(unsigned Size)
The instances of the Type class are immutable: once they are created, they are never changed...
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.
static bool ShouldSignReturnAddress(MachineFunction &MF)
bool hasEHFunclets() const
unsigned getPointerSize(unsigned AS=0) const
Layout pointer size FIXME: The defaults need to be removed once all of the backends/clients are updat...
int resolveFrameIndexReference(const MachineFunction &MF, int FI, unsigned &FrameReg, bool PreferFP=false) const
void addLiveIns(const MachineBasicBlock &MBB)
Adds all live-in registers of basic block MBB.
DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any DBG_VALUE and DBG_LABEL instructions...
unsigned getVarArgsGPRSize() const
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
void setCalleeSaveStackHasFreeSpace(bool s)
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...
void setImm(int64_t immVal)
static void fixupCalleeSaveRestoreStackOffset(MachineInstr &MI, unsigned LocalStackSize, bool NeedsWinCFI)
bool hasLocalEscape() const
void setHasStackFrame(bool s)
static cl::opt< bool > EnableRedZone("aarch64-redzone", cl::desc("enable use of redzone on AArch64"), cl::init(false), cl::Hidden)
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
const MachineBasicBlock & front() const
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
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.
virtual bool hasReservedCallFrame(const MachineFunction &MF) const
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.
unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
void emitCalleeSavedFrameMoves(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) const
The memory access writes data.
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.
size_type count() const
count - Returns the number of bits which are set.
static void InsertReturnAddressAuth(MachineFunction &MF, MachineBasicBlock &MBB)
unsigned getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call...
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
bool available(const MachineRegisterInfo &MRI, MCPhysReg Reg) const
Returns true if register Reg and no aliasing register is in the set.
void addScavengingFrameIndex(int FI)
Add a scavenging frame index.
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
unsigned estimateStackSize(const MachineFunction &MF) const
Estimate and return the size of the stack frame.
void setStackRealigned(bool s)
static const unsigned DefaultSafeSPDisplacement
This is the biggest offset to the stack pointer we can encode in aarch64 instructions (without using ...
Information about stack frame layout on the target.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
bool hasCalleeSaveStackFreeSpace() const
const WinEHFuncInfo * getWinEHFuncInfo() const
getWinEHFuncInfo - Return information about how the current function uses Windows exception handling...
void enterBasicBlockEnd(MachineBasicBlock &MBB)
Start tracking liveness from the end of basic block MBB.
const Function & getFunction() const
Return the LLVM function that this machine code represents.
static MachineBasicBlock::iterator InsertSEH(MachineBasicBlock::iterator MBBI, const TargetInstrInfo &TII, MachineInstr::MIFlag Flag)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool needsUnwindTableEntry() const
True if this function needs an unwind table.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
bool isPhysRegUsed(unsigned PhysReg) const
Return true if the specified register is modified or read in this function.
bool enableStackSlotScavenging(const MachineFunction &MF) const override
Returns true if the stack slot holes in the fixed and callee-save stack area should be used when allo...
CodeModel::Model getCodeModel() const
Returns the code model.
void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS) const override
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
static bool needsWinCFI(const MachineFunction &MF)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
static unsigned getArithExtendImm(AArch64_AM::ShiftExtendType ET, unsigned Imm)
getArithExtendImm - Encode the extend type and shift amount for an arithmetic instruction: imm: 3-bit...
static bool windowsRequiresStackProbe(MachineFunction &MF, unsigned StackSizeInBytes)
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register...
CATCHRET - Represents a return from a catch block funclet.
const MachineBasicBlock * getParent() const
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
The memory access reads data.
TargetSubtargetInfo - Generic base class for all target subtargets.
static void fixupSEHOpcode(MachineBasicBlock::iterator MBBI, unsigned LocalStackSize)
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
bool isReservedReg(const MachineFunction &MF, unsigned Reg) const
bool isLiveIn(unsigned Reg) const
Representation of each machine instruction.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
static void adaptForLdStOpt(MachineBasicBlock &MBB, MachineBasicBlock::iterator FirstSPPopI, MachineBasicBlock::iterator LastPopI)
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
A set of physical registers with utility functions to track liveness when walking backward/forward th...
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
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.
bool isEHFuncletEntry() const
Returns true if this is the entry block of an EH funclet.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned char TargetFlags=0) const
virtual const TargetFrameLowering * getFrameLowering() const
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...
MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const override
This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy p...
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
static bool produceCompactUnwindFrame(MachineFunction &MF)
reverse_iterator rbegin()
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool hasBasePointer(const MachineFunction &MF) const
iterator_range< const_set_bits_iterator > set_bits() 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...
const AArch64InstrInfo * getInstrInfo() const override
const MCPhysReg * getCalleeSavedRegs() const
Returns list of callee saved registers.
void addReg(MCPhysReg Reg)
Adds a physical register and all its sub-registers to the set.
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
bool isMaxCallFrameSizeComputed() const
bool hasStackFrame() const
bool hasPatchPoint() const
This method may be called any time after instruction selection is complete to determine if there is a...
StringRef - Represent a constant reference to a string, i.e.
unsigned getRegSizeInBits(const TargetRegisterClass &RC) const
Return the size in bits of a register from class RC.
static MCCFIInstruction createEscape(MCSymbol *L, StringRef Vals)
.cfi_escape Allows the user to add arbitrary bytes to the unwind info.
const MachineOperand & getOperand(unsigned i) const
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...
unsigned getBaseRegister() const
bool isReserved(unsigned PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
void setCalleeSavedStackSize(unsigned Size)
This class contains meta information specific to a module.
bool hasCalls() const
Return true if the current function has any function calls.