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