39#define DEBUG_TYPE "x86-fl"
41STATISTIC(NumFrameLoopProbe,
"Number of loop stack probes used in prologue");
43 "Number of extra stack probes generated in prologue");
44STATISTIC(NumFunctionUsingPush2Pop2,
"Number of funtions using push2/pop2");
52 STI(STI),
TII(*STI.getInstrInfo()),
TRI(STI.getRegisterInfo()) {
76 (
hasFP(MF) && !
TRI->hasStackRealignment(MF)) ||
109 return IsLP64 ? X86::SUB64ri32 : X86::SUB32ri;
113 return IsLP64 ? X86::ADD64ri32 : X86::ADD32ri;
117 return IsLP64 ? X86::SUB64rr : X86::SUB32rr;
121 return IsLP64 ? X86::ADD64rr : X86::ADD32rr;
125 return IsLP64 ? X86::AND64ri32 : X86::AND32ri;
129 return IsLP64 ? X86::LEA64r : X86::LEA32r;
135 return X86::MOV32ri64;
137 return X86::MOV64ri32;
161 return ST.is64Bit() ? (ST.hasPPX() ? X86::PUSHP64r : X86::PUSH64r)
165 return ST.is64Bit() ? (ST.hasPPX() ? X86::POPP64r : X86::POP64r)
169 return ST.hasPPX() ? X86::PUSH2P : X86::PUSH2;
172 return ST.hasPPX() ? X86::POP2P : X86::POP2;
179 if (Reg == X86::RAX || Reg == X86::EAX || Reg == X86::AX ||
180 Reg == X86::AH || Reg == X86::AL)
194 bool BreakNext =
false;
199 if (Reg != X86::EFLAGS)
220 if (Succ->isLiveIn(X86::EFLAGS))
233 bool InEpilogue)
const {
234 bool isSub = NumBytes < 0;
256 if (EmitInlineStackProbe && !InEpilogue) {
262 }
else if (
Offset > Chunk) {
284 MI->getOperand(3).setIsDead();
286 }
else if (
Offset > 8 * Chunk) {
311 MI->getOperand(3).setIsDead();
331 unsigned Opc = isSub ? (
Is64Bit ? X86::PUSH64r : X86::PUSH32r)
332 : (
Is64Bit ? X86::POP64r : X86::POP32r);
341 BuildStackAdjustment(
MBB,
MBBI,
DL, isSub ? -ThisVal : ThisVal, InEpilogue)
351 assert(
Offset != 0 &&
"zero offset stack adjustment requested");
369 if (UseLEA && !
STI.useLeaForSP())
374 "We shouldn't have allowed this insertion point");
391 MI->getOperand(3).setIsDead();
396template <
typename FoundT,
typename CalcT>
399 FoundT FoundStackAdjust,
401 bool doMergeWithPrevious)
const {
404 return CalcNewOffset(0);
420 if (doMergeWithPrevious && PI !=
MBB.
begin() && PI->isCFIInstruction())
425 unsigned Opc = PI->getOpcode();
427 if ((Opc == X86::ADD64ri32 || Opc == X86::ADD32ri) &&
428 PI->getOperand(0).getReg() ==
StackPtr) {
430 Offset = PI->getOperand(2).getImm();
431 }
else if ((Opc == X86::LEA32r || Opc == X86::LEA64_32r) &&
432 PI->getOperand(0).getReg() ==
StackPtr &&
433 PI->getOperand(1).getReg() ==
StackPtr &&
434 PI->getOperand(2).getImm() == 1 &&
435 PI->getOperand(3).getReg() == X86::NoRegister &&
436 PI->getOperand(5).getReg() == X86::NoRegister) {
438 Offset = PI->getOperand(4).getImm();
439 }
else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB32ri) &&
440 PI->getOperand(0).getReg() ==
StackPtr) {
442 Offset = -PI->getOperand(2).getImm();
444 return CalcNewOffset(0);
446 FoundStackAdjust(PI,
Offset);
450 if (doMergeWithPrevious ? (PI ==
MBB.
begin()) : (PI ==
MBB.
end()))
451 return CalcNewOffset(0);
453 PI = doMergeWithPrevious ? std::prev(PI) :
std::next(PI);
457 if (PI !=
MBB.
end() && PI->isCFIInstruction()) {
464 if (!doMergeWithPrevious)
467 return CalcNewOffset(
Offset);
473 bool doMergeWithPrevious)
const {
474 return mergeSPUpdates(
476 doMergeWithPrevious);
509 unsigned DwarfReg =
MRI->getDwarfRegNum(MachineFramePtr,
true);
532 unsigned DwarfReg =
MRI->getDwarfRegNum(Reg,
true);
543 CfaExpr.
push_back(dwarf::DW_CFA_expression);
552 unsigned DwarfFramePtr =
MRI->getDwarfRegNum(MachineFramePtr,
true);
568 int FI =
MI->getOperand(1).getIndex();
576 unsigned DwarfFramePtr =
MRI->getDwarfRegNum(MachineFramePtr,
true);
583 DefCfaExpr.
push_back(dwarf::DW_CFA_def_cfa_expression);
593void X86FrameLowering::emitZeroCallUsedRegs(
BitVector RegsToZero,
609 if (!X86::RFP80RegClass.
contains(Reg))
612 unsigned NumFPRegs = ST.is64Bit() ? 8 : 7;
613 for (
unsigned i = 0; i != NumFPRegs; ++i)
616 for (
unsigned i = 0; i != NumFPRegs; ++i)
624 if (
TRI->isGeneralPurposeRegister(MF, Reg)) {
626 RegsToZero.
reset(Reg);
641 std::optional<MachineFunction::DebugInstrOperandPair> InstrNum)
const {
648 emitStackProbeInline(MF,
MBB,
MBBI,
DL,
false);
651 emitStackProbeCall(MF,
MBB,
MBBI,
DL, InProlog, InstrNum);
662 return MI.getOpcode() == X86::STACKALLOC_W_PROBING;
664 if (Where != PrologMBB.
end()) {
666 emitStackProbeInline(MF, PrologMBB, Where,
DL,
true);
667 Where->eraseFromParent();
675 bool InProlog)
const {
678 emitStackProbeInlineWindowsCoreCLR64(MF,
MBB,
MBBI,
DL, InProlog);
680 emitStackProbeInlineGeneric(MF,
MBB,
MBBI,
DL, InProlog);
683void X86FrameLowering::emitStackProbeInlineGeneric(
692 "different expansion expected for CoreCLR 64 bit");
694 const uint64_t StackProbeSize = TLI.getStackProbeSize(MF);
695 uint64_t ProbeChunk = StackProbeSize * 8;
698 TRI->hasStackRealignment(MF) ? calculateMaxStackAlign(MF) : 0;
703 if (
Offset > ProbeChunk) {
705 MaxAlign % StackProbeSize);
708 MaxAlign % StackProbeSize);
712void X86FrameLowering::emitStackProbeInlineGenericBlock(
717 const bool NeedsDwarfCFI = needsDwarfCFI(MF);
721 const unsigned MovMIOpc =
Is64Bit ? X86::MOV64mi32 : X86::MOV32mi;
722 const uint64_t StackProbeSize = TLI.getStackProbeSize(MF);
726 assert(AlignOffset < StackProbeSize);
729 if (StackProbeSize <
Offset + AlignOffset) {
732 BuildStackAdjustment(
MBB,
MBBI,
DL, -StackAdjustment,
false)
734 if (!HasFP && NeedsDwarfCFI) {
745 NumFrameExtraProbe++;
746 CurrentOffset = StackProbeSize - AlignOffset;
752 while (CurrentOffset + StackProbeSize <
Offset) {
753 BuildStackAdjustment(
MBB,
MBBI,
DL, -StackProbeSize,
false)
756 if (!HasFP && NeedsDwarfCFI) {
766 NumFrameExtraProbe++;
767 CurrentOffset += StackProbeSize;
776 unsigned Opc =
Is64Bit ? X86::PUSH64r : X86::PUSH32r;
781 BuildStackAdjustment(
MBB,
MBBI,
DL, -ChunkSize,
false)
788void X86FrameLowering::emitStackProbeInlineGenericLoop(
796 "Inline stack probe loop will clobber live EFLAGS.");
798 const bool NeedsDwarfCFI = needsDwarfCFI(MF);
802 const unsigned MovMIOpc =
Is64Bit ? X86::MOV64mi32 : X86::MOV32mi;
803 const uint64_t StackProbeSize = TLI.getStackProbeSize(MF);
806 if (AlignOffset < StackProbeSize) {
808 BuildStackAdjustment(
MBB,
MBBI,
DL, -AlignOffset,
false)
816 NumFrameExtraProbe++;
829 MF.
insert(MBBIter, testMBB);
830 MF.
insert(MBBIter, tailMBB);
870 if (!HasFP && NeedsDwarfCFI) {
873 const Register DwarfFinalStackProbed =
880 nullptr,
TRI->getDwarfRegNum(DwarfFinalStackProbed,
true)));
887 BuildStackAdjustment(*testMBB, testMBB->
end(),
DL, -StackProbeSize,
921 BuildStackAdjustment(*tailMBB, TailMBBIter,
DL, -TailOffset,
927 if (!HasFP && NeedsDwarfCFI) {
937 nullptr,
TRI->getDwarfRegNum(DwarfStackPtr,
true)));
944void X86FrameLowering::emitStackProbeInlineWindowsCoreCLR64(
948 assert(
STI.is64Bit() &&
"different expansion needed for 32 bit");
955 "Inline stack probe loop will clobber live EFLAGS.");
990 MF.
insert(MBBIter, RoundMBB);
991 MF.
insert(MBBIter, LoopMBB);
992 MF.
insert(MBBIter, ContinueMBB);
1000 const int64_t ThreadEnvironmentStackLimit = 0x10;
1002 const int64_t PageMask = ~(
PageSize - 1);
1009 SizeReg = InProlog ? X86::RAX :
MRI.createVirtualRegister(RegClass),
1010 ZeroReg = InProlog ? X86::RCX :
MRI.createVirtualRegister(RegClass),
1011 CopyReg = InProlog ? X86::RDX :
MRI.createVirtualRegister(RegClass),
1012 TestReg = InProlog ? X86::RDX :
MRI.createVirtualRegister(RegClass),
1013 FinalReg = InProlog ? X86::RDX :
MRI.createVirtualRegister(RegClass),
1014 RoundedReg = InProlog ? X86::RDX :
MRI.createVirtualRegister(RegClass),
1015 LimitReg = InProlog ? X86::RCX :
MRI.createVirtualRegister(RegClass),
1016 JoinReg = InProlog ? X86::RCX :
MRI.createVirtualRegister(RegClass),
1017 ProbeReg = InProlog ? X86::RCX :
MRI.createVirtualRegister(RegClass);
1020 int64_t RCXShadowSlot = 0;
1021 int64_t RDXShadowSlot = 0;
1037 int64_t InitSlot = 8 + CalleeSaveSize + (
HasFP ? 8 : 0);
1041 RCXShadowSlot = InitSlot;
1043 RDXShadowSlot = InitSlot;
1044 if (IsRDXLiveIn && IsRCXLiveIn)
1085 .
addImm(ThreadEnvironmentStackLimit)
1096 BuildMI(RoundMBB,
DL,
TII.get(X86::AND64ri32), RoundedReg)
1141 TII.get(X86::MOV64rm), X86::RCX),
1142 X86::RSP,
false, RCXShadowSlot);
1145 TII.get(X86::MOV64rm), X86::RDX),
1146 X86::RSP,
false, RDXShadowSlot);
1151 BuildMI(*ContinueMBB, ContinueMBBI,
DL,
TII.get(X86::SUB64rr), X86::RSP)
1169 for (++BeforeMBBI; BeforeMBBI !=
MBB.
end(); ++BeforeMBBI) {
1185void X86FrameLowering::emitStackProbeCall(
1188 std::optional<MachineFunction::DebugInstrOperandPair> InstrNum)
const {
1194 "code model and indirect thunks not yet implemented.");
1198 "Stack probe calls will clobber live EFLAGS.");
1202 CallOp = IsLargeCodeModel ? X86::CALL64r : X86::CALL64pcrel32;
1204 CallOp = X86::CALLpcrel32;
1265 for (++ExpansionMBBI; ExpansionMBBI !=
MBBI; ++ExpansionMBBI)
1273 const uint64_t Win64MaxSEHOffset = 128;
1274 uint64_t SEHFrameOffset = std::min(SPAdjust, Win64MaxSEHOffset);
1276 return SEHFrameOffset & -16;
1284X86FrameLowering::calculateMaxStackAlign(
const MachineFunction &MF)
const {
1291 MaxAlign = (StackAlign > MaxAlign) ? StackAlign : MaxAlign;
1298 MaxAlign = (MaxAlign > 16) ? MaxAlign :
Align(16);
1300 MaxAlign =
Align(16);
1302 return MaxAlign.
value();
1315 const uint64_t StackProbeSize = TLI.getStackProbeSize(MF);
1316 const bool EmitInlineStackProbe = TLI.hasInlineStackProbe(MF);
1321 if (Reg ==
StackPtr && EmitInlineStackProbe && MaxAlign >= StackProbeSize) {
1323 NumFrameLoopProbe++;
1334 MF.
insert(MBBIter, entryMBB);
1335 MF.
insert(MBBIter, headMBB);
1336 MF.
insert(MBBIter, bodyMBB);
1337 MF.
insert(MBBIter, footMBB);
1338 const unsigned MovMIOpc =
Is64Bit ? X86::MOV64mi32 : X86::MOV32mi;
1347 BuildMI(entryMBB,
DL,
TII.get(TargetOpcode::COPY), FinalStackProbed)
1351 BuildMI(entryMBB,
DL,
TII.get(AndOp), FinalStackProbed)
1352 .
addReg(FinalStackProbed)
1357 MI->getOperand(3).setIsDead();
1361 .
addReg(FinalStackProbed)
1384 .
addReg(FinalStackProbed)
1414 .
addReg(FinalStackProbed)
1430 .
addReg(FinalStackProbed)
1449 MI->getOperand(3).setIsDead();
1457 "MF used frame lowering for wrong subtarget");
1466bool X86FrameLowering::isWin64Prologue(
const MachineFunction &MF)
const {
1470bool X86FrameLowering::needsDwarfCFI(
const MachineFunction &MF)
const {
1477 case X86::REPNE_PREFIX:
1478 case X86::REP_MOVSB_32:
1479 case X86::REP_MOVSB_64:
1480 case X86::REP_MOVSD_32:
1481 case X86::REP_MOVSD_64:
1482 case X86::REP_MOVSQ_32:
1483 case X86::REP_MOVSQ_64:
1484 case X86::REP_MOVSW_32:
1485 case X86::REP_MOVSW_64:
1486 case X86::REP_PREFIX:
1487 case X86::REP_STOSB_32:
1488 case X86::REP_STOSB_64:
1489 case X86::REP_STOSD_32:
1490 case X86::REP_STOSD_64:
1491 case X86::REP_STOSQ_32:
1492 case X86::REP_STOSQ_64:
1493 case X86::REP_STOSW_32:
1494 case X86::REP_STOSW_64:
1590 "MF used frame lowering for wrong subtarget");
1595 uint64_t MaxAlign = calculateMaxStackAlign(MF);
1601 bool FnHasClrFunclet =
1603 bool IsClrFunclet = IsFunclet && FnHasClrFunclet;
1604 bool HasFP =
hasFP(MF);
1605 bool IsWin64Prologue = isWin64Prologue(MF);
1610 bool NeedsWinCFI = NeedsWin64CFI || NeedsWinFPO;
1611 bool NeedsDwarfCFI = needsDwarfCFI(MF);
1617 bool HasWinCFI =
false;
1628 ArgBaseReg =
MI->getOperand(0).getReg();
1641 if (NeedsDwarfCFI) {
1643 unsigned DwarfStackPtr =
TRI->getDwarfRegNum(ArgBaseReg,
true);
1662 if (TailCallArgReserveSize && IsWin64Prologue)
1665 const bool EmitStackProbeCall =
1682 .
addUse(X86::NoRegister);
1690 "win64 prologue does not set the bit 60 in the saved frame pointer");
1732 !EmitStackProbeCall &&
1740 StackSize = std::max(MinSize, StackSize > 128 ? StackSize - 128 : 0);
1747 if (TailCallArgReserveSize != 0) {
1748 BuildStackAdjustment(
MBB,
MBBI,
DL, -(
int)TailCallArgReserveSize,
1771 Register Establisher = X86::NoRegister;
1777 if (IsWin64Prologue && IsFunclet && !IsClrFunclet) {
1797 if (
TRI->hasStackRealignment(MF) && !IsWin64Prologue)
1798 NumBytes =
alignTo(NumBytes, MaxAlign);
1806 if (NeedsDwarfCFI && !ArgBaseReg.
isValid()) {
1812 nullptr, -2 * stackGrowth + (
int)TailCallArgReserveSize),
1816 unsigned DwarfFramePtr =
TRI->getDwarfRegNum(MachineFramePtr,
true);
1820 (
int)TailCallArgReserveSize),
1833 assert(!IsWin64Prologue &&
1834 "win64 prologue does not store async context right below rbp");
1840 if (Attrs.hasAttrSomewhere(Attribute::SwiftAsync)) {
1875 if (!IsWin64Prologue && !IsFunclet) {
1884 if (NeedsDwarfCFI) {
1887 CfaExpr.
push_back(dwarf::DW_CFA_expression);
1889 unsigned DwarfReg =
TRI->getDwarfRegNum(MachineFramePtr,
true);
1901 unsigned DwarfFramePtr =
TRI->getDwarfRegNum(MachineFramePtr,
true);
1920 assert(!IsFunclet &&
"funclets without FPs not yet implemented");
1928 if (HasFP &&
TRI->hasStackRealignment(MF))
1936 unsigned ParentFrameNumBytes = NumBytes;
1938 NumBytes = getWinEHFuncletFrameSize(MF);
1941 bool PushedRegs =
false;
1947 unsigned Opc =
MBBI->getOpcode();
1948 return Opc == X86::PUSH32r || Opc == X86::PUSH64r || Opc == X86::PUSHP64r ||
1949 Opc == X86::PUSH2 || Opc == X86::PUSH2P;
1952 while (IsCSPush(
MBBI)) {
1957 unsigned Opc = LastCSPush->getOpcode();
1959 if (!HasFP && NeedsDwarfCFI) {
1965 if (Opc == X86::PUSH2 || Opc == X86::PUSH2P)
1978 if (Opc == X86::PUSH2 || Opc == X86::PUSH2P)
1980 .
addImm(LastCSPush->getOperand(1).getReg())
1988 if (!IsWin64Prologue && !IsFunclet &&
TRI->hasStackRealignment(MF) &&
1990 assert(HasFP &&
"There should be a frame pointer if stack is realigned.");
2004 NumBytes = mergeSPUpdates(
2018 uint64_t AlignedNumBytes = NumBytes;
2019 if (IsWin64Prologue && !IsFunclet &&
TRI->hasStackRealignment(MF))
2020 AlignedNumBytes =
alignTo(AlignedNumBytes, MaxAlign);
2021 if (AlignedNumBytes >= StackProbeSize && EmitStackProbeCall) {
2023 "The Red Zone is not accounted for in stack probes");
2045 int64_t
Alloc = isEAXAlive ? NumBytes - 8 : NumBytes;
2053 .
addImm(isEAXAlive ? NumBytes - 4 : NumBytes)
2072 }
else if (NumBytes) {
2076 if (NeedsWinCFI && NumBytes) {
2083 int SEHFrameOffset = 0;
2084 unsigned SPOrEstablisher;
2091 unsigned PSPSlotOffset = getPSPSlotOffsetFromSP(MF);
2095 Establisher,
false, PSPSlotOffset)
2102 false, PSPSlotOffset)
2109 SPOrEstablisher = Establisher;
2114 if (IsWin64Prologue && HasFP) {
2121 SPOrEstablisher,
false, SEHFrameOffset);
2124 .
addReg(SPOrEstablisher);
2127 if (NeedsWinCFI && !IsFunclet) {
2128 assert(!NeedsWinFPO &&
"this setframe incompatible with FPO data");
2137 }
else if (IsFunclet &&
STI.is32Bit()) {
2161 if (X86::FR64RegClass.
contains(Reg)) {
2164 if (IsWin64Prologue && IsFunclet)
2172 assert(!NeedsWinFPO &&
"SEH_SaveXMM incompatible with FPO data");
2182 if (NeedsWinCFI && HasWinCFI)
2186 if (FnHasClrFunclet && !IsFunclet) {
2190 unsigned PSPSlotOffset = getPSPSlotOffsetFromSP(MF);
2204 if (IsWin64Prologue &&
TRI->hasStackRealignment(MF)) {
2205 assert(HasFP &&
"There should be a frame pointer if stack is realigned.");
2206 BuildStackAlignAND(
MBB,
MBBI,
DL, SPOrEstablisher, MaxAlign);
2210 if (IsFunclet &&
STI.is32Bit())
2243 assert(UsedReg == BasePtr);
2252 int FI =
MI->getOperand(1).getIndex();
2253 unsigned MOVmr =
Is64Bit ? X86::MOV64mr : X86::MOV32mr;
2260 if (((!HasFP && NumBytes) || PushedRegs) && NeedsDwarfCFI) {
2262 if (!HasFP && NumBytes) {
2288 bool NeedsCLD =
false;
2302 if (
MI.isInlineAsm()) {
2334 switch (
MI.getOpcode()) {
2336 case X86::CLEANUPRET:
2358X86FrameLowering::getPSPSlotOffsetFromSP(
const MachineFunction &MF)
const {
2365 return static_cast<unsigned>(
Offset);
2369X86FrameLowering::getWinEHFuncletFrameSize(
const MachineFunction &MF)
const {
2376 WinEHXMMSlotInfo.
size() *
TRI->getSpillSize(X86::VR128RegClass);
2385 UsedSize = getPSPSlotOffsetFromSP(MF) +
SlotSize;
2396 return FrameSizeMinusRBP + XMMSize - CSSize;
2400 return Opc == X86::TCRETURNri || Opc == X86::TCRETURNdi ||
2401 Opc == X86::TCRETURNmi || Opc == X86::TCRETURNri64 ||
2402 Opc == X86::TCRETURNdi64 || Opc == X86::TCRETURNmi64;
2413 DL =
MBBI->getDebugLoc();
2421 bool NeedsWin64CFI =
2427 uint64_t MaxAlign = calculateMaxStackAlign(MF);
2430 bool HasFP =
hasFP(MF);
2439 unsigned Opc = X86::LEA32r;
2441 ArgBaseReg =
MI->getOperand(0).getReg();
2442 if (
STI.is64Bit()) {
2444 StackReg = X86::RSP;
2455 if (NeedsDwarfCFI) {
2456 unsigned DwarfStackPtr =
TRI->getDwarfRegNum(StackReg,
true);
2466 assert(HasFP &&
"EH funclets without FP not yet implemented");
2467 NumBytes = getWinEHFuncletFrameSize(MF);
2471 NumBytes = FrameSize - CSSize - TailCallArgReserveSize;
2475 if (
TRI->hasStackRealignment(MF) && !IsWin64Prologue)
2476 NumBytes =
alignTo(FrameSize, MaxAlign);
2478 NumBytes = StackSize - CSSize - TailCallArgReserveSize;
2480 uint64_t SEHStackAllocAmt = NumBytes;
2505 if (NeedsDwarfCFI) {
2507 unsigned DwarfStackPtr =
2508 TRI->getDwarfRegNum(
Is64Bit ? X86::RSP : X86::ESP,
true);
2514 unsigned DwarfFramePtr =
TRI->getDwarfRegNum(MachineFramePtr,
true);
2529 unsigned Opc = PI->getOpcode();
2531 if (Opc != X86::DBG_VALUE && !PI->isTerminator()) {
2533 (Opc != X86::POP32r && Opc != X86::POP64r && Opc != X86::BTR64ri8 &&
2534 Opc != X86::ADD64ri32 && Opc != X86::POPP64r && Opc != X86::POP2 &&
2535 Opc != X86::POP2P && Opc != X86::LEA64r))
2545 int FI =
MI->getOperand(1).getIndex();
2546 unsigned MOVrm =
Is64Bit ? X86::MOV64rm : X86::MOV32rm;
2553 if (IsFunclet && Terminator->getOpcode() == X86::CATCHRET)
2554 emitCatchRetReturnValue(
MBB, FirstCSPop, &*Terminator);
2557 DL =
MBBI->getDebugLoc();
2569 if (
TRI->hasStackRealignment(MF))
2573 IsWin64Prologue ? SEHStackAllocAmt - SEHFrameOffset : -CSSize;
2585 if (LEAAmount != 0) {
2595 }
else if (NumBytes) {
2598 if (!HasFP && NeedsDwarfCFI) {
2602 nullptr, CSSize + TailCallArgReserveSize +
SlotSize),
2611 if (!HasFP && NeedsDwarfCFI) {
2618 unsigned Opc = PI->getOpcode();
2620 if (Opc == X86::POP32r || Opc == X86::POP64r || Opc == X86::POPP64r ||
2621 Opc == X86::POP2 || Opc == X86::POP2P) {
2625 if (Opc == X86::POP2 || Opc == X86::POP2P)
2643 assert(
Offset >= 0 &&
"TCDelta should never be positive");
2670 else if (
TRI->hasStackRealignment(MF))
2684 int64_t FPDelta = 0;
2695 if (IsWin64Prologue) {
2704 uint64_t NumBytes = FrameSize - CSSize;
2714 FPDelta = FrameSize - SEHFrameOffset;
2716 "FPDelta isn't aligned per the Win64 ABI!");
2728 if (TailCallReturnAddrDelta < 0)
2729 Offset -= TailCallReturnAddrDelta;
2747 const auto it = WinEHXMMSlotInfo.find(FI);
2749 if (it == WinEHXMMSlotInfo.end())
2760 int Adjustment)
const {
2770 bool IgnoreSPUpdates)
const {
2820 "we don't handle this case!");
2852 std::vector<CalleeSavedInfo> &CSI)
const {
2856 unsigned CalleeSavedFrameSize = 0;
2857 unsigned XMMCalleeSavedFrameSize = 0;
2863 if (TailCallReturnAddrDelta < 0) {
2874 TailCallReturnAddrDelta -
SlotSize,
true);
2878 if (this->TRI->hasBasePointer(MF)) {
2904 for (
unsigned i = 0; i < CSI.size(); ++i) {
2905 if (
TRI->regsOverlap(CSI[i].getReg(),
FPReg)) {
2906 CSI.erase(CSI.begin() + i);
2921 unsigned NumRegsForPush2 = 0;
2922 if (
STI.hasPush2Pop2()) {
2924 return X86::GR64RegClass.contains(
I.getReg());
2926 bool NeedPadding = (SpillSlotOffset % 16 != 0) && (NumCSGPR % 2 == 0);
2927 bool UsePush2Pop2 = NeedPadding ? NumCSGPR > 2 : NumCSGPR > 1;
2929 NumRegsForPush2 = UsePush2Pop2 ?
alignDown(NumCSGPR, 2) : 0;
2946 (SpillSlotOffset % 16 == 0 ||
2968 "Expect even candidates for push2/pop2");
2970 ++NumFunctionUsingPush2Pop2;
2981 MVT VT = MVT::Other;
2982 if (X86::VK16RegClass.
contains(Reg))
2983 VT =
STI.hasBWI() ? MVT::v64i1 : MVT::v16i1;
2986 unsigned Size =
TRI->getSpillSize(*RC);
2987 Align Alignment =
TRI->getSpillAlign(*RC);
2989 assert(SpillSlotOffset < 0 &&
"SpillSlotOffset should always < 0 on X86");
2990 SpillSlotOffset = -
alignTo(-SpillSlotOffset, Alignment);
2993 SpillSlotOffset -=
Size;
2999 if (X86::VR128RegClass.
contains(Reg)) {
3000 WinEHXMMSlotInfo[
SlotIndex] = XMMCalleeSavedFrameSize;
3001 XMMCalleeSavedFrameSize +=
Size;
3026 auto UpdateLiveInCheckCanKill = [&](
Register Reg) {
3033 if (
MRI.isLiveIn(Reg))
3038 if (
MRI.isLiveIn(*AReg))
3042 auto UpdateLiveInGetKillRegState = [&](
Register Reg) {
3046 for (
auto RI = CSI.
rbegin(), RE = CSI.
rend(); RI != RE; ++RI) {
3054 .
addReg(Reg, UpdateLiveInGetKillRegState(Reg))
3055 .
addReg(Reg2, UpdateLiveInGetKillRegState(Reg2))
3059 .
addReg(Reg, UpdateLiveInGetKillRegState(Reg))
3065 unsigned Opc =
STI.is64Bit() ? X86::PUSH64r : X86::PUSH32r;
3066 Register BaseReg = this->TRI->getBaseRegister();
3080 MVT VT = MVT::Other;
3081 if (X86::VK16RegClass.
contains(Reg))
3082 VT =
STI.hasBWI() ? MVT::v64i1 : MVT::v16i1;
3101 "SEH should not use CATCHRET");
3106 if (
STI.is64Bit()) {
3138 if (
MI->getOpcode() == X86::CATCHRET) {
3156 MVT VT = MVT::Other;
3157 if (X86::VK16RegClass.
contains(Reg))
3158 VT =
STI.hasBWI() ? MVT::v64i1 : MVT::v16i1;
3169 unsigned Opc =
STI.is64Bit() ? X86::POP64r : X86::POP32r;
3170 Register BaseReg = this->TRI->getBaseRegister();
3176 for (
auto I = CSI.
begin(), E = CSI.
end();
I != E; ++
I) {
3205 SavedRegs.
set(BasePtr);
3213 if (
I->hasNestAttr() && !
I->use_empty())
3230 return Primary ? X86::R14 : X86::R13;
3232 return Primary ? X86::EBX : X86::EDI;
3237 return Primary ? X86::R11 : X86::R12;
3239 return Primary ? X86::R11D : X86::R12D;
3249 "nested function.");
3250 return Primary ? X86::EAX : X86::ECX;
3253 return Primary ? X86::EDX : X86::EAX;
3254 return Primary ? X86::ECX : X86::EAX;
3265 unsigned TlsReg, TlsOffset;
3270 assert(&(*MF.
begin()) == &PrologueMBB &&
"Shrink-wrapping not supported yet");
3274 "Scratch register is live-in");
3294 bool IsNested =
false;
3303 for (
const auto &LI : PrologueMBB.
liveins()) {
3322 TlsOffset =
IsLP64 ? 0x70 : 0x40;
3325 TlsOffset = 0x60 + 90 * 8;
3339 if (CompareStackPointer)
3340 ScratchReg =
IsLP64 ? X86::RSP : X86::ESP;
3363 TlsOffset = 0x48 + 90 * 4;
3376 if (CompareStackPointer)
3377 ScratchReg = X86::ESP;
3379 BuildMI(checkMBB,
DL,
TII.get(X86::LEA32r), ScratchReg)
3398 unsigned ScratchReg2;
3400 if (CompareStackPointer) {
3403 SaveScratch2 =
false;
3415 "Scratch register is live-in and not saved");
3421 BuildMI(checkMBB,
DL,
TII.get(X86::MOV32ri), ScratchReg2)
3432 BuildMI(checkMBB,
DL,
TII.get(X86::POP32r), ScratchReg2);
3448 const unsigned RegAX =
IsLP64 ? X86::RAX : X86::EAX;
3449 const unsigned Reg10 =
IsLP64 ? X86::R10 : X86::R10D;
3450 const unsigned Reg11 =
IsLP64 ? X86::R11 : X86::R11D;
3451 const unsigned MOVrr =
IsLP64 ? X86::MOV64rr : X86::MOV32rr;
3487 "code model and thunks not yet implemented.");
3504 BuildMI(allocMBB,
DL,
TII.get(X86::MORESTACK_RET_RESTORE_R10));
3513#ifdef EXPENSIVE_CHECKS
3524 for (
int i = 0, e = HiPELiteralsMD->
getNumOperands(); i != e; ++i) {
3526 if (
Node->getNumOperands() != 2)
3528 MDString *NodeName = dyn_cast<MDString>(
Node->getOperand(0));
3530 if (!NodeName || !NodeVal)
3533 if (ValConst && NodeName->
getString() == LiteralName) {
3539 " required but not provided");
3550 return MI.isMetaInstruction();
3576 assert(&(*MF.
begin()) == &PrologueMBB &&
"Shrink-wrapping not supported yet");
3581 if (!HiPELiteralsMD)
3583 "Can't generate HiPE prologue without runtime parameters");
3585 HiPELiteralsMD,
Is64Bit ?
"AMD64_LEAF_WORDS" :
"X86_LEAF_WORDS");
3586 const unsigned CCRegisteredArgs =
Is64Bit ? 6 : 5;
3587 const unsigned Guaranteed = HipeLeafWords *
SlotSize;
3594 "HiPE prologue is only supported on Linux operating systems.");
3604 unsigned MoreStackForCalls = 0;
3606 for (
auto &
MBB : MF) {
3607 for (
auto &
MI :
MBB) {
3627 if (
F->getName().contains(
"erlang.") ||
F->getName().contains(
"bif_") ||
3631 unsigned CalleeStkArity =
F->arg_size() > CCRegisteredArgs
3632 ?
F->arg_size() - CCRegisteredArgs
3634 if (HipeLeafWords - 1 > CalleeStkArity)
3636 std::max(MoreStackForCalls,
3637 (HipeLeafWords - 1 - CalleeStkArity) *
SlotSize);
3640 MaxStack += MoreStackForCalls;
3645 if (MaxStack > Guaranteed) {
3649 for (
const auto &LI : PrologueMBB.
liveins()) {
3657 unsigned ScratchReg,
SPReg, PReg, SPLimitOffset;
3658 unsigned LEAop, CMPop, CALLop;
3663 LEAop = X86::LEA64r;
3664 CMPop = X86::CMP64rm;
3665 CALLop = X86::CALL64pcrel32;
3669 LEAop = X86::LEA32r;
3670 CMPop = X86::CMP32rm;
3671 CALLop = X86::CALLpcrel32;
3676 "HiPE prologue scratch register is live-in");
3683 PReg,
false, SPLimitOffset);
3693 PReg,
false, SPLimitOffset);
3703#ifdef EXPENSIVE_CHECKS
3720 if (NumPops != 1 && NumPops != 2)
3728 if (!Prev->isCall() || !Prev->getOperand(1).isRegMask())
3732 unsigned FoundRegs = 0;
3738 Is64Bit ? X86::GR64_NOREX_NOSPRegClass : X86::GR32_NOREX_NOSPRegClass;
3740 for (
auto Candidate : RegClass) {
3748 if (
MRI.isReserved(Candidate))
3753 if (MO.isReg() && MO.isDef() &&
3754 TRI->isSuperOrSubRegisterEq(MO.getReg(), Candidate)) {
3763 Regs[FoundRegs++] = Candidate;
3764 if (FoundRegs == (
unsigned)NumPops)
3772 while (FoundRegs < (
unsigned)NumPops)
3773 Regs[FoundRegs++] = Regs[0];
3775 for (
int i = 0; i < NumPops; ++i)
3786 unsigned Opcode =
I->getOpcode();
3787 bool isDestroy = Opcode ==
TII.getCallFrameDestroyOpcode();
3800 if (!reserveCallFrame) {
3821 bool HasDwarfEHHandlers = !WindowsCFI && !MF.
getLandingPads().empty();
3823 if (HasDwarfEHHandlers && !isDestroy &&
3833 Amount -= InternalAmt;
3843 int64_t StackAdjustment = isDestroy ? Amount : -Amount;
3844 int64_t CfaAdjustment = StackAdjustment;
3846 if (StackAdjustment) {
3855 auto CalcNewOffset = [&StackAdjustment](int64_t
Offset) {
3856 return StackAdjustment +
Offset;
3859 mergeSPUpdates(
MBB, InsertPos, CalcCfaAdjust, CalcNewOffset,
true);
3861 mergeSPUpdates(
MBB, InsertPos, CalcCfaAdjust, CalcNewOffset,
false);
3863 if (StackAdjustment) {
3864 if (!(
F.hasMinSize() &&
3865 adjustStackWithPops(
MBB, InsertPos,
DL, StackAdjustment)))
3866 BuildStackAdjustment(
MBB, InsertPos,
DL, StackAdjustment,
3892 while (CI !=
B && !std::prev(CI)->isCall())
3894 BuildStackAdjustment(
MBB, CI,
DL, -InternalAmt,
false);
3910 if (TLI.hasInlineStackProbe(MF) || TLI.hasStackProbeSymbol(MF))
3946 bool CompactUnwind =
3965 "restoring EBP/ESI on non-32-bit target");
3977 int EHRegSize = MFI.getObjectSize(FI);
3982 X86::EBP,
true, -EHRegSize)
3988 int EndOffset = -EHRegOffset - EHRegSize;
4001 "end of registration object above normal EBP position!");
4002 }
else if (UsedReg == BasePtr) {
4012 assert(UsedReg == BasePtr);
4038 FrameBase.
Kind = DwarfFrameBase::CFA;
4044 return DwarfFrameBase{DwarfFrameBase::Register, {FrameRegister}};
4049struct X86FrameSortingObject {
4050 bool IsValid =
false;
4051 unsigned ObjectIndex = 0;
4052 unsigned ObjectSize = 0;
4054 unsigned ObjectNumUses = 0;
4070struct X86FrameSortingComparator {
4071 inline bool operator()(
const X86FrameSortingObject &
A,
4072 const X86FrameSortingObject &
B)
const {
4073 uint64_t DensityAScaled, DensityBScaled;
4093 DensityAScaled =
static_cast<uint64_t>(
A.ObjectNumUses) *
4095 DensityBScaled =
static_cast<uint64_t>(
B.ObjectNumUses) *
4106 if (DensityAScaled == DensityBScaled)
4107 return A.ObjectAlignment <
B.ObjectAlignment;
4109 return DensityAScaled < DensityBScaled;
4123 if (ObjectsToAllocate.
empty())
4135 for (
auto &Obj : ObjectsToAllocate) {
4136 SortingObjects[Obj].IsValid =
true;
4137 SortingObjects[Obj].ObjectIndex = Obj;
4141 if (ObjectSize == 0)
4143 SortingObjects[Obj].ObjectSize = 4;
4145 SortingObjects[Obj].ObjectSize = ObjectSize;
4149 for (
auto &
MBB : MF) {
4150 for (
auto &
MI :
MBB) {
4151 if (
MI.isDebugInstr())
4157 int Index = MO.getIndex();
4161 SortingObjects[Index].IsValid)
4162 SortingObjects[Index].ObjectNumUses++;
4177 for (
auto &Obj : SortingObjects) {
4181 ObjectsToAllocate[i++] = Obj.ObjectIndex;
4185 if (!
TRI->hasStackRealignment(MF) &&
hasFP(MF))
4186 std::reverse(ObjectsToAllocate.
begin(), ObjectsToAllocate.
end());
4198 Offset += getWinEHFuncletFrameSize(MF);
4218 adjustFrameForMsvcCxxEh(MF);
4222void X86FrameLowering::adjustFrameForMsvcCxxEh(
MachineFunction &MF)
const {
4230 int64_t MinFixedObjOffset = -
SlotSize;
4236 int FrameIndex =
H.CatchObj.FrameIndex;
4237 if (FrameIndex != INT_MAX) {
4240 MinFixedObjOffset -= std::abs(MinFixedObjOffset) %
Align;
4248 MinFixedObjOffset -= std::abs(MinFixedObjOffset) % 8;
4249 int64_t UnwindHelpOffset = MinFixedObjOffset -
SlotSize;
4276 MI->eraseFromParent();
4300 unsigned NumSpilledRegs) {
4302 unsigned AllocSize =
TRI->getSpillSize(*RC) * NumSpilledRegs;
4304 unsigned AlignedSize =
alignTo(AllocSize, StackAlign);
4305 return AlignedSize - AllocSize;
4311 int SPAdjust)
const {
4336 if (
FP.isValid() && needsDwarfCFI(MF)) {
4349 Offset +=
TRI->getSpillSize(*
TRI->getMinimalPhysRegClass(BP));
4352 if (
TII.isFrameSetup(*BeforeMI)) {
4354 BeforeMI = std::next(BeforeMI);
4359 unsigned DwarfStackPtr =
TRI->getDwarfRegNum(
StackPtr,
true);
4368 DefCfaExpr.
push_back(dwarf::DW_CFA_def_cfa_expression);
4380 int SPAdjust)
const {
4402 if (needsDwarfCFI(MF)) {
4412void X86FrameLowering::saveAndRestoreFPBPUsingSP(
4415 assert(SpillFP || SpillBP);
4419 unsigned NumRegs = 0;
4425 RC =
TRI->getMinimalPhysRegClass(
FP);
4432 RC =
TRI->getMinimalPhysRegClass(BP);
4437 spillFPBPUsingSP(MF, BeforeMI,
FP, BP, SPAdjust);
4438 restoreFPBPUsingSP(MF, AfterMI,
FP, BP, SPAdjust);
4441bool X86FrameLowering::skipSpillFPBP(
4443 if (
MI->getOpcode() == X86::LCMPXCHG16B_SAVE_RBX) {
4451 while (!(
MI->getOpcode() == TargetOpcode::COPY &&
4452 MI->getOperand(1).getReg() == X86::RBX) &&
4463 AccessFP = AccessBP =
false;
4465 if (
MI.findRegisterUseOperandIdx(
FP,
TRI,
false) != -1 ||
4466 MI.findRegisterDefOperandIdx(
FP,
TRI,
false,
true) != -1)
4470 if (
MI.findRegisterUseOperandIdx(BP,
TRI,
false) != -1 ||
4471 MI.findRegisterDefOperandIdx(BP,
TRI,
false,
true) != -1)
4474 return AccessFP || AccessBP;
4500void X86FrameLowering::checkInterferedAccess(
4503 bool SpillBP)
const {
4504 if (
DefMI == KillMI)
4519 "Interference usage of base pointer/frame "
4567 bool InsideEHLabels =
false;
4572 MI = *(std::prev(TermMI));
4580 isInvoke(*
MI, InsideEHLabels) || skipSpillFPBP(MF,
MI)) {
4585 if (
MI->getOpcode() == TargetOpcode::EH_LABEL) {
4586 InsideEHLabels = !InsideEHLabels;
4591 bool AccessFP, AccessBP;
4600 bool FPLive =
false, BPLive =
false;
4601 bool SpillFP =
false, SpillBP =
false;
4604 SpillFP |= AccessFP;
4605 SpillBP |= AccessBP;
4608 if (FPLive &&
MI->findRegisterDefOperandIdx(
FP,
TRI,
false,
true) != -1)
4610 if (
FP &&
MI->findRegisterUseOperandIdx(
FP,
TRI,
false) != -1)
4612 if (BPLive &&
MI->findRegisterDefOperandIdx(BP,
TRI,
false,
true) != -1)
4614 if (BP &&
MI->findRegisterUseOperandIdx(BP,
TRI,
false) != -1)
4618 }
while ((
MI != ME) &&
4619 (FPLive || BPLive ||
4623 if (FPLive && !SpillBP)
4628 if (KillMI->isCall() &&
DefMI != ME) {
4629 auto FrameSetup = std::next(
DefMI);
4633 while (FrameSetup != ME && !
TII.isFrameSetup(*FrameSetup) &&
4634 !FrameSetup->isCall())
4638 if (FrameSetup != ME &&
TII.isFrameSetup(*FrameSetup) &&
4639 (
TII.getFrameSize(*FrameSetup) ||
4641 while (!
TII.isFrameInstr(*KillMI))
4649 checkInterferedAccess(MF,
DefMI, KillMI, SpillFP, SpillBP);
4652 saveAndRestoreFPBPUsingSP(MF, &(*
DefMI), &(*KillMI), SpillFP, SpillBP);
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder MachineInstrBuilder & DefMI
static bool isFuncletReturnInstr(const MachineInstr &MI)
static const uint64_t kSplitStackAvailable
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Analysis containing CSE Info
Given that RA is a live value
const HexagonInstrInfo * TII
Module.h This file contains the declarations for the Module class.
static cl::opt< int > PageSize("imp-null-check-page-size", cl::desc("The page size of the target in bytes"), cl::init(4096), cl::Hidden)
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
static bool isTailCallOpcode(unsigned Opc)
unsigned const TargetRegisterInfo * TRI
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static constexpr MCPhysReg FPReg
static constexpr MCPhysReg SPReg
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static bool is64Bit(const char *name)
static unsigned calculateSetFPREG(uint64_t SPAdjust)
static unsigned GetScratchRegister(bool Is64Bit, bool IsLP64, const MachineFunction &MF, bool Primary)
GetScratchRegister - Get a temp register for performing work in the segmented stack and the Erlang/Hi...
static unsigned getADDriOpcode(bool IsLP64)
static unsigned getPUSH2Opcode(const X86Subtarget &ST)
static unsigned getMOVriOpcode(bool Use64BitReg, int64_t Imm)
static unsigned getLEArOpcode(bool IsLP64)
static unsigned getSUBriOpcode(bool IsLP64)
static bool flagsNeedToBePreservedBeforeTheTerminators(const MachineBasicBlock &MBB)
Check if the flags need to be preserved before the terminators.
static bool isFPBPAccess(const MachineInstr &MI, Register FP, Register BP, const TargetRegisterInfo *TRI, bool &AccessFP, bool &AccessBP)
static bool isOpcodeRep(unsigned Opcode)
Return true if an opcode is part of the REP group of instructions.
static unsigned getANDriOpcode(bool IsLP64, int64_t Imm)
static bool isEAXLiveIn(MachineBasicBlock &MBB)
static int computeFPBPAlignmentGap(MachineFunction &MF, const TargetRegisterClass *RC, unsigned NumSpilledRegs)
static unsigned getADDrrOpcode(bool IsLP64)
constexpr int64_t MaxSPChunk
static bool HasNestArgument(const MachineFunction *MF)
static unsigned getPOPOpcode(const X86Subtarget &ST)
static bool isInvoke(const MachineInstr &MI, bool InsideEHLabels)
static unsigned getPOP2Opcode(const X86Subtarget &ST)
static unsigned getHiPELiteral(NamedMDNode *HiPELiteralsMD, const StringRef LiteralName)
Lookup an ERTS parameter in the !hipe.literals named metadata node.
static bool blockEndIsUnreachable(const MachineBasicBlock &MBB, MachineBasicBlock::const_iterator MBBI)
static unsigned getSUBrrOpcode(bool IsLP64)
static unsigned getPUSHOpcode(const X86Subtarget &ST)
static const unsigned FramePtr
This class represents an incoming formal argument to a Function.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
reverse_iterator rend() const
bool empty() const
empty - Check if the array is empty.
reverse_iterator rbegin() const
LLVM Basic Block Representation.
iterator_range< const_set_bits_iterator > set_bits() const
static BranchProbability getOne()
static BranchProbability getZero()
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
This is the shared class of boolean and integer constants.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
bool hasPersonalityFn() const
Check whether this function has a personality function.
Constant * getPersonalityFn() const
Get the personality function associated with this function.
AttributeList getAttributes() const
Return the attribute list for this Function.
bool needsUnwindTableEntry() const
True if this function needs an unwind table.
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.
Module * getParent()
Get the module that this global value is contained inside of...
A set of physical registers with utility functions to track liveness when walking backward/forward th...
bool usesWindowsCFI() const
static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register, SMLoc Loc={})
.cfi_def_cfa_register modifies a rule for computing CFA.
static MCCFIInstruction createGnuArgsSize(MCSymbol *L, int64_t Size, SMLoc Loc={})
A special wrapper for .cfi_escape that indicates GNU_ARGS_SIZE.
static MCCFIInstruction createRestore(MCSymbol *L, unsigned Register, SMLoc Loc={})
.cfi_restore says that the rule for Register is now the same as it was at the beginning of the functi...
static MCCFIInstruction cfiDefCfa(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})
.cfi_def_cfa defines a rule for computing CFA as: take address from Register and add Offset to it.
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
static MCCFIInstruction createRememberState(MCSymbol *L, SMLoc Loc={})
.cfi_remember_state Save all current rules for all registers.
OpType getOperation() const
static MCCFIInstruction cfiDefCfaOffset(MCSymbol *L, int64_t Offset, SMLoc Loc={})
.cfi_def_cfa_offset modifies a rule for computing CFA.
static MCCFIInstruction createEscape(MCSymbol *L, StringRef Vals, SMLoc Loc={}, StringRef Comment="")
.cfi_escape Allows the user to add arbitrary bytes to the unwind info.
static MCCFIInstruction createAdjustCfaOffset(MCSymbol *L, int64_t Adjustment, SMLoc Loc={})
.cfi_adjust_cfa_offset Same as .cfi_def_cfa_offset, but Offset is a relative value that is added/subt...
static MCCFIInstruction createRestoreState(MCSymbol *L, SMLoc Loc={})
.cfi_restore_state Restore the previously saved state.
const MCObjectFileInfo * getObjectFileInfo() const
const MCRegisterInfo * getRegisterInfo() const
void reportError(SMLoc L, const Twine &Msg)
MCSection * getCompactUnwindSection() const
MCRegAliasIterator enumerates all registers aliasing Reg.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Wrapper class representing physical registers. Should be passed by value.
StringRef getString() const
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
bool hasEHPadSuccessor() const
bool isEHPad() const
Returns true if the block is a landing pad.
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
iterator_range< livein_iterator > liveins() const
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
bool isEHFuncletEntry() const
Returns true if this is the entry block of an EH funclet.
LivenessQueryResult computeRegisterLiveness(const TargetRegisterInfo *TRI, MCRegister Reg, const_iterator Before, unsigned Neighborhood=10) const
Return whether (physical) register Reg has been defined and not killed as of just before Before.
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
bool isReturnBlock() const
Convenience function that returns true if the block ends in a return instruction.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.
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_range< succ_iterator > successors()
reverse_iterator rbegin()
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 '...
@ LQR_Live
Register is known to be (at least partially) live.
void setMachineBlockAddressTaken()
Set this block to indicate that its address is used as something other than the target of a terminato...
bool isLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
bool isCleanupFuncletEntry() const
Returns true if this is the entry block of a cleanup funclet.
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.
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
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 adjustsStack() const
Return true if this function adjusts the stack – e.g., when calling another function.
void ensureMaxAlignment(Align Alignment)
Make sure the function is at least Align bytes aligned.
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...
void setObjectOffset(int ObjectIdx, int64_t SPOffset)
Set the stack frame offset of the specified object.
uint64_t getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
bool hasPatchPoint() const
This method may be called any time after instruction selection is complete to determine if there is a...
bool hasOpaqueSPAdjustment() const
Returns true if the function contains opaque dynamic stack adjustments.
void setCVBytesOfCalleeSavedRegisters(unsigned S)
int CreateSpillStackObject(uint64_t Size, Align Alignment)
Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
bool hasStackMap() const
This method may be called any time after instruction selection is complete to determine if there is a...
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
int getObjectIndexEnd() const
Return one past the maximum frame object index.
bool hasCopyImplyingStackAdjustment() const
Returns true if the function contains operations which will lower down to instructions which manipula...
bool hasStackObjects() const
Return true if there are any stack objects in this function.
int CreateFixedSpillStackObject(uint64_t Size, int64_t SPOffset, bool IsImmutable=false)
Create a spill slot at a fixed location on the stack.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
void setStackSize(uint64_t Size)
Set the size of the stack.
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
int getObjectIndexBegin() const
Return the minimum frame object index.
void setOffsetAdjustment(int64_t Adj)
Set the correction for frame offsets.
const WinEHFuncInfo * getWinEHFuncInfo() const
getWinEHFuncInfo - Return information about how the current function uses Windows exception handling.
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.
const std::vector< MCCFIInstruction > & getFrameInstructions() const
Returns a reference to a list of cfi instructions in the function's prologue.
bool hasInlineAsm() const
Returns true if the function contains any inline assembly.
void makeDebugValueSubstitution(DebugInstrOperandPair, DebugInstrOperandPair, unsigned SubReg=0)
Create a substitution between one <instr,operand> value to a different, new value.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align 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.
bool needsFrameMoves() const
True if this function needs frame moves for debug or exceptions.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
bool callsUnwindInit() const
void push_front(MachineBasicBlock *MBB)
const char * createExternalSymbolName(StringRef Name)
Allocate a string and populate it with the given external symbol name.
MCContext & getContext() const
bool callsEHReturn() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
bool verify(Pass *p=nullptr, const char *Banner=nullptr, raw_ostream *OS=nullptr, bool AbortOnError=true) const
Run the current MachineFunction through the machine code verifier, useful for debugger use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const std::vector< LandingPadInfo > & getLandingPads() const
Return a reference to the landing pad info for the current function.
bool shouldSplitStack() const
Should we be emitting segmented stack stuff for the function.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineBasicBlock & front() const
bool hasEHFunclets() const
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
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 & 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 & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
unsigned getNumOperands() const
Retuns the total number of operands.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
unsigned getDebugInstrNum()
Fetch the instruction number of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
@ MOVolatile
The memory access is volatile.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
MachineBasicBlock * getMBB() const
void setIsDead(bool Val=true)
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
static bool clobbersPhysReg(const uint32_t *RegMask, MCRegister PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
bool isReserved(MCRegister PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
bool isLiveIn(Register Reg) const
NamedMDNode * getNamedMetadata(StringRef Name) const
Return the first NamedMDNode in the module with the specified name.
unsigned getCodeViewFlag() const
Returns the CodeView Version by checking module flags.
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
MDNode * getOperand(unsigned i) const
unsigned getNumOperands() const
Wrapper class representing virtual and physical registers.
constexpr bool isValid() const
Represents a location in source code.
SlotIndex - An opaque wrapper around machine indexes.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
void append(StringRef RHS)
Append from a StringRef.
StringRef str() const
Explicit conversion to StringRef.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
StackOffset holds a fixed and a scalable offset in bytes.
int64_t getFixed() const
Returns the fixed component of the stack.
static StackOffset getFixed(int64_t Fixed)
StringRef - Represent a constant reference to a string, i.e.
static constexpr size_t npos
Information about stack frame layout on the target.
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
int getOffsetOfLocalArea() const
getOffsetOfLocalArea - This method returns the offset of the local area from the stack pointer on ent...
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
TargetInstrInfo - Interface to description of machine instruction set.
const Triple & getTargetTriple() const
CodeModel::Model getCodeModel() const
Returns the code model.
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
SwiftAsyncFramePointerMode SwiftAsyncFramePointer
Control when and how the Swift async frame pointer bit should be set.
bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual Register getFrameRegister(const MachineFunction &MF) const =0
Debug information queries.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual const TargetFrameLowering * getFrameLowering() const
bool isOSWindows() const
Tests whether the OS is Windows.
bool isOSDarwin() const
Is this a "Darwin" OS (macOS, iOS, tvOS, watchOS, XROS, or DriverKit).
bool has128ByteRedZone(const MachineFunction &MF) const
Return true if the function has a redzone (accessible bytes past the frame of the top of stack functi...
void spillFPBP(MachineFunction &MF) const override
If a function uses base pointer and the base pointer is clobbered by inline asm, RA doesn't detect th...
bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override
canSimplifyCallFramePseudos - If there is a reserved call frame, the call frame pseudos can be simpli...
bool needsFrameIndexResolution(const MachineFunction &MF) const override
X86FrameLowering(const X86Subtarget &STI, MaybeAlign StackAlignOverride)
const X86RegisterInfo * TRI
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
bool hasFPImpl(const MachineFunction &MF) const override
hasFPImpl - Return true if the specified function should have a dedicated frame pointer register.
MachineBasicBlock::iterator restoreWin32EHStackPointers(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, bool RestoreSP=false) const
Sets up EBP and optionally ESI based on the incoming EBP value.
int getInitialCFAOffset(const MachineFunction &MF) const override
Return initial CFA offset value i.e.
bool canUseAsPrologue(const MachineBasicBlock &MBB) const override
Check whether or not the given MBB can be used as a prologue for the target.
bool hasReservedCallFrame(const MachineFunction &MF) const override
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
void emitStackProbe(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, bool InProlog, std::optional< MachineFunction::DebugInstrOperandPair > InstrNum=std::nullopt) const
Emit target stack probe code.
void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS) const override
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
void emitCalleeSavedFrameMoves(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, bool IsPrologue) const
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
int64_t mergeSPAdd(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, int64_t AddOffset, bool doMergeWithPrevious) const
Equivalent to: mergeSPUpdates(MBB, MBBI, [AddOffset](int64_t Offset) { return AddOffset + Offset; },...
StackOffset getFrameIndexReferenceSP(const MachineFunction &MF, int FI, Register &SPReg, int Adjustment) const
bool assignCalleeSavedSpillSlots(MachineFunction &MF, const TargetRegisterInfo *TRI, std::vector< CalleeSavedInfo > &CSI) const override
bool enableShrinkWrapping(const MachineFunction &MF) const override
Returns true if the target will correctly handle shrink wrapping.
StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const override
getFrameIndexReference - This method should return the base register and offset used to reference a f...
void inlineStackProbe(MachineFunction &MF, MachineBasicBlock &PrologMBB) const override
Replace a StackProbe inline-stub with the actual probe code inline.
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...
MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const override
This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy p...
void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &DL, int64_t NumBytes, bool InEpilogue) const
Emit a series of instructions to increment / decrement the stack pointer by a constant value.
bool canUseAsEpilogue(const MachineBasicBlock &MBB) const override
Check whether or not the given MBB can be used as a epilogue for the target.
bool Is64Bit
Is64Bit implies that x86_64 instructions are available.
Register getInitialCFARegister(const MachineFunction &MF) const override
Return initial CFA register value i.e.
bool Uses64BitFramePtr
True if the 64-bit frame or stack pointer should be used.
unsigned getWinEHParentFrameOffset(const MachineFunction &MF) const override
void adjustForSegmentedStacks(MachineFunction &MF, MachineBasicBlock &PrologueMBB) const override
Adjust the prologue to have the function use segmented stacks.
DwarfFrameBase getDwarfFrameBase(const MachineFunction &MF) const override
Return the frame base information to be encoded in the DWARF subprogram debug info.
void emitCalleeSavedFrameMovesFullCFA(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) const override
Emits Dwarf Info specifying offsets of callee saved registers and frame pointer.
int getWin64EHFrameIndexRef(const MachineFunction &MF, int FI, Register &SPReg) const
bool canUseLEAForSPInEpilogue(const MachineFunction &MF) const
Check that LEA can be used on SP in an epilogue sequence for MF.
bool stackProbeFunctionModifiesSP() const override
Does the stack probe function call return with a modified stack pointer?
void orderFrameObjects(const MachineFunction &MF, SmallVectorImpl< int > &ObjectsToAllocate) const override
Order the symbols in the local stack.
void BuildCFI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, const MCCFIInstruction &CFIInst, MachineInstr::MIFlag Flag=MachineInstr::NoFlags) const
Wraps up getting a CFI index and building a MachineInstr for it.
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
void processFunctionBeforeFrameIndicesReplaced(MachineFunction &MF, RegScavenger *RS) const override
processFunctionBeforeFrameIndicesReplaced - This method is called immediately before MO_FrameIndex op...
StackOffset getFrameIndexReferencePreferSP(const MachineFunction &MF, int FI, Register &FrameReg, bool IgnoreSPUpdates) const override
Same as getFrameIndexReference, except that the stack pointer (as opposed to the frame pointer) will ...
void restoreWinEHStackPointersInParent(MachineFunction &MF) const
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...
void adjustForHiPEPrologue(MachineFunction &MF, MachineBasicBlock &PrologueMBB) const override
Erlang programs may need a special prologue to handle the stack size they might need at runtime.
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
void buildClearRegister(Register Reg, MachineBasicBlock &MBB, MachineBasicBlock::iterator Iter, DebugLoc &DL, bool AllowSideEffects=true) const override
int64_t getFrameAdjustment(const MachineInstr &I) const
Returns the stack pointer adjustment that happens inside the frame setup..destroy sequence (e....
X86MachineFunctionInfo - This class is derived from MachineFunction and contains private X86 target-s...
bool getForceFramePointer() const
void setPadForPush2Pop2(bool V)
bool isCandidateForPush2Pop2(Register Reg) const
unsigned getArgumentStackSize() const
bool getFPClobberedByCall() const
int getRestoreBasePointerOffset() const
int getSEHFramePtrSaveIndex() const
bool hasCFIAdjustCfa() const
int getTCReturnAddrDelta() const
void setRestoreBasePointer(const MachineFunction *MF)
bool getHasSEHFramePtrSave() const
DenseMap< int, unsigned > & getWinEHXMMSlotInfo()
bool getBPClobberedByCall() const
void setUsesRedZone(bool V)
bool hasPreallocatedCall() const
bool hasSwiftAsyncContext() const
void setHasSEHFramePtrSave(bool V)
bool getRestoreBasePointer() const
MachineInstr * getStackPtrSaveMI() const
size_t getNumCandidatesForPush2Pop2() const
AMXProgModelEnum getAMXProgModel() const
void addCandidateForPush2Pop2(Register Reg)
unsigned getCalleeSavedFrameSize() const
bool getHasPushSequences() const
bool padForPush2Pop2() const
void setStackPtrSaveMI(MachineInstr *MI)
bool getUsesRedZone() const
void setCalleeSavedFrameSize(unsigned bytes)
void setSEHFramePtrSaveIndex(int Index)
bool hasBasePointer(const MachineFunction &MF) const
Register getFrameRegister(const MachineFunction &MF) const override
unsigned findDeadCallerSavedReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI) const
findDeadCallerSavedReg - Return a caller-saved register that isn't live when it reaches the "return" ...
Register getStackRegister() const
unsigned getSlotSize() const
Register getFramePtr() const
Returns physical register used as frame pointer.
Register getBaseRegister() const
const X86TargetLowering * getTargetLowering() const override
bool isTargetDragonFly() const
bool isTargetWindowsMSVC() const
bool isTarget64BitILP32() const
Is this x86_64 with the ILP32 programming model (x32 ABI)?
bool isTargetDarwin() const
bool isTargetWin64() const
bool isTarget64BitLP64() const
Is this x86_64 with the LP64 programming model (standard AMD64, no x32)?
bool swiftAsyncContextIsDynamicallySet() const
Return whether FrameLowering should always set the "extended frame present" bit in FP,...
bool isTargetWindowsCoreCLR() const
const X86InstrInfo * getInstrInfo() const override
bool isCallingConvWin64(CallingConv::ID CC) const
bool isTargetFreeBSD() const
bool isTargetNaCl64() const
bool isTargetWin32() const
bool useIndirectThunkCalls() const
bool isTargetLinux() const
bool hasInlineStackProbe(const MachineFunction &MF) const override
Returns true if stack probing through inline assembly is requested.
StringRef getStackProbeSymbolName(const MachineFunction &MF) const override
Returns the name of the symbol used to emit stack probes or the empty string if not applicable.
bool hasStackProbeSymbol(const MachineFunction &MF) const override
Returns true if stack probing through a function call is requested.
unsigned getStackProbeSize(const MachineFunction &MF) const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
uint16_t StackAdjustment(const RuntimeFunction &RF)
StackAdjustment - calculated stack adjustment in words.
@ HiPE
Used by the High-Performance Erlang Compiler (HiPE).
@ X86_INTR
x86 hardware interrupt context.
@ Fast
Attempts to make calls as fast as possible (e.g.
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
@ X86_FastCall
'fast' analog of X86_StdCall.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Define
Register definition.
@ Kill
The last use of a register.
@ Undef
Value of the register doesn't matter.
Reg
All possible values of the reg field in the ModR/M byte.
@ MO_GOTPCREL
MO_GOTPCREL - On a symbol operand this indicates that the immediate is offset to the GOT entry for th...
This is an optimization pass for GlobalISel generic memory operations.
void stable_sort(R &&Range)
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.
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
MCRegister getX86SubSuperRegister(MCRegister Reg, unsigned Size, bool High=false)
@ DwarfCFI
DWARF-like instruction based exceptions.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
static const MachineInstrBuilder & addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset=0, bool mem=true)
addFrameReference - This function is used to add a reference to the base of an abstract object on the...
constexpr T alignDown(U Value, V Align, W Skew=0)
Returns the largest unsigned integer less than or equal to Value and is Skew mod Align.
IterT skipDebugInstructionsForward(IterT It, IterT End, bool SkipPseudoOp=true)
Increment It until it points to a non-debug instruction or to End and return the resulting iterator.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
auto reverse(ContainerTy &&C)
static const MachineInstrBuilder & addRegOffset(const MachineInstrBuilder &MIB, unsigned Reg, bool isKill, int Offset)
addRegOffset - This function is used to add a memory reference of the form [Reg + Offset],...
@ Always
Always set the bit.
@ Never
Never set the bit.
@ DeploymentBased
Determine whether to set the bit statically or dynamically based on the deployment target.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
IterT skipDebugInstructionsBackward(IterT It, IterT Begin, bool SkipPseudoOp=true)
Decrement It until it points to a non-debug instruction or to Begin and return the resulting iterator...
unsigned getUndefRegState(bool B)
unsigned getDefRegState(bool B)
unsigned getKillRegState(bool B)
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
bool isAsynchronousEHPersonality(EHPersonality Pers)
Returns true if this personality function catches asynchronous exceptions.
unsigned encodeSLEB128(int64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a SLEB128 value to an output stream.
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
void computeAndAddLiveIns(LivePhysRegs &LiveRegs, MachineBasicBlock &MBB)
Convenience function combining computeLiveIns() and addLiveIns().
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
void fullyRecomputeLiveIns(ArrayRef< MachineBasicBlock * > MBBs)
Convenience function for recomputing live-in's for a set of MBBs until the computation converges.
Implement std::hash so that hash_code can be used in STL containers.
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.
Pair of physical register and lane mask.
This class contains a discriminated union of information about pointers in memory operands,...
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
enum llvm::TargetFrameLowering::DwarfFrameBase::FrameBaseKind Kind
union llvm::TargetFrameLowering::DwarfFrameBase::@249 Location
SmallVector< WinEHTryBlockMapEntry, 4 > TryBlockMap
SmallVector< WinEHHandlerType, 1 > HandlerArray