LLVM  11.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"
14 #include "ARCMachineFunctionInfo.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 
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 
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 
96 void ARCFrameLowering::adjustStackToMatchRecords(
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.
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();
123  MachineBasicBlock::iterator MBBI = MBB.begin();
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))
165  .addExternalSymbol(store_funclet_name[Last - ARC::R15])
166  .addReg(ARC::BLINK, RegState::Implicit | RegState::Kill);
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");
181  generateStackAdjustment(MBB, MBBI, *ST.getInstrInfo(), dl,
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))
295  .addExternalSymbol(load_funclet_name[Last - ARC::R15])
296  .addReg(ARC::BLINK, RegState::Implicit | RegState::Kill);
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 
336 static std::vector<CalleeSavedInfo>::iterator
337 getSavedReg(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)
463  .addReg(Reg, RegState::Kill)
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->needsStackRealignment(MF);
497  return HasFP;
498 }
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition: Function.h:178
ARCFunctionInfo - This class is derived from MachineFunction private ARC target-specific information ...
BitVector & set()
Definition: BitVector.h:398
LLVMContext & Context
This class represents lattice values for constants.
Definition: AllocatorList.h:23
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:409
LLVM_NODISCARD unsigned addFrameInst(const MCCFIInstruction &Inst)
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
Insert Prologue into the function.
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int Offset)
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
Definition: MCDwarf.h:512
unsigned Reg
unsigned const TargetRegisterInfo * TRI
A debug info location.
Definition: DebugLoc.h:33
MachineModuleInfo & getMMI() const
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const override
Add explicit callee save registers.
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 ...
static cl::opt< bool > UseSaveRestoreFunclet("arc-save-restore-funclet", cl::Hidden, cl::desc("Use arc callee save/restore functions"), cl::init(true))
Function & getFunction()
Return the LLVM function that this machine code represents.
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
MachineBasicBlock & MBB
bool isFrameAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
const HexagonInstrInfo * TII
MachineBasicBlock iterator that automatically skips over MIs that are inside bundles (i...
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
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 ...
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:456
static const char * load_funclet_name[]
Context object for machine code objects.
Definition: MCContext.h:66
int getDwarfRegNum(MCRegister RegNum, bool isEH) const
Map a target register to an equivalent dwarf register number.
bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:32
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...
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
static const char * store_funclet_name[]
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
const ARCInstrInfo * getInstrInfo() const override
Definition: ARCSubtarget.h:48
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata *> MDs)
Definition: Metadata.h:1172
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:434
This file declares the machine register scavenger class.
unsigned const MachineRegisterInfo * MRI
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition: ArrayRef.h:298
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Align getSpillAlign(const TargetRegisterClass &RC) const
Return the minimum required alignment in bytes for a spill slot for a register of this class...
bool assignCalleeSavedSpillSlots(llvm::MachineFunction &, const llvm::TargetRegisterInfo *, std::vector< llvm::CalleeSavedInfo > &) const override
assignCalleeSavedSpillSlots - Allows target to override spill slot assignment logic.
void setStackSize(uint64_t Size)
Set the size of the stack.
DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any DBG_VALUE and DBG_LABEL instructions...
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register...
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...
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS) const override
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
void addScavengingFrameIndex(int FI)
Add a scavenging frame index.
static std::vector< CalleeSavedInfo >::iterator getSavedReg(std::vector< CalleeSavedInfo > &V, unsigned reg)
int CreateFixedSpillStackObject(uint64_t Size, int64_t SPOffset, bool IsImmutable=false)
Create a spill slot at a fixed location on the stack.
int64_t getImm() const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
static void generateStackAdjustment(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const ARCInstrInfo &TII, DebugLoc dl, int Amount, int StackPtr)
Representation of each machine instruction.
Definition: MachineInstr.h:62
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
static MCCFIInstruction cfiDefCfaOffset(MCSymbol *L, int Offset)
.cfi_def_cfa_offset modifies a rule for computing CFA.
Definition: MCDwarf.h:499
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
Insert Epilogue into the function.
TargetOptions Options
#define I(x, y, z)
Definition: MD5.cpp:59
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...
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const MCRegisterInfo * getRegisterInfo() const
Definition: MCContext.h:361
bool needsStackRealignment(const MachineFunction &MF) const
True if storage within the function requires the stack pointer to be aligned more than the normal cal...
void setObjectOffset(int ObjectIdx, int64_t SPOffset)
Set the stack frame offset of the specified object.
IRTranslator LLVM IR MI
#define LLVM_DEBUG(X)
Definition: Debug.h:122
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:466
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
MachineBasicBlock MachineBasicBlock::iterator MBBI
This class contains meta information specific to a module.
bool hasCalls() const
Return true if the current function has any function calls.
static void emitRegUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, DebugLoc dl, unsigned Reg, int NumBytes, bool IsAdd, const ARCInstrInfo *TII)
static unsigned determineLastCalleeSave(ArrayRef< CalleeSavedInfo > CSI)