Go to the documentation of this file.
37 #define DEBUG_TYPE "x86-fl"
39 STATISTIC(NumFrameLoopProbe,
"Number of loop stack probes used in prologue");
41 "Number of extra stack probes generated in prologue");
49 STI(STI),
TII(*STI.getInstrInfo()),
TRI(STI.getRegisterInfo()) {
73 (
hasFP(MF) && !
TRI->hasStackRealignment(MF)) ||
108 return X86::SUB64ri8;
109 return X86::SUB64ri32;
112 return X86::SUB32ri8;
120 return X86::ADD64ri8;
121 return X86::ADD64ri32;
124 return X86::ADD32ri8;
130 return IsLP64 ? X86::SUB64rr : X86::SUB32rr;
134 return IsLP64 ? X86::ADD64rr : X86::ADD32rr;
140 return X86::AND64ri8;
141 return X86::AND64ri32;
144 return X86::AND32ri8;
149 return IsLP64 ? X86::LEA64r : X86::LEA32r;
154 unsigned Reg = RegMask.PhysReg;
171 bool BreakNext =
false;
176 if (
Reg != X86::EFLAGS)
197 if (Succ->isLiveIn(X86::EFLAGS))
208 int64_t NumBytes,
bool InEpilogue)
const {
209 bool isSub = NumBytes < 0;
210 uint64_t
Offset = isSub ? -NumBytes : NumBytes;
214 uint64_t Chunk = (1LL << 31) - 1;
223 if (EmitInlineStackProbe && !InEpilogue) {
229 }
else if (
Offset > Chunk) {
240 unsigned MovRIOpc =
Is64Bit ? X86::MOV64ri : X86::MOV32ri;
241 unsigned AddSubRROpc =
250 MI->getOperand(3).setIsDead();
252 }
else if (
Offset > 8 * Chunk) {
276 MI->getOperand(3).setIsDead();
298 ? (
Is64Bit ? X86::PUSH64r : X86::PUSH32r)
299 : (
Is64Bit ? X86::POP64r : X86::POP32r);
308 BuildStackAdjustment(
MBB,
MBBI,
DL, isSub ? -ThisVal : ThisVal, InEpilogue)
318 assert(
Offset != 0 &&
"zero offset stack adjustment requested");
341 "We shouldn't have allowed this insertion point");
358 MI->getOperand(3).setIsDead();
365 bool doMergeWithPrevious)
const {
384 if (doMergeWithPrevious && PI !=
MBB.
begin() && PI->isCFIInstruction())
387 unsigned Opc = PI->getOpcode();
390 if ((Opc == X86::ADD64ri32 || Opc == X86::ADD64ri8 ||
391 Opc == X86::ADD32ri || Opc == X86::ADD32ri8) &&
392 PI->getOperand(0).getReg() ==
StackPtr){
394 Offset = PI->getOperand(2).getImm();
395 }
else if ((Opc == X86::LEA32r || Opc == X86::LEA64_32r) &&
396 PI->getOperand(0).getReg() ==
StackPtr &&
397 PI->getOperand(1).getReg() ==
StackPtr &&
398 PI->getOperand(2).getImm() == 1 &&
399 PI->getOperand(3).getReg() == X86::NoRegister &&
400 PI->getOperand(5).getReg() == X86::NoRegister) {
402 Offset = PI->getOperand(4).getImm();
403 }
else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 ||
404 Opc == X86::SUB32ri || Opc == X86::SUB32ri8) &&
405 PI->getOperand(0).getReg() ==
StackPtr) {
407 Offset = -PI->getOperand(2).getImm();
412 if (PI !=
MBB.
end() && PI->isCFIInstruction()) PI =
MBB.
erase(PI);
413 if (!doMergeWithPrevious)
444 unsigned DwarfReg =
MRI->getDwarfRegNum(MachineFramePtr,
true);
462 if (CSI.empty())
return;
465 for (std::vector<CalleeSavedInfo>::const_iterator
466 I = CSI.begin(),
E = CSI.end();
I !=
E; ++
I) {
468 unsigned Reg =
I->getReg();
469 unsigned DwarfReg =
MRI->getDwarfRegNum(
Reg,
true);
491 emitStackProbeInline(MF,
MBB,
MBBI,
DL,
false);
494 emitStackProbeCall(MF,
MBB,
MBBI,
DL, InProlog);
501 return MI.getOpcode() == X86::STACKALLOC_W_PROBING;
503 if (Where != PrologMBB.
end()) {
505 emitStackProbeInline(MF, PrologMBB, Where,
DL,
true);
506 Where->eraseFromParent();
514 bool InProlog)
const {
517 emitStackProbeInlineWindowsCoreCLR64(MF,
MBB,
MBBI,
DL, InProlog);
519 emitStackProbeInlineGeneric(MF,
MBB,
MBBI,
DL, InProlog);
522 void X86FrameLowering::emitStackProbeInlineGeneric(
531 "different expansion expected for CoreCLR 64 bit");
533 const uint64_t StackProbeSize = TLI.getStackProbeSize(MF);
534 uint64_t ProbeChunk = StackProbeSize * 8;
537 TRI->hasStackRealignment(MF) ? calculateMaxStackAlign(MF) : 0;
542 if (
Offset > ProbeChunk) {
544 MaxAlign % StackProbeSize);
547 MaxAlign % StackProbeSize);
551 void X86FrameLowering::emitStackProbeInlineGenericBlock(
554 uint64_t AlignOffset)
const {
556 const bool NeedsDwarfCFI = needsDwarfCFI(MF);
561 const unsigned MovMIOpc =
Is64Bit ? X86::MOV64mi32 : X86::MOV32mi;
562 const uint64_t StackProbeSize = TLI.getStackProbeSize(MF);
564 uint64_t CurrentOffset = 0;
566 assert(AlignOffset < StackProbeSize);
569 if (StackProbeSize <
Offset + AlignOffset) {
573 .
addImm(StackProbeSize - AlignOffset)
575 if (!HasFP && NeedsDwarfCFI) {
578 nullptr, StackProbeSize - AlignOffset));
580 MI->getOperand(3).setIsDead();
587 NumFrameExtraProbe++;
588 CurrentOffset = StackProbeSize - AlignOffset;
594 while (CurrentOffset + StackProbeSize <
Offset) {
599 MI->getOperand(3).setIsDead();
601 if (!HasFP && NeedsDwarfCFI) {
611 NumFrameExtraProbe++;
612 CurrentOffset += StackProbeSize;
616 uint64_t ChunkSize =
Offset - CurrentOffset;
623 MI->getOperand(3).setIsDead();
626 void X86FrameLowering::emitStackProbeInlineGenericLoop(
629 uint64_t AlignOffset)
const {
634 const unsigned MovMIOpc =
Is64Bit ? X86::MOV64mi32 : X86::MOV32mi;
635 const uint64_t StackProbeSize = TLI.getStackProbeSize(MF);
638 if (AlignOffset < StackProbeSize) {
645 MI->getOperand(3).setIsDead();
652 NumFrameExtraProbe++;
665 MF.
insert(MBBIter, testMBB);
666 MF.
insert(MBBIter, tailMBB);
718 unsigned TailOffset =
Offset % StackProbeSize;
732 void X86FrameLowering::emitStackProbeInlineWindowsCoreCLR64(
774 MF.
insert(MBBIter, RoundMBB);
775 MF.
insert(MBBIter, LoopMBB);
776 MF.
insert(MBBIter, ContinueMBB);
784 const int64_t ThreadEnvironmentStackLimit = 0x10;
786 const int64_t PageMask = ~(
PageSize - 1);
792 const Register SizeReg = InProlog ? X86::RAX
794 ZeroReg = InProlog ? X86::RCX
796 CopyReg = InProlog ? X86::RDX
798 TestReg = InProlog ? X86::RDX
800 FinalReg = InProlog ? X86::RDX
802 RoundedReg = InProlog ? X86::RDX
804 LimitReg = InProlog ? X86::RCX
806 JoinReg = InProlog ? X86::RCX
808 ProbeReg = InProlog ? X86::RCX
812 int64_t RCXShadowSlot = 0;
813 int64_t RDXShadowSlot = 0;
829 int64_t InitSlot = 8 + CalleeSaveSize + (
HasFP ? 8 : 0);
833 RCXShadowSlot = InitSlot;
835 RDXShadowSlot = InitSlot;
836 if (IsRDXLiveIn && IsRCXLiveIn)
877 .
addImm(ThreadEnvironmentStackLimit)
885 BuildMI(RoundMBB,
DL,
TII.get(X86::AND64ri32), RoundedReg)
926 TII.get(X86::MOV64rm), X86::RCX),
927 X86::RSP,
false, RCXShadowSlot);
930 TII.get(X86::MOV64rm), X86::RDX),
931 X86::RSP,
false, RDXShadowSlot);
937 BuildMI(*ContinueMBB, ContinueMBBI,
DL,
TII.get(X86::SUB64rr), X86::RSP)
950 for (++BeforeMBBI; BeforeMBBI !=
MBB.
end(); ++BeforeMBBI) {
960 CMBBI != ContinueMBBI; ++CMBBI) {
970 bool InProlog)
const {
976 "code model and indirect thunks not yet implemented.");
980 CallOp = IsLargeCodeModel ? X86::CALL64r : X86::CALL64pcrel32;
982 CallOp = X86::CALLpcrel32;
1024 for (++ExpansionMBBI; ExpansionMBBI !=
MBBI; ++ExpansionMBBI)
1032 const uint64_t Win64MaxSEHOffset = 128;
1033 uint64_t SEHFrameOffset =
std::min(SPAdjust, Win64MaxSEHOffset);
1035 return SEHFrameOffset & -16;
1042 uint64_t X86FrameLowering::calculateMaxStackAlign(
const MachineFunction &MF)
const {
1052 return MaxAlign.
value();
1058 uint64_t MaxAlign)
const {
1059 uint64_t Val = -MaxAlign;
1066 const bool EmitInlineStackProbe = TLI.hasInlineStackProbe(MF);
1071 if (
Reg ==
StackPtr && EmitInlineStackProbe && MaxAlign >= StackProbeSize) {
1073 NumFrameLoopProbe++;
1084 MF.
insert(MBBIter, entryMBB);
1085 MF.
insert(MBBIter, headMBB);
1086 MF.
insert(MBBIter, bodyMBB);
1087 MF.
insert(MBBIter, footMBB);
1088 const unsigned MovMIOpc =
Is64Bit ? X86::MOV64mi32 : X86::MOV32mi;
1095 BuildMI(entryMBB,
DL,
TII.get(TargetOpcode::COPY), FinalStackProbed)
1099 BuildMI(entryMBB,
DL,
TII.get(AndOp), FinalStackProbed)
1100 .
addReg(FinalStackProbed)
1105 MI->getOperand(3).setIsDead();
1109 .
addReg(FinalStackProbed)
1123 const unsigned SUBOpc =
1132 .
addReg(FinalStackProbed)
1154 const unsigned SUBOpc =
1164 .
addReg(FinalStackProbed)
1180 .
addReg(FinalStackProbed)
1202 MI->getOperand(3).setIsDead();
1210 "MF used frame lowering for wrong subtarget");
1216 bool X86FrameLowering::isWin64Prologue(
const MachineFunction &MF)
const {
1220 bool X86FrameLowering::needsDwarfCFI(
const MachineFunction &MF)
const {
1312 "MF used frame lowering for wrong subtarget");
1318 uint64_t MaxAlign = calculateMaxStackAlign(MF);
1324 bool FnHasClrFunclet =
1326 bool IsClrFunclet = IsFunclet && FnHasClrFunclet;
1327 bool HasFP =
hasFP(MF);
1328 bool IsWin64Prologue = isWin64Prologue(MF);
1333 bool NeedsWinCFI = NeedsWin64CFI || NeedsWinFPO;
1334 bool NeedsDwarfCFI = needsDwarfCFI(MF);
1340 bool HasWinCFI =
false;
1348 if (TailCallReturnAddrDelta && IsWin64Prologue)
1351 if (TailCallReturnAddrDelta < 0)
1355 const bool EmitStackProbeCall =
1377 !EmitStackProbeCall &&
1383 StackSize =
std::max(MinSize, StackSize > 128 ? StackSize - 128 : 0);
1390 if (TailCallReturnAddrDelta < 0) {
1391 BuildStackAdjustment(
MBB,
MBBI,
DL, TailCallReturnAddrDelta,
1410 uint64_t NumBytes = 0;
1414 Register Establisher = X86::NoRegister;
1420 if (IsWin64Prologue && IsFunclet && !IsClrFunclet) {
1435 uint64_t FrameSize = StackSize -
SlotSize;
1443 if (
TRI->hasStackRealignment(MF) && !IsWin64Prologue)
1444 NumBytes =
alignTo(NumBytes, MaxAlign);
1451 if (NeedsDwarfCFI) {
1459 unsigned DwarfFramePtr =
TRI->getDwarfRegNum(MachineFramePtr,
true);
1461 nullptr, DwarfFramePtr, 2 * stackGrowth));
1471 if (!IsWin64Prologue && !IsFunclet) {
1479 if (NeedsDwarfCFI) {
1482 unsigned DwarfFramePtr =
TRI->getDwarfRegNum(MachineFramePtr,
true);
1484 nullptr, DwarfFramePtr));
1497 assert(!IsFunclet &&
"funclets without FPs not yet implemented");
1504 if (HasFP &&
TRI->hasStackRealignment(MF))
1512 unsigned ParentFrameNumBytes = NumBytes;
1514 NumBytes = getWinEHFuncletFrameSize(MF);
1517 bool PushedRegs =
false;
1522 (
MBBI->getOpcode() == X86::PUSH32r ||
1523 MBBI->getOpcode() == X86::PUSH64r)) {
1528 if (!HasFP && NeedsDwarfCFI) {
1548 if (!IsWin64Prologue && !IsFunclet &&
TRI->hasStackRealignment(MF)) {
1549 assert(HasFP &&
"There should be a frame pointer if stack is realigned.");
1575 uint64_t AlignedNumBytes = NumBytes;
1576 if (IsWin64Prologue && !IsFunclet &&
TRI->hasStackRealignment(MF))
1577 AlignedNumBytes =
alignTo(AlignedNumBytes, MaxAlign);
1578 if (AlignedNumBytes >= StackProbeSize && EmitStackProbeCall) {
1580 "The Red Zone is not accounted for in stack probes");
1602 int64_t Alloc = isEAXAlive ? NumBytes - 8 : NumBytes;
1620 .
addImm(isEAXAlive ? NumBytes - 4 : NumBytes)
1639 }
else if (NumBytes) {
1643 if (NeedsWinCFI && NumBytes) {
1650 int SEHFrameOffset = 0;
1651 unsigned SPOrEstablisher;
1658 unsigned PSPSlotOffset = getPSPSlotOffsetFromSP(MF);
1662 Establisher,
false, PSPSlotOffset)
1669 false, PSPSlotOffset)
1676 SPOrEstablisher = Establisher;
1681 if (IsWin64Prologue && HasFP) {
1688 SPOrEstablisher,
false, SEHFrameOffset);
1691 .
addReg(SPOrEstablisher);
1694 if (NeedsWinCFI && !IsFunclet) {
1695 assert(!NeedsWinFPO &&
"this setframe incompatible with FPO data");
1731 if (IsWin64Prologue && IsFunclet)
1739 assert(!NeedsWinFPO &&
"SEH_SaveXMM incompatible with FPO data");
1749 if (NeedsWinCFI && HasWinCFI)
1753 if (FnHasClrFunclet && !IsFunclet) {
1757 unsigned PSPSlotOffset = getPSPSlotOffsetFromSP(MF);
1771 if (IsWin64Prologue &&
TRI->hasStackRealignment(MF)) {
1772 assert(HasFP &&
"There should be a frame pointer if stack is realigned.");
1773 BuildStackAlignAND(
MBB,
MBBI,
DL, SPOrEstablisher, MaxAlign);
1810 assert(UsedReg == BasePtr);
1817 if (((!HasFP && NumBytes) || PushedRegs) && NeedsDwarfCFI) {
1819 if (!HasFP && NumBytes) {
1859 switch (
MI.getOpcode()) {
1883 X86FrameLowering::getPSPSlotOffsetFromSP(
const MachineFunction &MF)
const {
1890 return static_cast<unsigned>(
Offset);
1894 X86FrameLowering::getWinEHFuncletFrameSize(
const MachineFunction &MF)
const {
1900 unsigned XMMSize = WinEHXMMSlotInfo.
size() *
1901 TRI->getSpillSize(X86::VR128RegClass);
1910 UsedSize = getPSPSlotOffsetFromSP(MF) +
SlotSize;
1921 return FrameSizeMinusRBP + XMMSize - CSSize;
1925 return Opc == X86::TCRETURNri || Opc == X86::TCRETURNdi ||
1926 Opc == X86::TCRETURNmi ||
1927 Opc == X86::TCRETURNri64 || Opc == X86::TCRETURNdi64 ||
1928 Opc == X86::TCRETURNmi64;
1939 DL =
MBBI->getDebugLoc();
1947 bool NeedsWin64CFI =
1953 uint64_t MaxAlign = calculateMaxStackAlign(MF);
1955 bool HasFP =
hasFP(MF);
1956 uint64_t NumBytes = 0;
1963 assert(HasFP &&
"EH funclets without FP not yet implemented");
1964 NumBytes = getWinEHFuncletFrameSize(MF);
1967 uint64_t FrameSize = StackSize -
SlotSize;
1968 NumBytes = FrameSize - CSSize;
1972 if (
TRI->hasStackRealignment(MF) && !IsWin64Prologue)
1973 NumBytes =
alignTo(FrameSize, MaxAlign);
1975 NumBytes = StackSize - CSSize;
1977 uint64_t SEHStackAllocAmt = NumBytes;
1986 if (NeedsDwarfCFI) {
1987 unsigned DwarfStackPtr =
1992 unsigned DwarfFramePtr =
TRI->getDwarfRegNum(MachineFramePtr,
true);
2006 unsigned Opc = PI->getOpcode();
2008 if (Opc != X86::DBG_VALUE && !PI->isTerminator()) {
2023 DL =
MBBI->getDebugLoc();
2036 if (
TRI->hasStackRealignment(MF))
2039 uint64_t LEAAmount =
2040 IsWin64Prologue ? SEHStackAllocAmt - SEHFrameOffset : -CSSize;
2049 if (LEAAmount != 0) {
2052 FramePtr,
false, LEAAmount);
2060 }
else if (NumBytes) {
2063 if (!
hasFP(MF) && NeedsDwarfCFI) {
2080 if (!
hasFP(MF) && NeedsDwarfCFI) {
2087 unsigned Opc = PI->getOpcode();
2089 if (Opc == X86::POP32r || Opc == X86::POP64r) {
2107 assert(
Offset >= 0 &&
"TCDelta should never be positive");
2136 else if (
TRI->hasStackRealignment(MF))
2149 bool HasFP =
hasFP(MF);
2151 int64_t FPDelta = 0;
2162 if (IsWin64Prologue) {
2166 uint64_t FrameSize = StackSize -
SlotSize;
2170 uint64_t NumBytes = FrameSize - CSSize;
2180 FPDelta = FrameSize - SEHFrameOffset;
2182 "FPDelta isn't aligned per the Win64 ABI!");
2187 assert(HasFP &&
"VLAs and dynamic stack realign, but no FP?!");
2195 }
else if (
TRI->hasStackRealignment(MF)) {
2213 if (TailCallReturnAddrDelta < 0)
2214 Offset -= TailCallReturnAddrDelta;
2225 const auto it = WinEHXMMSlotInfo.find(FI);
2227 if (
it == WinEHXMMSlotInfo.end())
2238 int Adjustment)
const {
2248 bool IgnoreSPUpdates)
const {
2298 "we don't handle this case!");
2330 std::vector<CalleeSavedInfo> &CSI)
const {
2334 unsigned CalleeSavedFrameSize = 0;
2335 unsigned XMMCalleeSavedFrameSize = 0;
2341 if (TailCallReturnAddrDelta < 0) {
2352 TailCallReturnAddrDelta -
SlotSize,
true);
2356 if (this->TRI->hasBasePointer(MF)) {
2374 for (
unsigned i = 0;
i < CSI.size(); ++
i) {
2375 if (
TRI->regsOverlap(CSI[
i].getReg(),FPReg)) {
2376 CSI.erase(CSI.begin() +
i);
2383 for (
unsigned i = CSI.size();
i != 0; --
i) {
2384 unsigned Reg = CSI[
i - 1].getReg();
2400 for (
unsigned i = CSI.size();
i != 0; --
i) {
2401 unsigned Reg = CSI[
i - 1].getReg();
2411 unsigned Size =
TRI->getSpillSize(*RC);
2412 Align Alignment =
TRI->getSpillAlign(*RC);
2414 assert(SpillSlotOffset < 0 &&
"SpillSlotOffset should always < 0 on X86");
2415 SpillSlotOffset = -
alignTo(-SpillSlotOffset, Alignment);
2418 SpillSlotOffset -=
Size;
2425 WinEHXMMSlotInfo[
SlotIndex] = XMMCalleeSavedFrameSize;
2426 XMMCalleeSavedFrameSize +=
Size;
2445 unsigned Opc =
STI.
is64Bit() ? X86::PUSH64r : X86::PUSH32r;
2446 for (
unsigned i = CSI.
size();
i != 0; --
i) {
2447 unsigned Reg = CSI[
i - 1].getReg();
2458 bool CanKill = !isLiveIn;
2480 for (
unsigned i = CSI.
size();
i != 0; --
i) {
2481 unsigned Reg = CSI[
i-1].getReg();
2510 "SEH should not use CATCHRET");
2559 for (
unsigned i = 0,
e = CSI.
size();
i !=
e; ++
i) {
2560 unsigned Reg = CSI[
i].getReg();
2575 unsigned Opc =
STI.
is64Bit() ? X86::POP64r : X86::POP32r;
2576 for (
unsigned i = 0,
e = CSI.
size();
i !=
e; ++
i) {
2577 unsigned Reg = CSI[
i].getReg();
2598 SavedRegs.
set(BasePtr);
2607 if (
I->hasNestAttr() && !
I->use_empty())
2624 return Primary ? X86::R14 : X86::R13;
2631 return Primary ? X86::R11 : X86::R12;
2633 return Primary ? X86::R11D : X86::R12D;
2643 "nested function.");
2659 unsigned TlsReg, TlsOffset;
2664 assert(&(*MF.
begin()) == &PrologueMBB &&
"Shrink-wrapping not supported yet");
2668 "Scratch register is live-in");
2697 bool IsNested =
false;
2706 for (
const auto &LI : PrologueMBB.
liveins()) {
2725 TlsOffset =
IsLP64 ? 0x70 : 0x40;
2728 TlsOffset = 0x60 + 90*8;
2742 if (CompareStackPointer)
2756 TlsOffset = 0x48 + 90*4;
2769 if (CompareStackPointer)
2782 unsigned ScratchReg2;
2784 if (CompareStackPointer) {
2787 SaveScratch2 =
false;
2799 "Scratch register is live-in and not saved");
2805 BuildMI(checkMBB,
DL,
TII.get(X86::MOV32ri), ScratchReg2)
2814 BuildMI(checkMBB,
DL,
TII.get(X86::POP32r), ScratchReg2);
2829 const unsigned Reg10 =
IsLP64 ? X86::R10 : X86::R10D;
2830 const unsigned Reg11 =
IsLP64 ? X86::R11 : X86::R11D;
2831 const unsigned MOVrr =
IsLP64 ? X86::MOV64rr : X86::MOV32rr;
2832 const unsigned MOVri =
IsLP64 ? X86::MOV64ri : X86::MOV32ri;
2867 "code model and thunks not yet implemented.");
2885 BuildMI(allocMBB,
DL,
TII.get(X86::MORESTACK_RET_RESTORE_R10));
2894 #ifdef EXPENSIVE_CHECKS
2907 if (Node->getNumOperands() != 2)
continue;
2908 MDString *NodeName = dyn_cast<MDString>(Node->getOperand(0));
2909 ValueAsMetadata *NodeVal = dyn_cast<ValueAsMetadata>(Node->getOperand(1));
2910 if (!NodeName || !NodeVal)
continue;
2912 if (ValConst && NodeName->
getString() == LiteralName) {
2918 +
" required but not provided");
2929 return MI.isMetaInstruction();
2955 assert(&(*MF.
begin()) == &PrologueMBB &&
"Shrink-wrapping not supported yet");
2960 if (!HiPELiteralsMD)
2962 "Can't generate HiPE prologue without runtime parameters");
2963 const unsigned HipeLeafWords
2965 Is64Bit ?
"AMD64_LEAF_WORDS" :
"X86_LEAF_WORDS");
2966 const unsigned CCRegisteredArgs =
Is64Bit ? 6 : 5;
2967 const unsigned Guaranteed = HipeLeafWords *
SlotSize;
2973 "HiPE prologue is only supported on Linux operating systems.");
2983 unsigned MoreStackForCalls = 0;
2985 for (
auto &
MBB : MF) {
2986 for (
auto &
MI :
MBB) {
3011 unsigned CalleeStkArity =
3012 F->arg_size() > CCRegisteredArgs ?
F->arg_size()-CCRegisteredArgs : 0;
3013 if (HipeLeafWords - 1 > CalleeStkArity)
3014 MoreStackForCalls =
std::max(MoreStackForCalls,
3015 (HipeLeafWords - 1 - CalleeStkArity) *
SlotSize);
3018 MaxStack += MoreStackForCalls;
3023 if (MaxStack > Guaranteed) {
3027 for (
const auto &LI : PrologueMBB.
liveins()) {
3035 unsigned ScratchReg, SPReg, PReg, SPLimitOffset;
3036 unsigned LEAop, CMPop, CALLop;
3041 LEAop = X86::LEA64r;
3042 CMPop = X86::CMP64rm;
3043 CALLop = X86::CALL64pcrel32;
3047 LEAop = X86::LEA32r;
3048 CMPop = X86::CMP32rm;
3049 CALLop = X86::CALLpcrel32;
3054 "HiPE prologue scratch register is live-in");
3058 SPReg,
false, -MaxStack);
3061 .
addReg(ScratchReg), PReg,
false, SPLimitOffset);
3066 addExternalSymbol(
"inc_stack_0");
3068 SPReg,
false, -MaxStack);
3070 .
addReg(ScratchReg), PReg,
false, SPLimitOffset);
3078 #ifdef EXPENSIVE_CHECKS
3095 if (NumPops != 1 && NumPops != 2)
3103 if (!Prev->isCall() || !Prev->getOperand(1).isRegMask())
3107 unsigned FoundRegs = 0;
3113 Is64Bit ? X86::GR64_NOREX_NOSPRegClass : X86::GR32_NOREX_NOSPRegClass;
3115 for (
auto Candidate : RegClass) {
3128 if (MO.isReg() && MO.isDef() &&
3129 TRI->isSuperOrSubRegisterEq(MO.getReg(), Candidate)) {
3138 Regs[FoundRegs++] = Candidate;
3139 if (FoundRegs == (
unsigned)NumPops)
3147 while (FoundRegs < (
unsigned)NumPops)
3148 Regs[FoundRegs++] = Regs[0];
3150 for (
int i = 0;
i < NumPops; ++
i)
3161 unsigned Opcode =
I->getOpcode();
3162 bool isDestroy = Opcode ==
TII.getCallFrameDestroyOpcode();
3164 uint64_t Amount =
TII.getFrameSize(*
I);
3175 if (!reserveCallFrame) {
3196 bool HasDwarfEHHandlers = !WindowsCFI && !MF.
getLandingPads().empty();
3198 if (HasDwarfEHHandlers && !isDestroy &&
3208 Amount -= InternalAmt;
3228 if (!(
F.hasMinSize() &&
3246 if (CfaAdjustment) {
3259 while (CI !=
B && !std::prev(CI)->isCall())
3261 BuildStackAdjustment(
MBB, CI,
DL, -InternalAmt,
false);
3270 return !
TRI->hasStackRealignment(MF) || !
MBB.
isLiveIn(X86::EFLAGS);
3296 bool CompactUnwind =
3316 "restoring EBP/ESI on non-32-bit target");
3328 int EHRegSize = MFI.getObjectSize(FI);
3333 X86::EBP,
true, -EHRegSize)
3339 int EndOffset = -EHRegOffset - EHRegSize;
3342 if (UsedReg == FramePtr) {
3352 "end of registration object above normal EBP position!");
3353 }
else if (UsedReg == BasePtr) {
3356 FramePtr,
false, EndOffset)
3363 assert(UsedReg == BasePtr);
3384 struct X86FrameSortingObject {
3385 bool IsValid =
false;
3386 unsigned ObjectIndex = 0;
3387 unsigned ObjectSize = 0;
3389 unsigned ObjectNumUses = 0;
3405 struct X86FrameSortingComparator {
3406 inline bool operator()(
const X86FrameSortingObject &A,
3407 const X86FrameSortingObject &
B)
const {
3408 uint64_t DensityAScaled, DensityBScaled;
3428 DensityAScaled =
static_cast<uint64_t
>(A.ObjectNumUses) *
3429 static_cast<uint64_t
>(
B.ObjectSize);
3430 DensityBScaled =
static_cast<uint64_t
>(
B.ObjectNumUses) *
3431 static_cast<uint64_t
>(A.ObjectSize);
3441 if (DensityAScaled == DensityBScaled)
3442 return A.ObjectAlignment <
B.ObjectAlignment;
3444 return DensityAScaled < DensityBScaled;
3458 if (ObjectsToAllocate.empty())
3470 for (
auto &Obj : ObjectsToAllocate) {
3471 SortingObjects[Obj].IsValid =
true;
3472 SortingObjects[Obj].ObjectIndex = Obj;
3476 if (ObjectSize == 0)
3478 SortingObjects[Obj].ObjectSize = 4;
3480 SortingObjects[Obj].ObjectSize = ObjectSize;
3484 for (
auto &
MBB : MF) {
3485 for (
auto &
MI :
MBB) {
3486 if (
MI.isDebugInstr())
3492 int Index = MO.getIndex();
3496 SortingObjects[
Index].IsValid)
3497 SortingObjects[
Index].ObjectNumUses++;
3512 for (
auto &Obj : SortingObjects) {
3516 ObjectsToAllocate[
i++] = Obj.ObjectIndex;
3520 if (!
TRI->hasStackRealignment(MF) &&
hasFP(MF))
3521 std::reverse(ObjectsToAllocate.begin(), ObjectsToAllocate.end());
3533 Offset += getWinEHFuncletFrameSize(MF);
3553 adjustFrameForMsvcCxxEh(MF);
3557 void X86FrameLowering::adjustFrameForMsvcCxxEh(
MachineFunction &MF)
const {
3565 int64_t MinFixedObjOffset = -
SlotSize;
3583 MinFixedObjOffset -=
std::abs(MinFixedObjOffset) % 8;
3584 int64_t UnwindHelpOffset = MinFixedObjOffset -
SlotSize;
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
bool hasReservedCallFrame(const MachineFunction &MF) const override
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
bool isAsynchronousEHPersonality(EHPersonality Pers)
Returns true if this personality function catches asynchronous exceptions.
static unsigned getADDriOpcode(bool IsLP64, int64_t Imm)
bool canUseAsEpilogue(const MachineBasicBlock &MBB) const override
Check whether or not the given MBB can be used as a epilogue for the target.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
This class represents an incoming formal argument to a Function.
const MCObjectFileInfo * getObjectFileInfo() const
const X86RegisterInfo * TRI
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
unsigned getArgumentStackSize() const
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.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
static unsigned calculateSetFPREG(uint64_t SPAdjust)
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const override
spillCalleeSavedRegisters - Issues instruction(s) to spill all callee saved registers and returns tru...
bool isLiveIn(MCPhysReg Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
bool hasStackProbeSymbol(MachineFunction &MF) const override
Returns true if stack probing through a function call is requested.
bool getRestoreBasePointer() const
Information about stack frame layout on the target.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
unsigned getNumOperands() const
const MCContext & getContext() const
const GlobalValue * getGlobal() const
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
bool isTargetLinux() const
const MCRegisterInfo * getRegisterInfo() const
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register.
const X86InstrInfo * getInstrInfo() const override
static bool is64Bit(const char *name)
const MachineInstrBuilder & addCFIIndex(unsigned CFIIndex) const
bool hasCopyImplyingStackAdjustment() const
Returns true if the function contains operations which will lower down to instructions which manipula...
Reference model for inliner Oz decision policy Note this model is also referenced by test Transforms Inline ML tests if replacing it
bool isEHFuncletEntry() const
Returns true if this is the entry block of an EH funclet.
return AArch64::GPR64RegClass contains(Reg)
void setCVBytesOfCalleeSavedRegisters(unsigned S)
static constexpr size_t npos
unsigned isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
unsigned getCodeViewFlag() const
Returns the CodeView Version by checking module flags.
void setCalleeSavedFrameSize(unsigned bytes)
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
Register getFrameRegister(const MachineFunction &MF) const override
static void recomputeLiveIns(MachineBasicBlock &MBB)
Convenience function for recomputing live-in's for MBB.
bool isTarget64BitILP32() const
Is this x86_64 with the ILP32 programming model (x32 ABI)?
static bool isEAXLiveIn(MachineBasicBlock &MBB)
bool assignCalleeSavedSpillSlots(MachineFunction &MF, const TargetRegisterInfo *TRI, std::vector< CalleeSavedInfo > &CSI) const override
assignCalleeSavedSpillSlots - Allows target to override spill slot assignment logic.
bool isReturnBlock() const
Convenience function that returns true if the block ends in a return instruction.
bool enableShrinkWrapping(const MachineFunction &MF) const override
Returns true if the target will correctly handle shrink wrapping.
DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any DBG_VALUE and DBG_LABEL instructions.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
static unsigned getSUBrrOpcode(bool IsLP64)
unsigned getStackProbeSize(MachineFunction &MF) const
void push_front(MachineBasicBlock *MBB)
ScalarTy getFixed() const
void setHasSEHFramePtrSave(bool V)
SmallVector< WinEHTryBlockMapEntry, 4 > TryBlockMap
static BranchProbability getZero()
iterator_range< livein_iterator > liveins() const
void setStackSize(uint64_t Size)
Set the size of the stack.
auto reverse(ContainerTy &&C, std::enable_if_t< has_rbegin< ContainerTy >::value > *=nullptr)
void orderFrameObjects(const MachineFunction &MF, SmallVectorImpl< int > &ObjectsToAllocate) const override
Order the symbols in the local stack.
static unsigned getANDriOpcode(bool IsLP64, int64_t Imm)
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],...
void insert(iterator MBBI, MachineBasicBlock *MBB)
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 hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
bool callsUnwindInit() const
int getRestoreBasePointerOffset() const
bool canUseAsPrologue(const MachineBasicBlock &MBB) const override
Check whether or not the given MBB can be used as a prologue for the target.
static bool HasNestArgument(const MachineFunction *MF)
int getObjectIndexEnd() const
Return one past the maximum frame object index.
iterator_range< iterator > terminators()
bool isTargetWin64() const
unsigned const TargetRegisterInfo * TRI
unsigned getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
bool empty() const
empty - Check if the array is empty.
bool has128ByteRedZone(const MachineFunction &MF) const
Return true if the function has a redzone (accessible bytes past the frame of the top of stack functi...
static MCCFIInstruction cfiDefCfaOffset(MCSymbol *L, int Offset)
.cfi_def_cfa_offset modifies a rule for computing CFA.
unsigned getUndefRegState(bool B)
static bool isTailCallOpcode(unsigned Opc)
LLVM Basic Block Representation.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
static bool flagsNeedToBePreservedBeforeTheTerminators(const MachineBasicBlock &MBB)
Check if the flags need to be preserved before the terminators.
bool hasStackObjects() const
Return true if there are any stack objects in this function.
bool getHasPushSequences() const
@ Tail
Tail - This calling convention attemps to make calls as fast as possible while guaranteeing that tail...
StackOffset getFrameIndexReferencePreferSP(const MachineFunction &MF, int FI, Register &FrameReg, bool IgnoreSPUpdates) const override
Same as getFrameIndexReference, except that the stack pointer (as opposed to the frame pointer) will ...
bool hasPreallocatedCall() const
static unsigned getADDrrOpcode(bool IsLP64)
EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
static unsigned getLEArOpcode(bool IsLP64)
void restoreWinEHStackPointersInParent(MachineFunction &MF) const
This is the shared class of boolean and integer constants.
unsigned getDefRegState(bool B)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
const MachineBasicBlock & front() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
TargetInstrInfo - Interface to description of machine instruction set.
int getOffsetOfLocalArea() const
getOffsetOfLocalArea - This method returns the offset of the local area from the stack pointer on ent...
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)
IterT skipDebugInstructionsBackward(IterT It, IterT Begin, bool SkipPseudoOp=false)
Decrement It until it points to a non-debug instruction or to Begin and return the resulting iterator...
int getWin64EHFrameIndexRef(const MachineFunction &MF, int FI, Register &SPReg) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
bool needsFrameIndexResolution(const MachineFunction &MF) const override
void setSEHFramePtrSaveIndex(int Index)
StackOffset getFrameIndexReferenceSP(const MachineFunction &MF, int FI, Register &SPReg, int Adjustment) const
void ensureMaxAlignment(Align Alignment)
Make sure the function is at least Align bytes aligned.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
bool isOSDarwin() const
isOSDarwin - Is this a "Darwin" OS (macOS, iOS, tvOS or watchOS).
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
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.
bool isTargetWin32() const
@ CATCHRET
CATCHRET - Represents a return from a catch block funclet.
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
const MachineOperand & getOperand(unsigned i) const
bool isReserved(MCRegister PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
int getTCReturnAddrDelta() const
Register getFramePtr() const
Returns physical register used as frame pointer.
unsigned getCalleeSavedFrameSize() const
bool canUseLEAForSPInEpilogue(const MachineFunction &MF) const
Check that LEA can be used on SP in an epilogue sequence for MF.
Register getBaseRegister() const
bool isTargetWindowsCoreCLR() const
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...
MCSection * getCompactUnwindSection() const
const HexagonInstrInfo * TII
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
uint64_t alignDown(uint64_t Value, uint64_t Align, uint64_t Skew=0)
Returns the largest uint64_t less than or equal to Value and is Skew mod Align.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
MachineOperand class - Representation of each machine instruction operand.
Pair of physical register and lane mask.
STATISTIC(NumFrameLoopProbe, "Number of loop stack probes used in prologue")
Flag
These should be considered private to the implementation of the MCInstrDesc class.
This class contains meta information specific to a module.
@ X86_INTR
X86_INTR - x86 hardware interrupt context.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
void processFunctionBeforeFrameIndicesReplaced(MachineFunction &MF, RegScavenger *RS) const override
processFunctionBeforeFrameIndicesReplaced - This method is called immediately before MO_FrameIndex op...
bool hasPersonalityFn() const
Check whether this function has a personality function.
bool shouldSplitStack() const
Should we be emitting segmented stack stuff for the function.
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
@ Define
Register definition.
void setHasWinCFI(bool v)
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
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.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
Analysis containing CSE Info
bool isCleanupFuncletEntry() const
Returns true if this is the entry block of a cleanup funclet.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
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.
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
This struct is a compact representation of a valid (non-zero power of two) alignment.
int getObjectIndexBegin() const
Return the minimum frame object index.
SlotIndex - An opaque wrapper around machine indexes.
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
bool hasInlineStackProbe(MachineFunction &MF) const override
Returns true if stack probing through inline assembly is requested.
@ Kill
The last use of a register.
void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS) const override
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register)
.cfi_def_cfa_register modifies a rule for computing CFA.
bool isTarget64BitLP64() const
Is this x86_64 with the LP64 programming model (standard AMD64, no x32)?
int CreateSpillStackObject(uint64_t Size, Align Alignment)
Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...
bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
MachineModuleInfo & getMMI() const
constexpr bool isInt< 8 >(int64_t x)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
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.
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
static bool clobbersPhysReg(const uint32_t *RegMask, MCRegister PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
int CreateFixedSpillStackObject(uint64_t Size, int64_t SPOffset, bool IsImmutable=false)
Create a spill slot at a fixed location on the stack.
constexpr bool isInt< 32 >(int64_t x)
void setIsDead(bool Val=true)
Representation of each machine instruction.
bool callsEHReturn() const
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
bool getUsesRedZone() const
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
static MCCFIInstruction createGnuArgsSize(MCSymbol *L, int Size)
A special wrapper for .cfi_escape that indicates GNU_ARGS_SIZE.
MCRegister getX86SubSuperRegister(MCRegister, unsigned, bool High=false)
Returns the sub or super register of a specific X86 register.
AMD64 Optimization Manual has some nice information about optimizing integer multiplication by a constant How much of it applies to Intel s X86 implementation There are definite trade offs to xmm0 cvttss2siq rdx jb L3 subss xmm0 rax cvttss2siq rdx xorq rdx rax ret instead of xmm1 cvttss2siq rcx movaps xmm2 subss xmm2 cvttss2siq rax rdx xorq rax ucomiss xmm0 cmovb rax ret Seems like the jb branch has high likelihood of being taken It would have saved a few instructions It s not possible to reference AH
DenseMap< int, unsigned > & getWinEHXMMSlotInfo()
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, MutableArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const override
restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee saved registers and returns...
@ Fast
Fast - This calling convention attempts to make calls as fast as possible (e.g.
This class contains a discriminated union of information about pointers in memory operands,...
IterT skipDebugInstructionsForward(IterT It, IterT End, bool SkipPseudoOp=false)
Increment It until it points to a non-debug instruction or to End and return the resulting iterator.
SmallVector< WinEHHandlerType, 1 > HandlerArray
@ CLEANUPRET
CLEANUPRET - Represents a return from a cleanup block funclet.
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
void setObjectOffset(int ObjectIdx, int64_t SPOffset)
Set the stack frame offset of the specified object.
iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
constexpr bool isUInt< 32 >(uint64_t x)
MDNode * getOperand(unsigned i) const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
const X86TargetLowering * getTargetLowering() const override
void setHasAddressTaken()
Set this block to reflect that it potentially is the target of an indirect branch.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
int mergeSPUpdates(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, bool doMergeWithPrevious) const
Check the instruction before/after the passed instruction.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
static bool blockEndIsUnreachable(const MachineBasicBlock &MBB, MachineBasicBlock::const_iterator MBBI)
const std::vector< LandingPadInfo > & getLandingPads() const
Return a reference to the landing pad info for the current function.
X86MachineFunctionInfo - This class is derived from MachineFunction and contains private X86 target-s...
static MCCFIInstruction cfiDefCfa(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.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
bool isTargetDragonFly() 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 setHasNosplitStack(bool b)
static BranchProbability getOne()
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
bool isTargetDarwin() const
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool hasPatchPoint() const
This method may be called any time after instruction selection is complete to determine if there is a...
MachineBasicBlock * getMBB() const
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
iterator_range< succ_iterator > successors()
bool isEHPad() const
Returns true if the block is a landing pad.
StringRef - Represent a constant reference to a string, i.e.
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 '...
MachineBasicBlock MachineBasicBlock::iterator MBBI
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
StackOffset is a class to represent an offset with 2 dimensions, named fixed and scalable,...
self_iterator getIterator()
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
void emitStackProbe(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, bool InProlog) const
Emit target stack probe code.
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...
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
void adjustForSegmentedStacks(MachineFunction &MF, MachineBasicBlock &PrologueMBB) const override
Adjust the prologue to have the function use segmented stacks.
@ MOVolatile
The memory access is volatile.
static StackOffset getFixed(ScalarTy Fixed)
@ MOLoad
The memory access reads data.
unsigned const MachineRegisterInfo * MRI
Align getMaxAlign() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
int64_t getFrameAdjustment(const MachineInstr &I) const
Returns the stack pointer adjustment that happens inside the frame setup..destroy sequence (e....
Wrapper class representing virtual and physical registers.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
bool isFrameAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
bool hasCalls() const
Return true if the current function has any function calls.
bool isOSWindows() const
Tests whether the OS is Windows.
bool isTargetFreeBSD() const
void stable_sort(R &&Range)
bool isLiveIn(Register Reg) const
unsigned getNumRegs() const
Return the number of registers in this class.
Function & getFunction()
Return the LLVM function that this machine code represents.
bool needsFrameMoves() const
True if this function needs frame moves for debug or exceptions.
bool isTargetWindowsMSVC() const
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
bool isCallingConvWin64(CallingConv::ID CC) const
unsigned findDeadCallerSavedReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI) const
findDeadCallerSavedReg - Return a caller-saved register that isn't live when it reaches the "return" ...
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
Iterator for intrusive lists based on ilist_node.
uint64_t value() const
This is a hole in the type system and should not be abused.
const WinEHFuncInfo * getWinEHFuncInfo() const
getWinEHFuncInfo - Return information about how the current function uses Windows exception handling.
void inlineStackProbe(MachineFunction &MF, MachineBasicBlock &PrologMBB) const override
Replace a StackProbe inline-stub with the actual probe code inline.
@ Undef
Value of the register doesn't matter.
bool hasBasePointer(const MachineFunction &MF) const
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
void setUsesRedZone(bool V)
bool needsUnwindTableEntry() const
True if this function needs an unwind table.
CodeModel::Model getCodeModel() const
Returns the code model.
bool getHasSEHFramePtrSave() const
Constant * getPersonalityFn() const
Get the personality function associated with this function.
bool hasEHFunclets() const
@ MOStore
The memory access writes data.
bool getForceFramePointer() const
X86FrameLowering(const X86Subtarget &STI, MaybeAlign StackAlignOverride)
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Function Alias Analysis false
unsigned getKillRegState(bool B)
LLVM_NODISCARD unsigned addFrameInst(const MCCFIInstruction &Inst)
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
static bool isFuncletReturnInstr(MachineInstr &MI)
bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override
canSimplifyCallFramePseudos - If there is a reserved call frame, the call frame pseudos can be simpli...
unsigned getSlotSize() const
uint16_t StackAdjustment(const RuntimeFunction &RF)
StackAdjustment - calculated stack adjustment in words.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool Is64Bit
Is64Bit implies that x86_64 instructions are available.
const Triple & getTargetTriple() const
StringRef getStackProbeSymbolName(MachineFunction &MF) const override
Returns the name of the symbol used to emit stack probes or the empty string if not applicable.
NamedMDNode * getNamedMetadata(const Twine &Name) const
Return the first NamedMDNode in the module with the specified name.
size_t size() const
size - Get the array size.
Align max(MaybeAlign Lhs, Align Rhs)
bool Uses64BitFramePtr
True if the 64-bit frame or stack pointer should be used.
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
bool is64Bit() const
Is this x86_64? (disregarding specific ABI / programming model)
void setOffsetAdjustment(int Adj)
Set the correction for frame offsets.
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int Offset)
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
Register getStackRegister() const
bool hasOpaqueSPAdjustment() const
Returns true if the function contains opaque dynamic stack adjustments.
const char * createExternalSymbolName(StringRef Name)
Allocate a string and populate it with the given external symbol name.
static unsigned getHiPELiteral(NamedMDNode *HiPELiteralsMD, const StringRef LiteralName)
Lookup an ERTS parameter in the !hipe.literals named metadata node.
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
bool hasStackMap() const
This method may be called any time after instruction selection is complete to determine if there is a...
@ X86_FastCall
X86_FastCall - 'fast' analog of X86_StdCall.
void setUsesMorestackAddr(bool b)
bool adjustsStack() const
Return true if this function adjusts the stack – e.g., when calling another function.
bool hasTailCall() const
Returns true if the function contains a tail call.
StringRef getString() const
bool reg_nodbg_empty(Register RegNo) const
reg_nodbg_empty - Return true if the only instructions using or defining Reg are Debug instructions.
unsigned getWinEHParentFrameOffset(const MachineFunction &MF) const override
static const uint64_t kSplitStackAvailable
bool usesWindowsCFI() const
int getSEHFramePtrSaveIndex() const
APFloat abs(APFloat X)
Returns the absolute value of the argument.
StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const override
getFrameIndexReference - This method should return the base register and offset used to reference a f...
const Module * getModule() const
bool useIndirectThunkCalls() const
@ DwarfCFI
DWARF-like instruction based exceptions.
bool isTargetNaCl64() const
static unsigned getSUBriOpcode(bool IsLP64, int64_t Imm)
int getInitialCFAOffset(const MachineFunction &MF) const override
Return initial CFA offset value i.e.
void emitCalleeSavedFrameMoves(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) const override
Emits Dwarf Info specifying offsets of callee saved registers and frame pointer.
MCRegAliasIterator enumerates all registers aliasing Reg.
Register getInitialCFARegister(const MachineFunction &MF) const override
Return initial CFA register value i.e.
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
static MCCFIInstruction createRestore(MCSymbol *L, unsigned Register)
.cfi_restore says that the rule for Register is now the same as it was at the beginning of the functi...