LLVM API Documentation

SystemZFrameLowering.cpp
Go to the documentation of this file.
00001 //===-- SystemZFrameLowering.cpp - Frame lowering for SystemZ -------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #include "SystemZFrameLowering.h"
00011 #include "SystemZCallingConv.h"
00012 #include "SystemZInstrBuilder.h"
00013 #include "SystemZInstrInfo.h"
00014 #include "SystemZMachineFunctionInfo.h"
00015 #include "SystemZRegisterInfo.h"
00016 #include "SystemZSubtarget.h"
00017 #include "llvm/CodeGen/MachineModuleInfo.h"
00018 #include "llvm/CodeGen/MachineRegisterInfo.h"
00019 #include "llvm/CodeGen/RegisterScavenging.h"
00020 #include "llvm/IR/Function.h"
00021 
00022 using namespace llvm;
00023 
00024 namespace {
00025 // The ABI-defined register save slots, relative to the incoming stack
00026 // pointer.
00027 static const TargetFrameLowering::SpillSlot SpillOffsetTable[] = {
00028   { SystemZ::R2D,  0x10 },
00029   { SystemZ::R3D,  0x18 },
00030   { SystemZ::R4D,  0x20 },
00031   { SystemZ::R5D,  0x28 },
00032   { SystemZ::R6D,  0x30 },
00033   { SystemZ::R7D,  0x38 },
00034   { SystemZ::R8D,  0x40 },
00035   { SystemZ::R9D,  0x48 },
00036   { SystemZ::R10D, 0x50 },
00037   { SystemZ::R11D, 0x58 },
00038   { SystemZ::R12D, 0x60 },
00039   { SystemZ::R13D, 0x68 },
00040   { SystemZ::R14D, 0x70 },
00041   { SystemZ::R15D, 0x78 },
00042   { SystemZ::F0D,  0x80 },
00043   { SystemZ::F2D,  0x88 },
00044   { SystemZ::F4D,  0x90 },
00045   { SystemZ::F6D,  0x98 }
00046 };
00047 } // end anonymous namespace
00048 
00049 SystemZFrameLowering::SystemZFrameLowering()
00050     : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 8,
00051                           -SystemZMC::CallFrameSize, 8) {
00052   // Create a mapping from register number to save slot offset.
00053   RegSpillOffsets.grow(SystemZ::NUM_TARGET_REGS);
00054   for (unsigned I = 0, E = array_lengthof(SpillOffsetTable); I != E; ++I)
00055     RegSpillOffsets[SpillOffsetTable[I].Reg] = SpillOffsetTable[I].Offset;
00056 }
00057 
00058 const TargetFrameLowering::SpillSlot *
00059 SystemZFrameLowering::getCalleeSavedSpillSlots(unsigned &NumEntries) const {
00060   NumEntries = array_lengthof(SpillOffsetTable);
00061   return SpillOffsetTable;
00062 }
00063 
00064 void SystemZFrameLowering::
00065 processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
00066                                      RegScavenger *RS) const {
00067   MachineFrameInfo *MFFrame = MF.getFrameInfo();
00068   MachineRegisterInfo &MRI = MF.getRegInfo();
00069   const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
00070   bool HasFP = hasFP(MF);
00071   SystemZMachineFunctionInfo *MFI = MF.getInfo<SystemZMachineFunctionInfo>();
00072   bool IsVarArg = MF.getFunction()->isVarArg();
00073 
00074   // va_start stores incoming FPR varargs in the normal way, but delegates
00075   // the saving of incoming GPR varargs to spillCalleeSavedRegisters().
00076   // Record these pending uses, which typically include the call-saved
00077   // argument register R6D.
00078   if (IsVarArg)
00079     for (unsigned I = MFI->getVarArgsFirstGPR(); I < SystemZ::NumArgGPRs; ++I)
00080       MRI.setPhysRegUsed(SystemZ::ArgGPRs[I]);
00081 
00082   // If the function requires a frame pointer, record that the hard
00083   // frame pointer will be clobbered.
00084   if (HasFP)
00085     MRI.setPhysRegUsed(SystemZ::R11D);
00086 
00087   // If the function calls other functions, record that the return
00088   // address register will be clobbered.
00089   if (MFFrame->hasCalls())
00090     MRI.setPhysRegUsed(SystemZ::R14D);
00091 
00092   // If we are saving GPRs other than the stack pointer, we might as well
00093   // save and restore the stack pointer at the same time, via STMG and LMG.
00094   // This allows the deallocation to be done by the LMG, rather than needing
00095   // a separate %r15 addition.
00096   const MCPhysReg *CSRegs = TRI->getCalleeSavedRegs(&MF);
00097   for (unsigned I = 0; CSRegs[I]; ++I) {
00098     unsigned Reg = CSRegs[I];
00099     if (SystemZ::GR64BitRegClass.contains(Reg) && MRI.isPhysRegUsed(Reg)) {
00100       MRI.setPhysRegUsed(SystemZ::R15D);
00101       break;
00102     }
00103   }
00104 }
00105 
00106 // Add GPR64 to the save instruction being built by MIB, which is in basic
00107 // block MBB.  IsImplicit says whether this is an explicit operand to the
00108 // instruction, or an implicit one that comes between the explicit start
00109 // and end registers.
00110 static void addSavedGPR(MachineBasicBlock &MBB, MachineInstrBuilder &MIB,
00111                         unsigned GPR64, bool IsImplicit) {
00112   const TargetRegisterInfo *RI =
00113       MBB.getParent()->getSubtarget().getRegisterInfo();
00114   unsigned GPR32 = RI->getSubReg(GPR64, SystemZ::subreg_l32);
00115   bool IsLive = MBB.isLiveIn(GPR64) || MBB.isLiveIn(GPR32);
00116   if (!IsLive || !IsImplicit) {
00117     MIB.addReg(GPR64, getImplRegState(IsImplicit) | getKillRegState(!IsLive));
00118     if (!IsLive)
00119       MBB.addLiveIn(GPR64);
00120   }
00121 }
00122 
00123 bool SystemZFrameLowering::
00124 spillCalleeSavedRegisters(MachineBasicBlock &MBB,
00125                           MachineBasicBlock::iterator MBBI,
00126                           const std::vector<CalleeSavedInfo> &CSI,
00127                           const TargetRegisterInfo *TRI) const {
00128   if (CSI.empty())
00129     return false;
00130 
00131   MachineFunction &MF = *MBB.getParent();
00132   const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
00133   SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>();
00134   bool IsVarArg = MF.getFunction()->isVarArg();
00135   DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
00136 
00137   // Scan the call-saved GPRs and find the bounds of the register spill area.
00138   unsigned LowGPR = 0;
00139   unsigned HighGPR = SystemZ::R15D;
00140   unsigned StartOffset = -1U;
00141   for (unsigned I = 0, E = CSI.size(); I != E; ++I) {
00142     unsigned Reg = CSI[I].getReg();
00143     if (SystemZ::GR64BitRegClass.contains(Reg)) {
00144       unsigned Offset = RegSpillOffsets[Reg];
00145       assert(Offset && "Unexpected GPR save");
00146       if (StartOffset > Offset) {
00147         LowGPR = Reg;
00148         StartOffset = Offset;
00149       }
00150     }
00151   }
00152 
00153   // Save the range of call-saved registers, for use by the epilogue inserter.
00154   ZFI->setLowSavedGPR(LowGPR);
00155   ZFI->setHighSavedGPR(HighGPR);
00156 
00157   // Include the GPR varargs, if any.  R6D is call-saved, so would
00158   // be included by the loop above, but we also need to handle the
00159   // call-clobbered argument registers.
00160   if (IsVarArg) {
00161     unsigned FirstGPR = ZFI->getVarArgsFirstGPR();
00162     if (FirstGPR < SystemZ::NumArgGPRs) {
00163       unsigned Reg = SystemZ::ArgGPRs[FirstGPR];
00164       unsigned Offset = RegSpillOffsets[Reg];
00165       if (StartOffset > Offset) {
00166         LowGPR = Reg; StartOffset = Offset;
00167       }
00168     }
00169   }
00170 
00171   // Save GPRs
00172   if (LowGPR) {
00173     assert(LowGPR != HighGPR && "Should be saving %r15 and something else");
00174 
00175     // Build an STMG instruction.
00176     MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(SystemZ::STMG));
00177 
00178     // Add the explicit register operands.
00179     addSavedGPR(MBB, MIB, LowGPR, false);
00180     addSavedGPR(MBB, MIB, HighGPR, false);
00181 
00182     // Add the address.
00183     MIB.addReg(SystemZ::R15D).addImm(StartOffset);
00184 
00185     // Make sure all call-saved GPRs are included as operands and are
00186     // marked as live on entry.
00187     for (unsigned I = 0, E = CSI.size(); I != E; ++I) {
00188       unsigned Reg = CSI[I].getReg();
00189       if (SystemZ::GR64BitRegClass.contains(Reg))
00190         addSavedGPR(MBB, MIB, Reg, true);
00191     }
00192 
00193     // ...likewise GPR varargs.
00194     if (IsVarArg)
00195       for (unsigned I = ZFI->getVarArgsFirstGPR(); I < SystemZ::NumArgGPRs; ++I)
00196         addSavedGPR(MBB, MIB, SystemZ::ArgGPRs[I], true);
00197   }
00198 
00199   // Save FPRs in the normal TargetInstrInfo way.
00200   for (unsigned I = 0, E = CSI.size(); I != E; ++I) {
00201     unsigned Reg = CSI[I].getReg();
00202     if (SystemZ::FP64BitRegClass.contains(Reg)) {
00203       MBB.addLiveIn(Reg);
00204       TII->storeRegToStackSlot(MBB, MBBI, Reg, true, CSI[I].getFrameIdx(),
00205                                &SystemZ::FP64BitRegClass, TRI);
00206     }
00207   }
00208 
00209   return true;
00210 }
00211 
00212 bool SystemZFrameLowering::
00213 restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
00214                             MachineBasicBlock::iterator MBBI,
00215                             const std::vector<CalleeSavedInfo> &CSI,
00216                             const TargetRegisterInfo *TRI) const {
00217   if (CSI.empty())
00218     return false;
00219 
00220   MachineFunction &MF = *MBB.getParent();
00221   const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
00222   SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>();
00223   bool HasFP = hasFP(MF);
00224   DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
00225 
00226   // Restore FPRs in the normal TargetInstrInfo way.
00227   for (unsigned I = 0, E = CSI.size(); I != E; ++I) {
00228     unsigned Reg = CSI[I].getReg();
00229     if (SystemZ::FP64BitRegClass.contains(Reg))
00230       TII->loadRegFromStackSlot(MBB, MBBI, Reg, CSI[I].getFrameIdx(),
00231                                 &SystemZ::FP64BitRegClass, TRI);
00232   }
00233 
00234   // Restore call-saved GPRs (but not call-clobbered varargs, which at
00235   // this point might hold return values).
00236   unsigned LowGPR = ZFI->getLowSavedGPR();
00237   unsigned HighGPR = ZFI->getHighSavedGPR();
00238   unsigned StartOffset = RegSpillOffsets[LowGPR];
00239   if (LowGPR) {
00240     // If we saved any of %r2-%r5 as varargs, we should also be saving
00241     // and restoring %r6.  If we're saving %r6 or above, we should be
00242     // restoring it too.
00243     assert(LowGPR != HighGPR && "Should be loading %r15 and something else");
00244 
00245     // Build an LMG instruction.
00246     MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(SystemZ::LMG));
00247 
00248     // Add the explicit register operands.
00249     MIB.addReg(LowGPR, RegState::Define);
00250     MIB.addReg(HighGPR, RegState::Define);
00251 
00252     // Add the address.
00253     MIB.addReg(HasFP ? SystemZ::R11D : SystemZ::R15D);
00254     MIB.addImm(StartOffset);
00255 
00256     // Do a second scan adding regs as being defined by instruction
00257     for (unsigned I = 0, E = CSI.size(); I != E; ++I) {
00258       unsigned Reg = CSI[I].getReg();
00259       if (Reg != LowGPR && Reg != HighGPR)
00260         MIB.addReg(Reg, RegState::ImplicitDefine);
00261     }
00262   }
00263 
00264   return true;
00265 }
00266 
00267 void SystemZFrameLowering::
00268 processFunctionBeforeFrameFinalized(MachineFunction &MF,
00269                                     RegScavenger *RS) const {
00270   MachineFrameInfo *MFFrame = MF.getFrameInfo();
00271   uint64_t MaxReach = (MFFrame->estimateStackSize(MF) +
00272                        SystemZMC::CallFrameSize * 2);
00273   if (!isUInt<12>(MaxReach)) {
00274     // We may need register scavenging slots if some parts of the frame
00275     // are outside the reach of an unsigned 12-bit displacement.
00276     // Create 2 for the case where both addresses in an MVC are
00277     // out of range.
00278     RS->addScavengingFrameIndex(MFFrame->CreateStackObject(8, 8, false));
00279     RS->addScavengingFrameIndex(MFFrame->CreateStackObject(8, 8, false));
00280   }
00281 }
00282 
00283 // Emit instructions before MBBI (in MBB) to add NumBytes to Reg.
00284 static void emitIncrement(MachineBasicBlock &MBB,
00285                           MachineBasicBlock::iterator &MBBI,
00286                           const DebugLoc &DL,
00287                           unsigned Reg, int64_t NumBytes,
00288                           const TargetInstrInfo *TII) {
00289   while (NumBytes) {
00290     unsigned Opcode;
00291     int64_t ThisVal = NumBytes;
00292     if (isInt<16>(NumBytes))
00293       Opcode = SystemZ::AGHI;
00294     else {
00295       Opcode = SystemZ::AGFI;
00296       // Make sure we maintain 8-byte stack alignment.
00297       int64_t MinVal = -uint64_t(1) << 31;
00298       int64_t MaxVal = (int64_t(1) << 31) - 8;
00299       if (ThisVal < MinVal)
00300         ThisVal = MinVal;
00301       else if (ThisVal > MaxVal)
00302         ThisVal = MaxVal;
00303     }
00304     MachineInstr *MI = BuildMI(MBB, MBBI, DL, TII->get(Opcode), Reg)
00305       .addReg(Reg).addImm(ThisVal);
00306     // The CC implicit def is dead.
00307     MI->getOperand(3).setIsDead();
00308     NumBytes -= ThisVal;
00309   }
00310 }
00311 
00312 void SystemZFrameLowering::emitPrologue(MachineFunction &MF) const {
00313   MachineBasicBlock &MBB = MF.front();
00314   MachineFrameInfo *MFFrame = MF.getFrameInfo();
00315   auto *ZII =
00316       static_cast<const SystemZInstrInfo *>(MF.getSubtarget().getInstrInfo());
00317   SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>();
00318   MachineBasicBlock::iterator MBBI = MBB.begin();
00319   MachineModuleInfo &MMI = MF.getMMI();
00320   const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
00321   const std::vector<CalleeSavedInfo> &CSI = MFFrame->getCalleeSavedInfo();
00322   bool HasFP = hasFP(MF);
00323   DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
00324 
00325   // The current offset of the stack pointer from the CFA.
00326   int64_t SPOffsetFromCFA = -SystemZMC::CFAOffsetFromInitialSP;
00327 
00328   if (ZFI->getLowSavedGPR()) {
00329     // Skip over the GPR saves.
00330     if (MBBI != MBB.end() && MBBI->getOpcode() == SystemZ::STMG)
00331       ++MBBI;
00332     else
00333       llvm_unreachable("Couldn't skip over GPR saves");
00334 
00335     // Add CFI for the GPR saves.
00336     for (auto &Save : CSI) {
00337       unsigned Reg = Save.getReg();
00338       if (SystemZ::GR64BitRegClass.contains(Reg)) {
00339         int64_t Offset = SPOffsetFromCFA + RegSpillOffsets[Reg];
00340         unsigned CFIIndex = MMI.addFrameInst(MCCFIInstruction::createOffset(
00341             nullptr, MRI->getDwarfRegNum(Reg, true), Offset));
00342         BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::CFI_INSTRUCTION))
00343             .addCFIIndex(CFIIndex);
00344       }
00345     }
00346   }
00347 
00348   uint64_t StackSize = getAllocatedStackSize(MF);
00349   if (StackSize) {
00350     // Allocate StackSize bytes.
00351     int64_t Delta = -int64_t(StackSize);
00352     emitIncrement(MBB, MBBI, DL, SystemZ::R15D, Delta, ZII);
00353 
00354     // Add CFI for the allocation.
00355     unsigned CFIIndex = MMI.addFrameInst(
00356         MCCFIInstruction::createDefCfaOffset(nullptr, SPOffsetFromCFA + Delta));
00357     BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::CFI_INSTRUCTION))
00358         .addCFIIndex(CFIIndex);
00359     SPOffsetFromCFA += Delta;
00360   }
00361 
00362   if (HasFP) {
00363     // Copy the base of the frame to R11.
00364     BuildMI(MBB, MBBI, DL, ZII->get(SystemZ::LGR), SystemZ::R11D)
00365       .addReg(SystemZ::R15D);
00366 
00367     // Add CFI for the new frame location.
00368     unsigned HardFP = MRI->getDwarfRegNum(SystemZ::R11D, true);
00369     unsigned CFIIndex = MMI.addFrameInst(
00370         MCCFIInstruction::createDefCfaRegister(nullptr, HardFP));
00371     BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::CFI_INSTRUCTION))
00372         .addCFIIndex(CFIIndex);
00373 
00374     // Mark the FramePtr as live at the beginning of every block except
00375     // the entry block.  (We'll have marked R11 as live on entry when
00376     // saving the GPRs.)
00377     for (auto I = std::next(MF.begin()), E = MF.end(); I != E; ++I)
00378       I->addLiveIn(SystemZ::R11D);
00379   }
00380 
00381   // Skip over the FPR saves.
00382   SmallVector<unsigned, 8> CFIIndexes;
00383   for (auto &Save : CSI) {
00384     unsigned Reg = Save.getReg();
00385     if (SystemZ::FP64BitRegClass.contains(Reg)) {
00386       if (MBBI != MBB.end() &&
00387           (MBBI->getOpcode() == SystemZ::STD ||
00388            MBBI->getOpcode() == SystemZ::STDY))
00389         ++MBBI;
00390       else
00391         llvm_unreachable("Couldn't skip over FPR save");
00392 
00393       // Add CFI for the this save.
00394       unsigned DwarfReg = MRI->getDwarfRegNum(Reg, true);
00395       int64_t Offset = getFrameIndexOffset(MF, Save.getFrameIdx());
00396       unsigned CFIIndex = MMI.addFrameInst(MCCFIInstruction::createOffset(
00397           nullptr, DwarfReg, SPOffsetFromCFA + Offset));
00398       CFIIndexes.push_back(CFIIndex);
00399     }
00400   }
00401   // Complete the CFI for the FPR saves, modelling them as taking effect
00402   // after the last save.
00403   for (auto CFIIndex : CFIIndexes) {
00404     BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::CFI_INSTRUCTION))
00405         .addCFIIndex(CFIIndex);
00406   }
00407 }
00408 
00409 void SystemZFrameLowering::emitEpilogue(MachineFunction &MF,
00410                                         MachineBasicBlock &MBB) const {
00411   MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
00412   auto *ZII =
00413       static_cast<const SystemZInstrInfo *>(MF.getSubtarget().getInstrInfo());
00414   SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>();
00415 
00416   // Skip the return instruction.
00417   assert(MBBI->isReturn() && "Can only insert epilogue into returning blocks");
00418 
00419   uint64_t StackSize = getAllocatedStackSize(MF);
00420   if (ZFI->getLowSavedGPR()) {
00421     --MBBI;
00422     unsigned Opcode = MBBI->getOpcode();
00423     if (Opcode != SystemZ::LMG)
00424       llvm_unreachable("Expected to see callee-save register restore code");
00425 
00426     unsigned AddrOpNo = 2;
00427     DebugLoc DL = MBBI->getDebugLoc();
00428     uint64_t Offset = StackSize + MBBI->getOperand(AddrOpNo + 1).getImm();
00429     unsigned NewOpcode = ZII->getOpcodeForOffset(Opcode, Offset);
00430 
00431     // If the offset is too large, use the largest stack-aligned offset
00432     // and add the rest to the base register (the stack or frame pointer).
00433     if (!NewOpcode) {
00434       uint64_t NumBytes = Offset - 0x7fff8;
00435       emitIncrement(MBB, MBBI, DL, MBBI->getOperand(AddrOpNo).getReg(),
00436                     NumBytes, ZII);
00437       Offset -= NumBytes;
00438       NewOpcode = ZII->getOpcodeForOffset(Opcode, Offset);
00439       assert(NewOpcode && "No restore instruction available");
00440     }
00441 
00442     MBBI->setDesc(ZII->get(NewOpcode));
00443     MBBI->getOperand(AddrOpNo + 1).ChangeToImmediate(Offset);
00444   } else if (StackSize) {
00445     DebugLoc DL = MBBI->getDebugLoc();
00446     emitIncrement(MBB, MBBI, DL, SystemZ::R15D, StackSize, ZII);
00447   }
00448 }
00449 
00450 bool SystemZFrameLowering::hasFP(const MachineFunction &MF) const {
00451   return (MF.getTarget().Options.DisableFramePointerElim(MF) ||
00452           MF.getFrameInfo()->hasVarSizedObjects() ||
00453           MF.getInfo<SystemZMachineFunctionInfo>()->getManipulatesSP());
00454 }
00455 
00456 int SystemZFrameLowering::getFrameIndexOffset(const MachineFunction &MF,
00457                                               int FI) const {
00458   const MachineFrameInfo *MFFrame = MF.getFrameInfo();
00459 
00460   // Start with the offset of FI from the top of the caller-allocated frame
00461   // (i.e. the top of the 160 bytes allocated by the caller).  This initial
00462   // offset is therefore negative.
00463   int64_t Offset = (MFFrame->getObjectOffset(FI) +
00464                     MFFrame->getOffsetAdjustment());
00465 
00466   // Make the offset relative to the incoming stack pointer.
00467   Offset -= getOffsetOfLocalArea();
00468 
00469   // Make the offset relative to the bottom of the frame.
00470   Offset += getAllocatedStackSize(MF);
00471 
00472   return Offset;
00473 }
00474 
00475 uint64_t SystemZFrameLowering::
00476 getAllocatedStackSize(const MachineFunction &MF) const {
00477   const MachineFrameInfo *MFFrame = MF.getFrameInfo();
00478 
00479   // Start with the size of the local variables and spill slots.
00480   uint64_t StackSize = MFFrame->getStackSize();
00481 
00482   // We need to allocate the ABI-defined 160-byte base area whenever
00483   // we allocate stack space for our own use and whenever we call another
00484   // function.
00485   if (StackSize || MFFrame->hasVarSizedObjects() || MFFrame->hasCalls())
00486     StackSize += SystemZMC::CallFrameSize;
00487 
00488   return StackSize;
00489 }
00490 
00491 bool
00492 SystemZFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
00493   // The ABI requires us to allocate 160 bytes of stack space for the callee,
00494   // with any outgoing stack arguments being placed above that.  It seems
00495   // better to make that area a permanent feature of the frame even if
00496   // we're using a frame pointer.
00497   return true;
00498 }
00499 
00500 void SystemZFrameLowering::
00501 eliminateCallFramePseudoInstr(MachineFunction &MF,
00502                               MachineBasicBlock &MBB,
00503                               MachineBasicBlock::iterator MI) const {
00504   switch (MI->getOpcode()) {
00505   case SystemZ::ADJCALLSTACKDOWN:
00506   case SystemZ::ADJCALLSTACKUP:
00507     assert(hasReservedCallFrame(MF) &&
00508            "ADJSTACKDOWN and ADJSTACKUP should be no-ops");
00509     MBB.erase(MI);
00510     break;
00511 
00512   default:
00513     llvm_unreachable("Unexpected call frame instruction");
00514   }
00515 }