[ARM] MVE integer min and max
[llvm-complete.git] / lib / Target / SystemZ / SystemZFrameLowering.cpp
blobda28faebb3264be8d3f463a12a5d2ae1c93b2283
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 //===----------------------------------------------------------------------===//
9 #include "SystemZFrameLowering.h"
10 #include "SystemZCallingConv.h"
11 #include "SystemZInstrBuilder.h"
12 #include "SystemZInstrInfo.h"
13 #include "SystemZMachineFunctionInfo.h"
14 #include "SystemZRegisterInfo.h"
15 #include "SystemZSubtarget.h"
16 #include "llvm/CodeGen/MachineModuleInfo.h"
17 #include "llvm/CodeGen/MachineRegisterInfo.h"
18 #include "llvm/CodeGen/RegisterScavenging.h"
19 #include "llvm/IR/Function.h"
21 using namespace llvm;
23 namespace {
24 // The ABI-defined register save slots, relative to the incoming stack
25 // pointer.
26 static const TargetFrameLowering::SpillSlot SpillOffsetTable[] = {
27 { SystemZ::R2D, 0x10 },
28 { SystemZ::R3D, 0x18 },
29 { SystemZ::R4D, 0x20 },
30 { SystemZ::R5D, 0x28 },
31 { SystemZ::R6D, 0x30 },
32 { SystemZ::R7D, 0x38 },
33 { SystemZ::R8D, 0x40 },
34 { SystemZ::R9D, 0x48 },
35 { SystemZ::R10D, 0x50 },
36 { SystemZ::R11D, 0x58 },
37 { SystemZ::R12D, 0x60 },
38 { SystemZ::R13D, 0x68 },
39 { SystemZ::R14D, 0x70 },
40 { SystemZ::R15D, 0x78 },
41 { SystemZ::F0D, 0x80 },
42 { SystemZ::F2D, 0x88 },
43 { SystemZ::F4D, 0x90 },
44 { SystemZ::F6D, 0x98 }
46 } // end anonymous namespace
48 SystemZFrameLowering::SystemZFrameLowering()
49 : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 8,
50 -SystemZMC::CallFrameSize, 8,
51 false /* StackRealignable */) {
52 // Create a mapping from register number to save slot offset.
53 RegSpillOffsets.grow(SystemZ::NUM_TARGET_REGS);
54 for (unsigned I = 0, E = array_lengthof(SpillOffsetTable); I != E; ++I)
55 RegSpillOffsets[SpillOffsetTable[I].Reg] = SpillOffsetTable[I].Offset;
58 const TargetFrameLowering::SpillSlot *
59 SystemZFrameLowering::getCalleeSavedSpillSlots(unsigned &NumEntries) const {
60 NumEntries = array_lengthof(SpillOffsetTable);
61 return SpillOffsetTable;
64 void SystemZFrameLowering::determineCalleeSaves(MachineFunction &MF,
65 BitVector &SavedRegs,
66 RegScavenger *RS) const {
67 TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
69 MachineFrameInfo &MFFrame = MF.getFrameInfo();
70 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
71 bool HasFP = hasFP(MF);
72 SystemZMachineFunctionInfo *MFI = MF.getInfo<SystemZMachineFunctionInfo>();
73 bool IsVarArg = MF.getFunction().isVarArg();
75 // va_start stores incoming FPR varargs in the normal way, but delegates
76 // the saving of incoming GPR varargs to spillCalleeSavedRegisters().
77 // Record these pending uses, which typically include the call-saved
78 // argument register R6D.
79 if (IsVarArg)
80 for (unsigned I = MFI->getVarArgsFirstGPR(); I < SystemZ::NumArgGPRs; ++I)
81 SavedRegs.set(SystemZ::ArgGPRs[I]);
83 // If there are any landing pads, entering them will modify r6/r7.
84 if (!MF.getLandingPads().empty()) {
85 SavedRegs.set(SystemZ::R6D);
86 SavedRegs.set(SystemZ::R7D);
89 // If the function requires a frame pointer, record that the hard
90 // frame pointer will be clobbered.
91 if (HasFP)
92 SavedRegs.set(SystemZ::R11D);
94 // If the function calls other functions, record that the return
95 // address register will be clobbered.
96 if (MFFrame.hasCalls())
97 SavedRegs.set(SystemZ::R14D);
99 // If we are saving GPRs other than the stack pointer, we might as well
100 // save and restore the stack pointer at the same time, via STMG and LMG.
101 // This allows the deallocation to be done by the LMG, rather than needing
102 // a separate %r15 addition.
103 const MCPhysReg *CSRegs = TRI->getCalleeSavedRegs(&MF);
104 for (unsigned I = 0; CSRegs[I]; ++I) {
105 unsigned Reg = CSRegs[I];
106 if (SystemZ::GR64BitRegClass.contains(Reg) && SavedRegs.test(Reg)) {
107 SavedRegs.set(SystemZ::R15D);
108 break;
113 // Add GPR64 to the save instruction being built by MIB, which is in basic
114 // block MBB. IsImplicit says whether this is an explicit operand to the
115 // instruction, or an implicit one that comes between the explicit start
116 // and end registers.
117 static void addSavedGPR(MachineBasicBlock &MBB, MachineInstrBuilder &MIB,
118 unsigned GPR64, bool IsImplicit) {
119 const TargetRegisterInfo *RI =
120 MBB.getParent()->getSubtarget().getRegisterInfo();
121 unsigned GPR32 = RI->getSubReg(GPR64, SystemZ::subreg_l32);
122 bool IsLive = MBB.isLiveIn(GPR64) || MBB.isLiveIn(GPR32);
123 if (!IsLive || !IsImplicit) {
124 MIB.addReg(GPR64, getImplRegState(IsImplicit) | getKillRegState(!IsLive));
125 if (!IsLive)
126 MBB.addLiveIn(GPR64);
130 bool SystemZFrameLowering::
131 spillCalleeSavedRegisters(MachineBasicBlock &MBB,
132 MachineBasicBlock::iterator MBBI,
133 const std::vector<CalleeSavedInfo> &CSI,
134 const TargetRegisterInfo *TRI) const {
135 if (CSI.empty())
136 return false;
138 MachineFunction &MF = *MBB.getParent();
139 const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
140 SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>();
141 bool IsVarArg = MF.getFunction().isVarArg();
142 DebugLoc DL;
144 // Scan the call-saved GPRs and find the bounds of the register spill area.
145 unsigned LowGPR = 0;
146 unsigned HighGPR = SystemZ::R15D;
147 unsigned StartOffset = -1U;
148 for (unsigned I = 0, E = CSI.size(); I != E; ++I) {
149 unsigned Reg = CSI[I].getReg();
150 if (SystemZ::GR64BitRegClass.contains(Reg)) {
151 unsigned Offset = RegSpillOffsets[Reg];
152 assert(Offset && "Unexpected GPR save");
153 if (StartOffset > Offset) {
154 LowGPR = Reg;
155 StartOffset = Offset;
160 // Save the range of call-saved registers, for use by the epilogue inserter.
161 ZFI->setLowSavedGPR(LowGPR);
162 ZFI->setHighSavedGPR(HighGPR);
164 // Include the GPR varargs, if any. R6D is call-saved, so would
165 // be included by the loop above, but we also need to handle the
166 // call-clobbered argument registers.
167 if (IsVarArg) {
168 unsigned FirstGPR = ZFI->getVarArgsFirstGPR();
169 if (FirstGPR < SystemZ::NumArgGPRs) {
170 unsigned Reg = SystemZ::ArgGPRs[FirstGPR];
171 unsigned Offset = RegSpillOffsets[Reg];
172 if (StartOffset > Offset) {
173 LowGPR = Reg; StartOffset = Offset;
178 // Save GPRs
179 if (LowGPR) {
180 assert(LowGPR != HighGPR && "Should be saving %r15 and something else");
182 // Build an STMG instruction.
183 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(SystemZ::STMG));
185 // Add the explicit register operands.
186 addSavedGPR(MBB, MIB, LowGPR, false);
187 addSavedGPR(MBB, MIB, HighGPR, false);
189 // Add the address.
190 MIB.addReg(SystemZ::R15D).addImm(StartOffset);
192 // Make sure all call-saved GPRs are included as operands and are
193 // marked as live on entry.
194 for (unsigned I = 0, E = CSI.size(); I != E; ++I) {
195 unsigned Reg = CSI[I].getReg();
196 if (SystemZ::GR64BitRegClass.contains(Reg))
197 addSavedGPR(MBB, MIB, Reg, true);
200 // ...likewise GPR varargs.
201 if (IsVarArg)
202 for (unsigned I = ZFI->getVarArgsFirstGPR(); I < SystemZ::NumArgGPRs; ++I)
203 addSavedGPR(MBB, MIB, SystemZ::ArgGPRs[I], true);
206 // Save FPRs/VRs in the normal TargetInstrInfo way.
207 for (unsigned I = 0, E = CSI.size(); I != E; ++I) {
208 unsigned Reg = CSI[I].getReg();
209 if (SystemZ::FP64BitRegClass.contains(Reg)) {
210 MBB.addLiveIn(Reg);
211 TII->storeRegToStackSlot(MBB, MBBI, Reg, true, CSI[I].getFrameIdx(),
212 &SystemZ::FP64BitRegClass, TRI);
214 if (SystemZ::VR128BitRegClass.contains(Reg)) {
215 MBB.addLiveIn(Reg);
216 TII->storeRegToStackSlot(MBB, MBBI, Reg, true, CSI[I].getFrameIdx(),
217 &SystemZ::VR128BitRegClass, TRI);
221 return true;
224 bool SystemZFrameLowering::
225 restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
226 MachineBasicBlock::iterator MBBI,
227 std::vector<CalleeSavedInfo> &CSI,
228 const TargetRegisterInfo *TRI) const {
229 if (CSI.empty())
230 return false;
232 MachineFunction &MF = *MBB.getParent();
233 const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
234 SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>();
235 bool HasFP = hasFP(MF);
236 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
238 // Restore FPRs/VRs in the normal TargetInstrInfo way.
239 for (unsigned I = 0, E = CSI.size(); I != E; ++I) {
240 unsigned Reg = CSI[I].getReg();
241 if (SystemZ::FP64BitRegClass.contains(Reg))
242 TII->loadRegFromStackSlot(MBB, MBBI, Reg, CSI[I].getFrameIdx(),
243 &SystemZ::FP64BitRegClass, TRI);
244 if (SystemZ::VR128BitRegClass.contains(Reg))
245 TII->loadRegFromStackSlot(MBB, MBBI, Reg, CSI[I].getFrameIdx(),
246 &SystemZ::VR128BitRegClass, TRI);
249 // Restore call-saved GPRs (but not call-clobbered varargs, which at
250 // this point might hold return values).
251 unsigned LowGPR = ZFI->getLowSavedGPR();
252 unsigned HighGPR = ZFI->getHighSavedGPR();
253 unsigned StartOffset = RegSpillOffsets[LowGPR];
254 if (LowGPR) {
255 // If we saved any of %r2-%r5 as varargs, we should also be saving
256 // and restoring %r6. If we're saving %r6 or above, we should be
257 // restoring it too.
258 assert(LowGPR != HighGPR && "Should be loading %r15 and something else");
260 // Build an LMG instruction.
261 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(SystemZ::LMG));
263 // Add the explicit register operands.
264 MIB.addReg(LowGPR, RegState::Define);
265 MIB.addReg(HighGPR, RegState::Define);
267 // Add the address.
268 MIB.addReg(HasFP ? SystemZ::R11D : SystemZ::R15D);
269 MIB.addImm(StartOffset);
271 // Do a second scan adding regs as being defined by instruction
272 for (unsigned I = 0, E = CSI.size(); I != E; ++I) {
273 unsigned Reg = CSI[I].getReg();
274 if (Reg != LowGPR && Reg != HighGPR &&
275 SystemZ::GR64BitRegClass.contains(Reg))
276 MIB.addReg(Reg, RegState::ImplicitDefine);
280 return true;
283 void SystemZFrameLowering::
284 processFunctionBeforeFrameFinalized(MachineFunction &MF,
285 RegScavenger *RS) const {
286 MachineFrameInfo &MFFrame = MF.getFrameInfo();
287 // Get the size of our stack frame to be allocated ...
288 uint64_t StackSize = (MFFrame.estimateStackSize(MF) +
289 SystemZMC::CallFrameSize);
290 // ... and the maximum offset we may need to reach into the
291 // caller's frame to access the save area or stack arguments.
292 int64_t MaxArgOffset = SystemZMC::CallFrameSize;
293 for (int I = MFFrame.getObjectIndexBegin(); I != 0; ++I)
294 if (MFFrame.getObjectOffset(I) >= 0) {
295 int64_t ArgOffset = SystemZMC::CallFrameSize +
296 MFFrame.getObjectOffset(I) +
297 MFFrame.getObjectSize(I);
298 MaxArgOffset = std::max(MaxArgOffset, ArgOffset);
301 uint64_t MaxReach = StackSize + MaxArgOffset;
302 if (!isUInt<12>(MaxReach)) {
303 // We may need register scavenging slots if some parts of the frame
304 // are outside the reach of an unsigned 12-bit displacement.
305 // Create 2 for the case where both addresses in an MVC are
306 // out of range.
307 RS->addScavengingFrameIndex(MFFrame.CreateStackObject(8, 8, false));
308 RS->addScavengingFrameIndex(MFFrame.CreateStackObject(8, 8, false));
312 // Emit instructions before MBBI (in MBB) to add NumBytes to Reg.
313 static void emitIncrement(MachineBasicBlock &MBB,
314 MachineBasicBlock::iterator &MBBI,
315 const DebugLoc &DL,
316 unsigned Reg, int64_t NumBytes,
317 const TargetInstrInfo *TII) {
318 while (NumBytes) {
319 unsigned Opcode;
320 int64_t ThisVal = NumBytes;
321 if (isInt<16>(NumBytes))
322 Opcode = SystemZ::AGHI;
323 else {
324 Opcode = SystemZ::AGFI;
325 // Make sure we maintain 8-byte stack alignment.
326 int64_t MinVal = -uint64_t(1) << 31;
327 int64_t MaxVal = (int64_t(1) << 31) - 8;
328 if (ThisVal < MinVal)
329 ThisVal = MinVal;
330 else if (ThisVal > MaxVal)
331 ThisVal = MaxVal;
333 MachineInstr *MI = BuildMI(MBB, MBBI, DL, TII->get(Opcode), Reg)
334 .addReg(Reg).addImm(ThisVal);
335 // The CC implicit def is dead.
336 MI->getOperand(3).setIsDead();
337 NumBytes -= ThisVal;
341 void SystemZFrameLowering::emitPrologue(MachineFunction &MF,
342 MachineBasicBlock &MBB) const {
343 assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
344 MachineFrameInfo &MFFrame = MF.getFrameInfo();
345 auto *ZII =
346 static_cast<const SystemZInstrInfo *>(MF.getSubtarget().getInstrInfo());
347 SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>();
348 MachineBasicBlock::iterator MBBI = MBB.begin();
349 MachineModuleInfo &MMI = MF.getMMI();
350 const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
351 const std::vector<CalleeSavedInfo> &CSI = MFFrame.getCalleeSavedInfo();
352 bool HasFP = hasFP(MF);
354 // Debug location must be unknown since the first debug location is used
355 // to determine the end of the prologue.
356 DebugLoc DL;
358 // The current offset of the stack pointer from the CFA.
359 int64_t SPOffsetFromCFA = -SystemZMC::CFAOffsetFromInitialSP;
361 if (ZFI->getLowSavedGPR()) {
362 // Skip over the GPR saves.
363 if (MBBI != MBB.end() && MBBI->getOpcode() == SystemZ::STMG)
364 ++MBBI;
365 else
366 llvm_unreachable("Couldn't skip over GPR saves");
368 // Add CFI for the GPR saves.
369 for (auto &Save : CSI) {
370 unsigned Reg = Save.getReg();
371 if (SystemZ::GR64BitRegClass.contains(Reg)) {
372 int64_t Offset = SPOffsetFromCFA + RegSpillOffsets[Reg];
373 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
374 nullptr, MRI->getDwarfRegNum(Reg, true), Offset));
375 BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::CFI_INSTRUCTION))
376 .addCFIIndex(CFIIndex);
381 uint64_t StackSize = MFFrame.getStackSize();
382 // We need to allocate the ABI-defined 160-byte base area whenever
383 // we allocate stack space for our own use and whenever we call another
384 // function.
385 if (StackSize || MFFrame.hasVarSizedObjects() || MFFrame.hasCalls()) {
386 StackSize += SystemZMC::CallFrameSize;
387 MFFrame.setStackSize(StackSize);
390 if (StackSize) {
391 // Determine if we want to store a backchain.
392 bool StoreBackchain = MF.getFunction().hasFnAttribute("backchain");
394 // If we need backchain, save current stack pointer. R1 is free at this
395 // point.
396 if (StoreBackchain)
397 BuildMI(MBB, MBBI, DL, ZII->get(SystemZ::LGR))
398 .addReg(SystemZ::R1D, RegState::Define).addReg(SystemZ::R15D);
400 // Allocate StackSize bytes.
401 int64_t Delta = -int64_t(StackSize);
402 emitIncrement(MBB, MBBI, DL, SystemZ::R15D, Delta, ZII);
404 // Add CFI for the allocation.
405 unsigned CFIIndex = MF.addFrameInst(
406 MCCFIInstruction::createDefCfaOffset(nullptr, SPOffsetFromCFA + Delta));
407 BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::CFI_INSTRUCTION))
408 .addCFIIndex(CFIIndex);
409 SPOffsetFromCFA += Delta;
411 if (StoreBackchain)
412 BuildMI(MBB, MBBI, DL, ZII->get(SystemZ::STG))
413 .addReg(SystemZ::R1D, RegState::Kill).addReg(SystemZ::R15D).addImm(0).addReg(0);
416 if (HasFP) {
417 // Copy the base of the frame to R11.
418 BuildMI(MBB, MBBI, DL, ZII->get(SystemZ::LGR), SystemZ::R11D)
419 .addReg(SystemZ::R15D);
421 // Add CFI for the new frame location.
422 unsigned HardFP = MRI->getDwarfRegNum(SystemZ::R11D, true);
423 unsigned CFIIndex = MF.addFrameInst(
424 MCCFIInstruction::createDefCfaRegister(nullptr, HardFP));
425 BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::CFI_INSTRUCTION))
426 .addCFIIndex(CFIIndex);
428 // Mark the FramePtr as live at the beginning of every block except
429 // the entry block. (We'll have marked R11 as live on entry when
430 // saving the GPRs.)
431 for (auto I = std::next(MF.begin()), E = MF.end(); I != E; ++I)
432 I->addLiveIn(SystemZ::R11D);
435 // Skip over the FPR/VR saves.
436 SmallVector<unsigned, 8> CFIIndexes;
437 for (auto &Save : CSI) {
438 unsigned Reg = Save.getReg();
439 if (SystemZ::FP64BitRegClass.contains(Reg)) {
440 if (MBBI != MBB.end() &&
441 (MBBI->getOpcode() == SystemZ::STD ||
442 MBBI->getOpcode() == SystemZ::STDY))
443 ++MBBI;
444 else
445 llvm_unreachable("Couldn't skip over FPR save");
446 } else if (SystemZ::VR128BitRegClass.contains(Reg)) {
447 if (MBBI != MBB.end() &&
448 MBBI->getOpcode() == SystemZ::VST)
449 ++MBBI;
450 else
451 llvm_unreachable("Couldn't skip over VR save");
452 } else
453 continue;
455 // Add CFI for the this save.
456 unsigned DwarfReg = MRI->getDwarfRegNum(Reg, true);
457 unsigned IgnoredFrameReg;
458 int64_t Offset =
459 getFrameIndexReference(MF, Save.getFrameIdx(), IgnoredFrameReg);
461 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
462 nullptr, DwarfReg, SPOffsetFromCFA + Offset));
463 CFIIndexes.push_back(CFIIndex);
465 // Complete the CFI for the FPR/VR saves, modelling them as taking effect
466 // after the last save.
467 for (auto CFIIndex : CFIIndexes) {
468 BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::CFI_INSTRUCTION))
469 .addCFIIndex(CFIIndex);
473 void SystemZFrameLowering::emitEpilogue(MachineFunction &MF,
474 MachineBasicBlock &MBB) const {
475 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
476 auto *ZII =
477 static_cast<const SystemZInstrInfo *>(MF.getSubtarget().getInstrInfo());
478 SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>();
479 MachineFrameInfo &MFFrame = MF.getFrameInfo();
481 // Skip the return instruction.
482 assert(MBBI->isReturn() && "Can only insert epilogue into returning blocks");
484 uint64_t StackSize = MFFrame.getStackSize();
485 if (ZFI->getLowSavedGPR()) {
486 --MBBI;
487 unsigned Opcode = MBBI->getOpcode();
488 if (Opcode != SystemZ::LMG)
489 llvm_unreachable("Expected to see callee-save register restore code");
491 unsigned AddrOpNo = 2;
492 DebugLoc DL = MBBI->getDebugLoc();
493 uint64_t Offset = StackSize + MBBI->getOperand(AddrOpNo + 1).getImm();
494 unsigned NewOpcode = ZII->getOpcodeForOffset(Opcode, Offset);
496 // If the offset is too large, use the largest stack-aligned offset
497 // and add the rest to the base register (the stack or frame pointer).
498 if (!NewOpcode) {
499 uint64_t NumBytes = Offset - 0x7fff8;
500 emitIncrement(MBB, MBBI, DL, MBBI->getOperand(AddrOpNo).getReg(),
501 NumBytes, ZII);
502 Offset -= NumBytes;
503 NewOpcode = ZII->getOpcodeForOffset(Opcode, Offset);
504 assert(NewOpcode && "No restore instruction available");
507 MBBI->setDesc(ZII->get(NewOpcode));
508 MBBI->getOperand(AddrOpNo + 1).ChangeToImmediate(Offset);
509 } else if (StackSize) {
510 DebugLoc DL = MBBI->getDebugLoc();
511 emitIncrement(MBB, MBBI, DL, SystemZ::R15D, StackSize, ZII);
515 bool SystemZFrameLowering::hasFP(const MachineFunction &MF) const {
516 return (MF.getTarget().Options.DisableFramePointerElim(MF) ||
517 MF.getFrameInfo().hasVarSizedObjects() ||
518 MF.getInfo<SystemZMachineFunctionInfo>()->getManipulatesSP());
521 bool
522 SystemZFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
523 // The ABI requires us to allocate 160 bytes of stack space for the callee,
524 // with any outgoing stack arguments being placed above that. It seems
525 // better to make that area a permanent feature of the frame even if
526 // we're using a frame pointer.
527 return true;
530 MachineBasicBlock::iterator SystemZFrameLowering::
531 eliminateCallFramePseudoInstr(MachineFunction &MF,
532 MachineBasicBlock &MBB,
533 MachineBasicBlock::iterator MI) const {
534 switch (MI->getOpcode()) {
535 case SystemZ::ADJCALLSTACKDOWN:
536 case SystemZ::ADJCALLSTACKUP:
537 assert(hasReservedCallFrame(MF) &&
538 "ADJSTACKDOWN and ADJSTACKUP should be no-ops");
539 return MBB.erase(MI);
540 break;
542 default:
543 llvm_unreachable("Unexpected call frame instruction");