LLVM 24.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 const char *store_funclet_name[] = {
28 "__st_r13_to_r15", "__st_r13_to_r16", "__st_r13_to_r17", "__st_r13_to_r18",
29 "__st_r13_to_r19", "__st_r13_to_r20", "__st_r13_to_r21", "__st_r13_to_r22",
30 "__st_r13_to_r23", "__st_r13_to_r24", "__st_r13_to_r25",
31};
32
33static const char *load_funclet_name[] = {
34 "__ld_r13_to_r15", "__ld_r13_to_r16", "__ld_r13_to_r17", "__ld_r13_to_r18",
35 "__ld_r13_to_r19", "__ld_r13_to_r20", "__ld_r13_to_r21", "__ld_r13_to_r22",
36 "__ld_r13_to_r23", "__ld_r13_to_r24", "__ld_r13_to_r25",
37};
38
41 const ARCInstrInfo &TII, DebugLoc dl,
42 int Amount, int StackPtr) {
43 unsigned AdjOp;
44 if (!Amount)
45 return;
46 bool Positive;
47 unsigned AbsAmount;
48 if (Amount < 0) {
49 AbsAmount = -Amount;
50 Positive = false;
51 } else {
52 AbsAmount = Amount;
53 Positive = true;
54 }
55
56 LLVM_DEBUG(dbgs() << "Internal: adjust stack by: " << Amount << ","
57 << AbsAmount << "\n");
58
59 assert((AbsAmount % 4 == 0) && "Stack adjustments must be 4-byte aligned.");
60 if (isUInt<6>(AbsAmount))
61 AdjOp = Positive ? ARC::ADD_rru6 : ARC::SUB_rru6;
62 else if (isInt<12>(AbsAmount))
63 AdjOp = Positive ? ARC::ADD_rrs12 : ARC::SUB_rrs12;
64 else
65 AdjOp = Positive ? ARC::ADD_rrlimm : ARC::SUB_rrlimm;
66
67 BuildMI(MBB, MBBI, dl, TII.get(AdjOp), StackPtr)
68 .addReg(StackPtr)
69 .addImm(AbsAmount);
70}
71
73 unsigned Last = 0;
74 for (auto Reg : CSI) {
75 assert(Reg.getReg() >= ARC::R13 && Reg.getReg() <= ARC::R25 &&
76 "Unexpected callee saved reg.");
77 if (Reg.getReg() > Last)
78 Last = Reg.getReg();
79 }
80 return Last;
81}
82
84 BitVector &SavedRegs,
85 RegScavenger *RS) const {
86 LLVM_DEBUG(dbgs() << "Determine Callee Saves: " << MF.getName() << "\n");
88 SavedRegs.set(ARC::BLINK);
89}
90
91void ARCFrameLowering::adjustStackToMatchRecords(
93 bool Allocate) const {
94 MachineFunction &MF = *MBB.getParent();
95 int ScalarAlloc = MF.getFrameInfo().getStackSize();
96
97 if (Allocate) {
98 // Allocate by adjusting by the negative of what the record holder tracked
99 // it tracked a positive offset in a downward growing stack.
100 ScalarAlloc = -ScalarAlloc;
101 }
102
104 ScalarAlloc, ARC::SP);
105}
106
107/// Insert prolog code into the function.
108/// For ARC, this inserts a call to a function that puts required callee saved
109/// registers onto the stack, when enough callee saved registers are required.
111 MachineBasicBlock &MBB) const {
112 LLVM_DEBUG(dbgs() << "Emit Prologue: " << MF.getName() << "\n");
113 auto *AFI = MF.getInfo<ARCFunctionInfo>();
114 MCContext &Context = MF.getContext();
115 const MCRegisterInfo *MRI = Context.getRegisterInfo();
116 const ARCInstrInfo *TII = MF.getSubtarget<ARCSubtarget>().getInstrInfo();
118 // Debug location must be unknown since the first debug location is used
119 // to determine the end of the prologue.
120 DebugLoc dl;
121 MachineFrameInfo &MFI = MF.getFrameInfo();
122 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
123 unsigned Last = determineLastCalleeSave(CSI);
124 unsigned StackSlotsUsedByFunclet = 0;
125 bool SavedBlink = false;
126 unsigned AlreadyAdjusted = 0;
127 if (MF.getFunction().isVarArg()) {
128 // Add in the varargs area here first.
129 LLVM_DEBUG(dbgs() << "Varargs\n");
130 unsigned VarArgsBytes = MFI.getObjectSize(AFI->getVarArgsFrameIndex());
131 unsigned Opc = ARC::SUB_rrlimm;
132 if (isUInt<6>(VarArgsBytes))
133 Opc = ARC::SUB_rru6;
134 else if (isInt<12>(VarArgsBytes))
135 Opc = ARC::SUB_rrs12;
136 BuildMI(MBB, MBBI, dl, TII->get(Opc), ARC::SP)
137 .addReg(ARC::SP)
138 .addImm(VarArgsBytes);
139 }
140 if (hasFP(MF)) {
141 LLVM_DEBUG(dbgs() << "Saving FP\n");
142 BuildMI(MBB, MBBI, dl, TII->get(ARC::ST_AW_rs9))
143 .addReg(ARC::SP, RegState::Define)
144 .addReg(ARC::FP)
145 .addReg(ARC::SP)
146 .addImm(-4);
147 AlreadyAdjusted += 4;
148 }
149 if (ST.getCLOpts().save_restore_funclet && Last > ARC::R14) {
150 LLVM_DEBUG(dbgs() << "Creating store funclet.\n");
151 // BL to __save_r13_to_<TRI->getRegAsmName()>
152 StackSlotsUsedByFunclet = Last - ARC::R12;
153 BuildMI(MBB, MBBI, dl, TII->get(ARC::PUSH_S_BLINK));
154 BuildMI(MBB, MBBI, dl, TII->get(ARC::SUB_rru6))
155 .addReg(ARC::SP)
156 .addReg(ARC::SP)
157 .addImm(4 * StackSlotsUsedByFunclet);
158 BuildMI(MBB, MBBI, dl, TII->get(ARC::BL))
161 AlreadyAdjusted += 4 * (StackSlotsUsedByFunclet + 1);
162 SavedBlink = true;
163 }
164 // If we haven't saved BLINK, but we need to...do that now.
165 if (MFI.hasCalls() && !SavedBlink) {
166 LLVM_DEBUG(dbgs() << "Creating save blink.\n");
167 BuildMI(MBB, MBBI, dl, TII->get(ARC::PUSH_S_BLINK));
168 AlreadyAdjusted += 4;
169 }
170 if (AFI->MaxCallStackReq > 0)
171 MFI.setStackSize(MFI.getStackSize() + AFI->MaxCallStackReq);
172 // We have already saved some of the stack...
173 LLVM_DEBUG(dbgs() << "Adjusting stack by: "
174 << (MFI.getStackSize() - AlreadyAdjusted) << "\n");
175 generateStackAdjustment(MBB, MBBI, *ST.getInstrInfo(), dl,
176 -(MFI.getStackSize() - AlreadyAdjusted), ARC::SP);
177
178 if (hasFP(MF)) {
179 LLVM_DEBUG(dbgs() << "Setting FP from SP.\n");
180 BuildMI(MBB, MBBI, dl,
181 TII->get(isUInt<6>(MFI.getStackSize()) ? ARC::ADD_rru6
182 : ARC::ADD_rrlimm),
183 ARC::FP)
184 .addReg(ARC::SP)
185 .addImm(MFI.getStackSize());
186 }
187
188 // Emit CFI records:
189 // .cfi_def_cfa_offset StackSize
190 // .cfi_offset fp, -StackSize
191 // .cfi_offset blink, -StackSize+4
192 unsigned CFIIndex = MF.addFrameInst(
194 BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
195 .addCFIIndex(CFIIndex)
197
198 int CurOffset = -4;
199 if (hasFP(MF)) {
201 nullptr, MRI->getDwarfRegNum(ARC::FP, true), CurOffset));
202 BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
203 .addCFIIndex(CFIIndex)
205 CurOffset -= 4;
206 }
207
208 if (MFI.hasCalls()) {
210 nullptr, MRI->getDwarfRegNum(ARC::BLINK, true), CurOffset));
211 BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
212 .addCFIIndex(CFIIndex)
214 }
215 // CFI for the rest of the registers.
216 for (const auto &Entry : CSI) {
217 MCRegister Reg = Entry.getReg();
218 int FI = Entry.getFrameIdx();
219 // Skip BLINK and FP.
220 if ((hasFP(MF) && Reg == ARC::FP) || (MFI.hasCalls() && Reg == ARC::BLINK))
221 continue;
223 nullptr, MRI->getDwarfRegNum(Reg, true), MFI.getObjectOffset(FI)));
224 BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
225 .addCFIIndex(CFIIndex)
227 }
228}
229
230/// Insert epilog code into the function.
231/// For ARC, this inserts a call to a function that restores callee saved
232/// registers onto the stack, when enough callee saved registers are required.
234 MachineBasicBlock &MBB) const {
235 LLVM_DEBUG(dbgs() << "Emit Epilogue: " << MF.getName() << "\n");
236 auto *AFI = MF.getInfo<ARCFunctionInfo>();
237 const ARCInstrInfo *TII = MF.getSubtarget<ARCSubtarget>().getInstrInfo();
238 MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator();
239 MachineFrameInfo &MFI = MF.getFrameInfo();
240 uint64_t StackSize = MF.getFrameInfo().getStackSize();
241 bool SavedBlink = false;
242 unsigned AmountAboveFunclet = 0;
243 // If we have variable sized frame objects, then we have to move
244 // the stack pointer to a known spot (fp - StackSize).
245 // Then, replace the frame pointer by (new) [sp,StackSize-4].
246 // Then, move the stack pointer the rest of the way (sp = sp + StackSize).
247 if (hasFP(MF)) {
248 unsigned Opc = ARC::SUB_rrlimm;
249 if (isUInt<6>(StackSize))
250 Opc = ARC::SUB_rru6;
251 BuildMI(MBB, MBBI, DebugLoc(), TII->get(Opc), ARC::SP)
252 .addReg(ARC::FP)
253 .addImm(StackSize);
254 AmountAboveFunclet += 4;
255 }
256
257 // Now, move the stack pointer to the bottom of the save area for the funclet.
258 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
259 unsigned Last = determineLastCalleeSave(CSI);
260 unsigned StackSlotsUsedByFunclet = 0;
261 // Now, restore the callee save registers.
262 if (ST.getCLOpts().save_restore_funclet && Last > ARC::R14) {
263 // BL to __ld_r13_to_<TRI->getRegAsmName()>
264 StackSlotsUsedByFunclet = Last - ARC::R12;
265 AmountAboveFunclet += 4 * (StackSlotsUsedByFunclet + 1);
266 SavedBlink = true;
267 }
268
269 if (MFI.hasCalls() && !SavedBlink) {
270 AmountAboveFunclet += 4;
271 SavedBlink = true;
272 }
273
274 // Move the stack pointer up to the point of the funclet.
275 if (unsigned MoveAmount = StackSize - AmountAboveFunclet) {
276 unsigned Opc = ARC::ADD_rrlimm;
277 if (isUInt<6>(MoveAmount))
278 Opc = ARC::ADD_rru6;
279 else if (isInt<12>(MoveAmount))
280 Opc = ARC::ADD_rrs12;
281 BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(Opc), ARC::SP)
282 .addReg(ARC::SP)
283 .addImm(StackSize - AmountAboveFunclet);
284 }
285
286 if (StackSlotsUsedByFunclet) {
287 // This part of the adjustment will always be < 64 bytes.
288 BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::BL))
291 unsigned Opc = ARC::ADD_rrlimm;
292 if (isUInt<6>(4 * StackSlotsUsedByFunclet))
293 Opc = ARC::ADD_rru6;
294 else if (isInt<12>(4 * StackSlotsUsedByFunclet))
295 Opc = ARC::ADD_rrs12;
296 BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(Opc), ARC::SP)
297 .addReg(ARC::SP)
298 .addImm(4 * (StackSlotsUsedByFunclet));
299 }
300 // Now, pop blink if necessary.
301 if (SavedBlink) {
302 BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::POP_S_BLINK));
303 }
304 // Now, pop fp if necessary.
305 if (hasFP(MF)) {
306 BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::LD_AB_rs9))
307 .addReg(ARC::FP, RegState::Define)
308 .addReg(ARC::SP, RegState::Define)
309 .addReg(ARC::SP)
310 .addImm(4);
311 }
312
313 // Relieve the varargs area if necessary.
314 if (MF.getFunction().isVarArg()) {
315 // Add in the varargs area here first.
316 LLVM_DEBUG(dbgs() << "Varargs\n");
317 unsigned VarArgsBytes = MFI.getObjectSize(AFI->getVarArgsFrameIndex());
318 unsigned Opc = ARC::ADD_rrlimm;
319 if (isUInt<6>(VarArgsBytes))
320 Opc = ARC::ADD_rru6;
321 else if (isInt<12>(VarArgsBytes))
322 Opc = ARC::ADD_rrs12;
323 BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(Opc))
324 .addReg(ARC::SP)
325 .addReg(ARC::SP)
326 .addImm(VarArgsBytes);
327 }
328}
329
330static std::vector<CalleeSavedInfo>::iterator
331getSavedReg(std::vector<CalleeSavedInfo> &V, unsigned reg) {
332 for (auto I = V.begin(), E = V.end(); I != E; ++I) {
333 if (reg == I->getReg())
334 return I;
335 }
336 return V.end();
337}
338
341 std::vector<CalleeSavedInfo> &CSI) const {
342 // Use this opportunity to assign the spill slots for all of the potential
343 // callee save registers (blink, fp, r13->r25) that we care about the
344 // placement for. We can calculate all of that data here.
345 int CurOffset = -4;
346 unsigned Last = determineLastCalleeSave(CSI);
347 MachineFrameInfo &MFI = MF.getFrameInfo();
348 if (hasFP(MF)) {
349 // Create a fixed slot at for FP
350 int StackObj = MFI.CreateFixedSpillStackObject(4, CurOffset, true);
351 LLVM_DEBUG(dbgs() << "Creating fixed object (" << StackObj << ") for FP at "
352 << CurOffset << "\n");
353 (void)StackObj;
354 CurOffset -= 4;
355 }
356 if (MFI.hasCalls() ||
357 (ST.getCLOpts().save_restore_funclet && Last > ARC::R14)) {
358 // Create a fixed slot for BLINK.
359 int StackObj = MFI.CreateFixedSpillStackObject(4, CurOffset, true);
360 LLVM_DEBUG(dbgs() << "Creating fixed object (" << StackObj
361 << ") for BLINK at " << CurOffset << "\n");
362 (void)StackObj;
363 CurOffset -= 4;
364 }
365
366 // Create slots for last down to r13.
367 for (unsigned Which = Last; Which > ARC::R12; Which--) {
368 auto RegI = getSavedReg(CSI, Which);
369 if (RegI == CSI.end() || RegI->getFrameIdx() == 0) {
370 // Always create the stack slot. If for some reason the register isn't in
371 // the save list, then don't worry about it.
372 int FI = MFI.CreateFixedSpillStackObject(4, CurOffset, true);
373 if (RegI != CSI.end())
374 RegI->setFrameIdx(FI);
375 } else
376 MFI.setObjectOffset(RegI->getFrameIdx(), CurOffset);
377 CurOffset -= 4;
378 }
379 for (auto &I : CSI) {
380 if (I.getReg() > ARC::R12)
381 continue;
382 if (I.getFrameIdx() == 0) {
383 I.setFrameIdx(MFI.CreateFixedSpillStackObject(4, CurOffset, true));
384 LLVM_DEBUG(dbgs() << "Creating fixed object (" << I.getFrameIdx()
385 << ") for other register at " << CurOffset << "\n");
386 } else {
387 MFI.setObjectOffset(I.getFrameIdx(), CurOffset);
388 LLVM_DEBUG(dbgs() << "Updating fixed object (" << I.getFrameIdx()
389 << ") for other register at " << CurOffset << "\n");
390 }
391 CurOffset -= 4;
392 }
393 return true;
394}
395
399 LLVM_DEBUG(dbgs() << "Spill callee saved registers: "
400 << MBB.getParent()->getName() << "\n");
401 // There are routines for saving at least 3 registers (r13 to r15, etc.)
402 unsigned Last = determineLastCalleeSave(CSI);
403 if (ST.getCLOpts().save_restore_funclet && Last > ARC::R14) {
404 // Use setObjectOffset for these registers.
405 // Needs to be in or before processFunctionBeforeFrameFinalized.
406 // Or, do assignCalleeSaveSpillSlots?
407 // Will be handled in prolog.
408 return true;
409 }
410 return false;
411}
412
416 LLVM_DEBUG(dbgs() << "Restore callee saved registers: "
417 << MBB.getParent()->getName() << "\n");
418 // There are routines for saving at least 3 registers (r13 to r15, etc.)
419 unsigned Last = determineLastCalleeSave(CSI);
420 if (ST.getCLOpts().save_restore_funclet && Last > ARC::R14) {
421 // Will be handled in epilog.
422 return true;
423 }
424 return false;
425}
426
427// Adjust local variables that are 4-bytes or larger to 4-byte boundary
429 MachineFunction &MF, RegScavenger *RS) const {
430 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
431 LLVM_DEBUG(dbgs() << "Process function before frame finalized: "
432 << MF.getName() << "\n");
433 MachineFrameInfo &MFI = MF.getFrameInfo();
434 LLVM_DEBUG(dbgs() << "Current stack size: " << MFI.getStackSize() << "\n");
435 const TargetRegisterClass *RC = &ARC::GPR32RegClass;
436 if (MFI.hasStackObjects()) {
437 int RegScavFI = MFI.CreateSpillStackObject(RegInfo->getSpillSize(*RC),
438 RegInfo->getSpillAlign(*RC));
439 RS->addScavengingFrameIndex(RegScavFI);
440 LLVM_DEBUG(dbgs() << "Created scavenging index RegScavFI=" << RegScavFI
441 << "\n");
442 }
443}
444
447 unsigned Reg, int NumBytes, bool IsAdd,
448 const ARCInstrInfo *TII) {
449 unsigned Opc;
450 if (isUInt<6>(NumBytes))
451 Opc = IsAdd ? ARC::ADD_rru6 : ARC::SUB_rru6;
452 else if (isInt<12>(NumBytes))
453 Opc = IsAdd ? ARC::ADD_rrs12 : ARC::SUB_rrs12;
454 else
455 Opc = IsAdd ? ARC::ADD_rrlimm : ARC::SUB_rrlimm;
456
457 BuildMI(MBB, MBBI, dl, TII->get(Opc), Reg)
459 .addImm(NumBytes);
460}
461
465 LLVM_DEBUG(dbgs() << "EmitCallFramePseudo: " << MF.getName() << "\n");
466 const ARCInstrInfo *TII = MF.getSubtarget<ARCSubtarget>().getInstrInfo();
467 MachineInstr &Old = *I;
468 DebugLoc dl = Old.getDebugLoc();
469 unsigned Amt = Old.getOperand(0).getImm();
470 auto *AFI = MF.getInfo<ARCFunctionInfo>();
471 if (!hasFP(MF)) {
472 if (Amt > AFI->MaxCallStackReq && Old.getOpcode() == ARC::ADJCALLSTACKDOWN)
473 AFI->MaxCallStackReq = Amt;
474 } else {
475 if (Amt != 0) {
476 assert((Old.getOpcode() == ARC::ADJCALLSTACKDOWN ||
477 Old.getOpcode() == ARC::ADJCALLSTACKUP) &&
478 "Unknown Frame Pseudo.");
479 bool IsAdd = (Old.getOpcode() == ARC::ADJCALLSTACKUP);
480 emitRegUpdate(MBB, I, dl, ARC::SP, Amt, IsAdd, TII);
481 }
482 }
483 return MBB.erase(I);
484}
485
487 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
488 bool HasFP = MF.disableFramePointerElim() ||
491 RegInfo->hasStackRealignment(MF);
492 return HasFP;
493}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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 unsigned determineLastCalleeSave(ArrayRef< CalleeSavedInfo > CSI)
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator MBBI
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
Register const TargetRegisterInfo * TRI
MachineRegisterInfo & MRI
This file declares the machine register scavenger class.
#define LLVM_DEBUG(...)
Definition Debug.h:119
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
assignCalleeSavedSpillSlots - Allows target to override spill slot assignment logic.
ARCFunctionInfo - This class is derived from MachineFunction private ARC target-specific information ...
const ARCInstrInfo * getInstrInfo() const override
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
BitVector & set()
Set all bits in the bitvector.
Definition BitVector.h:366
A debug info location.
Definition DebugLoc.h:126
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition Function.h:230
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:670
static MCCFIInstruction cfiDefCfaOffset(MCSymbol *L, int64_t Offset, SMLoc Loc={})
.cfi_def_cfa_offset modifies a rule for computing CFA.
Definition MCDwarf.h:643
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...
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
MachineInstrBundleIterator< MachineInstr > iterator
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.
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.
LLVM_ABI int CreateSpillStackObject(uint64_t Size, Align Alignment, TargetStackID::Value StackID=TargetStackID::Default)
Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...
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.
LLVM_ABI 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.
bool disableFramePointerElim() const
Returns true if frame pointer elimination should be disabled for this function.
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 & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
int64_t getImm() const
Represent a mutable reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:294
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...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:166
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Kill
The last use of a register.
@ Define
Register definition.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:190
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58