]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/lib/Target/ARC/ARCFrameLowering.cpp
MFC r355940:
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / lib / Target / ARC / ARCFrameLowering.cpp
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 }