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