39 unsigned StackAlignOverride)
42 STI(STI),
TII(*STI.getInstrInfo()),
TRI(STI.getRegisterInfo()) {
64 (
hasFP(MF) && !
TRI->needsStackRealignment(MF)) ||
87 TRI->needsStackRealignment(MF) ||
100 return X86::SUB64ri32;
103 return X86::SUB32ri8;
111 return X86::ADD64ri8;
112 return X86::ADD64ri32;
115 return X86::ADD32ri8;
121 return isLP64 ? X86::SUB64rr : X86::SUB32rr;
125 return isLP64 ? X86::ADD64rr : X86::ADD32rr;
131 return X86::AND64ri8;
132 return X86::AND64ri32;
135 return X86::AND32ri8;
140 return IsLP64 ? X86::LEA64r : X86::LEA32r;
156 if (MBBI == MBB.
end())
159 switch (MBBI->getOpcode()) {
161 case TargetOpcode::PATCHABLE_RET:
167 case X86::TCRETURNdi:
168 case X86::TCRETURNri:
169 case X86::TCRETURNmi:
170 case X86::TCRETURNdi64:
171 case X86::TCRETURNri64:
172 case X86::TCRETURNmi64:
174 case X86::EH_RETURN64: {
176 for (
unsigned i = 0, e = MBBI->getNumOperands(); i != e; ++i) {
187 for (
auto CS : AvailableRegs)
188 if (!Uses.
count(CS) && CS != X86::RIP && CS != X86::RSP &&
199 unsigned Reg = RegMask.PhysReg;
201 if (Reg == X86::RAX || Reg ==
X86::EAX || Reg == X86::AX ||
202 Reg == X86::AH || Reg ==
X86::AL)
216 bool BreakNext =
false;
220 unsigned Reg = MO.getReg();
221 if (Reg != X86::EFLAGS)
242 if (Succ->isLiveIn(X86::EFLAGS))
253 int64_t NumBytes,
bool InEpilogue)
const {
254 bool isSub = NumBytes < 0;
255 uint64_t
Offset = isSub ? -NumBytes : NumBytes;
259 uint64_t Chunk = (1LL << 31) - 1;
261 if (Offset > Chunk) {
272 unsigned MovRIOpc =
Is64Bit ? X86::MOV64ri : X86::MOV32ri;
273 unsigned AddSubRROpc =
284 }
else if (Offset > 8 * Chunk) {
302 BuildMI(MBB, MBBI, DL,
TII.get(MovRIOpc), Rax)
311 BuildMI(MBB, MBBI, DL,
TII.get(X86::XCHG64rm), Rax).addReg(Rax),
321 uint64_t ThisVal = std::min(Offset, Chunk);
330 ? (
Is64Bit ? X86::PUSH64r : X86::PUSH32r)
331 : (
Is64Bit ? X86::POP64r : X86::POP32r);
340 BuildStackAdjustment(MBB, MBBI, DL, isSub ? -ThisVal : ThisVal, InEpilogue)
350 assert(
Offset != 0 &&
"zero offset stack adjustment requested");
373 "We shouldn't have allowed this insertion point");
397 bool doMergeWithPrevious)
const {
398 if ((doMergeWithPrevious && MBBI == MBB.
begin()) ||
399 (!doMergeWithPrevious && MBBI == MBB.
end()))
416 if (doMergeWithPrevious && PI != MBB.
begin() && PI->isCFIInstruction())
419 unsigned Opc = PI->getOpcode();
422 if ((Opc == X86::ADD64ri32 || Opc == X86::ADD64ri8 ||
423 Opc == X86::ADD32ri || Opc == X86::ADD32ri8) &&
424 PI->getOperand(0).getReg() ==
StackPtr){
426 Offset = PI->getOperand(2).getImm();
427 }
else if ((Opc == X86::LEA32r || Opc == X86::LEA64_32r) &&
428 PI->getOperand(0).getReg() ==
StackPtr &&
429 PI->getOperand(1).getReg() ==
StackPtr &&
430 PI->getOperand(2).getImm() == 1 &&
431 PI->getOperand(3).getReg() == X86::NoRegister &&
432 PI->getOperand(5).getReg() == X86::NoRegister) {
434 Offset = PI->getOperand(4).getImm();
435 }
else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 ||
436 Opc == X86::SUB32ri || Opc == X86::SUB32ri8) &&
437 PI->getOperand(0).getReg() ==
StackPtr) {
439 Offset = -PI->getOperand(2).getImm();
444 if (PI != MBB.
end() && PI->isCFIInstruction()) PI = MBB.
erase(PI);
445 if (!doMergeWithPrevious)
457 BuildMI(MBB, MBBI, DL,
TII.get(TargetOpcode::CFI_INSTRUCTION))
458 .addCFIIndex(CFIIndex);
471 if (CSI.empty())
return;
474 for (std::vector<CalleeSavedInfo>::const_iterator
475 I = CSI.begin(),
E = CSI.end();
I !=
E; ++
I) {
477 unsigned Reg =
I->getReg();
488 const DebugLoc &DL,
bool InProlog)
const {
492 emitStackProbeInlineStub(MF, MBB, MBBI, DL,
true);
494 emitStackProbeInline(MF, MBB, MBBI, DL,
false);
497 emitStackProbeCall(MF, MBB, MBBI, DL, InProlog);
503 const StringRef ChkStkStubSymbol =
"__chkstk_stub";
507 if (
MI.isCall() &&
MI.getOperand(0).isSymbol() &&
508 ChkStkStubSymbol ==
MI.getOperand(0).getSymbolName()) {
514 if (ChkStkStub !=
nullptr) {
516 "Not expecting bundled instructions here");
518 assert(std::prev(MBBI) == ChkStkStub &&
519 "MBBI expected after __chkstk_stub.");
520 DebugLoc DL = PrologMBB.findDebugLoc(MBBI);
521 emitStackProbeInline(MF, PrologMBB, MBBI, DL,
true);
530 bool InProlog)
const {
532 assert(STI.
is64Bit() &&
"different expansion needed for 32 bit");
570 MF.
insert(MBBIter, RoundMBB);
571 MF.
insert(MBBIter, LoopMBB);
572 MF.
insert(MBBIter, ContinueMBB);
580 const int64_t ThreadEnvironmentStackLimit = 0x10;
582 const int64_t PageMask = ~(PageSize - 1);
588 const unsigned SizeReg = InProlog ? (
unsigned)X86::RAX
590 ZeroReg = InProlog ? (
unsigned)X86::RCX
592 CopyReg = InProlog ? (
unsigned)X86::RDX
594 TestReg = InProlog ? (
unsigned)X86::RDX
596 FinalReg = InProlog ? (
unsigned)X86::RDX
598 RoundedReg = InProlog ? (
unsigned)X86::RDX
600 LimitReg = InProlog ? (
unsigned)X86::RCX
602 JoinReg = InProlog ? (
unsigned)X86::RCX
604 ProbeReg = InProlog ? (
unsigned)X86::RCX
608 int64_t RCXShadowSlot = 0;
609 int64_t RDXShadowSlot = 0;
618 const bool HasFP =
hasFP(MF);
623 const bool IsRCXLiveIn = MBB.
isLiveIn(X86::RCX);
624 const bool IsRDXLiveIn = MBB.
isLiveIn(X86::RDX);
625 int64_t InitSlot = 8 + CalleeSaveSize + (HasFP ? 8 : 0);
629 RCXShadowSlot = InitSlot;
631 RDXShadowSlot = InitSlot;
632 if (IsRDXLiveIn && IsRCXLiveIn)
645 BuildMI(&MBB, DL, TII.
get(X86::MOV64rr), SizeReg).addReg(X86::RAX);
650 BuildMI(&MBB, DL, TII.
get(X86::XOR64rr), ZeroReg)
653 BuildMI(&MBB, DL, TII.
get(X86::MOV64rr), CopyReg).addReg(X86::RSP);
654 BuildMI(&MBB, DL, TII.
get(X86::SUB64rr), TestReg)
657 BuildMI(&MBB, DL, TII.
get(X86::CMOVB64rr), FinalReg)
668 BuildMI(&MBB, DL, TII.
get(X86::MOV64rm), LimitReg)
672 .
addImm(ThreadEnvironmentStackLimit)
676 BuildMI(&MBB, DL, TII.
get(X86::JAE_1)).addMBB(ContinueMBB);
680 BuildMI(RoundMBB, DL, TII.
get(X86::AND64ri32), RoundedReg)
683 BuildMI(RoundMBB, DL, TII.
get(X86::JMP_1)).addMBB(LoopMBB);
689 BuildMI(LoopMBB, DL, TII.
get(X86::PHI), JoinReg)
713 BuildMI(LoopMBB, DL, TII.
get(X86::JNE_1)).addMBB(LoopMBB);
721 TII.
get(X86::MOV64rm), X86::RCX),
722 X86::RSP,
false, RCXShadowSlot);
725 TII.
get(X86::MOV64rm), X86::RDX),
726 X86::RSP,
false, RDXShadowSlot);
732 BuildMI(*ContinueMBB, ContinueMBBI, DL, TII.
get(X86::SUB64rr), X86::RSP)
745 for (++BeforeMBBI; BeforeMBBI != MBB.
end(); ++BeforeMBBI) {
755 CMBBI != ContinueMBBI; ++CMBBI) {
765 bool InProlog)
const {
771 "code model and retpoline not yet implemented.");
775 CallOp = IsLargeCodeModel ? X86::CALL64r : X86::CALL64pcrel32;
777 CallOp = X86::CALLpcrel32;
789 BuildMI(MBB, MBBI, DL,
TII.get(X86::MOV64ri), X86::R11)
791 CI =
BuildMI(MBB, MBBI, DL,
TII.get(CallOp)).addReg(X86::R11);
819 for (++ExpansionMBBI; ExpansionMBBI != MBBI; ++ExpansionMBBI)
824 void X86FrameLowering::emitStackProbeInlineStub(
828 assert(InProlog &&
"ChkStkStub called outside prolog!");
830 BuildMI(MBB, MBBI, DL,
TII.get(X86::CALLpcrel32))
831 .addExternalSymbol(
"__chkstk_stub");
837 const uint64_t Win64MaxSEHOffset = 128;
838 uint64_t SEHFrameOffset = std::min(SPAdjust, Win64MaxSEHOffset);
840 return SEHFrameOffset & -16;
847 uint64_t X86FrameLowering::calculateMaxStackAlign(
const MachineFunction &MF)
const {
853 MaxAlign = (StackAlign > MaxAlign) ? StackAlign : MaxAlign;
863 uint64_t MaxAlign)
const {
864 uint64_t Val = -MaxAlign;
963 "MF used frame lowering for wrong subtarget");
969 uint64_t MaxAlign = calculateMaxStackAlign(MF);
975 bool FnHasClrFunclet =
977 bool IsClrFunclet = IsFunclet && FnHasClrFunclet;
978 bool HasFP =
hasFP(MF);
985 bool NeedsWinCFI = NeedsWin64CFI || NeedsWinFPO;
989 const unsigned MachineFramePtr =
993 bool HasWinCFI =
false;
1001 if (TailCallReturnAddrDelta && IsWin64Prologue)
1004 if (TailCallReturnAddrDelta < 0)
1012 unsigned StackProbeSize = 4096;
1034 !
TRI->needsStackRealignment(MF) &&
1044 StackSize =
std::max(MinSize, StackSize > 128 ? StackSize - 128 : 0);
1051 if (TailCallReturnAddrDelta < 0) {
1052 BuildStackAdjustment(MBB, MBBI, DL, TailCallReturnAddrDelta,
1071 uint64_t NumBytes = 0;
1075 unsigned Establisher = X86::NoRegister;
1081 if (IsWin64Prologue && IsFunclet && !IsClrFunclet) {
1096 uint64_t FrameSize = StackSize -
SlotSize;
1099 FrameSize += SlotSize;
1104 if (
TRI->needsStackRealignment(MF) && !IsWin64Prologue)
1105 NumBytes =
alignTo(NumBytes, MaxAlign);
1112 if (NeedsDwarfCFI) {
1120 unsigned DwarfFramePtr =
TRI->getDwarfRegNum(MachineFramePtr,
true);
1122 nullptr, DwarfFramePtr, 2 * stackGrowth));
1127 BuildMI(MBB, MBBI, DL,
TII.get(X86::SEH_PushReg))
1132 if (!IsWin64Prologue && !IsFunclet) {
1140 if (NeedsDwarfCFI) {
1143 unsigned DwarfFramePtr =
TRI->getDwarfRegNum(MachineFramePtr,
true);
1145 nullptr, DwarfFramePtr));
1151 BuildMI(MBB, MBBI, DL,
TII.get(X86::SEH_SetFrame))
1158 assert(!IsFunclet &&
"funclets without FPs not yet implemented");
1165 if (HasFP &&
TRI->needsStackRealignment(MF))
1173 unsigned ParentFrameNumBytes = NumBytes;
1175 NumBytes = getWinEHFuncletFrameSize(MF);
1178 bool PushedRegs =
false;
1179 int StackOffset = 2 * stackGrowth;
1181 while (MBBI != MBB.
end() &&
1183 (MBBI->getOpcode() == X86::PUSH32r ||
1184 MBBI->getOpcode() == X86::PUSH64r)) {
1186 unsigned Reg = MBBI->getOperand(0).getReg();
1189 if (!HasFP && NeedsDwarfCFI) {
1195 StackOffset += stackGrowth;
1200 BuildMI(MBB, MBBI, DL,
TII.get(X86::SEH_PushReg))
1209 if (!IsWin64Prologue && !IsFunclet &&
TRI->needsStackRealignment(MF)) {
1210 assert(HasFP &&
"There should be a frame pointer if stack is realigned.");
1211 BuildStackAlignAND(MBB, MBBI, DL,
StackPtr, MaxAlign);
1215 BuildMI(MBB, MBBI, DL,
TII.get(X86::SEH_StackAlign))
1236 uint64_t AlignedNumBytes = NumBytes;
1237 if (IsWin64Prologue && !IsFunclet &&
TRI->needsStackRealignment(MF))
1238 AlignedNumBytes =
alignTo(AlignedNumBytes, MaxAlign);
1239 if (AlignedNumBytes >= StackProbeSize && UseStackProbe) {
1241 "The Red Zone is not accounted for in stack probes");
1249 BuildMI(MBB, MBBI, DL,
TII.get(X86::PUSH64r))
1254 BuildMI(MBB, MBBI, DL,
TII.get(X86::PUSH32r))
1263 int Alloc = isEAXAlive ? NumBytes - 8 : NumBytes;
1269 BuildMI(MBB, MBBI, DL,
TII.get(X86::MOV64ri32), X86::RAX)
1273 BuildMI(MBB, MBBI, DL,
TII.get(X86::MOV64ri), X86::RAX)
1281 .addImm(isEAXAlive ? NumBytes - 4 : NumBytes)
1300 }
else if (NumBytes) {
1301 emitSPUpdate(MBB, MBBI, DL, -(int64_t)NumBytes,
false);
1304 if (NeedsWinCFI && NumBytes) {
1306 BuildMI(MBB, MBBI, DL,
TII.get(X86::SEH_StackAlloc))
1311 int SEHFrameOffset = 0;
1312 unsigned SPOrEstablisher;
1319 unsigned PSPSlotOffset = getPSPSlotOffsetFromSP(MF);
1323 Establisher,
false, PSPSlotOffset)
1330 false, PSPSlotOffset)
1337 SPOrEstablisher = Establisher;
1342 if (IsWin64Prologue && HasFP) {
1349 SPOrEstablisher,
false, SEHFrameOffset);
1351 BuildMI(MBB, MBBI, DL,
TII.get(X86::MOV64rr), FramePtr)
1352 .addReg(SPOrEstablisher);
1355 if (NeedsWinCFI && !IsFunclet) {
1356 assert(!NeedsWinFPO &&
"this setframe incompatible with FPO data");
1358 BuildMI(MBB, MBBI, DL,
TII.get(X86::SEH_SetFrame))
1389 if (X86::FR64RegClass.
contains(Reg)) {
1390 unsigned IgnoredFrameReg;
1392 Offset += SEHFrameOffset;
1395 assert(!NeedsWinFPO &&
"SEH_SaveXMM incompatible with FPO data");
1396 BuildMI(MBB, MBBI, DL,
TII.get(X86::SEH_SaveXMM))
1405 if (NeedsWinCFI && HasWinCFI)
1406 BuildMI(MBB, MBBI, DL,
TII.get(X86::SEH_EndPrologue))
1409 if (FnHasClrFunclet && !IsFunclet) {
1413 unsigned PSPSlotOffset = getPSPSlotOffsetFromSP(MF);
1427 if (IsWin64Prologue &&
TRI->needsStackRealignment(MF)) {
1428 assert(HasFP &&
"There should be a frame pointer if stack is realigned.");
1429 BuildStackAlignAND(MBB, MBBI, DL, SPOrEstablisher, MaxAlign);
1443 BuildMI(MBB, MBBI, DL,
TII.get(Opc), BasePtr)
1444 .addReg(SPOrEstablisher)
1452 .addReg(SPOrEstablisher)
1465 assert(UsedReg == BasePtr);
1472 if (((!HasFP && NumBytes) || PushedRegs) && NeedsDwarfCFI) {
1474 if (!HasFP && NumBytes) {
1478 nullptr, -StackSize + stackGrowth));
1537 X86FrameLowering::getPSPSlotOffsetFromSP(
const MachineFunction &MF)
const {
1543 return static_cast<unsigned>(
Offset);
1547 X86FrameLowering::getWinEHFuncletFrameSize(
const MachineFunction &MF)
const {
1559 UsedSize = getPSPSlotOffsetFromSP(MF) +
SlotSize;
1570 return FrameSizeMinusRBP - CSSize;
1574 return Opc == X86::TCRETURNri || Opc == X86::TCRETURNdi ||
1575 Opc == X86::TCRETURNmi ||
1576 Opc == X86::TCRETURNri64 || Opc == X86::TCRETURNdi64 ||
1577 Opc == X86::TCRETURNmi64;
1587 if (MBBI != MBB.
end())
1588 DL = MBBI->getDebugLoc();
1592 unsigned MachineFramePtr =
1596 bool NeedsWin64CFI =
1602 uint64_t MaxAlign = calculateMaxStackAlign(MF);
1604 bool HasFP =
hasFP(MF);
1605 uint64_t NumBytes = 0;
1607 bool NeedsDwarfCFI =
1613 assert(HasFP &&
"EH funclets without FP not yet implemented");
1614 NumBytes = getWinEHFuncletFrameSize(MF);
1617 uint64_t FrameSize = StackSize -
SlotSize;
1618 NumBytes = FrameSize - CSSize;
1622 if (
TRI->needsStackRealignment(MF) && !IsWin64Prologue)
1623 NumBytes =
alignTo(FrameSize, MaxAlign);
1625 NumBytes = StackSize - CSSize;
1627 uint64_t SEHStackAllocAmt = NumBytes;
1634 if (NeedsDwarfCFI) {
1635 unsigned DwarfStackPtr =
1638 nullptr, DwarfStackPtr, -
SlotSize));
1645 while (MBBI != MBB.
begin()) {
1647 unsigned Opc = PI->getOpcode();
1649 if (Opc != X86::DBG_VALUE && !PI->isTerminator()) {
1661 emitCatchRetReturnValue(MBB, FirstCSPop, &*Terminator);
1663 if (MBBI != MBB.
end())
1664 DL = MBBI->getDebugLoc();
1677 if (
TRI->needsStackRealignment(MF))
1680 uint64_t LEAAmount =
1681 IsWin64Prologue ? SEHStackAllocAmt - SEHFrameOffset : -CSSize;
1690 if (LEAAmount != 0) {
1693 FramePtr,
false, LEAAmount);
1701 }
else if (NumBytes) {
1704 if (!
hasFP(MF) && NeedsDwarfCFI) {
1719 BuildMI(MBB, MBBI, DL,
TII.get(X86::SEH_Epilogue));
1721 if (!
hasFP(MF) && NeedsDwarfCFI) {
1726 while (MBBI != MBB.
end()) {
1728 unsigned Opc = PI->getOpcode();
1730 if (Opc == X86::POP32r || Opc == X86::POP64r) {
1741 assert(Offset >= 0 &&
"TCDelta should never be positive");
1751 unsigned &FrameReg)
const {
1760 else if (
TRI->needsStackRealignment(MF))
1773 bool HasFP =
hasFP(MF);
1775 int64_t FPDelta = 0;
1777 if (IsWin64Prologue) {
1781 uint64_t FrameSize = StackSize -
SlotSize;
1784 FrameSize += SlotSize;
1785 uint64_t NumBytes = FrameSize - CSSize;
1789 return -SEHFrameOffset;
1795 FPDelta = FrameSize - SEHFrameOffset;
1797 "FPDelta isn't aligned per the Win64 ABI!");
1802 assert(HasFP &&
"VLAs and dynamic stack realign, but no FP?!");
1805 return Offset +
SlotSize + FPDelta;
1808 return Offset + StackSize;
1810 }
else if (
TRI->needsStackRealignment(MF)) {
1813 return Offset +
SlotSize + FPDelta;
1816 return Offset + StackSize;
1821 return Offset + StackSize;
1828 if (TailCallReturnAddrDelta < 0)
1829 Offset -= TailCallReturnAddrDelta;
1832 return Offset + FPDelta;
1836 int FI,
unsigned &FrameReg,
1837 int Adjustment)
const {
1845 int FI,
unsigned &FrameReg,
1846 bool IgnoreSPUpdates)
const {
1897 "we don't handle this case!");
1929 std::vector<CalleeSavedInfo> &CSI)
const {
1933 unsigned CalleeSavedFrameSize = 0;
1938 if (TailCallReturnAddrDelta < 0) {
1949 TailCallReturnAddrDelta -
SlotSize,
true);
1953 if (this->TRI->hasBasePointer(MF)) {
1971 for (
unsigned i = 0; i < CSI.size(); ++i) {
1973 CSI.erase(CSI.begin() + i);
1980 for (
unsigned i = CSI.size(); i != 0; --i) {
1981 unsigned Reg = CSI[i - 1].getReg();
1990 CSI[i - 1].setFrameIdx(SlotIndex);
1997 for (
unsigned i = CSI.size(); i != 0; --i) {
1998 unsigned Reg = CSI[i - 1].getReg();
2004 if (X86::VK16RegClass.
contains(Reg))
2013 SpillSlotOffset -=
Size;
2015 CSI[i - 1].setFrameIdx(SlotIndex);
2024 const std::vector<CalleeSavedInfo> &CSI,
2035 unsigned Opc =
STI.
is64Bit() ? X86::PUSH64r : X86::PUSH32r;
2036 for (
unsigned i = CSI.size(); i != 0; --i) {
2037 unsigned Reg = CSI[i - 1].getReg();
2048 bool CanKill = !isLiveIn;
2070 for (
unsigned i = CSI.size(); i != 0; --i) {
2071 unsigned Reg = CSI[i-1].getReg();
2077 if (X86::VK16RegClass.
contains(Reg))
2100 "SEH should not use CATCHRET");
2107 BuildMI(MBB, MBBI, DL,
TII.get(X86::LEA64r), X86::RAX)
2116 .addMBB(CatchRetTarget);
2126 std::vector<CalleeSavedInfo> &CSI,
2150 for (
unsigned i = 0, e = CSI.size(); i != e; ++i) {
2151 unsigned Reg = CSI[i].getReg();
2152 if (X86::GR64RegClass.
contains(Reg) ||
2158 if (X86::VK16RegClass.
contains(Reg))
2166 unsigned Opc =
STI.
is64Bit() ? X86::POP64r : X86::POP32r;
2167 for (
unsigned i = 0, e = CSI.size(); i != e; ++i) {
2168 unsigned Reg = CSI[i].getReg();
2169 if (!X86::GR64RegClass.
contains(Reg) &&
2189 SavedRegs.
set(BasePtr);
2198 if (
I->hasNestAttr())
2215 return Primary ? X86::R14 : X86::R13;
2222 return Primary ? X86::R11 : X86::R12;
2224 return Primary ? X86::R11D : X86::R12D;
2233 "nested function.");
2249 unsigned TlsReg, TlsOffset;
2254 assert(&(*MF.
begin()) == &PrologueMBB &&
"Shrink-wrapping not supported yet");
2258 "Scratch register is live-in");
2287 bool IsNested =
false;
2296 for (
const auto &LI : PrologueMBB.
liveins()) {
2315 TlsOffset =
IsLP64 ? 0x70 : 0x40;
2318 TlsOffset = 0x60 + 90*8;
2332 if (CompareStackPointer)
2335 BuildMI(checkMBB, DL,
TII.get(
IsLP64 ? X86::LEA64r : X86::LEA64_32r), ScratchReg).addReg(X86::RSP)
2338 BuildMI(checkMBB, DL,
TII.get(
IsLP64 ? X86::CMP64rm : X86::CMP32rm)).addReg(ScratchReg)
2346 TlsOffset = 0x48 + 90*4;
2359 if (CompareStackPointer)
2367 BuildMI(checkMBB, DL,
TII.get(X86::CMP32rm)).addReg(ScratchReg)
2372 unsigned ScratchReg2;
2374 if (CompareStackPointer) {
2377 SaveScratch2 =
false;
2389 "Scratch register is live-in and not saved");
2395 BuildMI(checkMBB, DL,
TII.get(X86::MOV32ri), ScratchReg2)
2404 BuildMI(checkMBB, DL,
TII.get(X86::POP32r), ScratchReg2);
2410 BuildMI(checkMBB, DL,
TII.get(X86::JA_1)).addMBB(&PrologueMBB);
2419 const unsigned Reg10 =
IsLP64 ? X86::R10 : X86::R10D;
2420 const unsigned Reg11 =
IsLP64 ? X86::R11 : X86::R11D;
2421 const unsigned MOVrr =
IsLP64 ? X86::MOV64rr : X86::MOV32rr;
2422 const unsigned MOVri =
IsLP64 ? X86::MOV64ri : X86::MOV32ri;
2425 BuildMI(allocMBB, DL,
TII.get(MOVrr), RegAX).addReg(Reg10);
2457 "code model and retpoline not yet implemented.");
2467 BuildMI(allocMBB, DL,
TII.get(X86::CALL64pcrel32))
2468 .addExternalSymbol(
"__morestack");
2470 BuildMI(allocMBB, DL,
TII.get(X86::CALLpcrel32))
2471 .addExternalSymbol(
"__morestack");
2475 BuildMI(allocMBB, DL,
TII.get(X86::MORESTACK_RET_RESTORE_R10));
2477 BuildMI(allocMBB, DL,
TII.get(X86::MORESTACK_RET));
2484 #ifdef EXPENSIVE_CHECKS 2495 for (
int i = 0, e = HiPELiteralsMD->
getNumOperands(); i != e; ++i) {
2500 if (!NodeName || !NodeVal)
continue;
2501 ConstantInt *ValConst = dyn_cast_or_null<ConstantInt>(NodeVal->getValue());
2502 if (ValConst && NodeName->
getString() == LiteralName) {
2508 +
" required but not provided");
2533 assert(&(*MF.
begin()) == &PrologueMBB &&
"Shrink-wrapping not supported yet");
2538 if (!HiPELiteralsMD)
2540 "Can't generate HiPE prologue without runtime parameters");
2541 const unsigned HipeLeafWords
2543 Is64Bit ?
"AMD64_LEAF_WORDS" :
"X86_LEAF_WORDS");
2544 const unsigned CCRegisteredArgs =
Is64Bit ? 6 : 5;
2545 const unsigned Guaranteed = HipeLeafWords *
SlotSize;
2551 "HiPE prologue is only supported on Linux operating systems.");
2561 unsigned MoreStackForCalls = 0;
2563 for (
auto &MBB : MF) {
2564 for (
auto &
MI : MBB) {
2589 unsigned CalleeStkArity =
2591 if (HipeLeafWords - 1 > CalleeStkArity)
2592 MoreStackForCalls =
std::max(MoreStackForCalls,
2593 (HipeLeafWords - 1 - CalleeStkArity) * SlotSize);
2596 MaxStack += MoreStackForCalls;
2601 if (MaxStack > Guaranteed) {
2605 for (
const auto &LI : PrologueMBB.
liveins()) {
2613 unsigned ScratchReg, SPReg, PReg, SPLimitOffset;
2614 unsigned LEAop, CMPop, CALLop;
2619 LEAop = X86::LEA64r;
2620 CMPop = X86::CMP64rm;
2621 CALLop = X86::CALL64pcrel32;
2625 LEAop = X86::LEA32r;
2626 CMPop = X86::CMP32rm;
2627 CALLop = X86::CALLpcrel32;
2632 "HiPE prologue scratch register is live-in");
2636 SPReg,
false, -MaxStack);
2639 .addReg(ScratchReg), PReg,
false, SPLimitOffset);
2640 BuildMI(stackCheckMBB, DL,
TII.get(X86::JAE_1)).addMBB(&PrologueMBB);
2644 addExternalSymbol(
"inc_stack_0");
2646 SPReg,
false, -MaxStack);
2648 .addReg(ScratchReg), PReg,
false, SPLimitOffset);
2649 BuildMI(incStackMBB, DL,
TII.get(X86::JLE_1)).addMBB(incStackMBB);
2656 #ifdef EXPENSIVE_CHECKS 2674 if (NumPops != 1 && NumPops != 2)
2679 if (MBBI == MBB.
begin())
2682 if (!Prev->isCall() || !Prev->getOperand(1).isRegMask())
2686 unsigned FoundRegs = 0;
2689 auto RegMask = Prev->getOperand(1);
2692 Is64Bit ? X86::GR64_NOREX_NOSPRegClass : X86::GR32_NOREX_NOSPRegClass;
2694 for (
auto Candidate : RegClass) {
2699 if (!RegMask.clobbersPhysReg(Candidate))
2703 if (
MRI.isReserved(Candidate))
2708 if (MO.isReg() && MO.isDef() &&
2709 TRI->isSuperOrSubRegisterEq(MO.getReg(), Candidate)) {
2718 Regs[FoundRegs++] = Candidate;
2719 if (FoundRegs == (
unsigned)NumPops)
2727 while (FoundRegs < (
unsigned)NumPops)
2728 Regs[FoundRegs++] = Regs[0];
2730 for (
int i = 0; i < NumPops; ++i)
2732 TII.get(
STI.
is64Bit() ? X86::POP64r : X86::POP32r), Regs[i]);
2741 unsigned Opcode = I->getOpcode();
2742 bool isDestroy = Opcode ==
TII.getCallFrameDestroyOpcode();
2744 uint64_t Amount = !reserveCallFrame ?
TII.getFrameSize(*I) : 0;
2749 if (!reserveCallFrame) {
2758 Amount =
alignTo(Amount, StackAlign);
2773 bool HasDwarfEHHandlers = !WindowsCFI && !MF.
getLandingPads().empty();
2775 if (HasDwarfEHHandlers && !isDestroy &&
2785 Amount -= InternalAmt;
2790 if (isDestroy && InternalAmt && DwarfCFI && !
hasFP(MF))
2797 if (StackAdjustment) {
2804 if (StackAdjustment) {
2806 adjustStackWithPops(MBB, InsertPos, DL, StackAdjustment)))
2807 BuildStackAdjustment(MBB, InsertPos, DL, StackAdjustment,
2812 if (DwarfCFI && !
hasFP(MF)) {
2823 if (CfaAdjustment) {
2833 if (isDestroy && InternalAmt) {
2842 while (CI != B && !std::prev(CI)->isCall())
2844 BuildStackAdjustment(MBB, CI, DL, -InternalAmt,
false);
2853 return !
TRI->needsStackRealignment(MF) || !MBB.
isLiveIn(X86::EFLAGS);
2891 const DebugLoc &DL,
bool RestoreSP)
const {
2895 "restoring EBP/ESI on non-32-bit target");
2907 int EHRegSize = MFI.getObjectSize(FI);
2912 X86::EBP,
true, -EHRegSize)
2918 int EndOffset = -EHRegOffset - EHRegSize;
2921 if (UsedReg == FramePtr) {
2924 BuildMI(MBB, MBBI, DL,
TII.get(ADDri), FramePtr)
2931 "end of registration object above normal EBP position!");
2932 }
else if (UsedReg == BasePtr) {
2935 FramePtr,
false, EndOffset)
2941 assert(UsedReg == BasePtr);
2943 UsedReg,
true, Offset)
2962 struct X86FrameSortingObject {
2963 bool IsValid =
false;
2964 unsigned ObjectIndex = 0;
2965 unsigned ObjectSize = 0;
2966 unsigned ObjectAlignment = 1;
2967 unsigned ObjectNumUses = 0;
2983 struct X86FrameSortingComparator {
2984 inline bool operator()(
const X86FrameSortingObject &A,
2985 const X86FrameSortingObject &
B) {
2986 uint64_t DensityAScaled, DensityBScaled;
3006 DensityAScaled =
static_cast<uint64_t
>(A.ObjectNumUses) *
3007 static_cast<uint64_t>(B.ObjectSize);
3008 DensityBScaled =
static_cast<uint64_t
>(B.ObjectNumUses) *
3009 static_cast<uint64_t>(A.ObjectSize);
3019 if (DensityAScaled == DensityBScaled)
3020 return A.ObjectAlignment < B.ObjectAlignment;
3022 return DensityAScaled < DensityBScaled;
3036 if (ObjectsToAllocate.
empty())
3048 for (
auto &Obj : ObjectsToAllocate) {
3049 SortingObjects[Obj].IsValid =
true;
3050 SortingObjects[Obj].ObjectIndex = Obj;
3054 if (ObjectSize == 0)
3056 SortingObjects[Obj].ObjectSize = 4;
3058 SortingObjects[Obj].ObjectSize = ObjectSize;
3062 for (
auto &MBB : MF) {
3063 for (
auto &
MI : MBB) {
3064 if (
MI.isDebugInstr())
3070 int Index = MO.getIndex();
3074 SortingObjects[
Index].IsValid)
3075 SortingObjects[Index].ObjectNumUses++;
3082 std::stable_sort(SortingObjects.begin(), SortingObjects.end(),
3083 X86FrameSortingComparator());
3091 for (
auto &Obj : SortingObjects) {
3095 ObjectsToAllocate[i++] = Obj.ObjectIndex;
3099 if (!
TRI->needsStackRealignment(MF) &&
hasFP(MF))
3100 std::reverse(ObjectsToAllocate.begin(), ObjectsToAllocate.end());
3112 Offset += getWinEHFuncletFrameSize(MF);
3136 int64_t MinFixedObjOffset = -
SlotSize;
3143 if (FrameIndex != INT_MAX) {
3154 MinFixedObjOffset -=
std::abs(MinFixedObjOffset) % 8;
3155 int64_t UnwindHelpOffset = MinFixedObjOffset -
SlotSize;
3163 auto MBBI = MBB.
begin();
void push_front(MachineBasicBlock *MBB)
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
constexpr bool isUInt< 32 >(uint64_t x)
bool isOSDarwin() const
isOSDarwin - Is this a "Darwin" OS (OS X, iOS, or watchOS).
bool is64Bit() const
Is this x86_64? (disregarding specific ABI / programming model)
static bool flagsNeedToBePreservedBeforeTheTerminators(const MachineBasicBlock &MBB)
Check if the flags need to be preserved before the terminators.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
bool usesWindowsCFI() const
bool hasBasePointer(const MachineFunction &MF) const
bool getRestoreBasePointer() const
bool hasStackMap() const
This method may be called any time after instruction selection is complete to determine if there is a...
SmallVector< WinEHHandlerType, 1 > HandlerArray
DILocation * get() const
Get the underlying DILocation.
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
This class represents an incoming formal argument to a Function.
MachineBasicBlock * getMBB() const
bool hasDebugInfo() const
Returns true if valid debug info is present.
MDNode * getOperand(unsigned i) const
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)
const X86InstrInfo * getInstrInfo() const override
bool hasStackObjects() const
Return true if there are any stack objects in this function.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
bool hasOpaqueSPAdjustment() const
Returns true if the function contains opaque dynamic stack adjustments.
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
bool isCleanupFuncletEntry() const
Returns true if this is the entry block of a cleanup funclet.
unsigned getReg() const
getReg - Returns the register number.
const TargetRegisterClass * getGPRsForTailCall(const MachineFunction &MF) const
getGPRsForTailCall - Returns a register class with registers that can be used in forming tail calls...
int getRestoreBasePointerOffset() const
static unsigned getLEArOpcode(unsigned IsLP64)
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int Offset)
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
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.
unsigned getCalleeSavedFrameSize() const
constexpr bool isInt< 8 >(int64_t x)
void setCalleeSavedFrameSize(unsigned bytes)
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
unsigned const TargetRegisterInfo * TRI
void setIsDead(bool Val=true)
bool adjustsStack() const
Return true if this function adjusts the stack – e.g., when calling another function.
MachineModuleInfo & getMMI() const
const MDOperand & getOperand(unsigned I) 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...
void setSEHFramePtrSaveIndex(int Index)
int getOffsetOfLocalArea() const
getOffsetOfLocalArea - This method returns the offset of the local area from the stack pointer on ent...
static BranchProbability getOne()
bool isTargetNaCl64() const
static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset)
.cfi_def_cfa_offset modifies a rule for computing CFA.
unsigned getSlotSize() const
static MCCFIInstruction createAdjustCfaOffset(MCSymbol *L, int Adjustment)
.cfi_adjust_cfa_offset Same as .cfi_def_cfa_offset, but Offset is a relative value that is added/subt...
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 ...
bool isTargetWindowsMSVC() const
X86FrameLowering(const X86Subtarget &STI, unsigned StackAlignOverride)
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
return AArch64::GPR64RegClass contains(Reg)
iterator_range< succ_iterator > successors()
union llvm::WinEHHandlerType::@189 CatchObj
The CatchObj starts out life as an LLVM alloca and is eventually turned frame index.
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
X86MachineFunctionInfo - This class is derived from MachineFunction and contains private X86 target-s...
bool Uses64BitFramePtr
True if the 64-bit frame or stack pointer should be used.
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...
bool isReturnBlock() const
Convenience function that returns true if the block ends in a return instruction. ...
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
const HexagonInstrInfo * TII
bool getHasSEHFramePtrSave() const
bool isTarget64BitLP64() const
Is this x86_64 with the LP64 programming model (standard AMD64, no x32)?
MachineBasicBlock iterator that automatically skips over MIs that are inside bundles (i...
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
iterator_range< iterator > terminators()
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
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...
unsigned getNumOperands() const
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.
static const uint64_t kSplitStackAvailable
virtual unsigned getFrameRegister(const MachineFunction &MF) const =0
Debug information queries.
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.
unsigned getBaseRegister() const
void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS) const override
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
unsigned getWinEHParentFrameOffset(const MachineFunction &MF) const override
int getTCReturnAddrDelta() const
uint16_t StackAdjustment(const RuntimeFunction &RF)
StackAdjustment - calculated stack adjustment in words.
bool canUseLEAForSPInEpilogue(const MachineFunction &MF) const
Check that LEA can be used on SP in an epilogue sequence for MF.
Fast - This calling convention attempts to make calls as fast as possible (e.g.
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register...
bool needsFrameIndexResolution(const MachineFunction &MF) const override
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 inlineStackProbe(MachineFunction &MF, MachineBasicBlock &PrologMBB) const override
Replace a StackProbe inline-stub with the actual probe code inline.
bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
static unsigned getANDriOpcode(bool IsLP64, int64_t Imm)
const MCContext & getContext() const
void setHasSEHFramePtrSave(bool V)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
int getObjectIndexBegin() const
Return the minimum frame object index.
NamedMDNode * getNamedMetadata(const Twine &Name) const
Return the first NamedMDNode in the module with the specified name.
static unsigned getHiPELiteral(NamedMDNode *HiPELiteralsMD, const StringRef LiteralName)
Lookup an ERTS parameter in the !hipe.literals named metadata node.
int getObjectIndexEnd() const
Return one past the maximum frame object index.
bool hasPersonalityFn() const
Check whether this function has a personality function.
bool hasCopyImplyingStackAdjustment() const
Returns true if the function contains operations which will lower down to instructions which manipula...
StringRef getStackProbeSymbolName(MachineFunction &MF) const override
Returns the name of the symbol used to emit stack probes or the empty string if not applicable...
static unsigned calculateSetFPREG(uint64_t SPAdjust)
void setHasNosplitStack(bool b)
bool Is64Bit
Is64Bit implies that x86_64 instructions are available.
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
unsigned getUndefRegState(bool B)
void BuildCFI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, const MCCFIInstruction &CFIInst) const
Wraps up getting a CFI index and building a MachineInstr for it.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
Analysis containing CSE Info
unsigned getKillRegState(bool B)
unsigned getCodeViewFlag() const
Returns the CodeView Version by checking module flags.
unsigned getStackRegister() const
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.
unsigned getInitialCFARegister(const MachineFunction &MF) const override
Return initial CFA register value i.e.
StringRef getString() const
bool isOSWindows() const
Tests whether the OS is Windows.
unsigned getDefRegState(bool B)
The memory access is volatile.
const X86TargetLowering * getTargetLowering() const override
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned getArgumentStackSize() const
unsigned getObjectAlignment(int ObjectIdx) const
Return the alignment of the specified stack object.
void addLiveIn(MCPhysReg PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
bool canUseAsPrologue(const MachineBasicBlock &MBB) const override
Check whether or not the given MBB can be used as a prologue for the target.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
unsigned const MachineRegisterInfo * MRI
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...
LLVM Basic Block Representation.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register)
.cfi_def_cfa_register modifies a rule for computing CFA.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
bool isBundled() const
Return true if this instruction part of a bundle.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
bool hasEHFunclets() const
void setStackSize(uint64_t Size)
Set the size of the stack.
static bool is64Bit(const char *name)
DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any DBG_VALUE and DBG_LABEL instructions...
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
const GlobalValue * getGlobal() const
static MCCFIInstruction createGnuArgsSize(MCSymbol *L, int Size)
A special wrapper for .cfi_escape that indicates GNU_ARGS_SIZE.
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
bool canUseAsEpilogue(const MachineBasicBlock &MBB) const override
Check whether or not the given MBB can be used as a epilogue for the target.
EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
void setFlag(MIFlag Flag)
Set a MI flag.
MCRegAliasIterator enumerates all registers aliasing Reg.
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]...
unsigned getMaxAlignment() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
unsigned getFramePtr() const
Returns physical register used as frame pointer.
bool isTargetFreeBSD() const
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const Triple & getTargetTriple() const
self_iterator getIterator()
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
bool isTargetDarwin() const
int CreateSpillStackObject(uint64_t Size, unsigned Alignment)
Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...
bool enableShrinkWrapping(const MachineFunction &MF) const override
Returns true if the target will correctly handle shrink wrapping.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
const MachineBasicBlock & front() const
bool useRetpolineIndirectCalls() const
bool isTargetWin64() const
This class contains a discriminated union of information about pointers in memory operands...
const char * createExternalSymbolName(StringRef Name)
Allocate a string and populate it with the given external symbol name.
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.
static unsigned getSUBriOpcode(unsigned IsLP64, int64_t Imm)
static bool isFuncletReturnInstr(MachineInstr &MI)
static unsigned getADDriOpcode(unsigned IsLP64, int64_t Imm)
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...
void emitStackProbe(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, bool InProlog) const
Emit target stack probe code.
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.
const std::vector< LandingPadInfo > & getLandingPads() const
Return a reference to the landing pad info for the current function.
Iterator for intrusive lists based on ilist_node.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
This is the shared class of boolean and integer constants.
constexpr bool isInt< 32 >(int64_t x)
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.
unsigned getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call...
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
bool regsOverlap(unsigned regA, unsigned regB) const
Returns true if the two registers are equal or alias each other.
bool shouldSplitStack() const
Should we be emitting segmented stack stuff for the function.
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
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...
MachineOperand class - Representation of each machine instruction operand.
Information about stack frame layout on the target.
void setUsesMorestackAddr(bool b)
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
int CreateFixedSpillStackObject(uint64_t Size, int64_t SPOffset, bool IsImmutable=false)
Create a spill slot at a fixed location on the stack.
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 isTargetWin32() const
int getFrameIndexReferencePreferSP(const MachineFunction &MF, int FI, unsigned &FrameReg, bool IgnoreSPUpdates) const override
Same as getFrameIndexReference, except that the stack pointer (as opposed to the frame pointer) will ...
const WinEHFuncInfo * getWinEHFuncInfo() const
getWinEHFuncInfo - Return information about how the current function uses Windows exception handling...
int64_t getFrameAdjustment(const MachineInstr &I) const
Returns the stack pointer adjustment that happens inside the frame setup..destroy sequence (e...
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...
void setOffsetAdjustment(int Adj)
Set the correction for frame offsets.
bool callsUnwindInit() const
bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override
canSimplifyCallFramePseudos - If there is a reserved call frame, the call frame pseudos can be simpli...
IterT skipDebugInstructionsBackward(IterT It, IterT Begin)
Decrement It until it points to a non-debug instruction or to Begin and return the resulting iterator...
const Function & getFunction() const
Return the LLVM function that this machine code represents.
bool isTarget64BitILP32() const
Is this x86_64 with the ILP32 programming model (x32 ABI)?
bool needsUnwindTableEntry() const
True if this function needs an unwind table.
bool callsEHReturn() const
unsigned getX86SubSuperRegister(unsigned, unsigned, bool High=false)
Returns the sub or super register of a specific X86 register.
static bool isTailCallOpcode(unsigned Opc)
bool isLiveIn(MCPhysReg Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
SmallVector< WinEHTryBlockMapEntry, 4 > TryBlockMap
bool getUsesRedZone() const
CodeModel::Model getCodeModel() const
Returns the code model.
X86_FastCall - 'fast' analog of X86_StdCall.
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
void setHasAddressTaken()
Set this block to reflect that it potentially is the target of an indirect branch.
IterT skipDebugInstructionsForward(IterT It, IterT End)
Increment It until it points to a non-debug instruction or to End and return the resulting iterator...
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
CATCHRET - Represents a return from a catch block funclet.
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.
int getFrameIndexReferenceSP(const MachineFunction &MF, int FI, unsigned &SPReg, int Adjustment) const
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
bool isLiveIn(unsigned Reg) const
Representation of each machine instruction.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
bool assignCalleeSavedSpillSlots(MachineFunction &MF, const TargetRegisterInfo *TRI, std::vector< CalleeSavedInfo > &CSI) const override
assignCalleeSavedSpillSlots - Allows target to override spill slot assignment logic.
void adjustForSegmentedStacks(MachineFunction &MF, MachineBasicBlock &PrologueMBB) const override
Adjust the prologue to have the function use segmented stacks.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
void ensureMaxAlignment(unsigned Align)
Make sure the function is at least Align bytes aligned.
int getSEHFramePtrSaveIndex() const
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.
bool isTargetDragonFly() const
LLVM_NODISCARD bool empty() const
bool verify(Pass *p=nullptr, const char *Banner=nullptr, bool AbortOnError=true) const
Run the current MachineFunction through the machine code verifier, useful for debugger use...
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.
StringRef getName() const
Return a constant reference to the value's name.
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned char TargetFlags=0) const
LLVM_NODISCARD size_t find_first_of(char C, size_t From=0) const
Find the first character in the string that is C, or npos if not found.
APFloat abs(APFloat X)
Returns the absolute value of the argument.
bool optForMinSize() const
Optimize this function for minimum size (-Oz).
Pair of physical register and lane mask.
virtual const TargetFrameLowering * getFrameLowering() const
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
void setCVBytesOfCalleeSavedRegisters(unsigned S)
static unsigned getSUBrrOpcode(unsigned isLP64)
iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
X86_INTR - x86 hardware interrupt context.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const X86RegisterInfo * TRI
const Module * getModule() const
const TargetRegisterClass * getMinimalPhysRegClass(unsigned Reg, MVT VT=MVT::Other) const
Returns the Register Class of a physical register of the given type, picking the most sub register cl...
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)
iterator_range< livein_iterator > liveins() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) - This node represents 'eh_return' gcc dwarf builtin...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isEAXLiveIn(MachineBasicBlock &MBB)
static unsigned getADDrrOpcode(unsigned isLP64)
void insert(iterator MBBI, MachineBasicBlock *MBB)
bool isAsynchronousEHPersonality(EHPersonality Pers)
Returns true if this personality function catches asynchronous exceptions.
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...
const MCRegisterInfo * getRegisterInfo() const
Constant * getPersonalityFn() const
Get the personality function associated with this function.
bool isTargetLinux() const
static unsigned findDeadCallerSavedReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const X86RegisterInfo *TRI, bool Is64Bit)
findDeadCallerSavedReg - Return a caller-saved register that isn't live when it reaches the "return" ...
bool isCallingConvWin64(CallingConv::ID CC) const
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
int getInitialCFAOffset(const MachineFunction &MF) const override
Return initial CFA offset value i.e.
int getFrameIndexReference(const MachineFunction &MF, int FI, unsigned &FrameReg) const override
getFrameIndexReference - This method should return the base register and offset used to reference a f...
void setUsesRedZone(bool V)
void setObjectOffset(int ObjectIdx, int64_t SPOffset)
Set the stack frame offset of the specified object.
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.
void emitCalleeSavedFrameMoves(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL) const
unsigned getFrameRegister(const MachineFunction &MF) const override
static BranchProbability getZero()
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...
void orderFrameObjects(const MachineFunction &MF, SmallVectorImpl< int > &ObjectsToAllocate) const override
Order the symbols in the local stack.
int mergeSPUpdates(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, bool doMergeWithPrevious) const
Check the instruction before/after the passed instruction.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
unsigned getNumOperands() const
Return number of MDNode operands.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t find(char C, size_t From=0) const
Search for the first character C in the string.
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
const MachineOperand & getOperand(unsigned i) const
static bool HasNestArgument(const MachineFunction *MF)
SlotIndex - An opaque wrapper around machine indexes.
bool hasTailCall() const
Returns true if the function contains a tail call.
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...
Function Alias Analysis false
unsigned createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
bool isReserved(unsigned PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
bool getHasPushSequences() const
This class contains meta information specific to a module.
bool hasCalls() const
Return true if the current function has any function calls.
unsigned isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
bool isTargetWindowsCoreCLR() const