1 //===- ARCFrameLowering.cpp - ARC Frame Information -------------*- C++ -*-===// 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 // 9 // This file contains the ARC implementation of the TargetFrameLowering class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "ARCFrameLowering.h" 14 #include "ARCMachineFunctionInfo.h" 15 #include "ARCSubtarget.h" 16 #include "llvm/CodeGen/MachineInstrBuilder.h" 17 #include "llvm/CodeGen/MachineModuleInfo.h" 18 #include "llvm/CodeGen/RegisterScavenging.h" 19 #include "llvm/CodeGen/TargetRegisterInfo.h" 20 #include "llvm/IR/Function.h" 21 #include "llvm/Support/Debug.h" 22 23 #define DEBUG_TYPE "arc-frame-lowering" 24 25 using namespace llvm; 26 27 static cl::opt<bool> 28 UseSaveRestoreFunclet("arc-save-restore-funclet", cl::Hidden, 29 cl::desc("Use arc callee save/restore functions"), 30 cl::init(true)); 31 32 static const char *store_funclet_name[] = { 33 "__st_r13_to_r15", "__st_r13_to_r16", "__st_r13_to_r17", "__st_r13_to_r18", 34 "__st_r13_to_r19", "__st_r13_to_r20", "__st_r13_to_r21", "__st_r13_to_r22", 35 "__st_r13_to_r23", "__st_r13_to_r24", "__st_r13_to_r25", 36 }; 37 38 static const char *load_funclet_name[] = { 39 "__ld_r13_to_r15", "__ld_r13_to_r16", "__ld_r13_to_r17", "__ld_r13_to_r18", 40 "__ld_r13_to_r19", "__ld_r13_to_r20", "__ld_r13_to_r21", "__ld_r13_to_r22", 41 "__ld_r13_to_r23", "__ld_r13_to_r24", "__ld_r13_to_r25", 42 }; 43 44 static void generateStackAdjustment(MachineBasicBlock &MBB, 45 MachineBasicBlock::iterator MBBI, 46 const ARCInstrInfo &TII, DebugLoc dl, 47 int Amount, int StackPtr) { 48 unsigned AdjOp; 49 if (!Amount) 50 return; 51 bool Positive; 52 unsigned AbsAmount; 53 if (Amount < 0) { 54 AbsAmount = -Amount; 55 Positive = false; 56 } else { 57 AbsAmount = Amount; 58 Positive = true; 59 } 60 61 LLVM_DEBUG(dbgs() << "Internal: adjust stack by: " << Amount << "," 62 << AbsAmount << "\n"); 63 64 assert((AbsAmount % 4 == 0) && "Stack adjustments must be 4-byte aligned."); 65 if (isUInt<6>(AbsAmount)) 66 AdjOp = Positive ? ARC::ADD_rru6 : ARC::SUB_rru6; 67 else if (isInt<12>(AbsAmount)) 68 AdjOp = Positive ? ARC::ADD_rrs12 : ARC::SUB_rrs12; 69 else 70 AdjOp = Positive ? ARC::ADD_rrlimm : ARC::SUB_rrlimm; 71 72 BuildMI(MBB, MBBI, dl, TII.get(AdjOp), StackPtr) 73 .addReg(StackPtr) 74 .addImm(AbsAmount); 75 } 76 77 static unsigned determineLastCalleeSave(ArrayRef<CalleeSavedInfo> CSI) { 78 unsigned Last = 0; 79 for (auto Reg : CSI) { 80 assert(Reg.getReg() >= ARC::R13 && Reg.getReg() <= ARC::R25 && 81 "Unexpected callee saved reg."); 82 if (Reg.getReg() > Last) 83 Last = Reg.getReg(); 84 } 85 return Last; 86 } 87 88 void ARCFrameLowering::determineCalleeSaves(MachineFunction &MF, 89 BitVector &SavedRegs, 90 RegScavenger *RS) const { 91 LLVM_DEBUG(dbgs() << "Determine Callee Saves: " << MF.getName() << "\n"); 92 TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); 93 SavedRegs.set(ARC::BLINK); 94 } 95 96 void ARCFrameLowering::adjustStackToMatchRecords( 97 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 98 bool Allocate) const { 99 MachineFunction &MF = *MBB.getParent(); 100 int ScalarAlloc = MF.getFrameInfo().getStackSize(); 101 102 if (Allocate) { 103 // Allocate by adjusting by the negative of what the record holder tracked 104 // it tracked a positive offset in a downward growing stack. 105 ScalarAlloc = -ScalarAlloc; 106 } 107 108 generateStackAdjustment(MBB, MBBI, *ST.getInstrInfo(), DebugLoc(), 109 ScalarAlloc, ARC::SP); 110 } 111 112 /// Insert prolog code into the function. 113 /// For ARC, this inserts a call to a function that puts required callee saved 114 /// registers onto the stack, when enough callee saved registers are required. 115 void ARCFrameLowering::emitPrologue(MachineFunction &MF, 116 MachineBasicBlock &MBB) const { 117 LLVM_DEBUG(dbgs() << "Emit Prologue: " << MF.getName() << "\n"); 118 auto *AFI = MF.getInfo<ARCFunctionInfo>(); 119 MachineModuleInfo &MMI = MF.getMMI(); 120 MCContext &Context = MMI.getContext(); 121 const MCRegisterInfo *MRI = Context.getRegisterInfo(); 122 const ARCInstrInfo *TII = MF.getSubtarget<ARCSubtarget>().getInstrInfo(); 123 MachineBasicBlock::iterator MBBI = MBB.begin(); 124 // Debug location must be unknown since the first debug location is used 125 // to determine the end of the prologue. 126 DebugLoc dl; 127 MachineFrameInfo &MFI = MF.getFrameInfo(); 128 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); 129 unsigned Last = determineLastCalleeSave(CSI); 130 unsigned StackSlotsUsedByFunclet = 0; 131 bool SavedBlink = false; 132 unsigned AlreadyAdjusted = 0; 133 if (MF.getFunction().isVarArg()) { 134 // Add in the varargs area here first. 135 LLVM_DEBUG(dbgs() << "Varargs\n"); 136 unsigned VarArgsBytes = MFI.getObjectSize(AFI->getVarArgsFrameIndex()); 137 unsigned Opc = ARC::SUB_rrlimm; 138 if (isUInt<6>(VarArgsBytes)) 139 Opc = ARC::SUB_rru6; 140 else if (isInt<12>(VarArgsBytes)) 141 Opc = ARC::SUB_rrs12; 142 BuildMI(MBB, MBBI, dl, TII->get(Opc), ARC::SP) 143 .addReg(ARC::SP) 144 .addImm(VarArgsBytes); 145 } 146 if (hasFP(MF)) { 147 LLVM_DEBUG(dbgs() << "Saving FP\n"); 148 BuildMI(MBB, MBBI, dl, TII->get(ARC::ST_AW_rs9)) 149 .addReg(ARC::SP, RegState::Define) 150 .addReg(ARC::FP) 151 .addReg(ARC::SP) 152 .addImm(-4); 153 AlreadyAdjusted += 4; 154 } 155 if (UseSaveRestoreFunclet && Last > ARC::R14) { 156 LLVM_DEBUG(dbgs() << "Creating store funclet.\n"); 157 // BL to __save_r13_to_<TRI->getRegAsmName()> 158 StackSlotsUsedByFunclet = Last - ARC::R12; 159 BuildMI(MBB, MBBI, dl, TII->get(ARC::PUSH_S_BLINK)); 160 BuildMI(MBB, MBBI, dl, TII->get(ARC::SUB_rru6)) 161 .addReg(ARC::SP) 162 .addReg(ARC::SP) 163 .addImm(4 * StackSlotsUsedByFunclet); 164 BuildMI(MBB, MBBI, dl, TII->get(ARC::BL)) 165 .addExternalSymbol(store_funclet_name[Last - ARC::R15]) 166 .addReg(ARC::BLINK, RegState::Implicit | RegState::Kill); 167 AlreadyAdjusted += 4 * (StackSlotsUsedByFunclet + 1); 168 SavedBlink = true; 169 } 170 // If we haven't saved BLINK, but we need to...do that now. 171 if (MFI.hasCalls() && !SavedBlink) { 172 LLVM_DEBUG(dbgs() << "Creating save blink.\n"); 173 BuildMI(MBB, MBBI, dl, TII->get(ARC::PUSH_S_BLINK)); 174 AlreadyAdjusted += 4; 175 } 176 if (AFI->MaxCallStackReq > 0) 177 MFI.setStackSize(MFI.getStackSize() + AFI->MaxCallStackReq); 178 // We have already saved some of the stack... 179 LLVM_DEBUG(dbgs() << "Adjusting stack by: " 180 << (MFI.getStackSize() - AlreadyAdjusted) << "\n"); 181 generateStackAdjustment(MBB, MBBI, *ST.getInstrInfo(), dl, 182 -(MFI.getStackSize() - AlreadyAdjusted), ARC::SP); 183 184 if (hasFP(MF)) { 185 LLVM_DEBUG(dbgs() << "Setting FP from SP.\n"); 186 BuildMI(MBB, MBBI, dl, 187 TII->get(isUInt<6>(MFI.getStackSize()) ? ARC::ADD_rru6 188 : ARC::ADD_rrlimm), 189 ARC::FP) 190 .addReg(ARC::SP) 191 .addImm(MFI.getStackSize()); 192 } 193 194 // Emit CFI records: 195 // .cfi_def_cfa_offset StackSize 196 // .cfi_offset fp, -StackSize 197 // .cfi_offset blink, -StackSize+4 198 unsigned CFIIndex = MF.addFrameInst( 199 MCCFIInstruction::cfiDefCfaOffset(nullptr, MFI.getStackSize())); 200 BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION)) 201 .addCFIIndex(CFIIndex) 202 .setMIFlags(MachineInstr::FrameSetup); 203 204 int CurOffset = -4; 205 if (hasFP(MF)) { 206 CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( 207 nullptr, MRI->getDwarfRegNum(ARC::FP, true), CurOffset)); 208 BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION)) 209 .addCFIIndex(CFIIndex) 210 .setMIFlags(MachineInstr::FrameSetup); 211 CurOffset -= 4; 212 } 213 214 if (MFI.hasCalls()) { 215 CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( 216 nullptr, MRI->getDwarfRegNum(ARC::BLINK, true), CurOffset)); 217 BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION)) 218 .addCFIIndex(CFIIndex) 219 .setMIFlags(MachineInstr::FrameSetup); 220 } 221 // CFI for the rest of the registers. 222 for (const auto &Entry : CSI) { 223 unsigned Reg = Entry.getReg(); 224 int FI = Entry.getFrameIdx(); 225 // Skip BLINK and FP. 226 if ((hasFP(MF) && Reg == ARC::FP) || (MFI.hasCalls() && Reg == ARC::BLINK)) 227 continue; 228 CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( 229 nullptr, MRI->getDwarfRegNum(Reg, true), MFI.getObjectOffset(FI))); 230 BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION)) 231 .addCFIIndex(CFIIndex) 232 .setMIFlags(MachineInstr::FrameSetup); 233 } 234 } 235 236 /// Insert epilog code into the function. 237 /// For ARC, this inserts a call to a function that restores callee saved 238 /// registers onto the stack, when enough callee saved registers are required. 239 void ARCFrameLowering::emitEpilogue(MachineFunction &MF, 240 MachineBasicBlock &MBB) const { 241 LLVM_DEBUG(dbgs() << "Emit Epilogue: " << MF.getName() << "\n"); 242 auto *AFI = MF.getInfo<ARCFunctionInfo>(); 243 const ARCInstrInfo *TII = MF.getSubtarget<ARCSubtarget>().getInstrInfo(); 244 MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator(); 245 MachineFrameInfo &MFI = MF.getFrameInfo(); 246 uint64_t StackSize = MF.getFrameInfo().getStackSize(); 247 bool SavedBlink = false; 248 unsigned AmountAboveFunclet = 0; 249 // If we have variable sized frame objects, then we have to move 250 // the stack pointer to a known spot (fp - StackSize). 251 // Then, replace the frame pointer by (new) [sp,StackSize-4]. 252 // Then, move the stack pointer the rest of the way (sp = sp + StackSize). 253 if (hasFP(MF)) { 254 unsigned Opc = ARC::SUB_rrlimm; 255 if (isUInt<6>(StackSize)) 256 Opc = ARC::SUB_rru6; 257 BuildMI(MBB, MBBI, DebugLoc(), TII->get(Opc), ARC::SP) 258 .addReg(ARC::FP) 259 .addImm(StackSize); 260 AmountAboveFunclet += 4; 261 } 262 263 // Now, move the stack pointer to the bottom of the save area for the funclet. 264 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); 265 unsigned Last = determineLastCalleeSave(CSI); 266 unsigned StackSlotsUsedByFunclet = 0; 267 // Now, restore the callee save registers. 268 if (UseSaveRestoreFunclet && Last > ARC::R14) { 269 // BL to __ld_r13_to_<TRI->getRegAsmName()> 270 StackSlotsUsedByFunclet = Last - ARC::R12; 271 AmountAboveFunclet += 4 * (StackSlotsUsedByFunclet + 1); 272 SavedBlink = true; 273 } 274 275 if (MFI.hasCalls() && !SavedBlink) { 276 AmountAboveFunclet += 4; 277 SavedBlink = true; 278 } 279 280 // Move the stack pointer up to the point of the funclet. 281 if (unsigned MoveAmount = StackSize - AmountAboveFunclet) { 282 unsigned Opc = ARC::ADD_rrlimm; 283 if (isUInt<6>(MoveAmount)) 284 Opc = ARC::ADD_rru6; 285 else if (isInt<12>(MoveAmount)) 286 Opc = ARC::ADD_rrs12; 287 BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(Opc), ARC::SP) 288 .addReg(ARC::SP) 289 .addImm(StackSize - AmountAboveFunclet); 290 } 291 292 if (StackSlotsUsedByFunclet) { 293 // This part of the adjustment will always be < 64 bytes. 294 BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::BL)) 295 .addExternalSymbol(load_funclet_name[Last - ARC::R15]) 296 .addReg(ARC::BLINK, RegState::Implicit | RegState::Kill); 297 unsigned Opc = ARC::ADD_rrlimm; 298 if (isUInt<6>(4 * StackSlotsUsedByFunclet)) 299 Opc = ARC::ADD_rru6; 300 else if (isInt<12>(4 * StackSlotsUsedByFunclet)) 301 Opc = ARC::ADD_rrs12; 302 BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(Opc), ARC::SP) 303 .addReg(ARC::SP) 304 .addImm(4 * (StackSlotsUsedByFunclet)); 305 } 306 // Now, pop blink if necessary. 307 if (SavedBlink) { 308 BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::POP_S_BLINK)); 309 } 310 // Now, pop fp if necessary. 311 if (hasFP(MF)) { 312 BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::LD_AB_rs9)) 313 .addReg(ARC::FP, RegState::Define) 314 .addReg(ARC::SP, RegState::Define) 315 .addReg(ARC::SP) 316 .addImm(4); 317 } 318 319 // Relieve the varargs area if necessary. 320 if (MF.getFunction().isVarArg()) { 321 // Add in the varargs area here first. 322 LLVM_DEBUG(dbgs() << "Varargs\n"); 323 unsigned VarArgsBytes = MFI.getObjectSize(AFI->getVarArgsFrameIndex()); 324 unsigned Opc = ARC::ADD_rrlimm; 325 if (isUInt<6>(VarArgsBytes)) 326 Opc = ARC::ADD_rru6; 327 else if (isInt<12>(VarArgsBytes)) 328 Opc = ARC::ADD_rrs12; 329 BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(Opc)) 330 .addReg(ARC::SP) 331 .addReg(ARC::SP) 332 .addImm(VarArgsBytes); 333 } 334 } 335 336 static std::vector<CalleeSavedInfo>::iterator 337 getSavedReg(std::vector<CalleeSavedInfo> &V, unsigned reg) { 338 for (auto I = V.begin(), E = V.end(); I != E; ++I) { 339 if (reg == I->getReg()) 340 return I; 341 } 342 return V.end(); 343 } 344 345 bool ARCFrameLowering::assignCalleeSavedSpillSlots( 346 MachineFunction &MF, const TargetRegisterInfo *TRI, 347 std::vector<CalleeSavedInfo> &CSI) const { 348 // Use this opportunity to assign the spill slots for all of the potential 349 // callee save registers (blink, fp, r13->r25) that we care about the 350 // placement for. We can calculate all of that data here. 351 int CurOffset = -4; 352 unsigned Last = determineLastCalleeSave(CSI); 353 MachineFrameInfo &MFI = MF.getFrameInfo(); 354 if (hasFP(MF)) { 355 // Create a fixed slot at for FP 356 int StackObj = MFI.CreateFixedSpillStackObject(4, CurOffset, true); 357 LLVM_DEBUG(dbgs() << "Creating fixed object (" << StackObj << ") for FP at " 358 << CurOffset << "\n"); 359 (void)StackObj; 360 CurOffset -= 4; 361 } 362 if (MFI.hasCalls() || (UseSaveRestoreFunclet && Last > ARC::R14)) { 363 // Create a fixed slot for BLINK. 364 int StackObj = MFI.CreateFixedSpillStackObject(4, CurOffset, true); 365 LLVM_DEBUG(dbgs() << "Creating fixed object (" << StackObj 366 << ") for BLINK at " << CurOffset << "\n"); 367 (void)StackObj; 368 CurOffset -= 4; 369 } 370 371 // Create slots for last down to r13. 372 for (unsigned Which = Last; Which > ARC::R12; Which--) { 373 auto RegI = getSavedReg(CSI, Which); 374 if (RegI == CSI.end() || RegI->getFrameIdx() == 0) { 375 // Always create the stack slot. If for some reason the register isn't in 376 // the save list, then don't worry about it. 377 int FI = MFI.CreateFixedSpillStackObject(4, CurOffset, true); 378 if (RegI != CSI.end()) 379 RegI->setFrameIdx(FI); 380 } else 381 MFI.setObjectOffset(RegI->getFrameIdx(), CurOffset); 382 CurOffset -= 4; 383 } 384 for (auto &I : CSI) { 385 if (I.getReg() > ARC::R12) 386 continue; 387 if (I.getFrameIdx() == 0) { 388 I.setFrameIdx(MFI.CreateFixedSpillStackObject(4, CurOffset, true)); 389 LLVM_DEBUG(dbgs() << "Creating fixed object (" << I.getFrameIdx() 390 << ") for other register at " << CurOffset << "\n"); 391 } else { 392 MFI.setObjectOffset(I.getFrameIdx(), CurOffset); 393 LLVM_DEBUG(dbgs() << "Updating fixed object (" << I.getFrameIdx() 394 << ") for other register at " << CurOffset << "\n"); 395 } 396 CurOffset -= 4; 397 } 398 return true; 399 } 400 401 bool ARCFrameLowering::spillCalleeSavedRegisters( 402 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, 403 ArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const { 404 LLVM_DEBUG(dbgs() << "Spill callee saved registers: " 405 << MBB.getParent()->getName() << "\n"); 406 // There are routines for saving at least 3 registers (r13 to r15, etc.) 407 unsigned Last = determineLastCalleeSave(CSI); 408 if (UseSaveRestoreFunclet && Last > ARC::R14) { 409 // Use setObjectOffset for these registers. 410 // Needs to be in or before processFunctionBeforeFrameFinalized. 411 // Or, do assignCalleeSaveSpillSlots? 412 // Will be handled in prolog. 413 return true; 414 } 415 return false; 416 } 417 418 bool ARCFrameLowering::restoreCalleeSavedRegisters( 419 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, 420 MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const { 421 LLVM_DEBUG(dbgs() << "Restore callee saved registers: " 422 << MBB.getParent()->getName() << "\n"); 423 // There are routines for saving at least 3 registers (r13 to r15, etc.) 424 unsigned Last = determineLastCalleeSave(CSI); 425 if (UseSaveRestoreFunclet && Last > ARC::R14) { 426 // Will be handled in epilog. 427 return true; 428 } 429 return false; 430 } 431 432 // Adjust local variables that are 4-bytes or larger to 4-byte boundary 433 void ARCFrameLowering::processFunctionBeforeFrameFinalized( 434 MachineFunction &MF, RegScavenger *RS) const { 435 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo(); 436 LLVM_DEBUG(dbgs() << "Process function before frame finalized: " 437 << MF.getName() << "\n"); 438 MachineFrameInfo &MFI = MF.getFrameInfo(); 439 LLVM_DEBUG(dbgs() << "Current stack size: " << MFI.getStackSize() << "\n"); 440 const TargetRegisterClass *RC = &ARC::GPR32RegClass; 441 if (MFI.hasStackObjects()) { 442 int RegScavFI = MFI.CreateStackObject(RegInfo->getSpillSize(*RC), 443 RegInfo->getSpillAlign(*RC), false); 444 RS->addScavengingFrameIndex(RegScavFI); 445 LLVM_DEBUG(dbgs() << "Created scavenging index RegScavFI=" << RegScavFI 446 << "\n"); 447 } 448 } 449 450 static void emitRegUpdate(MachineBasicBlock &MBB, 451 MachineBasicBlock::iterator &MBBI, DebugLoc dl, 452 unsigned Reg, int NumBytes, bool IsAdd, 453 const ARCInstrInfo *TII) { 454 unsigned Opc; 455 if (isUInt<6>(NumBytes)) 456 Opc = IsAdd ? ARC::ADD_rru6 : ARC::SUB_rru6; 457 else if (isInt<12>(NumBytes)) 458 Opc = IsAdd ? ARC::ADD_rrs12 : ARC::SUB_rrs12; 459 else 460 Opc = IsAdd ? ARC::ADD_rrlimm : ARC::SUB_rrlimm; 461 462 BuildMI(MBB, MBBI, dl, TII->get(Opc), Reg) 463 .addReg(Reg, RegState::Kill) 464 .addImm(NumBytes); 465 } 466 467 MachineBasicBlock::iterator ARCFrameLowering::eliminateCallFramePseudoInstr( 468 MachineFunction &MF, MachineBasicBlock &MBB, 469 MachineBasicBlock::iterator I) const { 470 LLVM_DEBUG(dbgs() << "EmitCallFramePseudo: " << MF.getName() << "\n"); 471 const ARCInstrInfo *TII = MF.getSubtarget<ARCSubtarget>().getInstrInfo(); 472 MachineInstr &Old = *I; 473 DebugLoc dl = Old.getDebugLoc(); 474 unsigned Amt = Old.getOperand(0).getImm(); 475 auto *AFI = MF.getInfo<ARCFunctionInfo>(); 476 if (!hasFP(MF)) { 477 if (Amt > AFI->MaxCallStackReq && Old.getOpcode() == ARC::ADJCALLSTACKDOWN) 478 AFI->MaxCallStackReq = Amt; 479 } else { 480 if (Amt != 0) { 481 assert((Old.getOpcode() == ARC::ADJCALLSTACKDOWN || 482 Old.getOpcode() == ARC::ADJCALLSTACKUP) && 483 "Unknown Frame Pseudo."); 484 bool IsAdd = (Old.getOpcode() == ARC::ADJCALLSTACKUP); 485 emitRegUpdate(MBB, I, dl, ARC::SP, Amt, IsAdd, TII); 486 } 487 } 488 return MBB.erase(I); 489 } 490 491 bool ARCFrameLowering::hasFP(const MachineFunction &MF) const { 492 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo(); 493 bool HasFP = MF.getTarget().Options.DisableFramePointerElim(MF) || 494 MF.getFrameInfo().hasVarSizedObjects() || 495 MF.getFrameInfo().isFrameAddressTaken() || 496 RegInfo->hasStackRealignment(MF); 497 return HasFP; 498 } 499