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;
157 if (MBBI == MBB.
end())
160 switch (MBBI->getOpcode()) {
162 case TargetOpcode::PATCHABLE_RET:
168 case X86::TCRETURNdi:
169 case X86::TCRETURNri:
170 case X86::TCRETURNmi:
171 case X86::TCRETURNdi64:
172 case X86::TCRETURNri64:
173 case X86::TCRETURNmi64:
175 case X86::EH_RETURN64: {
177 for (
unsigned i = 0, e = MBBI->getNumOperands();
i != e; ++
i) {
188 for (
auto CS : AvailableRegs)
189 if (!Uses.
count(CS) && CS != X86::RIP)
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))
252 int64_t NumBytes,
bool InEpilogue)
const {
253 bool isSub = NumBytes < 0;
254 uint64_t
Offset = isSub ? -NumBytes : NumBytes;
256 uint64_t Chunk = (1LL << 31) - 1;
260 if (Offset > Chunk) {
271 unsigned Opc =
Is64Bit ? X86::MOV64ri : X86::MOV32ri;
286 uint64_t ThisVal =
std::min(Offset, Chunk);
287 if (ThisVal == (
Is64Bit ? 8 : 4)) {
294 ? (
Is64Bit ? X86::PUSH64r : X86::PUSH32r)
295 : (
Is64Bit ? X86::POP64r : X86::POP32r);
308 MBB, MBBI, DL, isSub ? -ThisVal : ThisVal, InEpilogue);
321 assert(Offset != 0 &&
"zero offset stack adjustment requested");
344 "We shouldn't have allowed this insertion point");
354 bool IsSub = Offset < 0;
355 uint64_t AbsOffset = IsSub ? -Offset :
Offset;
368 bool doMergeWithPrevious)
const {
369 if ((doMergeWithPrevious && MBBI == MBB.
begin()) ||
370 (!doMergeWithPrevious && MBBI == MBB.
end()))
380 unsigned Opc = PI->getOpcode();
383 if (!doMergeWithPrevious && NI != MBB.
end() &&
384 NI->getOpcode() == TargetOpcode::CFI_INSTRUCTION) {
389 if ((Opc == X86::ADD64ri32 || Opc == X86::ADD64ri8 ||
390 Opc == X86::ADD32ri || Opc == X86::ADD32ri8) &&
391 PI->getOperand(0).getReg() ==
StackPtr){
393 Offset += PI->getOperand(2).getImm();
395 if (!doMergeWithPrevious) MBBI = NI;
396 }
else if ((Opc == X86::LEA32r || Opc == X86::LEA64_32r) &&
397 PI->getOperand(0).getReg() ==
StackPtr &&
398 PI->getOperand(1).getReg() ==
StackPtr &&
399 PI->getOperand(2).getImm() == 1 &&
400 PI->getOperand(3).getReg() == X86::NoRegister &&
401 PI->getOperand(5).getReg() == X86::NoRegister) {
403 Offset += PI->getOperand(4).getImm();
405 if (!doMergeWithPrevious) MBBI = NI;
406 }
else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 ||
407 Opc == X86::SUB32ri || Opc == X86::SUB32ri8) &&
408 PI->getOperand(0).getReg() ==
StackPtr) {
410 Offset -= PI->getOperand(2).getImm();
412 if (!doMergeWithPrevious) MBBI = NI;
424 BuildMI(MBB, MBBI, DL,
TII.
get(TargetOpcode::CFI_INSTRUCTION))
425 .addCFIIndex(CFIIndex);
438 if (CSI.empty())
return;
441 for (std::vector<CalleeSavedInfo>::const_iterator
442 I = CSI.begin(),
E = CSI.end();
I !=
E; ++
I) {
444 unsigned Reg =
I->getReg();
455 const DebugLoc &DL,
bool InProlog)
const {
459 emitStackProbeInlineStub(MF, MBB, MBBI, DL,
true);
461 emitStackProbeInline(MF, MBB, MBBI, DL,
false);
464 emitStackProbeCall(MF, MBB, MBBI, DL, InProlog);
470 const StringRef ChkStkStubSymbol =
"__chkstk_stub";
474 if (MI.isCall() && MI.getOperand(0).isSymbol() &&
475 ChkStkStubSymbol == MI.getOperand(0).getSymbolName()) {
481 if (ChkStkStub !=
nullptr) {
483 "Not expecting bundled instructions here");
485 assert(std::prev(MBBI) == ChkStkStub &&
486 "MBBI expected after __chkstk_stub.");
487 DebugLoc DL = PrologMBB.findDebugLoc(MBBI);
488 emitStackProbeInline(MF, PrologMBB, MBBI, DL,
true);
497 bool InProlog)
const {
499 assert(STI.
is64Bit() &&
"different expansion needed for 32 bit");
537 MF.
insert(MBBIter, RoundMBB);
538 MF.
insert(MBBIter, LoopMBB);
539 MF.
insert(MBBIter, ContinueMBB);
547 const int64_t ThreadEnvironmentStackLimit = 0x10;
549 const int64_t PageMask = ~(PageSize - 1);
555 const unsigned SizeReg = InProlog ? (
unsigned)X86::RAX
557 ZeroReg = InProlog ? (
unsigned)X86::RCX
559 CopyReg = InProlog ? (
unsigned)X86::RDX
561 TestReg = InProlog ? (
unsigned)X86::RDX
563 FinalReg = InProlog ? (
unsigned)X86::RDX
565 RoundedReg = InProlog ? (
unsigned)X86::RDX
567 LimitReg = InProlog ? (
unsigned)X86::RCX
569 JoinReg = InProlog ? (
unsigned)X86::RCX
571 ProbeReg = InProlog ? (
unsigned)X86::RCX
575 int64_t RCXShadowSlot = 0;
576 int64_t RDXShadowSlot = 0;
586 const bool HasFP =
hasFP(MF);
587 RCXShadowSlot = 8 + CalleeSaveSize + (HasFP ? 8 : 0);
588 RDXShadowSlot = RCXShadowSlot + 8;
598 BuildMI(&MBB, DL, TII.
get(X86::MOV64rr), SizeReg).addReg(X86::RAX);
603 BuildMI(&MBB, DL, TII.
get(X86::XOR64rr), ZeroReg)
606 BuildMI(&MBB, DL, TII.
get(X86::MOV64rr), CopyReg).addReg(X86::RSP);
607 BuildMI(&MBB, DL, TII.
get(X86::SUB64rr), TestReg)
610 BuildMI(&MBB, DL, TII.
get(X86::CMOVB64rr), FinalReg)
621 BuildMI(&MBB, DL, TII.
get(X86::MOV64rm), LimitReg)
625 .
addImm(ThreadEnvironmentStackLimit)
629 BuildMI(&MBB, DL, TII.
get(X86::JAE_1)).addMBB(ContinueMBB);
632 BuildMI(RoundMBB, DL, TII.
get(X86::AND64ri32), RoundedReg)
635 BuildMI(RoundMBB, DL, TII.
get(X86::JMP_1)).addMBB(LoopMBB);
641 BuildMI(LoopMBB, DL, TII.
get(X86::PHI), JoinReg)
662 BuildMI(LoopMBB, DL, TII.
get(X86::JNE_1)).addMBB(LoopMBB);
670 X86::RSP,
false, RCXShadowSlot);
673 X86::RSP,
false, RDXShadowSlot);
678 BuildMI(*ContinueMBB, ContinueMBBI, DL, TII.
get(X86::SUB64rr), X86::RSP)
691 for (++BeforeMBBI; BeforeMBBI != MBB.
end(); ++BeforeMBBI) {
701 CMBBI != ContinueMBBI; ++CMBBI) {
713 bool InProlog)
const {
718 CallOp = IsLargeCodeModel ? X86::CALL64r : X86::CALL64pcrel32;
720 CallOp = X86::CALLpcrel32;
725 Symbol =
"___chkstk_ms";
742 BuildMI(MBB, MBBI, DL, TII.
get(X86::MOV64ri), X86::R11)
743 .addExternalSymbol(Symbol);
744 CI =
BuildMI(MBB, MBBI, DL, TII.
get(CallOp)).addReg(X86::R11);
746 CI =
BuildMI(MBB, MBBI, DL, TII.
get(CallOp)).addExternalSymbol(Symbol);
749 unsigned AX =
Is64Bit ? X86::RAX : X86::EAX;
750 unsigned SP =
Is64Bit ? X86::RSP : X86::ESP;
761 BuildMI(MBB, MBBI, DL, TII.
get(X86::SUB64rr), X86::RSP)
768 for (++ExpansionMBBI; ExpansionMBBI != MBBI; ++ExpansionMBBI)
773 void X86FrameLowering::emitStackProbeInlineStub(
777 assert(InProlog &&
"ChkStkStub called outside prolog!");
779 BuildMI(MBB, MBBI, DL, TII.
get(X86::CALLpcrel32))
780 .addExternalSymbol(
"__chkstk_stub");
786 const uint64_t Win64MaxSEHOffset = 128;
787 uint64_t SEHFrameOffset =
std::min(SPAdjust, Win64MaxSEHOffset);
789 return SEHFrameOffset & -16;
796 uint64_t X86FrameLowering::calculateMaxStackAlign(
const MachineFunction &MF)
const {
802 MaxAlign = (StackAlign > MaxAlign) ? StackAlign : MaxAlign;
812 uint64_t MaxAlign)
const {
813 uint64_t Val = -MaxAlign;
911 "MF used frame lowering for wrong subtarget");
917 uint64_t MaxAlign = calculateMaxStackAlign(MF);
923 bool FnHasClrFunclet =
925 bool IsClrFunclet = IsFunclet && FnHasClrFunclet;
926 bool HasFP =
hasFP(MF);
933 const unsigned MachineFramePtr =
937 bool HasWinCFI =
false;
945 if (TailCallReturnAddrDelta && IsWin64Prologue)
948 if (TailCallReturnAddrDelta < 0)
956 unsigned StackProbeSize = 4096;
968 !
TRI->needsStackRealignment(MF) &&
977 StackSize = std::max(MinSize, StackSize > 128 ? StackSize - 128 : 0);
984 if (TailCallReturnAddrDelta < 0) {
985 BuildStackAdjustment(MBB, MBBI, DL, TailCallReturnAddrDelta,
1004 uint64_t NumBytes = 0;
1008 unsigned Establisher = X86::NoRegister;
1014 if (IsWin64Prologue && IsFunclet && !IsClrFunclet) {
1027 uint64_t FrameSize = StackSize -
SlotSize;
1030 FrameSize += SlotSize;
1035 if (
TRI->needsStackRealignment(MF) && !IsWin64Prologue)
1036 NumBytes =
alignTo(NumBytes, MaxAlign);
1045 "should calculate same local variable offset for funclets");
1052 if (NeedsDwarfCFI) {
1060 unsigned DwarfFramePtr =
TRI->getDwarfRegNum(MachineFramePtr,
true);
1062 nullptr, DwarfFramePtr, 2 * stackGrowth));
1067 BuildMI(MBB, MBBI, DL, TII.
get(X86::SEH_PushReg))
1072 if (!IsWin64Prologue && !IsFunclet) {
1080 if (NeedsDwarfCFI) {
1083 unsigned DwarfFramePtr =
TRI->getDwarfRegNum(MachineFramePtr,
true);
1085 nullptr, DwarfFramePtr));
1093 EveryMBB.addLiveIn(MachineFramePtr);
1096 assert(!IsFunclet &&
"funclets without FPs not yet implemented");
1102 unsigned ParentFrameNumBytes = NumBytes;
1104 NumBytes = getWinEHFuncletFrameSize(MF);
1107 bool PushedRegs =
false;
1108 int StackOffset = 2 * stackGrowth;
1110 while (MBBI != MBB.
end() &&
1112 (MBBI->getOpcode() == X86::PUSH32r ||
1113 MBBI->getOpcode() == X86::PUSH64r)) {
1115 unsigned Reg = MBBI->getOperand(0).getReg();
1118 if (!HasFP && NeedsDwarfCFI) {
1124 StackOffset += stackGrowth;
1137 if (!IsWin64Prologue && !IsFunclet &&
TRI->needsStackRealignment(MF)) {
1138 assert(HasFP &&
"There should be a frame pointer if stack is realigned.");
1139 BuildStackAlignAND(MBB, MBBI, DL,
StackPtr, MaxAlign);
1157 uint64_t AlignedNumBytes = NumBytes;
1158 if (IsWin64Prologue && !IsFunclet &&
TRI->needsStackRealignment(MF))
1159 AlignedNumBytes =
alignTo(AlignedNumBytes, MaxAlign);
1160 if (AlignedNumBytes >= StackProbeSize && UseStackProbe) {
1170 BuildMI(MBB, MBBI, DL, TII.
get(X86::PUSH32r))
1179 BuildMI(MBB, MBBI, DL, TII.
get(X86::MOV32ri), X86::EAX)
1183 BuildMI(MBB, MBBI, DL, TII.
get(X86::MOV64ri32), X86::RAX)
1187 BuildMI(MBB, MBBI, DL, TII.
get(X86::MOV64ri), X86::RAX)
1194 BuildMI(MBB, MBBI, DL, TII.
get(X86::MOV32ri), X86::EAX)
1195 .addImm(isEAXAlive ? NumBytes - 4 : NumBytes)
1210 }
else if (NumBytes) {
1214 if (NeedsWinCFI && NumBytes) {
1216 BuildMI(MBB, MBBI, DL, TII.
get(X86::SEH_StackAlloc))
1221 int SEHFrameOffset = 0;
1222 unsigned SPOrEstablisher;
1229 unsigned PSPSlotOffset = getPSPSlotOffsetFromSP(MF);
1233 Establisher,
false, PSPSlotOffset)
1240 false, PSPSlotOffset)
1247 SPOrEstablisher = Establisher;
1252 if (IsWin64Prologue && HasFP) {
1259 SPOrEstablisher,
false, SEHFrameOffset);
1262 .addReg(SPOrEstablisher);
1265 if (NeedsWinCFI && !IsFunclet) {
1267 BuildMI(MBB, MBBI, DL, TII.
get(X86::SEH_SetFrame))
1274 }
else if (IsFunclet && STI.
is32Bit()) {
1297 if (
unsigned Reg = TII.isStoreToStackSlot(FrameInstr, FI)) {
1298 if (X86::FR64RegClass.
contains(Reg)) {
1299 unsigned IgnoredFrameReg;
1301 Offset += SEHFrameOffset;
1304 BuildMI(MBB, MBBI, DL, TII.
get(X86::SEH_SaveXMM))
1313 if (NeedsWinCFI && HasWinCFI)
1314 BuildMI(MBB, MBBI, DL, TII.
get(X86::SEH_EndPrologue))
1317 if (FnHasClrFunclet && !IsFunclet) {
1321 unsigned PSPSlotOffset = getPSPSlotOffsetFromSP(MF);
1335 if (IsWin64Prologue &&
TRI->needsStackRealignment(MF)) {
1336 assert(HasFP &&
"There should be a frame pointer if stack is realigned.");
1337 BuildStackAlignAND(MBB, MBBI, DL, SPOrEstablisher, MaxAlign);
1341 if (IsFunclet && STI.
is32Bit())
1351 BuildMI(MBB, MBBI, DL, TII.
get(Opc), BasePtr)
1352 .addReg(SPOrEstablisher)
1360 .addReg(SPOrEstablisher)
1373 assert(UsedReg == BasePtr);
1380 if (((!HasFP && NumBytes) || PushedRegs) && NeedsDwarfCFI) {
1382 if (!HasFP && NumBytes) {
1386 nullptr, -StackSize + stackGrowth));
1446 X86FrameLowering::getPSPSlotOffsetFromSP(
const MachineFunction &MF)
const {
1452 return static_cast<unsigned>(
Offset);
1456 X86FrameLowering::getWinEHFuncletFrameSize(
const MachineFunction &MF)
const {
1468 UsedSize = getPSPSlotOffsetFromSP(MF) +
SlotSize;
1479 return FrameSizeMinusRBP - CSSize;
1483 return Opc == X86::TCRETURNri || Opc == X86::TCRETURNdi ||
1484 Opc == X86::TCRETURNmi ||
1485 Opc == X86::TCRETURNri64 || Opc == X86::TCRETURNdi64 ||
1486 Opc == X86::TCRETURNmi64;
1495 if (MBBI != MBB.
end())
1496 RetOpcode = MBBI->getOpcode();
1498 if (MBBI != MBB.
end())
1499 DL = MBBI->getDebugLoc();
1503 unsigned MachineFramePtr =
1514 uint64_t MaxAlign = calculateMaxStackAlign(MF);
1516 uint64_t NumBytes = 0;
1522 "SEH should not use CATCHRET");
1524 NumBytes = getWinEHFuncletFrameSize(MF);
1525 assert(
hasFP(MF) &&
"EH funclets without FP not yet implemented");
1526 TargetMBB = MBBI->getOperand(0).getMBB();
1533 NumBytes = getWinEHFuncletFrameSize(MF);
1534 assert(
hasFP(MF) &&
"EH funclets without FP not yet implemented");
1538 }
else if (
hasFP(MF)) {
1540 uint64_t FrameSize = StackSize -
SlotSize;
1541 NumBytes = FrameSize - CSSize;
1545 if (
TRI->needsStackRealignment(MF) && !IsWin64Prologue)
1546 NumBytes =
alignTo(FrameSize, MaxAlign);
1550 TII.
get(
Is64Bit ? X86::POP64r : X86::POP32r), MachineFramePtr)
1553 NumBytes = StackSize - CSSize;
1555 uint64_t SEHStackAllocAmt = NumBytes;
1559 while (MBBI != MBB.
begin()) {
1561 unsigned Opc = PI->getOpcode();
1563 if (Opc != X86::DBG_VALUE && !PI->isTerminator()) {
1576 unsigned ReturnReg = STI.
is64Bit() ? X86::RAX : X86::EAX;
1579 BuildMI(MBB, FirstCSPop, DL, TII.
get(X86::LEA64r), ReturnReg)
1587 BuildMI(MBB, FirstCSPop, DL, TII.
get(X86::MOV32ri), ReturnReg)
1595 if (MBBI != MBB.
end())
1596 DL = MBBI->getDebugLoc();
1609 if (
TRI->needsStackRealignment(MF))
1612 uint64_t LEAAmount =
1613 IsWin64Prologue ? SEHStackAllocAmt - SEHFrameOffset : -CSSize;
1622 if (LEAAmount != 0) {
1625 FramePtr,
false, LEAAmount);
1633 }
else if (NumBytes) {
1646 BuildMI(MBB, MBBI, DL, TII.
get(X86::SEH_Epilogue));
1651 assert(Offset >= 0 &&
"TCDelta should never be positive");
1667 unsigned &FrameReg)
const {
1675 else if (
TRI->needsStackRealignment(MF))
1688 bool HasFP =
hasFP(MF);
1690 int64_t FPDelta = 0;
1692 if (IsWin64Prologue) {
1696 uint64_t FrameSize = StackSize -
SlotSize;
1699 FrameSize += SlotSize;
1700 uint64_t NumBytes = FrameSize - CSSize;
1704 return -SEHFrameOffset;
1710 FPDelta = FrameSize - SEHFrameOffset;
1712 "FPDelta isn't aligned per the Win64 ABI!");
1717 assert(HasFP &&
"VLAs and dynamic stack realign, but no FP?!");
1720 return Offset +
SlotSize + FPDelta;
1723 return Offset + StackSize;
1725 }
else if (
TRI->needsStackRealignment(MF)) {
1728 return Offset +
SlotSize + FPDelta;
1731 return Offset + StackSize;
1736 return Offset + StackSize;
1743 if (TailCallReturnAddrDelta < 0)
1744 Offset -= TailCallReturnAddrDelta;
1747 return Offset + FPDelta;
1752 int FI,
unsigned &FrameReg,
1753 bool IgnoreSPUpdates)
const {
1804 "we don't handle this case!");
1838 return Offset + StackSize;
1843 std::vector<CalleeSavedInfo> &CSI)
const {
1847 unsigned CalleeSavedFrameSize = 0;
1859 for (
unsigned i = 0;
i < CSI.size(); ++
i) {
1861 CSI.erase(CSI.begin() +
i);
1868 for (
unsigned i = CSI.size();
i != 0; --
i) {
1869 unsigned Reg = CSI[
i - 1].getReg();
1878 CSI[
i - 1].setFrameIdx(SlotIndex);
1884 for (
unsigned i = CSI.size();
i != 0; --
i) {
1885 unsigned Reg = CSI[
i - 1].getReg();
1893 SpillSlotOffset -= RC->
getSize();
1896 CSI[
i - 1].setFrameIdx(SlotIndex);
1905 const std::vector<CalleeSavedInfo> &CSI,
1916 unsigned Opc = STI.
is64Bit() ? X86::PUSH64r : X86::PUSH32r;
1917 for (
unsigned i = CSI.size();
i != 0; --
i) {
1918 unsigned Reg = CSI[
i - 1].getReg();
1929 bool CanKill = !isLiveIn;
1951 for (
unsigned i = CSI.size();
i != 0; --
i) {
1952 unsigned Reg = CSI[
i-1].getReg();
1959 TII.storeRegToStackSlot(MBB, MI, Reg,
true, CSI[
i - 1].getFrameIdx(), RC,
1971 const std::vector<CalleeSavedInfo> &CSI,
1995 for (
unsigned i = 0, e = CSI.size();
i != e; ++
i) {
1996 unsigned Reg = CSI[
i].getReg();
1997 if (X86::GR64RegClass.
contains(Reg) ||
2002 TII.loadRegFromStackSlot(MBB, MI, Reg, CSI[
i].getFrameIdx(), RC, TRI);
2006 unsigned Opc = STI.
is64Bit() ? X86::POP64r : X86::POP32r;
2007 for (
unsigned i = 0, e = CSI.size();
i != e; ++
i) {
2008 unsigned Reg = CSI[
i].getReg();
2009 if (!X86::GR64RegClass.
contains(Reg) &&
2029 if (TailCallReturnAddrDelta < 0) {
2040 TailCallReturnAddrDelta -
SlotSize,
true);
2061 if (
I->hasNestAttr())
2078 return Primary ? X86::R14 : X86::R13;
2080 return Primary ? X86::EBX : X86::EDI;
2085 return Primary ? X86::R11 : X86::R12;
2087 return Primary ? X86::R11D : X86::R12D;
2096 "nested function.");
2097 return Primary ? X86::EAX : X86::ECX;
2100 return Primary ? X86::EDX : X86::EAX;
2101 return Primary ? X86::ECX : X86::EAX;
2112 unsigned TlsReg, TlsOffset;
2117 assert(&(*MF.
begin()) == &PrologueMBB &&
"Shrink-wrapping not supported yet");
2121 "Scratch register is live-in");
2142 bool IsNested =
false;
2151 for (
const auto &LI : PrologueMBB.
liveins()) {
2170 TlsOffset =
IsLP64 ? 0x70 : 0x40;
2173 TlsOffset = 0x60 + 90*8;
2187 if (CompareStackPointer)
2188 ScratchReg =
IsLP64 ? X86::RSP : X86::ESP;
2190 BuildMI(checkMBB, DL, TII.
get(
IsLP64 ? X86::LEA64r : X86::LEA64_32r), ScratchReg).addReg(X86::RSP)
2193 BuildMI(checkMBB, DL, TII.
get(
IsLP64 ? X86::CMP64rm : X86::CMP32rm)).addReg(ScratchReg)
2201 TlsOffset = 0x48 + 90*4;
2214 if (CompareStackPointer)
2215 ScratchReg = X86::ESP;
2217 BuildMI(checkMBB, DL, TII.
get(X86::LEA32r), ScratchReg).addReg(X86::ESP)
2222 BuildMI(checkMBB, DL, TII.
get(X86::CMP32rm)).addReg(ScratchReg)
2227 unsigned ScratchReg2;
2229 if (CompareStackPointer) {
2232 SaveScratch2 =
false;
2244 "Scratch register is live-in and not saved");
2250 BuildMI(checkMBB, DL, TII.
get(X86::MOV32ri), ScratchReg2)
2259 BuildMI(checkMBB, DL, TII.
get(X86::POP32r), ScratchReg2);
2265 BuildMI(checkMBB, DL, TII.
get(X86::JA_1)).addMBB(&PrologueMBB);
2273 const unsigned RegAX =
IsLP64 ? X86::RAX : X86::EAX;
2274 const unsigned Reg10 =
IsLP64 ? X86::R10 : X86::R10D;
2275 const unsigned Reg11 =
IsLP64 ? X86::R11 : X86::R11D;
2276 const unsigned MOVrr =
IsLP64 ? X86::MOV64rr : X86::MOV32rr;
2277 const unsigned MOVri =
IsLP64 ? X86::MOV64ri : X86::MOV32ri;
2280 BuildMI(allocMBB, DL, TII.
get(MOVrr), RegAX).addReg(Reg10);
2318 BuildMI(allocMBB, DL, TII.
get(X86::CALL64pcrel32))
2319 .addExternalSymbol(
"__morestack");
2321 BuildMI(allocMBB, DL, TII.
get(X86::CALLpcrel32))
2322 .addExternalSymbol(
"__morestack");
2326 BuildMI(allocMBB, DL, TII.
get(X86::MORESTACK_RET_RESTORE_R10));
2328 BuildMI(allocMBB, DL, TII.
get(X86::MORESTACK_RET));
2335 #ifdef EXPENSIVE_CHECKS
2351 if (!NodeName || !NodeVal)
continue;
2352 ConstantInt *ValConst = dyn_cast_or_null<ConstantInt>(NodeVal->getValue());
2353 if (ValConst && NodeName->
getString() == LiteralName) {
2359 +
" required but not provided");
2384 assert(&(*MF.
begin()) == &PrologueMBB &&
"Shrink-wrapping not supported yet");
2389 if (!HiPELiteralsMD)
2391 "Can't generate HiPE prologue without runtime parameters");
2392 const unsigned HipeLeafWords
2394 Is64Bit ?
"AMD64_LEAF_WORDS" :
"X86_LEAF_WORDS");
2395 const unsigned CCRegisteredArgs =
Is64Bit ? 6 : 5;
2396 const unsigned Guaranteed = HipeLeafWords *
SlotSize;
2402 "HiPE prologue is only supported on Linux operating systems.");
2412 unsigned MoreStackForCalls = 0;
2414 for (
auto &MBB : MF) {
2415 for (
auto &MI : MBB) {
2440 unsigned CalleeStkArity =
2442 if (HipeLeafWords - 1 > CalleeStkArity)
2443 MoreStackForCalls = std::max(MoreStackForCalls,
2444 (HipeLeafWords - 1 - CalleeStkArity) * SlotSize);
2447 MaxStack += MoreStackForCalls;
2452 if (MaxStack > Guaranteed) {
2456 for (
const auto &LI : PrologueMBB.
liveins()) {
2464 unsigned ScratchReg, SPReg, PReg, SPLimitOffset;
2465 unsigned LEAop, CMPop, CALLop;
2470 LEAop = X86::LEA64r;
2471 CMPop = X86::CMP64rm;
2472 CALLop = X86::CALL64pcrel32;
2476 LEAop = X86::LEA32r;
2477 CMPop = X86::CMP32rm;
2478 CALLop = X86::CALLpcrel32;
2483 "HiPE prologue scratch register is live-in");
2487 SPReg,
false, -MaxStack);
2490 .addReg(ScratchReg), PReg,
false, SPLimitOffset);
2491 BuildMI(stackCheckMBB, DL, TII.
get(X86::JAE_1)).addMBB(&PrologueMBB);
2495 addExternalSymbol(
"inc_stack_0");
2497 SPReg,
false, -MaxStack);
2499 .addReg(ScratchReg), PReg,
false, SPLimitOffset);
2500 BuildMI(incStackMBB, DL, TII.
get(X86::JLE_1)).addMBB(incStackMBB);
2507 #ifdef EXPENSIVE_CHECKS
2525 if (NumPops != 1 && NumPops != 2)
2530 if (MBBI == MBB.
begin())
2533 if (!Prev->isCall() || !Prev->getOperand(1).isRegMask())
2537 unsigned FoundRegs = 0;
2539 auto RegMask = Prev->getOperand(1);
2542 Is64Bit ? X86::GR64_NOREX_NOSPRegClass : X86::GR32_NOREX_NOSPRegClass;
2544 for (
auto Candidate : RegClass) {
2549 if (!RegMask.clobbersPhysReg(Candidate))
2554 if (MO.isReg() && MO.isDef() &&
2555 TRI->isSuperOrSubRegisterEq(MO.getReg(), Candidate)) {
2564 Regs[FoundRegs++] = Candidate;
2565 if (FoundRegs == (
unsigned)NumPops)
2573 while (FoundRegs < (
unsigned)NumPops)
2574 Regs[FoundRegs++] = Regs[0];
2576 for (
int i = 0;
i < NumPops; ++
i)
2578 TII.
get(STI.
is64Bit() ? X86::POP64r : X86::POP32r), Regs[
i]);
2587 unsigned Opcode = I->getOpcode();
2588 bool isDestroy = Opcode == TII.getCallFrameDestroyOpcode();
2590 uint64_t Amount = !reserveCallFrame ? I->getOperand(0).getImm() : 0;
2591 uint64_t InternalAmt = (isDestroy || Amount) ? I->getOperand(1).getImm() : 0;
2595 if (!reserveCallFrame) {
2604 Amount =
alignTo(Amount, StackAlign);
2619 bool HasDwarfEHHandlers = !WindowsCFI && !MF.
getLandingPads().empty();
2621 if (HasDwarfEHHandlers && !isDestroy &&
2631 Amount -= InternalAmt;
2636 if (isDestroy && InternalAmt && DwarfCFI && !
hasFP(MF))
2644 if (StackAdjustment) {
2651 if (StackAdjustment) {
2653 adjustStackWithPops(MBB, InsertPos, DL, StackAdjustment)))
2654 BuildStackAdjustment(MBB, InsertPos, DL, StackAdjustment,
2659 if (DwarfCFI && !
hasFP(MF)) {
2669 if (CfaAdjustment) {
2679 if (isDestroy && InternalAmt) {
2688 while (CI != B && !std::prev(CI)->isCall())
2690 BuildStackAdjustment(MBB, CI, DL, -InternalAmt,
false);
2699 return !
TRI->needsStackRealignment(MF) || !MBB.
isLiveIn(X86::EFLAGS);
2737 const DebugLoc &DL,
bool RestoreSP)
const {
2741 "restoring EBP/ESI on non-32-bit target");
2753 int EHRegSize = MFI.getObjectSize(FI);
2758 X86::EBP,
true, -EHRegSize)
2764 int EndOffset = -EHRegOffset - EHRegSize;
2767 if (UsedReg == FramePtr) {
2777 "end of registration object above normal EBP position!");
2778 }
else if (UsedReg == BasePtr) {
2781 FramePtr,
false, EndOffset)
2787 assert(UsedReg == BasePtr);
2789 UsedReg,
true, Offset)
2799 struct X86FrameSortingObject {
2800 bool IsValid =
false;
2801 unsigned ObjectIndex = 0;
2802 unsigned ObjectSize = 0;
2803 unsigned ObjectAlignment = 1;
2804 unsigned ObjectNumUses = 0;
2820 struct X86FrameSortingComparator {
2821 inline bool operator()(
const X86FrameSortingObject &
A,
2822 const X86FrameSortingObject &
B) {
2823 uint64_t DensityAScaled, DensityBScaled;
2843 DensityAScaled =
static_cast<uint64_t
>(A.ObjectNumUses) *
2844 static_cast<uint64_t>(B.ObjectSize);
2845 DensityBScaled =
static_cast<uint64_t
>(B.ObjectNumUses) *
2846 static_cast<uint64_t>(A.ObjectSize);
2856 if (DensityAScaled == DensityBScaled)
2857 return A.ObjectAlignment < B.ObjectAlignment;
2859 return DensityAScaled < DensityBScaled;
2873 if (ObjectsToAllocate.
empty())
2885 for (
auto &Obj : ObjectsToAllocate) {
2886 SortingObjects[Obj].IsValid =
true;
2887 SortingObjects[Obj].ObjectIndex = Obj;
2891 if (ObjectSize == 0)
2893 SortingObjects[Obj].ObjectSize = 4;
2895 SortingObjects[Obj].ObjectSize = ObjectSize;
2899 for (
auto &MBB : MF) {
2900 for (
auto &MI : MBB) {
2907 int Index = MO.getIndex();
2911 SortingObjects[Index].IsValid)
2912 SortingObjects[Index].ObjectNumUses++;
2919 std::stable_sort(SortingObjects.begin(), SortingObjects.end(),
2920 X86FrameSortingComparator());
2928 for (
auto &Obj : SortingObjects) {
2932 ObjectsToAllocate[i++] = Obj.ObjectIndex;
2936 if (!
TRI->needsStackRealignment(MF) &&
hasFP(MF))
2937 std::reverse(ObjectsToAllocate.begin(), ObjectsToAllocate.end());
2943 unsigned Offset = 16;
2949 Offset += getWinEHFuncletFrameSize(MF);
2969 int64_t MinFixedObjOffset = -
SlotSize;
2976 if (FrameIndex != INT_MAX) {
2979 MinFixedObjOffset -=
std::abs(MinFixedObjOffset) % Align;
2987 MinFixedObjOffset -=
std::abs(MinFixedObjOffset) % 8;
2988 int64_t UnwindHelpOffset = MinFixedObjOffset -
SlotSize;
2996 auto MBBI = MBB.
begin();
void push_front(MachineBasicBlock *MBB)
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 getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
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.
constexpr bool isUInt< 32 >(uint64_t x)
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
static bool flagsNeedToBePreservedBeforeTheTerminators(const MachineBasicBlock &MBB)
Check if the flags need to be preserved before the terminators.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
int getDwarfRegNum(unsigned RegNum, bool isEH) const
Map a target register to an equivalent dwarf register number.
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...
SmallVector< WinEHHandlerType, 1 > HandlerArray
const GlobalValue * getGlobal() const
iterator_range< livein_iterator > liveins() const
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
void setHasWinCFI(bool v)
bool isTargetCygMing() const
bool hasCopyImplyingStackAdjustment() const
Returns true if the function contains operations which will lower down to instructions which manipula...
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
const X86InstrInfo * getInstrInfo() const override
bool isTargetMachO() const
bool hasBasePointer(const MachineFunction &MF) const
unsigned getNumOperands() const
Return number of MDNode operands.
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI) const override
restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee saved registers and returns...
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
static unsigned getLEArOpcode(unsigned IsLP64)
bool callsEHReturn() const
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...
bool isCleanupFuncletEntry() const
Returns true if this is the entry block of a cleanup funclet.
unsigned getArgumentStackSize() const
const std::vector< LandingPadInfo > & getLandingPads() const
Return a reference to the landing pad info for the current function.
bool adjustsStack() const
Return true if this function adjusts the stack – e.g., when calling another function.
constexpr bool isInt< 8 >(int64_t x)
unsigned getCalleeSavedFrameSize() const
void setCalleeSavedFrameSize(unsigned bytes)
bool isTargetWindowsCoreCLR() const
void setIsDead(bool Val=true)
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
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)
iterator_range< mop_iterator > operands()
static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset)
.cfi_def_cfa_offset modifies a rule for computing CFA.
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...
X86FrameLowering(const X86Subtarget &STI, unsigned StackAlignOverride)
bool optForMinSize() const
Optimize this function for minimum size (-Oz).
return AArch64::GPR64RegClass contains(Reg)
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
iterator_range< succ_iterator > successors()
StringRef getName() const
Return a constant reference to the value's name.
X86MachineFunctionInfo - This class is derived from MachineFunction and contains private X86 target-s...
unsigned getMaxAlignment() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...
bool Uses64BitFramePtr
True if the 64-bit frame or stack pointer should be used.
unsigned getSize() const
Return the size of the register in bytes, which is also the size of a stack slot allocated to hold a ...
bool isTargetNaCl64() const
CLEANUPRET - Represents a return from a cleanup block funclet.
int getTCReturnAddrDelta() const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
DILocation * get() const
Get the underlying DILocation.
const HexagonInstrInfo * TII
bool isTargetDarwin() const
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
X86_INTR - x86 hardware interrupt context.
bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const Module * getModule() const
Constant * getPersonalityFn() const
Get the personality function associated with this function.
Reg
All possible values of the reg field in the ModR/M byte.
iterator_range< iterator > terminators()
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.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
bool isFrameAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
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...
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
static const uint64_t kSplitStackAvailable
bool hasDebugInfo() const
Returns true if valid debug info is present.
virtual unsigned getFrameRegister(const MachineFunction &MF) const =0
Debug information queries.
LLVM_NODISCARD unsigned addFrameInst(const MCCFIInstruction &Inst)
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
int CreateFixedSpillStackObject(uint64_t Size, int64_t SPOffset, bool Immutable=false)
Create a spill slot at a fixed location on the stack.
void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS) const override
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
LLVM_NODISCARD bool empty() const
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
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
uint16_t StackAdjustment(const RuntimeFunction &RF)
StackAdjustment - calculated stack adjustment in words.
const MachineBasicBlock & front() const
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register...
int getObjectIndexBegin() const
Return the minimum frame object index.
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...
bool hasStackObjects() const
Return true if there are any stack objects in this function.
bool isLiveIn(unsigned Reg) const
int getOffsetAdjustment() const
Return the correction for frame offsets.
void inlineStackProbe(MachineFunction &MF, MachineBasicBlock &PrologMBB) const override
Replace a StackProbe inline-stub with the actual probe code inline.
static unsigned getANDriOpcode(bool IsLP64, int64_t Imm)
bool isBundled() const
Return true if this instruction part of a bundle.
bool is64Bit() const
Is this x86_64? (disregarding specific ABI / programming model)
void setHasSEHFramePtrSave(bool V)
X86_FastCall - 'fast' analog of X86_StdCall.
static unsigned getHiPELiteral(NamedMDNode *HiPELiteralsMD, const StringRef LiteralName)
Lookup an ERTS parameter in the !hipe.literals named metadata node.
static cl::opt< int > PageSize("imp-null-check-page-size", cl::desc("The page size of the target in bytes"), cl::init(4096))
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
static unsigned calculateSetFPREG(uint64_t SPAdjust)
bool getHasSEHFramePtrSave() const
bool Is64Bit
Is64Bit implies that x86_64 instructions are available.
unsigned getUndefRegState(bool B)
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
unsigned getKillRegState(bool B)
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
TargetInstrInfo - Interface to description of machine instruction set.
bool isDebugValue() const
unsigned getDefRegState(bool B)
The memory access is volatile.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool hasStackMap() const
This method may be called any time after instruction selection is complete to determine if there is a...
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.
bool regsOverlap(unsigned regA, unsigned regB) const
Returns true if the two registers are equal or alias each other.
unsigned const MachineRegisterInfo * MRI
bool isCallingConvWin64(CallingConv::ID CC) const
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.
CodeModel::Model getCodeModel() const
Returns the code model.
LLVM Basic Block Representation.
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
unsigned getAlignment() const
Return the minimum required alignment for a register of this class.
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.
void setStackSize(uint64_t Size)
Set the size of the stack.
static bool is64Bit(const char *name)
void emitCalleeSavedFrameMoves(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL) const
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
const MachineOperand & getOperand(unsigned i) const
bool isTargetWin32() const
static MCCFIInstruction createGnuArgsSize(MCSymbol *L, int Size)
A special wrapper for .cfi_escape that indicates GNU_ARGS_SIZE.
bool hasPersonalityFn() const
Check whether this function has a personality function.
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]...
bool shouldSplitStack() const
Should we be emitting segmented stack stuff for the function.
bool isEHFuncletEntry() const
Returns true if this is the entry block of an EH funclet.
MDNode * getOperand(unsigned i) const
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const TargetRegisterClass * getGPRsForTailCall(const MachineFunction &MF) const
getGPRsForTailCall - Returns a register class with registers that can be used in forming tail calls...
self_iterator getIterator()
int mergeSPUpdates(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, bool doMergeWithPrevious) const
Check the instruction before/after the passed instruction.
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool Immutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
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...
This class contains a discriminated union of information about pointers in memory operands...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned getBaseRegister() const
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
unsigned getStackRegister() const
static unsigned getSUBriOpcode(unsigned IsLP64, int64_t Imm)
bool isReturnBlock() const
Convenience function that returns true if the block ends in a return instruction. ...
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 bool isFuncletReturnInstr(MachineInstr &MI)
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
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...
DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any DBG_VALUE instructions.
The memory access writes data.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
bool hasCalls() const
Return true if the current function has any function calls.
virtual const TargetFrameLowering * getFrameLowering() const
StringRef getString() const
const MDOperand & getOperand(unsigned I) const
int getRestoreBasePointerOffset() const
bool isTargetWindowsMSVC() const
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.
const MCContext & getContext() const
bool isTarget64BitILP32() const
Is this x86_64 with the ILP32 programming model (x32 ABI)?
MachineOperand class - Representation of each machine instruction operand.
unsigned getObjectAlignment(int ObjectIdx) const
Return the alignment of the specified stack object.
int getOffsetOfLocalArea() const
getOffsetOfLocalArea - This method returns the offset of the local area from the stack pointer on ent...
void emitStackProbe(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, bool InProlog) const
Emit target stack probe code.
unsigned getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call...
Information about stack frame layout on the target.
void setUsesMorestackAddr(bool b)
bool isTargetLinux() const
bool needsUnwindTableEntry() const
True if this function needs an unwind table.
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 ...
void setOffsetAdjustment(int Adj)
Set the correction for frame offsets.
bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override
canSimplifyCallFramePseudos - If there is a reserved call frame, the call frame pseudos can be simpli...
bool getHasPushSequences() const
IterT skipDebugInstructionsBackward(IterT It, IterT Begin)
Decrement It until it points to a non-debug instruction or to Begin and return the resulting iterator...
unsigned getX86SubSuperRegister(unsigned, unsigned, bool High=false)
Returns the sub or super register of a specific X86 register.
static bool isTailCallOpcode(unsigned Opc)
SmallVector< WinEHTryBlockMapEntry, 4 > TryBlockMap
const TargetInstrInfo & TII
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, unsigned base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SynchronizationScope SynchScope=CrossThread, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
bool hasEHFunclets() 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...
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.
bool canUseLEAForSPInEpilogue(const MachineFunction &MF) const
Check that LEA can be used on SP in an epilogue sequence for MF.
bool isTargetDragonFly() const
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.
const MCRegisterInfo * getRegisterInfo() const
The memory access reads data.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
Representation of each machine instruction.
int getSEHFramePtrSaveIndex() const
bool assignCalleeSavedSpillSlots(MachineFunction &MF, const TargetRegisterInfo *TRI, std::vector< CalleeSavedInfo > &CSI) const override
assignCalleeSavedSpillSlots - Allows target to override spill slot assignment logic.
NamedMDNode * getNamedMetadata(const Twine &Name) const
Return the first NamedMDNode in the module with the specified name.
void adjustForSegmentedStacks(MachineFunction &MF, MachineBasicBlock &PrologueMBB) const override
Adjust the prologue to have the function use segmented stacks.
bool hasPatchPoint() const
This method may be called any time after instruction selection is complete to determine if there is a...
void ensureMaxAlignment(unsigned Align)
Make sure the function is at least Align bytes aligned.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
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.
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned char TargetFlags=0) const
bool isTarget64BitLP64() const
Is this x86_64 with the LP64 programming model (standard AMD64, no x32)?
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
bool isCall(QueryType Type=AnyInBundle) const
APFloat abs(APFloat X)
Returns the absolute value of the argument.
Pair of physical register and lane mask.
bool callsUnwindInit() const
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
unsigned getSlotSize() const
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
static unsigned getSUBrrOpcode(unsigned isLP64)
const WinEHFuncInfo * getWinEHFuncInfo() const
getWinEHFuncInfo - Return information about how the current function uses Windows exception handling...
iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
union llvm::WinEHHandlerType::@61 CatchObj
The CatchObj starts out life as an LLVM alloca and is eventually turned frame index.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
const X86RegisterInfo * TRI
bool isLiveIn(MCPhysReg Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) - This node represents 'eh_return' gcc dwarf builtin...
unsigned getReg() const
getReg - Returns the register number.
StringRef getValueAsString() const
Return the attribute's value as a string.
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.
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.
bool isTargetWin64() const
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...
void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, int64_t NumBytes, bool InEpilogue) const
Emit a series of instructions to increment / decrement the stack pointer by a constant value...
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) 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 isTargetFreeBSD() const
static const unsigned FramePtr
unsigned getNumOperands() const
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)
bool hasOpaqueSPAdjustment() const
Returns true if the function contains opaque dynamic stack adjustments.
void setObjectOffset(int ObjectIdx, int64_t SPOffset)
Set the stack frame offset of the specified object.
StringRef - Represent a constant reference to a string, i.e.
MachineModuleInfo & getMMI() const
unsigned getFrameRegister(const MachineFunction &MF) const override
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...
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
int getObjectIndexEnd() const
Return one past the maximum frame object index.
void orderFrameObjects(const MachineFunction &MF, SmallVectorImpl< int > &ObjectsToAllocate) const override
Order the symbols in the local stack.
static bool HasNestArgument(const MachineFunction *MF)
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
SlotIndex - An opaque wrapper around machine indexes.
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Fast - This calling convention attempts to make calls as fast as possible (e.g.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
bool getRestoreBasePointer() const
This class contains meta information specific to a module.
bool usesWindowsCFI() const