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