LLVM 19.0.0git
ARCFrameLowering.cpp
Go to the documentation of this file.
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"
15#include "ARCSubtarget.h"
20#include "llvm/IR/Function.h"
21#include "llvm/Support/Debug.h"
22
23#define DEBUG_TYPE "arc-frame-lowering"
24
25using namespace llvm;
26
27static 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
32static 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
38static 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
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
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
89 BitVector &SavedRegs,
90 RegScavenger *RS) const {
91 LLVM_DEBUG(dbgs() << "Determine Callee Saves: " << MF.getName() << "\n");
93 SavedRegs.set(ARC::BLINK);
94}
95
96void ARCFrameLowering::adjustStackToMatchRecords(
98 bool Allocate) const {
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
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.
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();
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))
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");
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(
200 BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
201 .addCFIIndex(CFIIndex)
203
204 int CurOffset = -4;
205 if (hasFP(MF)) {
207 nullptr, MRI->getDwarfRegNum(ARC::FP, true), CurOffset));
208 BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
209 .addCFIIndex(CFIIndex)
211 CurOffset -= 4;
212 }
213
214 if (MFI.hasCalls()) {
216 nullptr, MRI->getDwarfRegNum(ARC::BLINK, true), CurOffset));
217 BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
218 .addCFIIndex(CFIIndex)
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;
229 nullptr, MRI->getDwarfRegNum(Reg, true), MFI.getObjectOffset(FI)));
230 BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
231 .addCFIIndex(CFIIndex)
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.
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();
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))
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
336static std::vector<CalleeSavedInfo>::iterator
337getSavedReg(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
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
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
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
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
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)
464 .addImm(NumBytes);
465}
466
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
492 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
493 bool HasFP = MF.getTarget().Options.DisableFramePointerElim(MF) ||
496 RegInfo->hasStackRealignment(MF);
497 return HasFP;
498}
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator MBBI
static const char * load_funclet_name[]
static void emitRegUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, DebugLoc dl, unsigned Reg, int NumBytes, bool IsAdd, const ARCInstrInfo *TII)
static const char * store_funclet_name[]
static void generateStackAdjustment(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const ARCInstrInfo &TII, DebugLoc dl, int Amount, int StackPtr)
static std::vector< CalleeSavedInfo >::iterator getSavedReg(std::vector< CalleeSavedInfo > &V, unsigned reg)
static cl::opt< bool > UseSaveRestoreFunclet("arc-save-restore-funclet", cl::Hidden, cl::desc("Use arc callee save/restore functions"), cl::init(true))
static unsigned determineLastCalleeSave(ArrayRef< CalleeSavedInfo > CSI)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_DEBUG(X)
Definition: Debug.h:101
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
unsigned const TargetRegisterInfo * TRI
LLVMContext & Context
This file declares the machine register scavenger class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, MutableArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const override
restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee saved registers and returns...
void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS) const override
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const override
This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy p...
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const override
Add explicit callee save registers.
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
Insert Prologue into the function.
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
Insert Epilogue into the function.
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register.
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const override
spillCalleeSavedRegisters - Issues instruction(s) to spill all callee saved registers and returns tru...
bool assignCalleeSavedSpillSlots(llvm::MachineFunction &, const llvm::TargetRegisterInfo *, std::vector< llvm::CalleeSavedInfo > &) const override
ARCFunctionInfo - This class is derived from MachineFunction private ARC target-specific information ...
const ARCInstrInfo * getInstrInfo() const override
Definition: ARCSubtarget.h:51
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
BitVector & set()
Definition: BitVector.h:351
A debug info location.
Definition: DebugLoc.h:33
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition: Function.h:213
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int Offset, SMLoc Loc={})
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
Definition: MCDwarf.h:583
static MCCFIInstruction cfiDefCfaOffset(MCSymbol *L, int Offset, SMLoc Loc={})
.cfi_def_cfa_offset modifies a rule for computing CFA.
Definition: MCDwarf.h:556
Context object for machine code objects.
Definition: MCContext.h:76
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
bool hasCalls() const
Return true if the current function has any function calls.
bool isFrameAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
void setObjectOffset(int ObjectIdx, int64_t SPOffset)
Set the stack frame offset of the specified object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
bool hasStackObjects() const
Return true if there are any stack objects in this function.
int CreateFixedSpillStackObject(uint64_t Size, int64_t SPOffset, bool IsImmutable=false)
Create a spill slot at a fixed location on the stack.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
void setStackSize(uint64_t Size)
Set the size of the stack.
unsigned addFrameInst(const MCCFIInstruction &Inst)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Function & getFunction()
Return the LLVM function that this machine code represents.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
MachineModuleInfo & getMMI() const
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
const MachineInstrBuilder & addCFIIndex(unsigned CFIIndex) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
Representation of each machine instruction.
Definition: MachineInstr.h:68
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:543
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:472
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:553
This class contains meta information specific to a module.
int64_t getImm() const
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition: ArrayRef.h:307
void addScavengingFrameIndex(int FI)
Add a scavenging frame index.
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
TargetOptions Options
bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Align getSpillAlign(const TargetRegisterClass &RC) const
Return the minimum required alignment in bytes for a spill slot for a register of this class.
bool hasStackRealignment(const MachineFunction &MF) const
True if stack realignment is required and still possible.
unsigned getSpillSize(const TargetRegisterClass &RC) const
Return the size in bytes of the stack slot allocated to hold a spilled copy of a register from class ...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Define
Register definition.
@ Kill
The last use of a register.
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:450
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163