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