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