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