1//===-- SystemZFrameLowering.cpp - Frame lowering for SystemZ -------------===// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7//===----------------------------------------------------------------------===// 26// The ABI-defined register save slots, relative to the CFA (i.e. 27// incoming stack pointer + SystemZMC::ELFCallFrameSize). 29 { SystemZ::R2D, 0x10 },
30 { SystemZ::R3D, 0x18 },
31 { SystemZ::R4D, 0x20 },
32 { SystemZ::R5D, 0x28 },
33 { SystemZ::R6D, 0x30 },
34 { SystemZ::R7D, 0x38 },
35 { SystemZ::R8D, 0x40 },
36 { SystemZ::R9D, 0x48 },
37 { SystemZ::R10D, 0x50 },
38 { SystemZ::R11D, 0x58 },
39 { SystemZ::R12D, 0x60 },
40 { SystemZ::R13D, 0x68 },
41 { SystemZ::R14D, 0x70 },
42 { SystemZ::R15D, 0x78 },
43 { SystemZ::F0D, 0x80 },
44 { SystemZ::F2D, 0x88 },
45 { SystemZ::F4D, 0x90 },
46 { SystemZ::F6D, 0x98 }
50 {SystemZ::R4D, 0x00}, {SystemZ::R5D, 0x08}, {SystemZ::R6D, 0x10},
51 {SystemZ::R7D, 0x18}, {SystemZ::R8D, 0x20}, {SystemZ::R9D, 0x28},
52 {SystemZ::R10D, 0x30}, {SystemZ::R11D, 0x38}, {SystemZ::R12D, 0x40},
53 {SystemZ::R13D, 0x48}, {SystemZ::R14D, 0x50}, {SystemZ::R15D, 0x58}};
54}
// end anonymous namespace 58bool StackReal,
unsigned PointerSize)
60 PointerSize(PointerSize) {}
62std::unique_ptr<SystemZFrameLowering>
67return std::make_unique<SystemZXPLINKFrameLowering>(PtrSz);
68return std::make_unique<SystemZELFFrameLowering>(PtrSz);
72structSZFrameSortingObj {
73bool IsValid =
false;
// True if we care about this Object. 74uint32_t ObjectIndex = 0;
// Index of Object into MFI list. 75uint64_t ObjectSize = 0;
// Size of Object in bytes. 76uint32_t D12Count = 0;
// 12-bit displacement only. 77uint32_t DPairCount = 0;
// 12 or 20 bit displacement. 79typedef std::vector<SZFrameSortingObj> SZFrameObjVec;
82// TODO: Move to base class. 88// Make a vector of sorting objects to track all MFI objects and mark those 89// to be sorted as valid. 90if (ObjectsToAllocate.
size() <= 1)
93for (
auto &Obj : ObjectsToAllocate) {
94 SortingObjects[Obj].IsValid =
true;
95 SortingObjects[Obj].ObjectIndex = Obj;
99// Examine uses for each object and record short (12-bit) and "pair" 100// displacement types. 103if (
MI.isDebugInstr())
105for (
unsignedI = 0, E =
MI.getNumOperands();
I != E; ++
I) {
111 SortingObjects[Index].IsValid) {
112if (
TII->hasDisplacementPairInsn(
MI.getOpcode()))
113 SortingObjects[Index].DPairCount++;
115 SortingObjects[Index].D12Count++;
120// Sort all objects for short/paired displacements, which should be 121// sufficient as it seems like all frame objects typically are within the 122// long displacement range. Sorting works by computing the "density" as 123// Count / ObjectSize. The comparisons of two such fractions are refactored 124// by multiplying both sides with A.ObjectSize * B.ObjectSize, in order to 125// eliminate the (fp) divisions. A higher density object needs to go after 126// in the list in order for it to end up lower on the stack. 127auto CmpD12 = [](
const SZFrameSortingObj &
A,
const SZFrameSortingObj &
B) {
128// Put all invalid and variable sized objects at the end. 129if (!
A.IsValid || !
B.IsValid)
131if (!
A.ObjectSize || !
B.ObjectSize)
132returnA.ObjectSize > 0;
133uint64_t ADensityCmp =
A.D12Count *
B.ObjectSize;
134uint64_t BDensityCmp =
B.D12Count *
A.ObjectSize;
135if (ADensityCmp != BDensityCmp)
136return ADensityCmp < BDensityCmp;
137returnA.DPairCount *
B.ObjectSize <
B.DPairCount *
A.ObjectSize;
139 std::stable_sort(SortingObjects.begin(), SortingObjects.end(), CmpD12);
141// Now modify the original list to represent the final order that 144for (
auto &Obj : SortingObjects) {
145// All invalid items are sorted at the end, so it's safe to stop. 148 ObjectsToAllocate[
Idx++] = Obj.ObjectIndex;
154// The ELF ABI requires us to allocate 160 bytes of stack space for the 155// callee, with any outgoing stack arguments being placed above that. It 156// seems better to make that area a permanent feature of the frame even if 157// we're using a frame pointer. Similarly, 64-bit XPLINK requires 96 bytes 158// of stack space for the register save area. 164 std::vector<CalleeSavedInfo> &CSI)
const{
169returntrue;
// Early exit if no callee saved registers are modified! 172unsigned HighGPR = SystemZ::R15D;
174for (
auto &CS : CSI) {
178if (SystemZ::GR64BitRegClass.
contains(Reg) && StartSPOffset >
Offset) {
185 CS.setFrameIdx(FrameIdx);
187 CS.setFrameIdx(INT32_MAX);
190// Save the range of call-saved registers, for use by the 191// prologue/epilogue inserters. 194// Also save the GPR varargs, if any. R6D is call-saved, so would 195// already be included, but we also need to handle the call-clobbered 196// argument registers. 201if (StartSPOffset >
Offset) {
202 LowGPR = Reg; StartSPOffset =
Offset;
208// Create fixed stack objects for the remaining registers. 211 CurrOffset += StartSPOffset;
213for (
auto &CS : CSI) {
214if (CS.getFrameIdx() != INT32_MAX)
218unsignedSize =
TRI->getSpillSize(*RC);
220assert(CurrOffset % 8 == 0 &&
221"8-byte alignment required for for all register save slots");
222int FrameIdx = MFFrame.CreateFixedSpillStackObject(
Size, CurrOffset);
223 CS.setFrameIdx(FrameIdx);
236bool HasFP =
hasFP(MF);
240// va_start stores incoming FPR varargs in the normal way, but delegates 241// the saving of incoming GPR varargs to spillCalleeSavedRegisters(). 242// Record these pending uses, which typically include the call-saved 243// argument register R6D. 248// If there are any landing pads, entering them will modify r6/r7. 250 SavedRegs.
set(SystemZ::R6D);
251 SavedRegs.
set(SystemZ::R7D);
254// If the function requires a frame pointer, record that the hard 255// frame pointer will be clobbered. 257 SavedRegs.
set(SystemZ::R11D);
259// If the function calls other functions, record that the return 260// address register will be clobbered. 262 SavedRegs.
set(SystemZ::R14D);
264// If we are saving GPRs other than the stack pointer, we might as well 265// save and restore the stack pointer at the same time, via STMG and LMG. 266// This allows the deallocation to be done by the LMG, rather than needing 267// a separate %r15 addition. 269for (
unsignedI = 0; CSRegs[
I]; ++
I) {
270unsigned Reg = CSRegs[
I];
271if (SystemZ::GR64BitRegClass.
contains(Reg) && SavedRegs.
test(Reg)) {
272 SavedRegs.
set(SystemZ::R15D);
280Align(8),
/* StackRealignable */false, PointerSize),
283// Due to the SystemZ ABI, the DWARF CFA (Canonical Frame Address) is not 284// equal to the incoming stack pointer, but to incoming stack pointer plus 285// 160. Instead of using a Local Area Offset, the Register save area will 286// be occupied by fixed frame objects, and all offsets are actually 289// Create a mapping from register number to save slot offset. 290// These offsets are relative to the start of the register save area. 291 RegSpillOffsets.
grow(SystemZ::NUM_TARGET_REGS);
292for (
constauto &Entry : ELFSpillOffsetTable)
293 RegSpillOffsets[Entry.Reg] = Entry.Offset;
296// Add GPR64 to the save instruction being built by MIB, which is in basic 297// block MBB. IsImplicit says whether this is an explicit operand to the 298// instruction, or an implicit one that comes between the explicit start 301unsigned GPR64,
bool IsImplicit) {
306if (!IsLive || !IsImplicit) {
329"Should be saving %r15 and something else");
331// Build an STMG instruction. 334// Add the explicit register operands. 341// Make sure all call-saved GPRs are included as operands and are 342// marked as live on entry. 345if (SystemZ::GR64BitRegClass.
contains(Reg))
349// ...likewise GPR varargs. 355// Save FPRs/VRs in the normal TargetInstrInfo way. 358if (SystemZ::FP64BitRegClass.
contains(Reg)) {
363if (SystemZ::VR128BitRegClass.
contains(Reg)) {
382bool HasFP =
hasFP(MF);
385// Restore FPRs/VRs in the normal TargetInstrInfo way. 388if (SystemZ::FP64BitRegClass.
contains(Reg))
391if (SystemZ::VR128BitRegClass.
contains(Reg))
396// Restore call-saved GPRs (but not call-clobbered varargs, which at 397// this point might hold return values). 400// If we saved any of %r2-%r5 as varargs, we should also be saving 401// and restoring %r6. If we're saving %r6 or above, we should be 404"Should be loading %r15 and something else");
406// Build an LMG instruction. 409// Add the explicit register operands. 414 MIB.
addReg(HasFP ? SystemZ::R11D : SystemZ::R15D);
417// Do a second scan adding regs as being defined by instruction 420if (Reg != RestoreGPRs.
LowGPR && Reg != RestoreGPRs.
HighGPR &&
421 SystemZ::GR64BitRegClass.contains(Reg))
437// Create the incoming register save area. 440// Get the size of our stack frame to be allocated ... 443// ... and the maximum offset we may need to reach into the 444// caller's frame to access the save area or stack arguments. 445 int64_t MaxArgOffset = 0;
450 MaxArgOffset = std::max(MaxArgOffset, ArgOffset);
453uint64_t MaxReach = StackSize + MaxArgOffset;
454if (!isUInt<12>(MaxReach)) {
455// We may need register scavenging slots if some parts of the frame 456// are outside the reach of an unsigned 12-bit displacement. 457// Create 2 for the case where both addresses in an MVC are 465// If R6 is used as an argument register it is still callee saved. If it in 466// this case is not clobbered (and restored) it should never be marked as 470for (
auto &MO :
MRI->use_nodbg_operands(SystemZ::R6D))
474// Emit instructions before MBBI (in MBB) to add NumBytes to Reg. 481 int64_t ThisVal = NumBytes;
482if (isInt<16>(NumBytes))
483 Opcode = SystemZ::AGHI;
485 Opcode = SystemZ::AGFI;
486// Make sure we maintain 8-byte stack alignment. 487 int64_t MinVal = -
uint64_t(1) << 31;
488 int64_t MaxVal = (int64_t(1) << 31) - 8;
491elseif (ThisVal > MaxVal)
496// The CC implicit def is dead. 497MI->getOperand(3).setIsDead();
502// Add CFI for the new CFA offset. 513// Add CFI for the new frame location. 520unsigned RegNum =
MRI->getDwarfRegNum(Reg,
true);
538bool HasFP =
hasFP(MF);
540// In GHC calling convention C stack space, including the ABI-defined 541// 160-byte base area, is (de)allocated by GHC itself. This stack space may 542// be used by LLVM as spill slots for the tail recursive GHC functions. Thus 543// do not allocate stack space here, too. 547"Pre allocated stack space for GHC function is too small");
551"In GHC calling convention a frame pointer is not supported");
557// Debug location must be unknown since the first debug location is used 558// to determine the end of the prologue. 561// The current offset of the stack pointer from the CFA. 565// Skip over the GPR saves. 571// Add CFI for the GPR saves. 572for (
auto &Save : CSI) {
574if (SystemZ::GR64BitRegClass.
contains(Reg)) {
575int FI = Save.getFrameIdx();
578nullptr,
MRI->getDwarfRegNum(Reg,
true),
Offset));
586// We need to allocate the ABI-defined 160-byte base area whenever 587// we allocate stack space for our own use and whenever we call another 589bool HasStackObject =
false;
592 HasStackObject =
true;
595if (HasStackObject || MFFrame.
hasCalls())
597// Don't allocate the incoming reg save area. 604// Allocate StackSize bytes. 605 int64_t Delta = -int64_t(StackSize);
606constunsigned ProbeSize = TLI.getStackProbeSize(MF);
611// Stack probing may involve looping, but splitting the prologue block 612// is not possible at this point since it would invalidate the 613// SaveBlocks / RestoreBlocks sets of PEI in the single block function 614// case. Build a pseudo to be handled later by inlineStackProbe(). 620// If we need backchain, save current stack pointer. R1 is free at 632 SPOffsetFromCFA += Delta;
636// Copy the base of the frame to R11. 640// Add CFI for the new frame location. 643// Mark the FramePtr as live at the beginning of every block except 644// the entry block. (We'll have marked R11 as live on entry when 647 MBBJ.addLiveIn(SystemZ::R11D);
650// Skip over the FPR/VR saves. 652for (
auto &Save : CSI) {
654if (SystemZ::FP64BitRegClass.
contains(Reg)) {
656 (
MBBI->getOpcode() == SystemZ::STD ||
657MBBI->getOpcode() == SystemZ::STDY))
661 }
elseif (SystemZ::VR128BitRegClass.
contains(Reg)) {
663MBBI->getOpcode() == SystemZ::VST)
670// Add CFI for the this save. 671unsigned DwarfReg =
MRI->getDwarfRegNum(Reg,
true);
678nullptr, DwarfReg, SPOffsetFromCFA +
Offset));
681// Complete the CFI for the FPR/VR saves, modelling them as taking effect 682// after the last save. 683for (
auto CFIIndex : CFIIndexes) {
697// See SystemZELFFrameLowering::emitPrologue 701// Skip the return instruction. 702assert(
MBBI->isReturn() &&
"Can only insert epilogue into returning blocks");
704uint64_t StackSize = MFFrame.getStackSize();
707unsigned Opcode =
MBBI->getOpcode();
708if (Opcode != SystemZ::LMG)
711unsigned AddrOpNo = 2;
714unsigned NewOpcode = ZII->getOpcodeForOffset(Opcode,
Offset);
716// If the offset is too large, use the largest stack-aligned offset 717// and add the rest to the base register (the stack or frame pointer). 723 NewOpcode = ZII->getOpcodeForOffset(Opcode,
Offset);
724assert(NewOpcode &&
"No restore instruction available");
727MBBI->setDesc(ZII->get(NewOpcode));
728MBBI->getOperand(AddrOpNo + 1).ChangeToImmediate(
Offset);
729 }
elseif (StackSize) {
744if (
MI.getOpcode() == SystemZ::PROBED_STACKALLOC) {
748if (StackAllocMI ==
nullptr)
751constunsigned ProbeSize = TLI.getStackProbeSize(MF);
752uint64_t NumFullBlocks = StackSize / ProbeSize;
753uint64_t Residual = StackSize % ProbeSize;
759// Allocate a block of Size bytes on the stack and probe it. 762bool EmitCFI) ->
void {
765 SPOffsetFromCFA -=
Size;
768// Probe by means of a volatile compare. 771BuildMI(InsMBB, InsPt,
DL, ZII->get(SystemZ::CG))
784if (NumFullBlocks < 3) {
785// Emit unrolled probe statements. 786for (
unsignedint i = 0; i < NumFullBlocks; i++)
787 allocateAndProbe(*
MBB,
MBBI, ProbeSize,
true/*EmitCFI*/);
789// Emit a loop probing the pages. 790uint64_t LoopAlloc = ProbeSize * NumFullBlocks;
791 SPOffsetFromCFA -= LoopAlloc;
793// Use R0D to hold the exit value. 808 allocateAndProbe(*
MBB,
MBB->
end(), ProbeSize,
false/*EmitCFI*/);
820 allocateAndProbe(*
MBB,
MBBI, Residual,
true/*EmitCFI*/);
828if (DoneMBB !=
nullptr) {
829// Compute the live-in lists for the new blocks. 841// Our incoming SP is actually SystemZMC::ELFCallFrameSize below the CFA, so 842// add that difference here. 852bool BackChain = Subtarget.hasBackChain();
853bool SoftFloat = Subtarget.hasSoftFloat();
854unsignedOffset = RegSpillOffsets[Reg];
856if (SystemZ::GR64BitRegClass.
contains(Reg))
857// Put all GPRs at the top of the Register save area with packed 858// stack. Make room for the backchain if needed. 859Offset += BackChain ? 24 : 32;
882bool BackChain = Subtarget.hasBackChain();
883bool SoftFloat = Subtarget.hasSoftFloat();
884if (HasPackedStackAttr && BackChain && !SoftFloat)
887return HasPackedStackAttr && CallConv;
894 RegSpillOffsets(-1) {
896// Create a mapping from register number to save slot offset. 897// These offsets are relative to the start of the local are area. 898 RegSpillOffsets.
grow(SystemZ::NUM_TARGET_REGS);
899for (
constauto &Entry : XPLINKSpillOffsetTable)
900 RegSpillOffsets[Entry.Reg] = Entry.Offset;
916// Checks if the function is a potential candidate for being a XPLeaf routine. 924// If function calls other functions including alloca, then it is not a XPLeaf 929// If the function has var Sized Objects, then it is not a XPLeaf routine. 933// If the function adjusts the stack, then it is not a XPLeaf routine. 937// If function modifies the stack pointer register, then it is not a XPLeaf 939if (
MRI.isPhysRegModified(Regs->getStackPointerRegister()))
942// If function modifies the ADA register, then it is not a XPLeaf routine. 943if (
MRI.isPhysRegModified(Regs->getAddressOfCalleeRegister()))
946// If function modifies the return address register, then it is not a XPLeaf 948if (
MRI.isPhysRegModified(Regs->getReturnFunctionAddressRegister()))
951// If the backchain pointer should be stored, then it is not a XPLeaf routine. 955// If function acquires its own stack frame, then it is not a XPLeaf routine. 956// At the time this function is called, only slots for local variables are 957// allocated, so this is a very rough estimate. 966 std::vector<CalleeSavedInfo> &CSI)
const{
971auto &GRRegClass = SystemZ::GR64BitRegClass;
973// At this point, the result of isXPLeafCandidate() is not accurate because 974// the size of the save area has not yet been determined. If 975// isXPLeafCandidate() indicates a potential leaf function, and there are no 976// callee-save registers, then it is indeed a leaf function, and we can early 978// TODO: It is possible for leaf functions to use callee-saved registers. 979// It can use the 0-2k range between R4 and the caller's stack frame without 980// acquiring its own stack frame. 985// For non-leaf functions: 986// - the address of callee (entry point) register R6 must be saved 988 CSI.back().setRestored(
false);
990// The return address register R7 must be saved and restored. 991 CSI.push_back(
CalleeSavedInfo(Regs.getReturnFunctionAddressRegister()));
993// If the function needs a frame pointer, or if the backchain pointer should 994// be stored, then save the stack pointer register R4. 995if (
hasFP(MF) || Subtarget.hasBackChain())
998// If this function has an associated personality function then the 999// environment register R5 must be saved in the DSA. 1003// Scan the call-saved GPRs and find the bounds of the register spill area. 1005int LowRestoreOffset = INT32_MAX;
1007int LowSpillOffset = INT32_MAX;
1011// Query index of the saved frame pointer. 1014for (
auto &CS : CSI) {
1016intOffset = RegSpillOffsets[Reg];
1018if (GRRegClass.contains(Reg)) {
1019if (LowSpillOffset >
Offset) {
1023if (CS.isRestored() && LowRestoreOffset >
Offset) {
1024 LowRestoreOffset =
Offset;
1025 LowRestoreGPR = Reg;
1028if (
Offset > HighOffset) {
1032// Non-volatile GPRs are saved in the dedicated register save area at 1033// the bottom of the stack and are not truly part of the "normal" stack 1034// frame. Mark the frame index as NoAlloc to indicate it as such. 1040 CS.setFrameIdx(FrameIdx);
1046Align Alignment =
TRI->getSpillAlign(*RC);
1047unsignedSize =
TRI->getSpillSize(*RC);
1050 CS.setFrameIdx(FrameIdx);
1054// Save the range of call-saved registers, for use by the 1055// prologue/epilogue inserters. 1059// Save the range of call-saved registers, for use by the epilogue inserter. 1060assert(LowSpillGPR &&
"Expected registers to spill");
1071bool HasFP =
hasFP(MF);
1075// If the function requires a frame pointer, record that the hard 1076// frame pointer will be clobbered. 1078 SavedRegs.
set(Regs.getFramePointerRegister());
1096if (SpillGPRs.LowGPR) {
1097assert(SpillGPRs.LowGPR != SpillGPRs.HighGPR &&
1098"Should be saving multiple registers");
1100// Build an STM/STMG instruction. 1103// Add the explicit register operands. 1107// Add the address r4 1108 MIB.
addReg(Regs.getStackPointerRegister());
1110// Add the partial offset 1111// We cannot add the actual offset as, at the stack is not finalized 1112 MIB.
addImm(SpillGPRs.GPROffset);
1114// Make sure all call-saved GPRs are included as operands and are 1115// marked as live on entry. 1116auto &GRRegClass = SystemZ::GR64BitRegClass;
1119if (GRRegClass.contains(Reg))
1124// Spill FPRs to the stack in the normal TargetInstrInfo way 1127if (SystemZ::FP64BitRegClass.
contains(Reg)) {
1132if (SystemZ::VR128BitRegClass.
contains(Reg)) {
1157// Restore FPRs in the normal TargetInstrInfo way. 1160if (SystemZ::FP64BitRegClass.
contains(Reg))
1163if (SystemZ::VR128BitRegClass.
contains(Reg))
1168// Restore call-saved GPRs (but not call-clobbered varargs, which at 1169// this point might hold return values). 1174// Build an LG/L instruction. 1176 .
addReg(Regs.getStackPointerRegister())
1180// Build an LMG/LM instruction. 1183// Add the explicit register operands. 1188 MIB.
addReg(Regs.getStackPointerRegister());
1191// Do a second scan adding regs as being defined by instruction 1205assert(&MF.
front() == &
MBB &&
"Shrink-wrapping not yet supported");
1216bool HasFP =
hasFP(MF);
1217// Debug location must be unknown since the first debug location is used 1218// to determine the end of the prologue. 1222constuint64_t StackSize = MFFrame.getStackSize();
1224if (ZFI->getSpillGPRRegs().LowGPR) {
1225// Skip over the GPR saves. 1226if ((
MBBI !=
MBB.
end()) && ((
MBBI->getOpcode() == SystemZ::STMG))) {
1227constint Operand = 3;
1228// Now we can set the offset for the operation, since now the Stack 1229// has been finalized. 1230Offset = Regs.getStackPointerBias() +
MBBI->getOperand(Operand).getImm();
1231// Maximum displacement for STMG instruction. 1232if (isInt<20>(
Offset - StackSize))
1235 StoreInstr = &*
MBBI;
1244// Allocate StackSize bytes. 1245 int64_t Delta = -int64_t(StackSize);
1247// In case the STM(G) instruction also stores SP (R4), but the displacement 1248// is too large, the SP register is manipulated first before storing, 1249// resulting in the wrong value stored and retrieved later. In this case, we 1250// need to temporarily save the value of SP, and store it later to memory. 1251if (StoreInstr && HasFP) {
1252// Insert LR r0,r4 before STMG instruction. 1256// Insert ST r0,xxx(,r4) after STMG instruction. 1267// If the requested stack size is larger than the guard page, then we need 1268// to check if we need to call the stack extender. This requires adding a 1269// conditional branch, but splitting the prologue block is not possible at 1270// this point since it would invalidate the SaveBlocks / RestoreBlocks sets 1271// of PEI in the single block function case. Build a pseudo to be handled 1272// later by inlineStackProbe(). 1273constuint64_t GuardPageSize = 1024 * 1024;
1274if (StackSize > GuardPageSize) {
1275assert(StoreInstr &&
"Wrong insertion point");
1276BuildMI(
MBB, InsertPt,
DL, ZII->get(SystemZ::XPLINK_STACKALLOC));
1281// Copy the base of the frame to Frame Pointer Register. 1283 Regs.getFramePointerRegister())
1284 .
addReg(Regs.getStackPointerRegister());
1286// Mark the FramePtr as live at the beginning of every block except 1287// the entry block. (We'll have marked R8 as live on entry when 1290B.addLiveIn(Regs.getFramePointerRegister());
1293// Save GPRs used for varargs, if any. 1298// FixedRegs is the number of used registers, accounting for shadow 1300unsigned FixedRegs = ZFI->getVarArgsFirstGPR() + ZFI->getVarArgsFirstFPR();
1303uint64_t StartOffset = MFFrame.getOffsetAdjustment() +
1304 MFFrame.getStackSize() + Regs.getCallFrameSize() +
1306unsigned Reg = GPRs[
I];
1309 .
addReg(Regs.getStackPointerRegister())
1327// Skip the return instruction. 1328assert(
MBBI->isReturn() &&
"Can only insert epilogue into returning blocks");
1330uint64_t StackSize = MFFrame.getStackSize();
1332unsignedSPReg = Regs.getStackPointerRegister();
1340// Emit a compare of the stack pointer against the stack floor, and a call to 1341// the LE stack extender if needed. 1349if (
MI.getOpcode() == SystemZ::XPLINK_STACKALLOC) {
1353if (StackAllocMI ==
nullptr)
1356bool NeedSaveSP =
hasFP(MF);
1357bool NeedSaveArg = PrologMBB.
isLiveIn(SystemZ::R3D);
1358const int64_t SaveSlotR3 = 2192;
1363// The 2nd half of block MBB after split. 1366// Add new basic block for the call to the stack overflow function. 1372BuildMI(StackExtMBB,
DL, ZII->get(SystemZ::LG), SystemZ::R3D)
1377BuildMI(StackExtMBB,
DL, ZII->get(SystemZ::CallBASR_STACKEXT))
1386// In this case, the incoming value of r4 is saved in r0 so the 1387// latter register is unavailable. Store r3 in its corresponding 1388// slot in the parameter list instead. Do this at the start of 1389// the prolog before r4 is manipulated by anything else. 1399BuildMI(
MBB, StackAllocMI,
DL, ZII->get(SystemZ::LLGT), SystemZ::R3D)
1421BuildMI(*NextMBB, StackAllocMI,
DL, ZII->get(SystemZ::LGR))
1425// In this case, the incoming value of r4 is saved in r0 so the 1426// latter register is unavailable. We stored r3 in its corresponding 1427// slot in the parameter list instead and we now restore it from there. 1429BuildMI(*NextMBB, StackAllocMI,
DL, ZII->get(SystemZ::LGR))
1433BuildMI(*NextMBB, StackAllocMI,
DL, ZII->get(SystemZ::LG))
1441// Add jump back from stack extension BB. 1447// Compute the live-in lists for the new blocks. 1461// Setup stack frame offset 1464// Nothing to do for leaf functions. 1469// Although the XPLINK specifications for AMODE64 state that minimum size 1470// of the param area is minimum 32 bytes and no rounding is otherwise 1471// specified, we round this area in 64 bytes increments to be compatible 1472// with existing compilers. 1476// Add frame values with positive object offsets. Since the displacement from 1477// the SP/FP is calculated by ObjectOffset + StackSize + Bias, object offsets 1478// with positive values are in the caller's stack frame. We need to include 1479// that since it is accessed by displacement to SP/FP. 1480 int64_t LargestArgOffset = 0;
1484 LargestArgOffset = std::max(ObjOffset, LargestArgOffset);
1488uint64_t MaxReach = (StackSize + Regs.getCallFrameSize() +
1489 Regs.getStackPointerBias() + LargestArgOffset);
1491if (!isUInt<12>(MaxReach)) {
1492// We may need register scavenging slots if some parts of the frame 1493// are outside the reach of an unsigned 12-bit displacement. 1499// Determines the size of the frame, and creates the deferred spill objects. 1511// Add the size of the register save area and the reserved area to the size. 1512 StackSize += Regs->getCallFrameSize();
1515// We now know the stack size. Update the stack objects for the register save 1516// area now. This has no impact on the stack frame layout, as this is already 1517// computed. However, it makes sure that all callee saved registers have a 1518// valid offset assigned. 1523 SPOffset -= StackSize;
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
const HexagonInstrInfo * TII
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
unsigned const TargetRegisterInfo * TRI
static constexpr Register SPReg
This file declares the machine register scavenger class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
static void emitIncrement(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &DL, Register Reg, int64_t NumBytes, const TargetInstrInfo *TII)
static void buildDefCFAReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, unsigned Reg, const SystemZInstrInfo *ZII)
static void buildCFAOffs(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, int Offset, const SystemZInstrInfo *ZII)
static bool isXPLeafCandidate(const MachineFunction &MF)
static void addSavedGPR(MachineBasicBlock &MBB, MachineInstrBuilder &MIB, unsigned GPR64, bool IsImplicit)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool empty() const
empty - Check if the array is empty.
bool test(unsigned Idx) const
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Store the specified register of the given register class to the specified stack frame index.
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Load the specified register of the given register class from the specified stack frame index.
static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register, SMLoc Loc={})
.cfi_def_cfa_register modifies a rule for computing CFA.
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
static MCCFIInstruction cfiDefCfaOffset(MCSymbol *L, int64_t Offset, SMLoc Loc={})
.cfi_def_cfa_offset modifies a rule for computing CFA.
const MCRegisterInfo * getRegisterInfo() const
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
bool isLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
void setMaxCallFrameSize(uint64_t S)
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
bool adjustsStack() const
Return true if this function adjusts the stack – e.g., when calling another function.
int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
bool hasCalls() const
Return true if the current function has any function calls.
void setObjectOffset(int ObjectIdx, int64_t SPOffset)
Set the stack frame offset of the specified object.
uint64_t getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
int CreateSpillStackObject(uint64_t Size, Align Alignment)
Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...
uint64_t estimateStackSize(const MachineFunction &MF) const
Estimate and return the size of the stack frame.
void setStackID(int ObjectIdx, uint8_t ID)
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
int getObjectIndexEnd() const
Return one past the maximum frame object index.
int CreateFixedSpillStackObject(uint64_t Size, int64_t SPOffset, bool IsImmutable=false)
Create a spill slot at a fixed location on the stack.
uint8_t getStackID(int ObjectIdx) const
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
void setStackSize(uint64_t Size)
Set the size of the stack.
int getObjectIndexBegin() const
Return the minimum frame object index.
bool isDeadObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a dead object.
void setOffsetAdjustment(int64_t Adj)
Set the correction for frame offsets.
unsigned addFrameInst(const MCCFIInstruction &Inst)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
void push_back(MachineBasicBlock *MBB)
MCContext & getContext() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const std::vector< LandingPadInfo > & getLandingPads() const
Return a reference to the landing pad info for the current function.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineBasicBlock & front() const
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addCFIIndex(unsigned CFIIndex) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
A description of a memory reference used in the backend.
@ MOVolatile
The memory access is volatile.
@ MOLoad
The memory access reads data.
MachineOperand class - Representation of each machine instruction operand.
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
void addScavengingFrameIndex(int FI)
Add a scavenging frame index.
Wrapper class representing virtual and physical registers.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset holds a fixed and a scalable offset in bytes.
int64_t getFixed() const
Returns the fixed component of the stack.
static StackOffset getFixed(int64_t Fixed)
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBII, MutableArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const override
restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee saved registers and returns...
int getOrCreateFramePointerSaveIndex(MachineFunction &MF) const override
void orderFrameObjects(const MachineFunction &MF, SmallVectorImpl< int > &ObjectsToAllocate) const override
Order the symbols in the local stack frame.
bool assignCalleeSavedSpillSlots(MachineFunction &MF, const TargetRegisterInfo *TRI, std::vector< CalleeSavedInfo > &CSI) const override
unsigned getBackchainOffset(MachineFunction &MF) const override
void inlineStackProbe(MachineFunction &MF, MachineBasicBlock &PrologMBB) const override
Replace a StackProbe stub (if any) with the actual probe code inline.
bool hasFPImpl(const MachineFunction &MF) const override
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
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...
bool usePackedStack(MachineFunction &MF) const
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const override
spillCalleeSavedRegisters - Issues instruction(s) to spill all callee saved registers and returns tru...
SystemZELFFrameLowering(unsigned PointerSize)
unsigned getRegSpillOffset(MachineFunction &MF, Register Reg) const
void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS) const override
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
bool hasReservedCallFrame(const MachineFunction &MF) const override
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
static std::unique_ptr< SystemZFrameLowering > create(const SystemZSubtarget &STI)
unsigned getPointerSize() const
SystemZFrameLowering(StackDirection D, Align StackAl, int LAO, Align TransAl, bool StackReal, unsigned PointerSize)
Register getVarArgsFirstGPR() const
int getFramePointerSaveIndex() const
SystemZ::GPRRegs getRestoreGPRRegs() const
void setRestoreGPRRegs(Register Low, Register High, unsigned Offs)
void setFramePointerSaveIndex(int Idx)
SystemZ::GPRRegs getSpillGPRRegs() const
void setSpillGPRRegs(Register Low, Register High, unsigned Offs)
const SystemZInstrInfo * getInstrInfo() const override
const SystemZTargetLowering * getTargetLowering() const override
bool isTargetXPLINK64() const
SystemZCallingConventionRegisters * getSpecialRegisters() const
XPLINK64 calling convention specific use registers Particular to z/OS when in 64 bit mode.
void inlineStackProbe(MachineFunction &MF, MachineBasicBlock &PrologMBB) const override
Replace a StackProbe stub (if any) with the actual probe code inline.
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBII, MutableArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const override
restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee saved registers and returns...
int getOrCreateFramePointerSaveIndex(MachineFunction &MF) const override
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
void determineFrameLayout(MachineFunction &MF) const
SystemZXPLINKFrameLowering(unsigned PointerSize)
bool hasFPImpl(const MachineFunction &MF) const override
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const override
spillCalleeSavedRegisters - Issues instruction(s) to spill all callee saved registers and returns tru...
void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS) const override
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
bool assignCalleeSavedSpillSlots(MachineFunction &MF, const TargetRegisterInfo *TRI, std::vector< CalleeSavedInfo > &CSI) const override
Information about stack frame layout on the target.
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
int getOffsetOfLocalArea() const
getOffsetOfLocalArea - This method returns the offset of the local area from the stack pointer on ent...
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
virtual StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const
getFrameIndexReference - This method should return the base register and offset used to reference a f...
TargetInstrInfo - Interface to description of machine instruction set.
const TargetMachine & getTargetMachine() const
virtual bool hasInlineStackProbe(const MachineFunction &MF) const
unsigned getPointerSize(unsigned AS) const
Get the pointer size for this target.
bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetLowering * getTargetLowering() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
@ Define
Register definition.
@ Kill
The last use of a register.
@ Undef
Value of the register doesn't matter.
const int64_t ELFCallFrameSize
const int64_t ELFCFAOffsetFromInitialSP
MachineBasicBlock * splitBlockBefore(MachineBasicBlock::iterator MI, MachineBasicBlock *MBB)
const unsigned CCMASK_CMP_GT
MachineBasicBlock * emitBlockAfter(MachineBasicBlock *MBB)
const unsigned CCMASK_ICMP
const unsigned XPLINK64NumArgGPRs
const MCPhysReg ELFArgGPRs[ELFNumArgGPRs]
const unsigned CCMASK_CMP_LT
const unsigned ELFNumArgGPRs
const MCPhysReg XPLINK64ArgGPRs[XPLINK64NumArgGPRs]
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned getImplRegState(bool B)
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
unsigned getKillRegState(bool B)
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
void fullyRecomputeLiveIns(ArrayRef< MachineBasicBlock * > MBBs)
Convenience function for recomputing live-in's for a set of MBBs until the computation converges.
This struct is a compact representation of a valid (non-zero power of two) alignment.
This class contains a discriminated union of information about pointers in memory operands,...