LLVM 20.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 MCContext &Context = MF.getContext();
120 const MCRegisterInfo *MRI = Context.getRegisterInfo();
121 const ARCInstrInfo *TII = MF.getSubtarget<ARCSubtarget>().getInstrInfo();
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))
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");
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(
199 BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
200 .addCFIIndex(CFIIndex)
202
203 int CurOffset = -4;
204 if (hasFP(MF)) {
206 nullptr, MRI->getDwarfRegNum(ARC::FP, true), CurOffset));
207 BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
208 .addCFIIndex(CFIIndex)
210 CurOffset -= 4;
211 }
212
213 if (MFI.hasCalls()) {
215 nullptr, MRI->getDwarfRegNum(ARC::BLINK, true), CurOffset));
216 BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
217 .addCFIIndex(CFIIndex)
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;
228 nullptr, MRI->getDwarfRegNum(Reg, true), MFI.getObjectOffset(FI)));
229 BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
230 .addCFIIndex(CFIIndex)
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.
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();
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))
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
335static std::vector<CalleeSavedInfo>::iterator
336getSavedReg(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
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
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
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
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
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)
463 .addImm(NumBytes);
464}
465
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
491 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
492 bool HasFP = MF.getTarget().Options.DisableFramePointerElim(MF) ||
495 RegInfo->hasStackRealignment(MF);
496 return HasFP;
497}
unsigned const MachineRegisterInfo * MRI
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)
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator MBBI
#define LLVM_DEBUG(...)
Definition: Debug.h:106
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
unsigned const TargetRegisterInfo * TRI
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...
bool hasFPImpl(const MachineFunction &MF) const override
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 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:234
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
Definition: MCDwarf.h:617
static MCCFIInstruction cfiDefCfaOffset(MCSymbol *L, int64_t Offset, SMLoc Loc={})
.cfi_def_cfa_offset modifies a rule for computing CFA.
Definition: MCDwarf.h:590
Context object for machine code objects.
Definition: MCContext.h:83
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.
MCContext & getContext() const
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
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:69
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:575
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:499
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:585
int64_t getImm() const
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition: ArrayRef.h:310
void addScavengingFrameIndex(int FI)
Add a scavenging frame index.
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
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:443
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