1//===-- SystemZFrameLowering.cpp - Frame lowering for SystemZ -------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "SystemZFrameLowering.h" 11#include "SystemZCallingConv.h" 12#include "SystemZInstrBuilder.h" 13#include "SystemZMachineFunctionInfo.h" 14#include "SystemZTargetMachine.h" 15#include "llvm/CodeGen/MachineModuleInfo.h" 16#include "llvm/CodeGen/MachineRegisterInfo.h" 17#include "llvm/IR/Function.h" 18 19using namespace llvm; 20 21SystemZFrameLowering::SystemZFrameLowering(const SystemZTargetMachine &tm, 22 const SystemZSubtarget &sti) 23 : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 8, 24 -SystemZMC::CallFrameSize), 25 TM(tm), 26 STI(sti) { 27 // The ABI-defined register save slots, relative to the incoming stack 28 // pointer. 29 static const unsigned SpillOffsetTable[][2] = { 30 { SystemZ::R2D, 0x10 }, 31 { SystemZ::R3D, 0x18 }, 32 { SystemZ::R4D, 0x20 }, 33 { SystemZ::R5D, 0x28 }, 34 { SystemZ::R6D, 0x30 }, 35 { SystemZ::R7D, 0x38 }, 36 { SystemZ::R8D, 0x40 }, 37 { SystemZ::R9D, 0x48 }, 38 { SystemZ::R10D, 0x50 }, 39 { SystemZ::R11D, 0x58 }, 40 { SystemZ::R12D, 0x60 }, 41 { SystemZ::R13D, 0x68 }, 42 { SystemZ::R14D, 0x70 }, 43 { SystemZ::R15D, 0x78 }, 44 { SystemZ::F0D, 0x80 }, 45 { SystemZ::F2D, 0x88 }, 46 { SystemZ::F4D, 0x90 }, 47 { SystemZ::F6D, 0x98 } 48 }; 49 50 // Create a mapping from register number to save slot offset. 51 RegSpillOffsets.grow(SystemZ::NUM_TARGET_REGS); 52 for (unsigned I = 0, E = array_lengthof(SpillOffsetTable); I != E; ++I) 53 RegSpillOffsets[SpillOffsetTable[I][0]] = SpillOffsetTable[I][1]; 54} 55 56void SystemZFrameLowering:: 57processFunctionBeforeCalleeSavedScan(MachineFunction &MF, 58 RegScavenger *RS) const { 59 MachineFrameInfo *MFFrame = MF.getFrameInfo(); 60 MachineRegisterInfo &MRI = MF.getRegInfo(); 61 const TargetRegisterInfo *TRI = MF.getTarget().getRegisterInfo(); 62 bool HasFP = hasFP(MF); 63 SystemZMachineFunctionInfo *MFI = MF.getInfo<SystemZMachineFunctionInfo>(); 64 bool IsVarArg = MF.getFunction()->isVarArg(); 65 66 // va_start stores incoming FPR varargs in the normal way, but delegates 67 // the saving of incoming GPR varargs to spillCalleeSavedRegisters(). 68 // Record these pending uses, which typically include the call-saved 69 // argument register R6D. 70 if (IsVarArg) 71 for (unsigned I = MFI->getVarArgsFirstGPR(); I < SystemZ::NumArgGPRs; ++I) 72 MRI.setPhysRegUsed(SystemZ::ArgGPRs[I]); 73 74 // If the function requires a frame pointer, record that the hard 75 // frame pointer will be clobbered. 76 if (HasFP) 77 MRI.setPhysRegUsed(SystemZ::R11D); 78 79 // If the function calls other functions, record that the return 80 // address register will be clobbered. 81 if (MFFrame->hasCalls()) 82 MRI.setPhysRegUsed(SystemZ::R14D); 83 84 // If we are saving GPRs other than the stack pointer, we might as well 85 // save and restore the stack pointer at the same time, via STMG and LMG. 86 // This allows the deallocation to be done by the LMG, rather than needing 87 // a separate %r15 addition. 88 const uint16_t *CSRegs = TRI->getCalleeSavedRegs(&MF); 89 for (unsigned I = 0; CSRegs[I]; ++I) { 90 unsigned Reg = CSRegs[I]; 91 if (SystemZ::GR64BitRegClass.contains(Reg) && MRI.isPhysRegUsed(Reg)) { 92 MRI.setPhysRegUsed(SystemZ::R15D); 93 break; 94 } 95 } 96} 97 98// Add GPR64 to the save instruction being built by MIB, which is in basic 99// block MBB. IsImplicit says whether this is an explicit operand to the 100// instruction, or an implicit one that comes between the explicit start 101// and end registers. 102static void addSavedGPR(MachineBasicBlock &MBB, MachineInstrBuilder &MIB, 103 const SystemZTargetMachine &TM, 104 unsigned GPR64, bool IsImplicit) { 105 const SystemZRegisterInfo *RI = TM.getRegisterInfo(); 106 unsigned GPR32 = RI->getSubReg(GPR64, SystemZ::subreg_32bit); 107 bool IsLive = MBB.isLiveIn(GPR64) || MBB.isLiveIn(GPR32); 108 if (!IsLive || !IsImplicit) { 109 MIB.addReg(GPR64, getImplRegState(IsImplicit) | getKillRegState(!IsLive)); 110 if (!IsLive) 111 MBB.addLiveIn(GPR64); 112 } 113} 114 115bool SystemZFrameLowering:: 116spillCalleeSavedRegisters(MachineBasicBlock &MBB, 117 MachineBasicBlock::iterator MBBI, 118 const std::vector<CalleeSavedInfo> &CSI, 119 const TargetRegisterInfo *TRI) const { 120 if (CSI.empty()) 121 return false; 122 123 MachineFunction &MF = *MBB.getParent(); 124 const TargetInstrInfo *TII = MF.getTarget().getInstrInfo(); 125 SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>(); 126 bool IsVarArg = MF.getFunction()->isVarArg(); 127 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 128 129 // Scan the call-saved GPRs and find the bounds of the register spill area. 130 unsigned SavedGPRFrameSize = 0; 131 unsigned LowGPR = 0; 132 unsigned HighGPR = SystemZ::R15D; 133 unsigned StartOffset = -1U; 134 for (unsigned I = 0, E = CSI.size(); I != E; ++I) { 135 unsigned Reg = CSI[I].getReg(); 136 if (SystemZ::GR64BitRegClass.contains(Reg)) { 137 SavedGPRFrameSize += 8; 138 unsigned Offset = RegSpillOffsets[Reg]; 139 assert(Offset && "Unexpected GPR save"); 140 if (StartOffset > Offset) { 141 LowGPR = Reg; 142 StartOffset = Offset; 143 } 144 } 145 } 146 147 // Save information about the range and location of the call-saved 148 // registers, for use by the epilogue inserter. 149 ZFI->setSavedGPRFrameSize(SavedGPRFrameSize); 150 ZFI->setLowSavedGPR(LowGPR); 151 ZFI->setHighSavedGPR(HighGPR); 152 153 // Include the GPR varargs, if any. R6D is call-saved, so would 154 // be included by the loop above, but we also need to handle the 155 // call-clobbered argument registers. 156 if (IsVarArg) { 157 unsigned FirstGPR = ZFI->getVarArgsFirstGPR(); 158 if (FirstGPR < SystemZ::NumArgGPRs) { 159 unsigned Reg = SystemZ::ArgGPRs[FirstGPR]; 160 unsigned Offset = RegSpillOffsets[Reg]; 161 if (StartOffset > Offset) { 162 LowGPR = Reg; StartOffset = Offset; 163 } 164 } 165 } 166 167 // Save GPRs 168 if (LowGPR) { 169 assert(LowGPR != HighGPR && "Should be saving %r15 and something else"); 170 171 // Build an STMG instruction. 172 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(SystemZ::STMG)); 173 174 // Add the explicit register operands. 175 addSavedGPR(MBB, MIB, TM, LowGPR, false); 176 addSavedGPR(MBB, MIB, TM, HighGPR, false); 177 178 // Add the address. 179 MIB.addReg(SystemZ::R15D).addImm(StartOffset); 180 181 // Make sure all call-saved GPRs are included as operands and are 182 // marked as live on entry. 183 for (unsigned I = 0, E = CSI.size(); I != E; ++I) { 184 unsigned Reg = CSI[I].getReg(); 185 if (SystemZ::GR64BitRegClass.contains(Reg)) 186 addSavedGPR(MBB, MIB, TM, Reg, true); 187 } 188 189 // ...likewise GPR varargs. 190 if (IsVarArg) 191 for (unsigned I = ZFI->getVarArgsFirstGPR(); I < SystemZ::NumArgGPRs; ++I) 192 addSavedGPR(MBB, MIB, TM, SystemZ::ArgGPRs[I], true); 193 } 194 195 // Save FPRs in the normal TargetInstrInfo way. 196 for (unsigned I = 0, E = CSI.size(); I != E; ++I) { 197 unsigned Reg = CSI[I].getReg(); 198 if (SystemZ::FP64BitRegClass.contains(Reg)) { 199 MBB.addLiveIn(Reg); 200 TII->storeRegToStackSlot(MBB, MBBI, Reg, true, CSI[I].getFrameIdx(), 201 &SystemZ::FP64BitRegClass, TRI); 202 } 203 } 204 205 return true; 206} 207 208bool SystemZFrameLowering:: 209restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 210 MachineBasicBlock::iterator MBBI, 211 const std::vector<CalleeSavedInfo> &CSI, 212 const TargetRegisterInfo *TRI) const { 213 if (CSI.empty()) 214 return false; 215 216 MachineFunction &MF = *MBB.getParent(); 217 const TargetInstrInfo *TII = MF.getTarget().getInstrInfo(); 218 SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>(); 219 bool HasFP = hasFP(MF); 220 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 221 222 // Restore FPRs in the normal TargetInstrInfo way. 223 for (unsigned I = 0, E = CSI.size(); I != E; ++I) { 224 unsigned Reg = CSI[I].getReg(); 225 if (SystemZ::FP64BitRegClass.contains(Reg)) 226 TII->loadRegFromStackSlot(MBB, MBBI, Reg, CSI[I].getFrameIdx(), 227 &SystemZ::FP64BitRegClass, TRI); 228 } 229 230 // Restore call-saved GPRs (but not call-clobbered varargs, which at 231 // this point might hold return values). 232 unsigned LowGPR = ZFI->getLowSavedGPR(); 233 unsigned HighGPR = ZFI->getHighSavedGPR(); 234 unsigned StartOffset = RegSpillOffsets[LowGPR]; 235 if (LowGPR) { 236 // If we saved any of %r2-%r5 as varargs, we should also be saving 237 // and restoring %r6. If we're saving %r6 or above, we should be 238 // restoring it too. 239 assert(LowGPR != HighGPR && "Should be loading %r15 and something else"); 240 241 // Build an LMG instruction. 242 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(SystemZ::LMG)); 243 244 // Add the explicit register operands. 245 MIB.addReg(LowGPR, RegState::Define); 246 MIB.addReg(HighGPR, RegState::Define); 247 248 // Add the address. 249 MIB.addReg(HasFP ? SystemZ::R11D : SystemZ::R15D); 250 MIB.addImm(StartOffset); 251 252 // Do a second scan adding regs as being defined by instruction 253 for (unsigned I = 0, E = CSI.size(); I != E; ++I) { 254 unsigned Reg = CSI[I].getReg(); 255 if (Reg != LowGPR && Reg != HighGPR) 256 MIB.addReg(Reg, RegState::ImplicitDefine); 257 } 258 } 259 260 return true; 261} 262 263// Emit instructions before MBBI (in MBB) to add NumBytes to Reg. 264static void emitIncrement(MachineBasicBlock &MBB, 265 MachineBasicBlock::iterator &MBBI, 266 const DebugLoc &DL, 267 unsigned Reg, int64_t NumBytes, 268 const TargetInstrInfo *TII) { 269 while (NumBytes) { 270 unsigned Opcode; 271 int64_t ThisVal = NumBytes; 272 if (isInt<16>(NumBytes)) 273 Opcode = SystemZ::AGHI; 274 else { 275 Opcode = SystemZ::AGFI; 276 // Make sure we maintain 8-byte stack alignment. 277 int64_t MinVal = -int64_t(1) << 31; 278 int64_t MaxVal = (int64_t(1) << 31) - 8; 279 if (ThisVal < MinVal) 280 ThisVal = MinVal; 281 else if (ThisVal > MaxVal) 282 ThisVal = MaxVal; 283 } 284 MachineInstr *MI = BuildMI(MBB, MBBI, DL, TII->get(Opcode), Reg) 285 .addReg(Reg).addImm(ThisVal); 286 // The PSW implicit def is dead. 287 MI->getOperand(3).setIsDead(); 288 NumBytes -= ThisVal; 289 } 290} 291 292void SystemZFrameLowering::emitPrologue(MachineFunction &MF) const { 293 MachineBasicBlock &MBB = MF.front(); 294 MachineFrameInfo *MFFrame = MF.getFrameInfo(); 295 const SystemZInstrInfo *ZII = 296 static_cast<const SystemZInstrInfo*>(MF.getTarget().getInstrInfo()); 297 SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>(); 298 MachineBasicBlock::iterator MBBI = MBB.begin(); 299 MachineModuleInfo &MMI = MF.getMMI(); 300 std::vector<MachineMove> &Moves = MMI.getFrameMoves(); 301 const std::vector<CalleeSavedInfo> &CSI = MFFrame->getCalleeSavedInfo(); 302 bool HasFP = hasFP(MF); 303 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 304 305 // The current offset of the stack pointer from the CFA. 306 int64_t SPOffsetFromCFA = -SystemZMC::CFAOffsetFromInitialSP; 307 308 if (ZFI->getLowSavedGPR()) { 309 // Skip over the GPR saves. 310 if (MBBI != MBB.end() && MBBI->getOpcode() == SystemZ::STMG) 311 ++MBBI; 312 else 313 llvm_unreachable("Couldn't skip over GPR saves"); 314 315 // Add CFI for the GPR saves. 316 MCSymbol *GPRSaveLabel = MMI.getContext().CreateTempSymbol(); 317 BuildMI(MBB, MBBI, DL, 318 ZII->get(TargetOpcode::PROLOG_LABEL)).addSym(GPRSaveLabel); 319 for (std::vector<CalleeSavedInfo>::const_iterator 320 I = CSI.begin(), E = CSI.end(); I != E; ++I) { 321 unsigned Reg = I->getReg(); 322 if (SystemZ::GR64BitRegClass.contains(Reg)) { 323 int64_t Offset = SPOffsetFromCFA + RegSpillOffsets[Reg]; 324 MachineLocation StackSlot(MachineLocation::VirtualFP, Offset); 325 MachineLocation RegValue(Reg); 326 Moves.push_back(MachineMove(GPRSaveLabel, StackSlot, RegValue)); 327 } 328 } 329 } 330 331 uint64_t StackSize = getAllocatedStackSize(MF); 332 if (StackSize) { 333 // Allocate StackSize bytes. 334 int64_t Delta = -int64_t(StackSize); 335 emitIncrement(MBB, MBBI, DL, SystemZ::R15D, Delta, ZII); 336 337 // Add CFI for the allocation. 338 MCSymbol *AdjustSPLabel = MMI.getContext().CreateTempSymbol(); 339 BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::PROLOG_LABEL)) 340 .addSym(AdjustSPLabel); 341 MachineLocation FPDest(MachineLocation::VirtualFP); 342 MachineLocation FPSrc(MachineLocation::VirtualFP, SPOffsetFromCFA + Delta); 343 Moves.push_back(MachineMove(AdjustSPLabel, FPDest, FPSrc)); 344 SPOffsetFromCFA += Delta; 345 } 346 347 if (HasFP) { 348 // Copy the base of the frame to R11. 349 BuildMI(MBB, MBBI, DL, ZII->get(SystemZ::LGR), SystemZ::R11D) 350 .addReg(SystemZ::R15D); 351 352 // Add CFI for the new frame location. 353 MCSymbol *SetFPLabel = MMI.getContext().CreateTempSymbol(); 354 BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::PROLOG_LABEL)) 355 .addSym(SetFPLabel); 356 MachineLocation HardFP(SystemZ::R11D); 357 MachineLocation VirtualFP(MachineLocation::VirtualFP); 358 Moves.push_back(MachineMove(SetFPLabel, HardFP, VirtualFP)); 359 360 // Mark the FramePtr as live at the beginning of every block except 361 // the entry block. (We'll have marked R11 as live on entry when 362 // saving the GPRs.) 363 for (MachineFunction::iterator 364 I = llvm::next(MF.begin()), E = MF.end(); I != E; ++I) 365 I->addLiveIn(SystemZ::R11D); 366 } 367 368 // Skip over the FPR saves. 369 MCSymbol *FPRSaveLabel = 0; 370 for (std::vector<CalleeSavedInfo>::const_iterator 371 I = CSI.begin(), E = CSI.end(); I != E; ++I) { 372 unsigned Reg = I->getReg(); 373 if (SystemZ::FP64BitRegClass.contains(Reg)) { 374 if (MBBI != MBB.end() && 375 (MBBI->getOpcode() == SystemZ::STD || 376 MBBI->getOpcode() == SystemZ::STDY)) 377 ++MBBI; 378 else 379 llvm_unreachable("Couldn't skip over FPR save"); 380 381 // Add CFI for the this save. 382 if (!FPRSaveLabel) 383 FPRSaveLabel = MMI.getContext().CreateTempSymbol(); 384 unsigned Reg = I->getReg(); 385 int64_t Offset = getFrameIndexOffset(MF, I->getFrameIdx()); 386 MachineLocation Slot(MachineLocation::VirtualFP, 387 SPOffsetFromCFA + Offset); 388 MachineLocation RegValue(Reg); 389 Moves.push_back(MachineMove(FPRSaveLabel, Slot, RegValue)); 390 } 391 } 392 // Complete the CFI for the FPR saves, modelling them as taking effect 393 // after the last save. 394 if (FPRSaveLabel) 395 BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::PROLOG_LABEL)) 396 .addSym(FPRSaveLabel); 397} 398 399void SystemZFrameLowering::emitEpilogue(MachineFunction &MF, 400 MachineBasicBlock &MBB) const { 401 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 402 const SystemZInstrInfo *ZII = 403 static_cast<const SystemZInstrInfo*>(MF.getTarget().getInstrInfo()); 404 SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>(); 405 406 // Skip the return instruction. 407 assert(MBBI->getOpcode() == SystemZ::RET && 408 "Can only insert epilogue into returning blocks"); 409 410 uint64_t StackSize = getAllocatedStackSize(MF); 411 if (ZFI->getLowSavedGPR()) { 412 --MBBI; 413 unsigned Opcode = MBBI->getOpcode(); 414 if (Opcode != SystemZ::LMG) 415 llvm_unreachable("Expected to see callee-save register restore code"); 416 417 unsigned AddrOpNo = 2; 418 DebugLoc DL = MBBI->getDebugLoc(); 419 uint64_t Offset = StackSize + MBBI->getOperand(AddrOpNo + 1).getImm(); 420 unsigned NewOpcode = ZII->getOpcodeForOffset(Opcode, Offset); 421 422 // If the offset is too large, use the largest stack-aligned offset 423 // and add the rest to the base register (the stack or frame pointer). 424 if (!NewOpcode) { 425 uint64_t NumBytes = Offset - 0x7fff8; 426 emitIncrement(MBB, MBBI, DL, MBBI->getOperand(AddrOpNo).getReg(), 427 NumBytes, ZII); 428 Offset -= NumBytes; 429 NewOpcode = ZII->getOpcodeForOffset(Opcode, Offset); 430 assert(NewOpcode && "No restore instruction available"); 431 } 432 433 MBBI->setDesc(ZII->get(NewOpcode)); 434 MBBI->getOperand(AddrOpNo + 1).ChangeToImmediate(Offset); 435 } else if (StackSize) { 436 DebugLoc DL = MBBI->getDebugLoc(); 437 emitIncrement(MBB, MBBI, DL, SystemZ::R15D, StackSize, ZII); 438 } 439} 440 441bool SystemZFrameLowering::hasFP(const MachineFunction &MF) const { 442 return (MF.getTarget().Options.DisableFramePointerElim(MF) || 443 MF.getFrameInfo()->hasVarSizedObjects() || 444 MF.getInfo<SystemZMachineFunctionInfo>()->getManipulatesSP()); 445} 446 447int SystemZFrameLowering::getFrameIndexOffset(const MachineFunction &MF, 448 int FI) const { 449 const MachineFrameInfo *MFFrame = MF.getFrameInfo(); 450 451 // Start with the offset of FI from the top of the caller-allocated frame 452 // (i.e. the top of the 160 bytes allocated by the caller). This initial 453 // offset is therefore negative. 454 int64_t Offset = (MFFrame->getObjectOffset(FI) + 455 MFFrame->getOffsetAdjustment()); 456 if (FI >= 0) 457 // Non-fixed objects are allocated below the incoming stack pointer. 458 // Account for the space at the top of the frame that we choose not 459 // to allocate. 460 Offset += getUnallocatedTopBytes(MF); 461 462 // Make the offset relative to the incoming stack pointer. 463 Offset -= getOffsetOfLocalArea(); 464 465 // Make the offset relative to the bottom of the frame. 466 Offset += getAllocatedStackSize(MF); 467 468 return Offset; 469} 470 471uint64_t SystemZFrameLowering:: 472getUnallocatedTopBytes(const MachineFunction &MF) const { 473 return MF.getInfo<SystemZMachineFunctionInfo>()->getSavedGPRFrameSize(); 474} 475 476uint64_t SystemZFrameLowering:: 477getAllocatedStackSize(const MachineFunction &MF) const { 478 const MachineFrameInfo *MFFrame = MF.getFrameInfo(); 479 480 // Start with the size of the local variables and spill slots. 481 uint64_t StackSize = MFFrame->getStackSize(); 482 483 // Remove any bytes that we choose not to allocate. 484 StackSize -= getUnallocatedTopBytes(MF); 485 486 // Include space for an emergency spill slot, if one might be needed. 487 StackSize += getEmergencySpillSlotSize(MF); 488 489 // We need to allocate the ABI-defined 160-byte base area whenever 490 // we allocate stack space for our own use and whenever we call another 491 // function. 492 if (StackSize || MFFrame->hasVarSizedObjects() || MFFrame->hasCalls()) 493 StackSize += SystemZMC::CallFrameSize; 494 495 return StackSize; 496} 497 498unsigned SystemZFrameLowering:: 499getEmergencySpillSlotSize(const MachineFunction &MF) const { 500 const MachineFrameInfo *MFFrame = MF.getFrameInfo(); 501 uint64_t MaxReach = MFFrame->getStackSize() + SystemZMC::CallFrameSize * 2; 502 return isUInt<12>(MaxReach) ? 0 : 8; 503} 504 505unsigned SystemZFrameLowering:: 506getEmergencySpillSlotOffset(const MachineFunction &MF) const { 507 assert(getEmergencySpillSlotSize(MF) && "No emergency spill slot"); 508 return SystemZMC::CallFrameSize; 509} 510 511bool 512SystemZFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { 513 // The ABI requires us to allocate 160 bytes of stack space for the callee, 514 // with any outgoing stack arguments being placed above that. It seems 515 // better to make that area a permanent feature of the frame even if 516 // we're using a frame pointer. 517 return true; 518} 519 520void SystemZFrameLowering:: 521eliminateCallFramePseudoInstr(MachineFunction &MF, 522 MachineBasicBlock &MBB, 523 MachineBasicBlock::iterator MI) const { 524 switch (MI->getOpcode()) { 525 case SystemZ::ADJCALLSTACKDOWN: 526 case SystemZ::ADJCALLSTACKUP: 527 assert(hasReservedCallFrame(MF) && 528 "ADJSTACKDOWN and ADJSTACKUP should be no-ops"); 529 MBB.erase(MI); 530 break; 531 532 default: 533 llvm_unreachable("Unexpected call frame instruction"); 534 } 535} 536