LLVM 22.0.0git
SystemZFrameLowering.cpp
Go to the documentation of this file.
1//===-- SystemZFrameLowering.cpp - Frame lowering for SystemZ -------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
10#include "SystemZCallingConv.h"
11#include "SystemZInstrInfo.h"
13#include "SystemZRegisterInfo.h"
14#include "SystemZSubtarget.h"
21#include "llvm/IR/CallingConv.h"
22#include "llvm/IR/Function.h"
24
25using namespace llvm;
26
27namespace {
28// The ABI-defined register save slots, relative to the CFA (i.e.
29// incoming stack pointer + SystemZMC::ELFCallFrameSize).
30static const TargetFrameLowering::SpillSlot ELFSpillOffsetTable[] = {
31 { SystemZ::R2D, 0x10 },
32 { SystemZ::R3D, 0x18 },
33 { SystemZ::R4D, 0x20 },
34 { SystemZ::R5D, 0x28 },
35 { SystemZ::R6D, 0x30 },
36 { SystemZ::R7D, 0x38 },
37 { SystemZ::R8D, 0x40 },
38 { SystemZ::R9D, 0x48 },
39 { SystemZ::R10D, 0x50 },
40 { SystemZ::R11D, 0x58 },
41 { SystemZ::R12D, 0x60 },
42 { SystemZ::R13D, 0x68 },
43 { SystemZ::R14D, 0x70 },
44 { SystemZ::R15D, 0x78 },
45 { SystemZ::F0D, 0x80 },
46 { SystemZ::F2D, 0x88 },
47 { SystemZ::F4D, 0x90 },
48 { SystemZ::F6D, 0x98 }
49};
50
51static const TargetFrameLowering::SpillSlot XPLINKSpillOffsetTable[] = {
52 {SystemZ::R4D, 0x00}, {SystemZ::R5D, 0x08}, {SystemZ::R6D, 0x10},
53 {SystemZ::R7D, 0x18}, {SystemZ::R8D, 0x20}, {SystemZ::R9D, 0x28},
54 {SystemZ::R10D, 0x30}, {SystemZ::R11D, 0x38}, {SystemZ::R12D, 0x40},
55 {SystemZ::R13D, 0x48}, {SystemZ::R14D, 0x50}, {SystemZ::R15D, 0x58}};
56} // end anonymous namespace
57
59 int LAO, Align TransAl,
60 bool StackReal, unsigned PointerSize)
61 : TargetFrameLowering(D, StackAl, LAO, TransAl, StackReal),
62 PointerSize(PointerSize) {}
63
64std::unique_ptr<SystemZFrameLowering>
66 unsigned PtrSz =
68 if (STI.isTargetXPLINK64())
69 return std::make_unique<SystemZXPLINKFrameLowering>(PtrSz);
70 return std::make_unique<SystemZELFFrameLowering>(PtrSz);
71}
72
73namespace {
74struct SZFrameSortingObj {
75 bool IsValid = false; // True if we care about this Object.
76 uint32_t ObjectIndex = 0; // Index of Object into MFI list.
77 uint64_t ObjectSize = 0; // Size of Object in bytes.
78 uint32_t D12Count = 0; // 12-bit displacement only.
79 uint32_t DPairCount = 0; // 12 or 20 bit displacement.
80};
81typedef std::vector<SZFrameSortingObj> SZFrameObjVec;
82} // namespace
83
84// TODO: Move to base class.
86 const MachineFunction &MF, SmallVectorImpl<int> &ObjectsToAllocate) const {
87 const MachineFrameInfo &MFI = MF.getFrameInfo();
88 auto *TII = MF.getSubtarget<SystemZSubtarget>().getInstrInfo();
89
90 // Make a vector of sorting objects to track all MFI objects and mark those
91 // to be sorted as valid.
92 if (ObjectsToAllocate.size() <= 1)
93 return;
94 SZFrameObjVec SortingObjects(MFI.getObjectIndexEnd());
95 for (auto &Obj : ObjectsToAllocate) {
96 SortingObjects[Obj].IsValid = true;
97 SortingObjects[Obj].ObjectIndex = Obj;
98 SortingObjects[Obj].ObjectSize = MFI.getObjectSize(Obj);
99 }
100
101 // Examine uses for each object and record short (12-bit) and "pair"
102 // displacement types.
103 for (auto &MBB : MF)
104 for (auto &MI : MBB) {
105 if (MI.isDebugInstr())
106 continue;
107 for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) {
108 const MachineOperand &MO = MI.getOperand(I);
109 if (!MO.isFI())
110 continue;
111 int Index = MO.getIndex();
112 if (Index >= 0 && Index < MFI.getObjectIndexEnd() &&
113 SortingObjects[Index].IsValid) {
114 if (TII->hasDisplacementPairInsn(MI.getOpcode()))
115 SortingObjects[Index].DPairCount++;
116 else if (!(MI.getDesc().TSFlags & SystemZII::Has20BitOffset))
117 SortingObjects[Index].D12Count++;
118 }
119 }
120 }
121
122 // Sort all objects for short/paired displacements, which should be
123 // sufficient as it seems like all frame objects typically are within the
124 // long displacement range. Sorting works by computing the "density" as
125 // Count / ObjectSize. The comparisons of two such fractions are refactored
126 // by multiplying both sides with A.ObjectSize * B.ObjectSize, in order to
127 // eliminate the (fp) divisions. A higher density object needs to go after
128 // in the list in order for it to end up lower on the stack.
129 auto CmpD12 = [](const SZFrameSortingObj &A, const SZFrameSortingObj &B) {
130 // Put all invalid and variable sized objects at the end.
131 if (!A.IsValid || !B.IsValid)
132 return A.IsValid;
133 if (!A.ObjectSize || !B.ObjectSize)
134 return A.ObjectSize > 0;
135 uint64_t ADensityCmp = A.D12Count * B.ObjectSize;
136 uint64_t BDensityCmp = B.D12Count * A.ObjectSize;
137 if (ADensityCmp != BDensityCmp)
138 return ADensityCmp < BDensityCmp;
139 return A.DPairCount * B.ObjectSize < B.DPairCount * A.ObjectSize;
140 };
141 llvm::stable_sort(SortingObjects, CmpD12);
142
143 // Now modify the original list to represent the final order that
144 // we want.
145 unsigned Idx = 0;
146 for (auto &Obj : SortingObjects) {
147 // All invalid items are sorted at the end, so it's safe to stop.
148 if (!Obj.IsValid)
149 break;
150 ObjectsToAllocate[Idx++] = Obj.ObjectIndex;
151 }
152}
153
155 const MachineFunction &MF) const {
156 // The ELF ABI requires us to allocate 160 bytes of stack space for the
157 // callee, with any outgoing stack arguments being placed above that. It
158 // seems better to make that area a permanent feature of the frame even if
159 // we're using a frame pointer. Similarly, 64-bit XPLINK requires 96 bytes
160 // of stack space for the register save area.
161 return true;
162}
163
166 std::vector<CalleeSavedInfo> &CSI) const {
168 MachineFrameInfo &MFFrame = MF.getFrameInfo();
169 bool IsVarArg = MF.getFunction().isVarArg();
170 if (CSI.empty())
171 return true; // Early exit if no callee saved registers are modified!
172
173 unsigned LowGPR = 0;
174 unsigned HighGPR = SystemZ::R15D;
175 int StartSPOffset = SystemZMC::ELFCallFrameSize;
176 for (auto &CS : CSI) {
177 MCRegister Reg = CS.getReg();
178 int Offset = getRegSpillOffset(MF, Reg);
179 if (Offset) {
180 if (SystemZ::GR64BitRegClass.contains(Reg) && StartSPOffset > Offset) {
181 LowGPR = Reg;
182 StartSPOffset = Offset;
183 }
185 int FrameIdx =
186 MFFrame.CreateFixedSpillStackObject(getPointerSize(), Offset);
187 CS.setFrameIdx(FrameIdx);
188 } else
189 CS.setFrameIdx(INT32_MAX);
190 }
191
192 // Save the range of call-saved registers, for use by the
193 // prologue/epilogue inserters.
194 ZFI->setRestoreGPRRegs(LowGPR, HighGPR, StartSPOffset);
195 if (IsVarArg) {
196 // Also save the GPR varargs, if any. R6D is call-saved, so would
197 // already be included, but we also need to handle the call-clobbered
198 // argument registers.
199 Register FirstGPR = ZFI->getVarArgsFirstGPR();
200 if (FirstGPR < SystemZ::ELFNumArgGPRs) {
201 unsigned Reg = SystemZ::ELFArgGPRs[FirstGPR];
202 int Offset = getRegSpillOffset(MF, Reg);
203 if (StartSPOffset > Offset) {
204 LowGPR = Reg; StartSPOffset = Offset;
205 }
206 }
207 }
208 ZFI->setSpillGPRRegs(LowGPR, HighGPR, StartSPOffset);
209
210 // Create fixed stack objects for the remaining registers.
211 int CurrOffset = -SystemZMC::ELFCallFrameSize;
212 if (usePackedStack(MF))
213 CurrOffset += StartSPOffset;
214
215 for (auto &CS : CSI) {
216 if (CS.getFrameIdx() != INT32_MAX)
217 continue;
218 MCRegister Reg = CS.getReg();
219 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
220 unsigned Size = TRI->getSpillSize(*RC);
221 CurrOffset -= Size;
222 assert(CurrOffset % 8 == 0 &&
223 "8-byte alignment required for for all register save slots");
224 int FrameIdx = MFFrame.CreateFixedSpillStackObject(Size, CurrOffset);
225 CS.setFrameIdx(FrameIdx);
226 }
227
228 return true;
229}
230
232 BitVector &SavedRegs,
233 RegScavenger *RS) const {
235
236 MachineFrameInfo &MFFrame = MF.getFrameInfo();
238 bool HasFP = hasFP(MF);
240 bool IsVarArg = MF.getFunction().isVarArg();
241
242 // va_start stores incoming FPR varargs in the normal way, but delegates
243 // the saving of incoming GPR varargs to spillCalleeSavedRegisters().
244 // Record these pending uses, which typically include the call-saved
245 // argument register R6D.
246 if (IsVarArg)
247 for (unsigned I = MFI->getVarArgsFirstGPR(); I < SystemZ::ELFNumArgGPRs; ++I)
248 SavedRegs.set(SystemZ::ELFArgGPRs[I]);
249
250 // If there are any landing pads, entering them will modify r6/r7.
251 if (!MF.getLandingPads().empty()) {
252 SavedRegs.set(SystemZ::R6D);
253 SavedRegs.set(SystemZ::R7D);
254 }
255
256 // If the function requires a frame pointer, record that the hard
257 // frame pointer will be clobbered.
258 if (HasFP)
259 SavedRegs.set(SystemZ::R11D);
260
261 // If the function calls other functions, record that the return
262 // address register will be clobbered.
263 if (MFFrame.hasCalls())
264 SavedRegs.set(SystemZ::R14D);
265
266 // If we are saving GPRs other than the stack pointer, we might as well
267 // save and restore the stack pointer at the same time, via STMG and LMG.
268 // This allows the deallocation to be done by the LMG, rather than needing
269 // a separate %r15 addition.
270 const MCPhysReg *CSRegs = TRI->getCalleeSavedRegs(&MF);
271 for (unsigned I = 0; CSRegs[I]; ++I) {
272 unsigned Reg = CSRegs[I];
273 if (SystemZ::GR64BitRegClass.contains(Reg) && SavedRegs.test(Reg)) {
274 SavedRegs.set(SystemZ::R15D);
275 break;
276 }
277 }
278}
279
281 : SystemZFrameLowering(TargetFrameLowering::StackGrowsDown, Align(8), 0,
282 Align(8), /* StackRealignable */ false, PointerSize),
283 RegSpillOffsets(0) {
284
285 // Due to the SystemZ ABI, the DWARF CFA (Canonical Frame Address) is not
286 // equal to the incoming stack pointer, but to incoming stack pointer plus
287 // 160. Instead of using a Local Area Offset, the Register save area will
288 // be occupied by fixed frame objects, and all offsets are actually
289 // relative to CFA.
290
291 // Create a mapping from register number to save slot offset.
292 // These offsets are relative to the start of the register save area.
293 RegSpillOffsets.grow(SystemZ::NUM_TARGET_REGS);
294 for (const auto &Entry : ELFSpillOffsetTable)
295 RegSpillOffsets[Entry.Reg] = Entry.Offset;
296}
297
298// Add GPR64 to the save instruction being built by MIB, which is in basic
299// block MBB. IsImplicit says whether this is an explicit operand to the
300// instruction, or an implicit one that comes between the explicit start
301// and end registers.
303 unsigned GPR64, bool IsImplicit) {
304 const TargetRegisterInfo *RI =
306 Register GPR32 = RI->getSubReg(GPR64, SystemZ::subreg_l32);
307 bool IsLive = MBB.isLiveIn(GPR64) || MBB.isLiveIn(GPR32);
308 if (!IsLive || !IsImplicit) {
309 MIB.addReg(GPR64, getImplRegState(IsImplicit) | getKillRegState(!IsLive));
310 if (!IsLive)
311 MBB.addLiveIn(GPR64);
312 }
313}
314
318 if (CSI.empty())
319 return false;
320
324 bool IsVarArg = MF.getFunction().isVarArg();
325 DebugLoc DL;
326
327 // Save GPRs
328 SystemZ::GPRRegs SpillGPRs = ZFI->getSpillGPRRegs();
329 if (SpillGPRs.LowGPR) {
330 assert(SpillGPRs.LowGPR != SpillGPRs.HighGPR &&
331 "Should be saving %r15 and something else");
332
333 // Build an STMG instruction.
334 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(SystemZ::STMG));
335
336 // Add the explicit register operands.
337 addSavedGPR(MBB, MIB, SpillGPRs.LowGPR, false);
338 addSavedGPR(MBB, MIB, SpillGPRs.HighGPR, false);
339
340 // Add the address.
341 MIB.addReg(SystemZ::R15D).addImm(SpillGPRs.GPROffset);
342
343 // Make sure all call-saved GPRs are included as operands and are
344 // marked as live on entry.
345 for (const CalleeSavedInfo &I : CSI) {
346 MCRegister Reg = I.getReg();
347 if (SystemZ::GR64BitRegClass.contains(Reg))
348 addSavedGPR(MBB, MIB, Reg, true);
349 }
350
351 // ...likewise GPR varargs.
352 if (IsVarArg)
353 for (unsigned I = ZFI->getVarArgsFirstGPR(); I < SystemZ::ELFNumArgGPRs; ++I)
354 addSavedGPR(MBB, MIB, SystemZ::ELFArgGPRs[I], true);
355 }
356
357 // Save FPRs/VRs in the normal TargetInstrInfo way.
358 for (const CalleeSavedInfo &I : CSI) {
359 MCRegister Reg = I.getReg();
360 if (SystemZ::FP64BitRegClass.contains(Reg)) {
361 MBB.addLiveIn(Reg);
362 TII->storeRegToStackSlot(MBB, MBBI, Reg, true, I.getFrameIdx(),
363 &SystemZ::FP64BitRegClass, TRI, Register());
364 }
365 if (SystemZ::VR128BitRegClass.contains(Reg)) {
366 MBB.addLiveIn(Reg);
367 TII->storeRegToStackSlot(MBB, MBBI, Reg, true, I.getFrameIdx(),
368 &SystemZ::VR128BitRegClass, TRI, Register());
369 }
370 }
371
372 return true;
373}
374
378 if (CSI.empty())
379 return false;
380
384 bool HasFP = hasFP(MF);
385 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
386
387 // Restore FPRs/VRs in the normal TargetInstrInfo way.
388 for (const CalleeSavedInfo &I : CSI) {
389 MCRegister Reg = I.getReg();
390 if (SystemZ::FP64BitRegClass.contains(Reg))
391 TII->loadRegFromStackSlot(MBB, MBBI, Reg, I.getFrameIdx(),
392 &SystemZ::FP64BitRegClass, TRI, Register());
393 if (SystemZ::VR128BitRegClass.contains(Reg))
394 TII->loadRegFromStackSlot(MBB, MBBI, Reg, I.getFrameIdx(),
395 &SystemZ::VR128BitRegClass, TRI, Register());
396 }
397
398 // Restore call-saved GPRs (but not call-clobbered varargs, which at
399 // this point might hold return values).
400 SystemZ::GPRRegs RestoreGPRs = ZFI->getRestoreGPRRegs();
401 if (RestoreGPRs.LowGPR) {
402 // If we saved any of %r2-%r5 as varargs, we should also be saving
403 // and restoring %r6. If we're saving %r6 or above, we should be
404 // restoring it too.
405 assert(RestoreGPRs.LowGPR != RestoreGPRs.HighGPR &&
406 "Should be loading %r15 and something else");
407
408 // Build an LMG instruction.
409 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(SystemZ::LMG));
410
411 // Add the explicit register operands.
412 MIB.addReg(RestoreGPRs.LowGPR, RegState::Define);
413 MIB.addReg(RestoreGPRs.HighGPR, RegState::Define);
414
415 // Add the address.
416 MIB.addReg(HasFP ? SystemZ::R11D : SystemZ::R15D);
417 MIB.addImm(RestoreGPRs.GPROffset);
418
419 // Do a second scan adding regs as being defined by instruction
420 for (const CalleeSavedInfo &I : CSI) {
421 MCRegister Reg = I.getReg();
422 if (Reg != RestoreGPRs.LowGPR && Reg != RestoreGPRs.HighGPR &&
423 SystemZ::GR64BitRegClass.contains(Reg))
425 }
426 }
427
428 return true;
429}
430
432 MachineFunction &MF, RegScavenger *RS) const {
433 MachineFrameInfo &MFFrame = MF.getFrameInfo();
436 bool BackChain = MF.getSubtarget<SystemZSubtarget>().hasBackChain();
437
438 if (!usePackedStack(MF) || BackChain)
439 // Create the incoming register save area.
441
442 // Get the size of our stack frame to be allocated ...
443 uint64_t StackSize = (MFFrame.estimateStackSize(MF) +
445 // ... and the maximum offset we may need to reach into the
446 // caller's frame to access the save area or stack arguments.
447 int64_t MaxArgOffset = 0;
448 for (int I = MFFrame.getObjectIndexBegin(); I != 0; ++I)
449 if (MFFrame.getObjectOffset(I) >= 0) {
450 int64_t ArgOffset = MFFrame.getObjectOffset(I) +
451 MFFrame.getObjectSize(I);
452 MaxArgOffset = std::max(MaxArgOffset, ArgOffset);
453 }
454
455 uint64_t MaxReach = StackSize + MaxArgOffset;
456 if (!isUInt<12>(MaxReach)) {
457 // We may need register scavenging slots if some parts of the frame
458 // are outside the reach of an unsigned 12-bit displacement.
459 // Create 2 for the case where both addresses in an MVC are
460 // out of range.
465 }
466
467 // If R6 is used as an argument register it is still callee saved. If it in
468 // this case is not clobbered (and restored) it should never be marked as
469 // killed.
470 if (MF.front().isLiveIn(SystemZ::R6D) &&
471 ZFI->getRestoreGPRRegs().LowGPR != SystemZ::R6D)
472 for (auto &MO : MRI->use_nodbg_operands(SystemZ::R6D))
473 MO.setIsKill(false);
474}
475
476// Emit instructions before MBBI (in MBB) to add NumBytes to Reg.
479 Register Reg, int64_t NumBytes,
480 const TargetInstrInfo *TII) {
481 while (NumBytes) {
482 unsigned Opcode;
483 int64_t ThisVal = NumBytes;
484 if (isInt<16>(NumBytes))
485 Opcode = SystemZ::AGHI;
486 else {
487 Opcode = SystemZ::AGFI;
488 // Make sure we maintain 8-byte stack alignment.
489 int64_t MinVal = -uint64_t(1) << 31;
490 int64_t MaxVal = (int64_t(1) << 31) - 8;
491 if (ThisVal < MinVal)
492 ThisVal = MinVal;
493 else if (ThisVal > MaxVal)
494 ThisVal = MaxVal;
495 }
496 MachineInstr *MI = BuildMI(MBB, MBBI, DL, TII->get(Opcode), Reg)
497 .addReg(Reg).addImm(ThisVal);
498 // The CC implicit def is dead.
499 MI->getOperand(3).setIsDead();
500 NumBytes -= ThisVal;
501 }
502}
503
504// Add CFI for the new CFA offset.
507 const DebugLoc &DL, int Offset,
508 const SystemZInstrInfo *ZII) {
509 unsigned CFIIndex = MBB.getParent()->addFrameInst(
511 BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::CFI_INSTRUCTION))
512 .addCFIIndex(CFIIndex);
513}
514
515// Add CFI for the new frame location.
518 const DebugLoc &DL, unsigned Reg,
519 const SystemZInstrInfo *ZII) {
522 unsigned RegNum = MRI->getDwarfRegNum(Reg, true);
523 unsigned CFIIndex = MF.addFrameInst(
525 BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::CFI_INSTRUCTION))
526 .addCFIIndex(CFIIndex);
527}
528
530 MachineBasicBlock &MBB) const {
531 assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
533 const SystemZTargetLowering &TLI = *STI.getTargetLowering();
534 MachineFrameInfo &MFFrame = MF.getFrameInfo();
535 auto *ZII = STI.getInstrInfo();
539 const std::vector<CalleeSavedInfo> &CSI = MFFrame.getCalleeSavedInfo();
540 bool HasFP = hasFP(MF);
541
542 // In GHC calling convention C stack space, including the ABI-defined
543 // 160-byte base area, is (de)allocated by GHC itself. This stack space may
544 // be used by LLVM as spill slots for the tail recursive GHC functions. Thus
545 // do not allocate stack space here, too.
547 if (MFFrame.getStackSize() > 2048 * sizeof(long)) {
549 "Pre allocated stack space for GHC function is too small");
550 }
551 if (HasFP) {
553 "In GHC calling convention a frame pointer is not supported");
554 }
556 return;
557 }
558
559 // Debug location must be unknown since the first debug location is used
560 // to determine the end of the prologue.
561 DebugLoc DL;
562 // Add mcount instrumentation if necessary.
563 if (MF.getFunction()
564 .getFnAttribute("systemz-instrument-function-entry")
565 .getValueAsString() == "mcount") {
566
567 // Store return address 8 bytes above stack pointer.
568 BuildMI(MBB, MBBI, DL, ZII->get(SystemZ::STG))
569 .addReg(SystemZ::R14D)
570 .addReg(SystemZ::R15D)
571 .addImm(8)
572 .addReg(0);
573
574 // Call mcount (Regmask from CC AnyReg since mcount preserves all normal
575 // argument registers).
576 const uint32_t *Mask = MF.getSubtarget<SystemZSubtarget>()
577 .getSpecialRegisters()
578 ->getCallPreservedMask(MF, CallingConv::AnyReg);
579 BuildMI(MBB, MBBI, DL, ZII->get(SystemZ::CallBRASL))
580 .addExternalSymbol("mcount")
581 .addRegMask(Mask);
582
583 // Reload return address from 8 bytes above stack pointer.
584 BuildMI(MBB, MBBI, DL, ZII->get(SystemZ::LG))
585 .addReg(SystemZ::R14D, RegState::Define)
586 .addReg(SystemZ::R15D)
587 .addImm(8)
588 .addReg(0);
589 }
590
591 // The current offset of the stack pointer from the CFA.
592 int64_t SPOffsetFromCFA = -SystemZMC::ELFCFAOffsetFromInitialSP;
593
594 if (ZFI->getSpillGPRRegs().LowGPR) {
595 // Skip over the GPR saves.
596 if (MBBI != MBB.end() && MBBI->getOpcode() == SystemZ::STMG)
597 ++MBBI;
598 else
599 llvm_unreachable("Couldn't skip over GPR saves");
600
601 // Add CFI for the GPR saves.
602 for (auto &Save : CSI) {
603 MCRegister Reg = Save.getReg();
604 if (SystemZ::GR64BitRegClass.contains(Reg)) {
605 int FI = Save.getFrameIdx();
606 int64_t Offset = MFFrame.getObjectOffset(FI);
607 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
608 nullptr, MRI->getDwarfRegNum(Reg, true), Offset));
609 BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::CFI_INSTRUCTION))
610 .addCFIIndex(CFIIndex);
611 }
612 }
613 }
614
615 uint64_t StackSize = MFFrame.getStackSize();
616 // We need to allocate the ABI-defined 160-byte base area whenever
617 // we allocate stack space for our own use and whenever we call another
618 // function.
619 bool HasStackObject = false;
620 for (unsigned i = 0, e = MFFrame.getObjectIndexEnd(); i != e; ++i)
621 if (!MFFrame.isDeadObjectIndex(i)) {
622 HasStackObject = true;
623 break;
624 }
625 if (HasStackObject || MFFrame.hasCalls())
626 StackSize += SystemZMC::ELFCallFrameSize;
627 // Don't allocate the incoming reg save area.
628 StackSize = StackSize > SystemZMC::ELFCallFrameSize
629 ? StackSize - SystemZMC::ELFCallFrameSize
630 : 0;
631 MFFrame.setStackSize(StackSize);
632
633 if (StackSize) {
634 // Allocate StackSize bytes.
635 int64_t Delta = -int64_t(StackSize);
636 const unsigned ProbeSize = TLI.getStackProbeSize(MF);
637 bool FreeProbe = (ZFI->getSpillGPRRegs().GPROffset &&
638 (ZFI->getSpillGPRRegs().GPROffset + StackSize) < ProbeSize);
639 if (!FreeProbe &&
641 // Stack probing may involve looping, but splitting the prologue block
642 // is not possible at this point since it would invalidate the
643 // SaveBlocks / RestoreBlocks sets of PEI in the single block function
644 // case. Build a pseudo to be handled later by inlineStackProbe().
645 BuildMI(MBB, MBBI, DL, ZII->get(SystemZ::PROBED_STACKALLOC))
646 .addImm(StackSize);
647 }
648 else {
649 bool StoreBackchain = MF.getSubtarget<SystemZSubtarget>().hasBackChain();
650 // If we need backchain, save current stack pointer. R1 is free at
651 // this point.
652 if (StoreBackchain)
653 BuildMI(MBB, MBBI, DL, ZII->get(SystemZ::LGR))
654 .addReg(SystemZ::R1D, RegState::Define).addReg(SystemZ::R15D);
655 emitIncrement(MBB, MBBI, DL, SystemZ::R15D, Delta, ZII);
656 buildCFAOffs(MBB, MBBI, DL, SPOffsetFromCFA + Delta, ZII);
657 if (StoreBackchain)
658 BuildMI(MBB, MBBI, DL, ZII->get(SystemZ::STG))
659 .addReg(SystemZ::R1D, RegState::Kill).addReg(SystemZ::R15D)
661 }
662 SPOffsetFromCFA += Delta;
663 }
664
665 if (HasFP) {
666 // Copy the base of the frame to R11.
667 BuildMI(MBB, MBBI, DL, ZII->get(SystemZ::LGR), SystemZ::R11D)
668 .addReg(SystemZ::R15D);
669
670 // Add CFI for the new frame location.
671 buildDefCFAReg(MBB, MBBI, DL, SystemZ::R11D, ZII);
672
673 // Mark the FramePtr as live at the beginning of every block except
674 // the entry block. (We'll have marked R11 as live on entry when
675 // saving the GPRs.)
676 for (MachineBasicBlock &MBBJ : llvm::drop_begin(MF))
677 MBBJ.addLiveIn(SystemZ::R11D);
678 }
679
680 // Skip over the FPR/VR saves.
681 SmallVector<unsigned, 8> CFIIndexes;
682 for (auto &Save : CSI) {
683 MCRegister Reg = Save.getReg();
684 if (SystemZ::FP64BitRegClass.contains(Reg)) {
685 if (MBBI != MBB.end() &&
686 (MBBI->getOpcode() == SystemZ::STD ||
687 MBBI->getOpcode() == SystemZ::STDY))
688 ++MBBI;
689 else
690 llvm_unreachable("Couldn't skip over FPR save");
691 } else if (SystemZ::VR128BitRegClass.contains(Reg)) {
692 if (MBBI != MBB.end() &&
693 MBBI->getOpcode() == SystemZ::VST)
694 ++MBBI;
695 else
696 llvm_unreachable("Couldn't skip over VR save");
697 } else
698 continue;
699
700 // Add CFI for the this save.
701 unsigned DwarfReg = MRI->getDwarfRegNum(Reg, true);
702 Register IgnoredFrameReg;
703 int64_t Offset =
704 getFrameIndexReference(MF, Save.getFrameIdx(), IgnoredFrameReg)
705 .getFixed();
706
707 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
708 nullptr, DwarfReg, SPOffsetFromCFA + Offset));
709 CFIIndexes.push_back(CFIIndex);
710 }
711 // Complete the CFI for the FPR/VR saves, modelling them as taking effect
712 // after the last save.
713 for (auto CFIIndex : CFIIndexes) {
714 BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::CFI_INSTRUCTION))
715 .addCFIIndex(CFIIndex);
716 }
717}
718
720 MachineBasicBlock &MBB) const {
722 auto *ZII =
723 static_cast<const SystemZInstrInfo *>(MF.getSubtarget().getInstrInfo());
725 MachineFrameInfo &MFFrame = MF.getFrameInfo();
726
727 // See SystemZELFFrameLowering::emitPrologue
729 return;
730
731 // Skip the return instruction.
732 assert(MBBI->isReturn() && "Can only insert epilogue into returning blocks");
733
734 uint64_t StackSize = MFFrame.getStackSize();
735 if (ZFI->getRestoreGPRRegs().LowGPR) {
736 --MBBI;
737 unsigned Opcode = MBBI->getOpcode();
738 if (Opcode != SystemZ::LMG)
739 llvm_unreachable("Expected to see callee-save register restore code");
740
741 unsigned AddrOpNo = 2;
742 DebugLoc DL = MBBI->getDebugLoc();
743 uint64_t Offset = StackSize + MBBI->getOperand(AddrOpNo + 1).getImm();
744 unsigned NewOpcode = ZII->getOpcodeForOffset(Opcode, Offset);
745
746 // If the offset is too large, use the largest stack-aligned offset
747 // and add the rest to the base register (the stack or frame pointer).
748 if (!NewOpcode) {
749 uint64_t NumBytes = Offset - 0x7fff8;
750 emitIncrement(MBB, MBBI, DL, MBBI->getOperand(AddrOpNo).getReg(),
751 NumBytes, ZII);
752 Offset -= NumBytes;
753 NewOpcode = ZII->getOpcodeForOffset(Opcode, Offset);
754 assert(NewOpcode && "No restore instruction available");
755 }
756
757 MBBI->setDesc(ZII->get(NewOpcode));
758 MBBI->getOperand(AddrOpNo + 1).ChangeToImmediate(Offset);
759 } else if (StackSize) {
760 DebugLoc DL = MBBI->getDebugLoc();
761 emitIncrement(MBB, MBBI, DL, SystemZ::R15D, StackSize, ZII);
762 }
763}
764
766 MachineFunction &MF, MachineBasicBlock &PrologMBB) const {
767 auto *ZII =
768 static_cast<const SystemZInstrInfo *>(MF.getSubtarget().getInstrInfo());
770 const SystemZTargetLowering &TLI = *STI.getTargetLowering();
771
772 MachineInstr *StackAllocMI = nullptr;
773 for (MachineInstr &MI : PrologMBB)
774 if (MI.getOpcode() == SystemZ::PROBED_STACKALLOC) {
775 StackAllocMI = &MI;
776 break;
777 }
778 if (StackAllocMI == nullptr)
779 return;
780 uint64_t StackSize = StackAllocMI->getOperand(0).getImm();
781 const unsigned ProbeSize = TLI.getStackProbeSize(MF);
782 uint64_t NumFullBlocks = StackSize / ProbeSize;
783 uint64_t Residual = StackSize % ProbeSize;
784 int64_t SPOffsetFromCFA = -SystemZMC::ELFCFAOffsetFromInitialSP;
785 MachineBasicBlock *MBB = &PrologMBB;
786 MachineBasicBlock::iterator MBBI = StackAllocMI;
787 const DebugLoc DL = StackAllocMI->getDebugLoc();
788
789 // Allocate a block of Size bytes on the stack and probe it.
790 auto allocateAndProbe = [&](MachineBasicBlock &InsMBB,
791 MachineBasicBlock::iterator InsPt, unsigned Size,
792 bool EmitCFI) -> void {
793 emitIncrement(InsMBB, InsPt, DL, SystemZ::R15D, -int64_t(Size), ZII);
794 if (EmitCFI) {
795 SPOffsetFromCFA -= Size;
796 buildCFAOffs(InsMBB, InsPt, DL, SPOffsetFromCFA, ZII);
797 }
798 // Probe by means of a volatile compare.
801 BuildMI(InsMBB, InsPt, DL, ZII->get(SystemZ::CG))
802 .addReg(SystemZ::R0D, RegState::Undef)
803 .addReg(SystemZ::R15D).addImm(Size - 8).addReg(0)
804 .addMemOperand(MMO);
805 };
806
807 bool StoreBackchain = MF.getSubtarget<SystemZSubtarget>().hasBackChain();
808 if (StoreBackchain)
809 BuildMI(*MBB, MBBI, DL, ZII->get(SystemZ::LGR))
810 .addReg(SystemZ::R1D, RegState::Define).addReg(SystemZ::R15D);
811
812 MachineBasicBlock *DoneMBB = nullptr;
813 MachineBasicBlock *LoopMBB = nullptr;
814 if (NumFullBlocks < 3) {
815 // Emit unrolled probe statements.
816 for (unsigned int i = 0; i < NumFullBlocks; i++)
817 allocateAndProbe(*MBB, MBBI, ProbeSize, true/*EmitCFI*/);
818 } else {
819 // Emit a loop probing the pages.
820 uint64_t LoopAlloc = ProbeSize * NumFullBlocks;
821 SPOffsetFromCFA -= LoopAlloc;
822
823 // Use R0D to hold the exit value.
824 BuildMI(*MBB, MBBI, DL, ZII->get(SystemZ::LGR), SystemZ::R0D)
825 .addReg(SystemZ::R15D);
826 buildDefCFAReg(*MBB, MBBI, DL, SystemZ::R0D, ZII);
827 emitIncrement(*MBB, MBBI, DL, SystemZ::R0D, -int64_t(LoopAlloc), ZII);
828 buildCFAOffs(*MBB, MBBI, DL, -int64_t(SystemZMC::ELFCallFrameSize + LoopAlloc),
829 ZII);
830
832 LoopMBB = SystemZ::emitBlockAfter(MBB);
833 MBB->addSuccessor(LoopMBB);
834 LoopMBB->addSuccessor(LoopMBB);
835 LoopMBB->addSuccessor(DoneMBB);
836
837 MBB = LoopMBB;
838 allocateAndProbe(*MBB, MBB->end(), ProbeSize, false/*EmitCFI*/);
839 BuildMI(*MBB, MBB->end(), DL, ZII->get(SystemZ::CLGR))
840 .addReg(SystemZ::R15D).addReg(SystemZ::R0D);
841 BuildMI(*MBB, MBB->end(), DL, ZII->get(SystemZ::BRC))
843
844 MBB = DoneMBB;
845 MBBI = DoneMBB->begin();
846 buildDefCFAReg(*MBB, MBBI, DL, SystemZ::R15D, ZII);
847 }
848
849 if (Residual)
850 allocateAndProbe(*MBB, MBBI, Residual, true/*EmitCFI*/);
851
852 if (StoreBackchain)
853 BuildMI(*MBB, MBBI, DL, ZII->get(SystemZ::STG))
854 .addReg(SystemZ::R1D, RegState::Kill).addReg(SystemZ::R15D)
856
857 StackAllocMI->eraseFromParent();
858 if (DoneMBB != nullptr) {
859 // Compute the live-in lists for the new blocks.
860 fullyRecomputeLiveIns({DoneMBB, LoopMBB});
861 }
862}
863
865 return (MF.getTarget().Options.DisableFramePointerElim(MF) ||
867}
868
870 const MachineFunction &MF, int FI, Register &FrameReg) const {
871 // Our incoming SP is actually SystemZMC::ELFCallFrameSize below the CFA, so
872 // add that difference here.
876}
877
879 Register Reg) const {
880 bool IsVarArg = MF.getFunction().isVarArg();
881 const SystemZSubtarget &Subtarget = MF.getSubtarget<SystemZSubtarget>();
882 bool BackChain = Subtarget.hasBackChain();
883 bool SoftFloat = Subtarget.hasSoftFloat();
884 unsigned Offset = RegSpillOffsets[Reg];
885 if (usePackedStack(MF) && !(IsVarArg && !SoftFloat)) {
886 if (SystemZ::GR64BitRegClass.contains(Reg))
887 // Put all GPRs at the top of the Register save area with packed
888 // stack. Make room for the backchain if needed.
889 Offset += BackChain ? 24 : 32;
890 else
891 Offset = 0;
892 }
893 return Offset;
894}
895
897 MachineFunction &MF) const {
899 int FI = ZFI->getFramePointerSaveIndex();
900 if (!FI) {
901 MachineFrameInfo &MFFrame = MF.getFrameInfo();
903 FI = MFFrame.CreateFixedObject(getPointerSize(), Offset, false);
905 }
906 return FI;
907}
908
910 bool HasPackedStackAttr = MF.getFunction().hasFnAttribute("packed-stack");
911 const SystemZSubtarget &Subtarget = MF.getSubtarget<SystemZSubtarget>();
912 bool BackChain = Subtarget.hasBackChain();
913 bool SoftFloat = Subtarget.hasSoftFloat();
914 if (HasPackedStackAttr && BackChain && !SoftFloat)
915 report_fatal_error("packed-stack + backchain + hard-float is unsupported.");
916 bool CallConv = MF.getFunction().getCallingConv() != CallingConv::GHC;
917 return HasPackedStackAttr && CallConv;
918}
919
921 : SystemZFrameLowering(TargetFrameLowering::StackGrowsDown, Align(32), 0,
922 Align(32), /* StackRealignable */ false,
923 PointerSize),
924 RegSpillOffsets(-1) {
925
926 // Create a mapping from register number to save slot offset.
927 // These offsets are relative to the start of the local are area.
928 RegSpillOffsets.grow(SystemZ::NUM_TARGET_REGS);
929 for (const auto &Entry : XPLINKSpillOffsetTable)
930 RegSpillOffsets[Entry.Reg] = Entry.Offset;
931}
932
934 MachineFunction &MF) const {
936 int FI = ZFI->getFramePointerSaveIndex();
937 if (!FI) {
938 MachineFrameInfo &MFFrame = MF.getFrameInfo();
939 FI = MFFrame.CreateFixedObject(getPointerSize(), 0, false);
942 }
943 return FI;
944}
945
946// Checks if the function is a potential candidate for being a XPLeaf routine.
947static bool isXPLeafCandidate(const MachineFunction &MF) {
948 const MachineFrameInfo &MFFrame = MF.getFrameInfo();
949 const MachineRegisterInfo &MRI = MF.getRegInfo();
950 const SystemZSubtarget &Subtarget = MF.getSubtarget<SystemZSubtarget>();
951 auto *Regs =
952 static_cast<SystemZXPLINK64Registers *>(Subtarget.getSpecialRegisters());
953
954 // If function calls other functions including alloca, then it is not a XPLeaf
955 // routine.
956 if (MFFrame.hasCalls())
957 return false;
958
959 // If the function has var Sized Objects, then it is not a XPLeaf routine.
960 if (MFFrame.hasVarSizedObjects())
961 return false;
962
963 // If the function adjusts the stack, then it is not a XPLeaf routine.
964 if (MFFrame.adjustsStack())
965 return false;
966
967 // If function modifies the stack pointer register, then it is not a XPLeaf
968 // routine.
969 if (MRI.isPhysRegModified(Regs->getStackPointerRegister()))
970 return false;
971
972 // If function modifies the ADA register, then it is not a XPLeaf routine.
973 if (MRI.isPhysRegModified(Regs->getAddressOfCalleeRegister()))
974 return false;
975
976 // If function modifies the return address register, then it is not a XPLeaf
977 // routine.
978 if (MRI.isPhysRegModified(Regs->getReturnFunctionAddressRegister()))
979 return false;
980
981 // If the backchain pointer should be stored, then it is not a XPLeaf routine.
982 if (MF.getSubtarget<SystemZSubtarget>().hasBackChain())
983 return false;
984
985 // If function acquires its own stack frame, then it is not a XPLeaf routine.
986 // At the time this function is called, only slots for local variables are
987 // allocated, so this is a very rough estimate.
988 if (MFFrame.estimateStackSize(MF) > 0)
989 return false;
990
991 return true;
992}
993
996 std::vector<CalleeSavedInfo> &CSI) const {
997 MachineFrameInfo &MFFrame = MF.getFrameInfo();
999 const SystemZSubtarget &Subtarget = MF.getSubtarget<SystemZSubtarget>();
1000 auto &Regs = Subtarget.getSpecialRegisters<SystemZXPLINK64Registers>();
1001 auto &GRRegClass = SystemZ::GR64BitRegClass;
1002
1003 // At this point, the result of isXPLeafCandidate() is not accurate because
1004 // the size of the save area has not yet been determined. If
1005 // isXPLeafCandidate() indicates a potential leaf function, and there are no
1006 // callee-save registers, then it is indeed a leaf function, and we can early
1007 // exit.
1008 // TODO: It is possible for leaf functions to use callee-saved registers.
1009 // It can use the 0-2k range between R4 and the caller's stack frame without
1010 // acquiring its own stack frame.
1011 bool IsLeaf = CSI.empty() && isXPLeafCandidate(MF);
1012 if (IsLeaf)
1013 return true;
1014
1015 // For non-leaf functions:
1016 // - the address of callee (entry point) register R6 must be saved
1017 CSI.push_back(CalleeSavedInfo(Regs.getAddressOfCalleeRegister()));
1018 CSI.back().setRestored(false);
1019
1020 // The return address register R7 must be saved and restored.
1021 CSI.push_back(CalleeSavedInfo(Regs.getReturnFunctionAddressRegister()));
1022
1023 // If the function needs a frame pointer, or if the backchain pointer should
1024 // be stored, then save the stack pointer register R4.
1025 if (hasFP(MF) || Subtarget.hasBackChain())
1026 CSI.push_back(CalleeSavedInfo(Regs.getStackPointerRegister()));
1027
1028 // If this function has an associated personality function then the
1029 // environment register R5 must be saved in the DSA.
1030 if (!MF.getLandingPads().empty())
1031 CSI.push_back(CalleeSavedInfo(Regs.getADARegister()));
1032
1033 // Scan the call-saved GPRs and find the bounds of the register spill area.
1034 Register LowRestoreGPR = 0;
1035 int LowRestoreOffset = INT32_MAX;
1036 Register LowSpillGPR = 0;
1037 int LowSpillOffset = INT32_MAX;
1038 Register HighGPR = 0;
1039 int HighOffset = -1;
1040
1041 // Query index of the saved frame pointer.
1042 int FPSI = MFI->getFramePointerSaveIndex();
1043
1044 for (auto &CS : CSI) {
1045 MCRegister Reg = CS.getReg();
1046 int Offset = RegSpillOffsets[Reg];
1047 if (Offset >= 0) {
1048 if (GRRegClass.contains(Reg)) {
1049 if (LowSpillOffset > Offset) {
1050 LowSpillOffset = Offset;
1051 LowSpillGPR = Reg;
1052 }
1053 if (CS.isRestored() && LowRestoreOffset > Offset) {
1054 LowRestoreOffset = Offset;
1055 LowRestoreGPR = Reg;
1056 }
1057
1058 if (Offset > HighOffset) {
1059 HighOffset = Offset;
1060 HighGPR = Reg;
1061 }
1062 // Non-volatile GPRs are saved in the dedicated register save area at
1063 // the bottom of the stack and are not truly part of the "normal" stack
1064 // frame. Mark the frame index as NoAlloc to indicate it as such.
1065 unsigned RegSize = getPointerSize();
1066 int FrameIdx =
1067 (FPSI && Offset == 0)
1068 ? FPSI
1070 CS.setFrameIdx(FrameIdx);
1071 MFFrame.setStackID(FrameIdx, TargetStackID::NoAlloc);
1072 }
1073 } else {
1074 MCRegister Reg = CS.getReg();
1075 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
1076 Align Alignment = TRI->getSpillAlign(*RC);
1077 unsigned Size = TRI->getSpillSize(*RC);
1078 Alignment = std::min(Alignment, getStackAlign());
1079 int FrameIdx = MFFrame.CreateStackObject(Size, Alignment, true);
1080 CS.setFrameIdx(FrameIdx);
1081 }
1082 }
1083
1084 // Save the range of call-saved registers, for use by the
1085 // prologue/epilogue inserters.
1086 if (LowRestoreGPR)
1087 MFI->setRestoreGPRRegs(LowRestoreGPR, HighGPR, LowRestoreOffset);
1088
1089 // Save the range of call-saved registers, for use by the epilogue inserter.
1090 assert(LowSpillGPR && "Expected registers to spill");
1091 MFI->setSpillGPRRegs(LowSpillGPR, HighGPR, LowSpillOffset);
1092
1093 return true;
1094}
1095
1097 BitVector &SavedRegs,
1098 RegScavenger *RS) const {
1100
1101 bool HasFP = hasFP(MF);
1102 const SystemZSubtarget &Subtarget = MF.getSubtarget<SystemZSubtarget>();
1103 auto &Regs = Subtarget.getSpecialRegisters<SystemZXPLINK64Registers>();
1104
1105 // If the function requires a frame pointer, record that the hard
1106 // frame pointer will be clobbered.
1107 if (HasFP)
1108 SavedRegs.set(Regs.getFramePointerRegister());
1109}
1110
1114 if (CSI.empty())
1115 return true;
1116
1117 MachineFunction &MF = *MBB.getParent();
1119 const SystemZSubtarget &Subtarget = MF.getSubtarget<SystemZSubtarget>();
1120 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
1121 auto &Regs = Subtarget.getSpecialRegisters<SystemZXPLINK64Registers>();
1122 SystemZ::GPRRegs SpillGPRs = ZFI->getSpillGPRRegs();
1123 DebugLoc DL;
1124
1125 // Save GPRs
1126 if (SpillGPRs.LowGPR) {
1127 assert(SpillGPRs.LowGPR != SpillGPRs.HighGPR &&
1128 "Should be saving multiple registers");
1129
1130 // Build an STM/STMG instruction.
1131 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(SystemZ::STMG));
1132
1133 // Add the explicit register operands.
1134 addSavedGPR(MBB, MIB, SpillGPRs.LowGPR, false);
1135 addSavedGPR(MBB, MIB, SpillGPRs.HighGPR, false);
1136
1137 // Add the address r4
1138 MIB.addReg(Regs.getStackPointerRegister());
1139
1140 // Add the partial offset
1141 // We cannot add the actual offset as, at the stack is not finalized
1142 MIB.addImm(SpillGPRs.GPROffset);
1143
1144 // Make sure all call-saved GPRs are included as operands and are
1145 // marked as live on entry.
1146 auto &GRRegClass = SystemZ::GR64BitRegClass;
1147 for (const CalleeSavedInfo &I : CSI) {
1148 MCRegister Reg = I.getReg();
1149 if (GRRegClass.contains(Reg))
1150 addSavedGPR(MBB, MIB, Reg, true);
1151 }
1152 }
1153
1154 // Spill FPRs to the stack in the normal TargetInstrInfo way
1155 for (const CalleeSavedInfo &I : CSI) {
1156 MCRegister Reg = I.getReg();
1157 if (SystemZ::FP64BitRegClass.contains(Reg)) {
1158 MBB.addLiveIn(Reg);
1159 TII->storeRegToStackSlot(MBB, MBBI, Reg, true, I.getFrameIdx(),
1160 &SystemZ::FP64BitRegClass, TRI, Register());
1161 }
1162 if (SystemZ::VR128BitRegClass.contains(Reg)) {
1163 MBB.addLiveIn(Reg);
1164 TII->storeRegToStackSlot(MBB, MBBI, Reg, true, I.getFrameIdx(),
1165 &SystemZ::VR128BitRegClass, TRI, Register());
1166 }
1167 }
1168
1169 return true;
1170}
1171
1175
1176 if (CSI.empty())
1177 return false;
1178
1179 MachineFunction &MF = *MBB.getParent();
1181 const SystemZSubtarget &Subtarget = MF.getSubtarget<SystemZSubtarget>();
1182 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
1183 auto &Regs = Subtarget.getSpecialRegisters<SystemZXPLINK64Registers>();
1184
1185 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
1186
1187 // Restore FPRs in the normal TargetInstrInfo way.
1188 for (const CalleeSavedInfo &I : CSI) {
1189 MCRegister Reg = I.getReg();
1190 if (SystemZ::FP64BitRegClass.contains(Reg))
1191 TII->loadRegFromStackSlot(MBB, MBBI, Reg, I.getFrameIdx(),
1192 &SystemZ::FP64BitRegClass, TRI, Register());
1193 if (SystemZ::VR128BitRegClass.contains(Reg))
1194 TII->loadRegFromStackSlot(MBB, MBBI, Reg, I.getFrameIdx(),
1195 &SystemZ::VR128BitRegClass, TRI, Register());
1196 }
1197
1198 // Restore call-saved GPRs (but not call-clobbered varargs, which at
1199 // this point might hold return values).
1200 SystemZ::GPRRegs RestoreGPRs = ZFI->getRestoreGPRRegs();
1201 if (RestoreGPRs.LowGPR) {
1202 assert(isInt<20>(Regs.getStackPointerBias() + RestoreGPRs.GPROffset));
1203 if (RestoreGPRs.LowGPR == RestoreGPRs.HighGPR)
1204 // Build an LG/L instruction.
1205 BuildMI(MBB, MBBI, DL, TII->get(SystemZ::LG), RestoreGPRs.LowGPR)
1206 .addReg(Regs.getStackPointerRegister())
1207 .addImm(Regs.getStackPointerBias() + RestoreGPRs.GPROffset)
1208 .addReg(0);
1209 else {
1210 // Build an LMG/LM instruction.
1211 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(SystemZ::LMG));
1212
1213 // Add the explicit register operands.
1214 MIB.addReg(RestoreGPRs.LowGPR, RegState::Define);
1215 MIB.addReg(RestoreGPRs.HighGPR, RegState::Define);
1216
1217 // Add the address.
1218 MIB.addReg(Regs.getStackPointerRegister());
1219 MIB.addImm(Regs.getStackPointerBias() + RestoreGPRs.GPROffset);
1220
1221 // Do a second scan adding regs as being defined by instruction
1222 for (const CalleeSavedInfo &I : CSI) {
1223 MCRegister Reg = I.getReg();
1224 if (Reg > RestoreGPRs.LowGPR && Reg < RestoreGPRs.HighGPR)
1226 }
1227 }
1228 }
1229
1230 return true;
1231}
1232
1234 MachineBasicBlock &MBB) const {
1235 assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
1236 const SystemZSubtarget &Subtarget = MF.getSubtarget<SystemZSubtarget>();
1239 auto *ZII = Subtarget.getInstrInfo();
1240 auto &Regs = Subtarget.getSpecialRegisters<SystemZXPLINK64Registers>();
1241 MachineFrameInfo &MFFrame = MF.getFrameInfo();
1242 MachineInstr *StoreInstr = nullptr;
1243
1245
1246 bool HasFP = hasFP(MF);
1247 // Debug location must be unknown since the first debug location is used
1248 // to determine the end of the prologue.
1249 DebugLoc DL;
1250 uint64_t Offset = 0;
1251
1252 const uint64_t StackSize = MFFrame.getStackSize();
1253
1254 if (ZFI->getSpillGPRRegs().LowGPR) {
1255 // Skip over the GPR saves.
1256 if ((MBBI != MBB.end()) && ((MBBI->getOpcode() == SystemZ::STMG))) {
1257 const int Operand = 3;
1258 // Now we can set the offset for the operation, since now the Stack
1259 // has been finalized.
1260 Offset = Regs.getStackPointerBias() + MBBI->getOperand(Operand).getImm();
1261 // Maximum displacement for STMG instruction.
1262 if (isInt<20>(Offset - StackSize))
1263 Offset -= StackSize;
1264 else
1265 StoreInstr = &*MBBI;
1266 MBBI->getOperand(Operand).setImm(Offset);
1267 ++MBBI;
1268 } else
1269 llvm_unreachable("Couldn't skip over GPR saves");
1270 }
1271
1272 if (StackSize) {
1273 MachineBasicBlock::iterator InsertPt = StoreInstr ? StoreInstr : MBBI;
1274 // Allocate StackSize bytes.
1275 int64_t Delta = -int64_t(StackSize);
1276
1277 // In case the STM(G) instruction also stores SP (R4), but the displacement
1278 // is too large, the SP register is manipulated first before storing,
1279 // resulting in the wrong value stored and retrieved later. In this case, we
1280 // need to temporarily save the value of SP, and store it later to memory.
1281 if (StoreInstr && HasFP) {
1282 // Insert LR r0,r4 before STMG instruction.
1283 BuildMI(MBB, InsertPt, DL, ZII->get(SystemZ::LGR))
1284 .addReg(SystemZ::R0D, RegState::Define)
1285 .addReg(SystemZ::R4D);
1286 // Insert ST r0,xxx(,r4) after STMG instruction.
1287 BuildMI(MBB, MBBI, DL, ZII->get(SystemZ::STG))
1288 .addReg(SystemZ::R0D, RegState::Kill)
1289 .addReg(SystemZ::R4D)
1290 .addImm(Offset)
1291 .addReg(0);
1292 }
1293
1294 emitIncrement(MBB, InsertPt, DL, Regs.getStackPointerRegister(), Delta,
1295 ZII);
1296
1297 // If the requested stack size is larger than the guard page, then we need
1298 // to check if we need to call the stack extender. This requires adding a
1299 // conditional branch, but splitting the prologue block is not possible at
1300 // this point since it would invalidate the SaveBlocks / RestoreBlocks sets
1301 // of PEI in the single block function case. Build a pseudo to be handled
1302 // later by inlineStackProbe().
1303 const uint64_t GuardPageSize = 1024 * 1024;
1304 if (StackSize > GuardPageSize) {
1305 assert(StoreInstr && "Wrong insertion point");
1306 BuildMI(MBB, InsertPt, DL, ZII->get(SystemZ::XPLINK_STACKALLOC));
1307 }
1308 }
1309
1310 if (HasFP) {
1311 // Copy the base of the frame to Frame Pointer Register.
1312 BuildMI(MBB, MBBI, DL, ZII->get(SystemZ::LGR),
1313 Regs.getFramePointerRegister())
1314 .addReg(Regs.getStackPointerRegister());
1315
1316 // Mark the FramePtr as live at the beginning of every block except
1317 // the entry block. (We'll have marked R8 as live on entry when
1318 // saving the GPRs.)
1320 B.addLiveIn(Regs.getFramePointerRegister());
1321 }
1322
1323 // Save GPRs used for varargs, if any.
1324 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
1325 bool IsVarArg = MF.getFunction().isVarArg();
1326
1327 if (IsVarArg) {
1328 // FixedRegs is the number of used registers, accounting for shadow
1329 // registers.
1330 unsigned FixedRegs = ZFI->getVarArgsFirstGPR() + ZFI->getVarArgsFirstFPR();
1331 auto &GPRs = SystemZ::XPLINK64ArgGPRs;
1332 for (unsigned I = FixedRegs; I < SystemZ::XPLINK64NumArgGPRs; I++) {
1333 uint64_t StartOffset = MFFrame.getOffsetAdjustment() +
1334 MFFrame.getStackSize() + Regs.getCallFrameSize() +
1336 unsigned Reg = GPRs[I];
1337 BuildMI(MBB, MBBI, DL, TII->get(SystemZ::STG))
1338 .addReg(Reg)
1339 .addReg(Regs.getStackPointerRegister())
1340 .addImm(StartOffset)
1341 .addReg(0);
1342 if (!MBB.isLiveIn(Reg))
1343 MBB.addLiveIn(Reg);
1344 }
1345 }
1346}
1347
1349 MachineBasicBlock &MBB) const {
1350 const SystemZSubtarget &Subtarget = MF.getSubtarget<SystemZSubtarget>();
1353 MachineFrameInfo &MFFrame = MF.getFrameInfo();
1354 auto *ZII = Subtarget.getInstrInfo();
1355 auto &Regs = Subtarget.getSpecialRegisters<SystemZXPLINK64Registers>();
1356
1357 // Skip the return instruction.
1358 assert(MBBI->isReturn() && "Can only insert epilogue into returning blocks");
1359
1360 uint64_t StackSize = MFFrame.getStackSize();
1361 if (StackSize) {
1362 unsigned SPReg = Regs.getStackPointerRegister();
1363 if (ZFI->getRestoreGPRRegs().LowGPR != SPReg) {
1364 DebugLoc DL = MBBI->getDebugLoc();
1365 emitIncrement(MBB, MBBI, DL, SPReg, StackSize, ZII);
1366 }
1367 }
1368}
1369
1370// Emit a compare of the stack pointer against the stack floor, and a call to
1371// the LE stack extender if needed.
1373 MachineFunction &MF, MachineBasicBlock &PrologMBB) const {
1374 auto *ZII =
1375 static_cast<const SystemZInstrInfo *>(MF.getSubtarget().getInstrInfo());
1376
1377 MachineInstr *StackAllocMI = nullptr;
1378 for (MachineInstr &MI : PrologMBB)
1379 if (MI.getOpcode() == SystemZ::XPLINK_STACKALLOC) {
1380 StackAllocMI = &MI;
1381 break;
1382 }
1383 if (StackAllocMI == nullptr)
1384 return;
1385
1386 bool NeedSaveSP = hasFP(MF);
1387 bool NeedSaveArg = PrologMBB.isLiveIn(SystemZ::R3D);
1388 const int64_t SaveSlotR3 = 2192;
1389
1390 MachineBasicBlock &MBB = PrologMBB;
1391 const DebugLoc DL = StackAllocMI->getDebugLoc();
1392
1393 // The 2nd half of block MBB after split.
1394 MachineBasicBlock *NextMBB;
1395
1396 // Add new basic block for the call to the stack overflow function.
1397 MachineBasicBlock *StackExtMBB =
1399 MF.push_back(StackExtMBB);
1400
1401 // LG r3,72(,r3)
1402 BuildMI(StackExtMBB, DL, ZII->get(SystemZ::LG), SystemZ::R3D)
1403 .addReg(SystemZ::R3D)
1404 .addImm(72)
1405 .addReg(0);
1406 // BASR r3,r3
1407 BuildMI(StackExtMBB, DL, ZII->get(SystemZ::CallBASR_STACKEXT))
1408 .addReg(SystemZ::R3D);
1409 if (NeedSaveArg) {
1410 if (!NeedSaveSP) {
1411 // LGR r0,r3
1412 BuildMI(MBB, StackAllocMI, DL, ZII->get(SystemZ::LGR))
1413 .addReg(SystemZ::R0D, RegState::Define)
1414 .addReg(SystemZ::R3D);
1415 } else {
1416 // In this case, the incoming value of r4 is saved in r0 so the
1417 // latter register is unavailable. Store r3 in its corresponding
1418 // slot in the parameter list instead. Do this at the start of
1419 // the prolog before r4 is manipulated by anything else.
1420 // STG r3, 2192(r4)
1421 BuildMI(MBB, MBB.begin(), DL, ZII->get(SystemZ::STG))
1422 .addReg(SystemZ::R3D)
1423 .addReg(SystemZ::R4D)
1424 .addImm(SaveSlotR3)
1425 .addReg(0);
1426 }
1427 }
1428 // LLGT r3,1208
1429 BuildMI(MBB, StackAllocMI, DL, ZII->get(SystemZ::LLGT), SystemZ::R3D)
1430 .addReg(0)
1431 .addImm(1208)
1432 .addReg(0);
1433 // CG r4,64(,r3)
1434 BuildMI(MBB, StackAllocMI, DL, ZII->get(SystemZ::CG))
1435 .addReg(SystemZ::R4D)
1436 .addReg(SystemZ::R3D)
1437 .addImm(64)
1438 .addReg(0);
1439 // JLL b'0100',F'37'
1440 BuildMI(MBB, StackAllocMI, DL, ZII->get(SystemZ::BRC))
1443 .addMBB(StackExtMBB);
1444
1445 NextMBB = SystemZ::splitBlockBefore(StackAllocMI, &MBB);
1446 MBB.addSuccessor(NextMBB);
1447 MBB.addSuccessor(StackExtMBB);
1448 if (NeedSaveArg) {
1449 if (!NeedSaveSP) {
1450 // LGR r3, r0
1451 BuildMI(*NextMBB, StackAllocMI, DL, ZII->get(SystemZ::LGR))
1452 .addReg(SystemZ::R3D, RegState::Define)
1453 .addReg(SystemZ::R0D, RegState::Kill);
1454 } else {
1455 // In this case, the incoming value of r4 is saved in r0 so the
1456 // latter register is unavailable. We stored r3 in its corresponding
1457 // slot in the parameter list instead and we now restore it from there.
1458 // LGR r3, r0
1459 BuildMI(*NextMBB, StackAllocMI, DL, ZII->get(SystemZ::LGR))
1460 .addReg(SystemZ::R3D, RegState::Define)
1461 .addReg(SystemZ::R0D);
1462 // LG r3, 2192(r3)
1463 BuildMI(*NextMBB, StackAllocMI, DL, ZII->get(SystemZ::LG))
1464 .addReg(SystemZ::R3D, RegState::Define)
1465 .addReg(SystemZ::R3D)
1466 .addImm(SaveSlotR3)
1467 .addReg(0);
1468 }
1469 }
1470
1471 // Add jump back from stack extension BB.
1472 BuildMI(StackExtMBB, DL, ZII->get(SystemZ::J)).addMBB(NextMBB);
1473 StackExtMBB->addSuccessor(NextMBB);
1474
1475 StackAllocMI->eraseFromParent();
1476
1477 // Compute the live-in lists for the new blocks.
1478 fullyRecomputeLiveIns({StackExtMBB, NextMBB});
1479}
1480
1482 return (MF.getFrameInfo().hasVarSizedObjects());
1483}
1484
1486 MachineFunction &MF, RegScavenger *RS) const {
1487 MachineFrameInfo &MFFrame = MF.getFrameInfo();
1488 const SystemZSubtarget &Subtarget = MF.getSubtarget<SystemZSubtarget>();
1489 auto &Regs = Subtarget.getSpecialRegisters<SystemZXPLINK64Registers>();
1490
1491 // Setup stack frame offset
1492 MFFrame.setOffsetAdjustment(Regs.getStackPointerBias());
1493
1494 // Nothing to do for leaf functions.
1495 uint64_t StackSize = MFFrame.estimateStackSize(MF);
1496 if (StackSize == 0 && MFFrame.getCalleeSavedInfo().empty())
1497 return;
1498
1499 // Although the XPLINK specifications for AMODE64 state that minimum size
1500 // of the param area is minimum 32 bytes and no rounding is otherwise
1501 // specified, we round this area in 64 bytes increments to be compatible
1502 // with existing compilers.
1503 MFFrame.setMaxCallFrameSize(
1504 std::max(64U, (unsigned)alignTo(MFFrame.getMaxCallFrameSize(), 64)));
1505
1506 // Add frame values with positive object offsets. Since the displacement from
1507 // the SP/FP is calculated by ObjectOffset + StackSize + Bias, object offsets
1508 // with positive values are in the caller's stack frame. We need to include
1509 // that since it is accessed by displacement to SP/FP.
1510 int64_t LargestArgOffset = 0;
1511 for (int I = MFFrame.getObjectIndexBegin(); I != 0; ++I) {
1512 if (MFFrame.getObjectOffset(I) >= 0) {
1513 int64_t ObjOffset = MFFrame.getObjectOffset(I) + MFFrame.getObjectSize(I);
1514 LargestArgOffset = std::max(ObjOffset, LargestArgOffset);
1515 }
1516 }
1517
1518 uint64_t MaxReach = (StackSize + Regs.getCallFrameSize() +
1519 Regs.getStackPointerBias() + LargestArgOffset);
1520
1521 if (!isUInt<12>(MaxReach)) {
1522 // We may need register scavenging slots if some parts of the frame
1523 // are outside the reach of an unsigned 12-bit displacement.
1526 }
1527}
1528
1529// Determines the size of the frame, and creates the deferred spill objects.
1531 MachineFunction &MF) const {
1532 MachineFrameInfo &MFFrame = MF.getFrameInfo();
1533 const SystemZSubtarget &Subtarget = MF.getSubtarget<SystemZSubtarget>();
1534 auto *Regs =
1535 static_cast<SystemZXPLINK64Registers *>(Subtarget.getSpecialRegisters());
1536
1537 uint64_t StackSize = MFFrame.getStackSize();
1538 if (StackSize == 0)
1539 return;
1540
1541 // Add the size of the register save area and the reserved area to the size.
1542 StackSize += Regs->getCallFrameSize();
1543 MFFrame.setStackSize(StackSize);
1544
1545 // We now know the stack size. Update the stack objects for the register save
1546 // area now. This has no impact on the stack frame layout, as this is already
1547 // computed. However, it makes sure that all callee saved registers have a
1548 // valid offset assigned.
1549 for (int FrameIdx = MFFrame.getObjectIndexBegin(); FrameIdx != 0;
1550 ++FrameIdx) {
1551 if (MFFrame.getStackID(FrameIdx) == TargetStackID::NoAlloc) {
1552 int64_t SPOffset = MFFrame.getObjectOffset(FrameIdx);
1553 SPOffset -= StackSize;
1554 MFFrame.setObjectOffset(FrameIdx, SPOffset);
1555 }
1556 }
1557}
unsigned const MachineRegisterInfo * MRI
unsigned RegSize
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
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
uint64_t Size
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
#define I(x, y, z)
Definition: MD5.cpp:58
Register const TargetRegisterInfo * TRI
static constexpr MCPhysReg SPReg
This file declares the machine register scavenger class.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition: Value.cpp:480
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),...
Definition: ArrayRef.h:41
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:142
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
Definition: Attributes.cpp:400
bool test(unsigned Idx) const
Definition: BitVector.h:461
BitVector & set()
Definition: BitVector.h:351
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
A debug info location.
Definition: DebugLoc.h:124
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
Definition: Function.cpp:762
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition: Function.h:270
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition: Function.h:227
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.cpp:727
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.
void grow(IndexT n)
Definition: IndexedMap.h:69
static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register, SMLoc Loc={})
.cfi_def_cfa_register modifies a rule for computing CFA.
Definition: MCDwarf.h:592
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.
Definition: MCDwarf.h:627
static MCCFIInstruction cfiDefCfaOffset(MCSymbol *L, int64_t Offset, SMLoc Loc={})
.cfi_def_cfa_offset modifies a rule for computing CFA.
Definition: MCDwarf.h:600
const MCRegisterInfo * getRegisterInfo() const
Definition: MCContext.h:414
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
LLVM_ABI 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.
LLVM_ABI 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)
LLVM_ABI 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.
LLVM_ABI 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.
LLVM_ABI int CreateSpillStackObject(uint64_t Size, Align Alignment)
Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...
LLVM_ABI 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.
LLVM_ABI 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 & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
const MachineInstrBuilder & addCFIIndex(unsigned CFIIndex) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
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.
Definition: MachineInstr.h:72
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:511
LLVM_ABI void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:595
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.
int64_t getImm() const
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...
Definition: ArrayRef.h:303
void addScavengingFrameIndex(int FI)
Add a scavenging frame index.
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
size_t size() const
Definition: SmallVector.h:79
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:574
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
StackOffset holds a fixed and a scalable offset in bytes.
Definition: TypeSize.h:34
int64_t getFixed() const
Returns the fixed component of the stack.
Definition: TypeSize.h:50
static StackOffset getFixed(int64_t Fixed)
Definition: TypeSize.h:43
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)
SystemZFrameLowering(StackDirection D, Align StackAl, int LAO, Align TransAl, bool StackReal, unsigned PointerSize)
void setRestoreGPRRegs(Register Low, Register High, unsigned Offs)
void setSpillGPRRegs(Register Low, Register High, unsigned Offs)
const SystemZInstrInfo * getInstrInfo() const override
const SystemZTargetLowering * getTargetLowering() const override
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.
TargetOptions Options
LLVM_ABI bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
virtual const TargetLowering * getTargetLowering() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ AnyReg
OBSOLETED - Used for stack based JavaScript calls.
Definition: CallingConv.h:60
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
Definition: CallingConv.h:50
@ 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
Definition: SystemZ.h:37
MachineBasicBlock * emitBlockAfter(MachineBasicBlock *MBB)
const unsigned CCMASK_ICMP
Definition: SystemZ.h:47
const unsigned XPLINK64NumArgGPRs
const MCPhysReg ELFArgGPRs[ELFNumArgGPRs]
const unsigned CCMASK_CMP_LT
Definition: SystemZ.h:36
const unsigned ELFNumArgGPRs
const MCPhysReg XPLINK64ArgGPRs[XPLINK64NumArgGPRs]
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition: STLExtras.h:338
@ Offset
Definition: DWP.cpp:477
void stable_sort(R &&Range)
Definition: STLExtras.h:2077
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned getImplRegState(bool B)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition: Error.cpp:167
unsigned getKillRegState(bool B)
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
void fullyRecomputeLiveIns(ArrayRef< MachineBasicBlock * > MBBs)
Convenience function for recomputing live-in's for a set of MBBs until the computation converges.
Definition: LivePhysRegs.h:225
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
This class contains a discriminated union of information about pointers in memory operands,...