LLVM  10.0.0svn
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 
77 static unsigned
78 determineLastCalleeSave(const std::vector<CalleeSavedInfo> &CSI) {
79  unsigned Last = 0;
80  for (auto Reg : CSI) {
81  assert(Reg.getReg() >= ARC::R13 && Reg.getReg() <= ARC::R25 &&
82  "Unexpected callee saved reg.");
83  if (Reg.getReg() > Last)
84  Last = Reg.getReg();
85  }
86  return Last;
87 }
88 
90  BitVector &SavedRegs,
91  RegScavenger *RS) const {
92  LLVM_DEBUG(dbgs() << "Determine Callee Saves: " << MF.getName() << "\n");
94  SavedRegs.set(ARC::BLINK);
95 }
96 
97 void ARCFrameLowering::adjustStackToMatchRecords(
99  bool Allocate) const {
100  MachineFunction &MF = *MBB.getParent();
101  int ScalarAlloc = MF.getFrameInfo().getStackSize();
102 
103  if (Allocate) {
104  // Allocate by adjusting by the negative of what the record holder tracked
105  // it tracked a positive offset in a downward growing stack.
106  ScalarAlloc = -ScalarAlloc;
107  }
108 
109  generateStackAdjustment(MBB, MBBI, *ST.getInstrInfo(), DebugLoc(),
110  ScalarAlloc, ARC::SP);
111 }
112 
113 /// Insert prolog code into the function.
114 /// For ARC, this inserts a call to a function that puts required callee saved
115 /// registers onto the stack, when enough callee saved registers are required.
117  MachineBasicBlock &MBB) const {
118  LLVM_DEBUG(dbgs() << "Emit Prologue: " << MF.getName() << "\n");
119  auto *AFI = MF.getInfo<ARCFunctionInfo>();
120  MachineModuleInfo &MMI = MF.getMMI();
121  MCContext &Context = MMI.getContext();
122  const MCRegisterInfo *MRI = Context.getRegisterInfo();
123  const ARCInstrInfo *TII = MF.getSubtarget<ARCSubtarget>().getInstrInfo();
124  MachineBasicBlock::iterator MBBI = MBB.begin();
125  // Debug location must be unknown since the first debug location is used
126  // to determine the end of the prologue.
127  DebugLoc dl;
128  MachineFrameInfo &MFI = MF.getFrameInfo();
129  const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
130  unsigned Last = determineLastCalleeSave(CSI);
131  unsigned StackSlotsUsedByFunclet = 0;
132  bool SavedBlink = false;
133  unsigned AlreadyAdjusted = 0;
134  if (MF.getFunction().isVarArg()) {
135  // Add in the varargs area here first.
136  LLVM_DEBUG(dbgs() << "Varargs\n");
137  unsigned VarArgsBytes = MFI.getObjectSize(AFI->getVarArgsFrameIndex());
138  unsigned Opc = ARC::SUB_rrlimm;
139  if (isUInt<6>(VarArgsBytes))
140  Opc = ARC::SUB_rru6;
141  else if (isInt<12>(VarArgsBytes))
142  Opc = ARC::SUB_rrs12;
143  BuildMI(MBB, MBBI, dl, TII->get(Opc), ARC::SP)
144  .addReg(ARC::SP)
145  .addImm(VarArgsBytes);
146  }
147  if (hasFP(MF)) {
148  LLVM_DEBUG(dbgs() << "Saving FP\n");
149  BuildMI(MBB, MBBI, dl, TII->get(ARC::ST_AW_rs9))
150  .addReg(ARC::SP, RegState::Define)
151  .addReg(ARC::FP)
152  .addReg(ARC::SP)
153  .addImm(-4);
154  AlreadyAdjusted += 4;
155  }
156  if (UseSaveRestoreFunclet && Last > ARC::R14) {
157  LLVM_DEBUG(dbgs() << "Creating store funclet.\n");
158  // BL to __save_r13_to_<TRI->getRegAsmName()>
159  StackSlotsUsedByFunclet = Last - ARC::R12;
160  BuildMI(MBB, MBBI, dl, TII->get(ARC::PUSH_S_BLINK));
161  BuildMI(MBB, MBBI, dl, TII->get(ARC::SUB_rru6))
162  .addReg(ARC::SP)
163  .addReg(ARC::SP)
164  .addImm(4 * StackSlotsUsedByFunclet);
165  BuildMI(MBB, MBBI, dl, TII->get(ARC::BL))
166  .addExternalSymbol(store_funclet_name[Last - ARC::R15])
167  .addReg(ARC::BLINK, RegState::Implicit | RegState::Kill);
168  AlreadyAdjusted += 4 * (StackSlotsUsedByFunclet + 1);
169  SavedBlink = true;
170  }
171  // If we haven't saved BLINK, but we need to...do that now.
172  if (MFI.hasCalls() && !SavedBlink) {
173  LLVM_DEBUG(dbgs() << "Creating save blink.\n");
174  BuildMI(MBB, MBBI, dl, TII->get(ARC::PUSH_S_BLINK));
175  AlreadyAdjusted += 4;
176  }
177  if (AFI->MaxCallStackReq > 0)
178  MFI.setStackSize(MFI.getStackSize() + AFI->MaxCallStackReq);
179  // We have already saved some of the stack...
180  LLVM_DEBUG(dbgs() << "Adjusting stack by: "
181  << (MFI.getStackSize() - AlreadyAdjusted) << "\n");
182  generateStackAdjustment(MBB, MBBI, *ST.getInstrInfo(), dl,
183  -(MFI.getStackSize() - AlreadyAdjusted), ARC::SP);
184 
185  if (hasFP(MF)) {
186  LLVM_DEBUG(dbgs() << "Setting FP from SP.\n");
187  BuildMI(MBB, MBBI, dl,
188  TII->get(isUInt<6>(MFI.getStackSize()) ? ARC::ADD_rru6
189  : ARC::ADD_rrlimm),
190  ARC::FP)
191  .addReg(ARC::SP)
192  .addImm(MFI.getStackSize());
193  }
194 
195  // Emit CFI records:
196  // .cfi_def_cfa_offset StackSize
197  // .cfi_offset fp, -StackSize
198  // .cfi_offset blink, -StackSize+4
199  unsigned CFIIndex = MF.addFrameInst(
201  BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
202  .addCFIIndex(CFIIndex)
204 
205  int CurOffset = -4;
206  if (hasFP(MF)) {
208  nullptr, MRI->getDwarfRegNum(ARC::FP, true), CurOffset));
209  BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
210  .addCFIIndex(CFIIndex)
212  CurOffset -= 4;
213  }
214 
215  if (MFI.hasCalls()) {
217  nullptr, MRI->getDwarfRegNum(ARC::BLINK, true), CurOffset));
218  BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
219  .addCFIIndex(CFIIndex)
221  }
222  // CFI for the rest of the registers.
223  for (const auto &Entry : CSI) {
224  unsigned Reg = Entry.getReg();
225  int FI = Entry.getFrameIdx();
226  // Skip BLINK and FP.
227  if ((hasFP(MF) && Reg == ARC::FP) || (MFI.hasCalls() && Reg == ARC::BLINK))
228  continue;
230  nullptr, MRI->getDwarfRegNum(Reg, true), MFI.getObjectOffset(FI)));
231  BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
232  .addCFIIndex(CFIIndex)
234  }
235 }
236 
237 /// Insert epilog code into the function.
238 /// For ARC, this inserts a call to a function that restores callee saved
239 /// registers onto the stack, when enough callee saved registers are required.
241  MachineBasicBlock &MBB) const {
242  LLVM_DEBUG(dbgs() << "Emit Epilogue: " << MF.getName() << "\n");
243  auto *AFI = MF.getInfo<ARCFunctionInfo>();
244  const ARCInstrInfo *TII = MF.getSubtarget<ARCSubtarget>().getInstrInfo();
246  MachineFrameInfo &MFI = MF.getFrameInfo();
247  uint64_t StackSize = MF.getFrameInfo().getStackSize();
248  bool SavedBlink = false;
249  unsigned AmountAboveFunclet = 0;
250  // If we have variable sized frame objects, then we have to move
251  // the stack pointer to a known spot (fp - StackSize).
252  // Then, replace the frame pointer by (new) [sp,StackSize-4].
253  // Then, move the stack pointer the rest of the way (sp = sp + StackSize).
254  if (hasFP(MF)) {
255  unsigned Opc = ARC::SUB_rrlimm;
256  if (isUInt<6>(StackSize))
257  Opc = ARC::SUB_rru6;
258  BuildMI(MBB, MBBI, DebugLoc(), TII->get(Opc), ARC::SP)
259  .addReg(ARC::FP)
260  .addImm(StackSize);
261  AmountAboveFunclet += 4;
262  }
263 
264  // Now, move the stack pointer to the bottom of the save area for the funclet.
265  const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
266  unsigned Last = determineLastCalleeSave(CSI);
267  unsigned StackSlotsUsedByFunclet = 0;
268  // Now, restore the callee save registers.
269  if (UseSaveRestoreFunclet && Last > ARC::R14) {
270  // BL to __ld_r13_to_<TRI->getRegAsmName()>
271  StackSlotsUsedByFunclet = Last - ARC::R12;
272  AmountAboveFunclet += 4 * (StackSlotsUsedByFunclet + 1);
273  SavedBlink = true;
274  }
275 
276  if (MFI.hasCalls() && !SavedBlink) {
277  AmountAboveFunclet += 4;
278  SavedBlink = true;
279  }
280 
281  // Move the stack pointer up to the point of the funclet.
282  if (unsigned MoveAmount = StackSize - AmountAboveFunclet) {
283  unsigned Opc = ARC::ADD_rrlimm;
284  if (isUInt<6>(MoveAmount))
285  Opc = ARC::ADD_rru6;
286  else if (isInt<12>(MoveAmount))
287  Opc = ARC::ADD_rrs12;
288  BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(Opc), ARC::SP)
289  .addReg(ARC::SP)
290  .addImm(StackSize - AmountAboveFunclet);
291  }
292 
293  if (StackSlotsUsedByFunclet) {
294  // This part of the adjustment will always be < 64 bytes.
295  BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::BL))
296  .addExternalSymbol(load_funclet_name[Last - ARC::R15])
297  .addReg(ARC::BLINK, RegState::Implicit | RegState::Kill);
298  unsigned Opc = ARC::ADD_rrlimm;
299  if (isUInt<6>(4 * StackSlotsUsedByFunclet))
300  Opc = ARC::ADD_rru6;
301  else if (isInt<12>(4 * StackSlotsUsedByFunclet))
302  Opc = ARC::ADD_rrs12;
303  BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(Opc), ARC::SP)
304  .addReg(ARC::SP)
305  .addImm(4 * (StackSlotsUsedByFunclet));
306  }
307  // Now, pop blink if necessary.
308  if (SavedBlink) {
309  BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::POP_S_BLINK));
310  }
311  // Now, pop fp if necessary.
312  if (hasFP(MF)) {
313  BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::LD_AB_rs9))
314  .addReg(ARC::FP, RegState::Define)
315  .addReg(ARC::SP, RegState::Define)
316  .addReg(ARC::SP)
317  .addImm(4);
318  }
319 
320  // Relieve the varargs area if necessary.
321  if (MF.getFunction().isVarArg()) {
322  // Add in the varargs area here first.
323  LLVM_DEBUG(dbgs() << "Varargs\n");
324  unsigned VarArgsBytes = MFI.getObjectSize(AFI->getVarArgsFrameIndex());
325  unsigned Opc = ARC::ADD_rrlimm;
326  if (isUInt<6>(VarArgsBytes))
327  Opc = ARC::ADD_rru6;
328  else if (isInt<12>(VarArgsBytes))
329  Opc = ARC::ADD_rrs12;
330  BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(Opc))
331  .addReg(ARC::SP)
332  .addReg(ARC::SP)
333  .addImm(VarArgsBytes);
334  }
335 }
336 
337 static std::vector<CalleeSavedInfo>::iterator
338 getSavedReg(std::vector<CalleeSavedInfo> &V, unsigned reg) {
339  for (auto I = V.begin(), E = V.end(); I != E; ++I) {
340  if (reg == I->getReg())
341  return I;
342  }
343  return V.end();
344 }
345 
348  std::vector<CalleeSavedInfo> &CSI) const {
349  // Use this opportunity to assign the spill slots for all of the potential
350  // callee save registers (blink, fp, r13->r25) that we care about the
351  // placement for. We can calculate all of that data here.
352  int CurOffset = -4;
353  unsigned Last = determineLastCalleeSave(CSI);
354  MachineFrameInfo &MFI = MF.getFrameInfo();
355  if (hasFP(MF)) {
356  // Create a fixed slot at for FP
357  int StackObj = MFI.CreateFixedSpillStackObject(4, CurOffset, true);
358  LLVM_DEBUG(dbgs() << "Creating fixed object (" << StackObj << ") for FP at "
359  << CurOffset << "\n");
360  (void)StackObj;
361  CurOffset -= 4;
362  }
363  if (MFI.hasCalls() || (UseSaveRestoreFunclet && Last > ARC::R14)) {
364  // Create a fixed slot for BLINK.
365  int StackObj = MFI.CreateFixedSpillStackObject(4, CurOffset, true);
366  LLVM_DEBUG(dbgs() << "Creating fixed object (" << StackObj
367  << ") for BLINK at " << CurOffset << "\n");
368  (void)StackObj;
369  CurOffset -= 4;
370  }
371 
372  // Create slots for last down to r13.
373  for (unsigned Which = Last; Which > ARC::R12; Which--) {
374  auto RegI = getSavedReg(CSI, Which);
375  if (RegI == CSI.end() || RegI->getFrameIdx() == 0) {
376  // Always create the stack slot. If for some reason the register isn't in
377  // the save list, then don't worry about it.
378  int FI = MFI.CreateFixedSpillStackObject(4, CurOffset, true);
379  if (RegI != CSI.end())
380  RegI->setFrameIdx(FI);
381  } else
382  MFI.setObjectOffset(RegI->getFrameIdx(), CurOffset);
383  CurOffset -= 4;
384  }
385  for (auto &I : CSI) {
386  if (I.getReg() > ARC::R12)
387  continue;
388  if (I.getFrameIdx() == 0) {
389  I.setFrameIdx(MFI.CreateFixedSpillStackObject(4, CurOffset, true));
390  LLVM_DEBUG(dbgs() << "Creating fixed object (" << I.getFrameIdx()
391  << ") for other register at " << CurOffset << "\n");
392  } else {
393  MFI.setObjectOffset(I.getFrameIdx(), CurOffset);
394  LLVM_DEBUG(dbgs() << "Updating fixed object (" << I.getFrameIdx()
395  << ") for other register at " << CurOffset << "\n");
396  }
397  CurOffset -= 4;
398  }
399  return true;
400 }
401 
404  const std::vector<CalleeSavedInfo> &CSI,
405  const TargetRegisterInfo *TRI) const {
406  LLVM_DEBUG(dbgs() << "Spill callee saved registers: "
407  << MBB.getParent()->getName() << "\n");
408  // There are routines for saving at least 3 registers (r13 to r15, etc.)
409  unsigned Last = determineLastCalleeSave(CSI);
410  if (UseSaveRestoreFunclet && Last > ARC::R14) {
411  // Use setObjectOffset for these registers.
412  // Needs to be in or before processFunctionBeforeFrameFinalized.
413  // Or, do assignCalleeSaveSpillSlots?
414  // Will be handled in prolog.
415  return true;
416  }
417  return false;
418 }
419 
422  std::vector<CalleeSavedInfo> &CSI, const TargetRegisterInfo *TRI) const {
423  LLVM_DEBUG(dbgs() << "Restore callee saved registers: "
424  << MBB.getParent()->getName() << "\n");
425  // There are routines for saving at least 3 registers (r13 to r15, etc.)
426  unsigned Last = determineLastCalleeSave(CSI);
427  if (UseSaveRestoreFunclet && Last > ARC::R14) {
428  // Will be handled in epilog.
429  return true;
430  }
431  return false;
432 }
433 
434 // Adjust local variables that are 4-bytes or larger to 4-byte boundary
436  MachineFunction &MF, RegScavenger *RS) const {
437  const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
438  LLVM_DEBUG(dbgs() << "Process function before frame finalized: "
439  << MF.getName() << "\n");
440  MachineFrameInfo &MFI = MF.getFrameInfo();
441  LLVM_DEBUG(dbgs() << "Current stack size: " << MFI.getStackSize() << "\n");
442  const TargetRegisterClass *RC = &ARC::GPR32RegClass;
443  if (MFI.hasStackObjects()) {
444  int RegScavFI = MFI.CreateStackObject(
445  RegInfo->getSpillSize(*RC), RegInfo->getSpillAlignment(*RC), false);
446  RS->addScavengingFrameIndex(RegScavFI);
447  LLVM_DEBUG(dbgs() << "Created scavenging index RegScavFI=" << RegScavFI
448  << "\n");
449  }
450 }
451 
454  unsigned Reg, int NumBytes, bool IsAdd,
455  const ARCInstrInfo *TII) {
456  unsigned Opc;
457  if (isUInt<6>(NumBytes))
458  Opc = IsAdd ? ARC::ADD_rru6 : ARC::SUB_rru6;
459  else if (isInt<12>(NumBytes))
460  Opc = IsAdd ? ARC::ADD_rrs12 : ARC::SUB_rrs12;
461  else
462  Opc = IsAdd ? ARC::ADD_rrlimm : ARC::SUB_rrlimm;
463 
464  BuildMI(MBB, MBBI, dl, TII->get(Opc), Reg)
465  .addReg(Reg, RegState::Kill)
466  .addImm(NumBytes);
467 }
468 
472  LLVM_DEBUG(dbgs() << "EmitCallFramePseudo: " << MF.getName() << "\n");
473  const ARCInstrInfo *TII = MF.getSubtarget<ARCSubtarget>().getInstrInfo();
474  MachineInstr &Old = *I;
475  DebugLoc dl = Old.getDebugLoc();
476  unsigned Amt = Old.getOperand(0).getImm();
477  auto *AFI = MF.getInfo<ARCFunctionInfo>();
478  if (!hasFP(MF)) {
479  if (Amt > AFI->MaxCallStackReq && Old.getOpcode() == ARC::ADJCALLSTACKDOWN)
480  AFI->MaxCallStackReq = Amt;
481  } else {
482  if (Amt != 0) {
483  assert((Old.getOpcode() == ARC::ADJCALLSTACKDOWN ||
484  Old.getOpcode() == ARC::ADJCALLSTACKUP) &&
485  "Unknown Frame Pseudo.");
486  bool IsAdd = (Old.getOpcode() == ARC::ADJCALLSTACKUP);
487  emitRegUpdate(MBB, I, dl, ARC::SP, Amt, IsAdd, TII);
488  }
489  }
490  return MBB.erase(I);
491 }
492 
494  const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
495  bool HasFP = MF.getTarget().Options.DisableFramePointerElim(MF) ||
498  RegInfo->needsStackRealignment(MF);
499  return HasFP;
500 }
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition: Function.h:176
ARCFunctionInfo - This class is derived from MachineFunction private ARC target-specific information ...
BitVector & set()
Definition: BitVector.h:397
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:385
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:507
unsigned Reg
static unsigned determineLastCalleeSave(const std::vector< CalleeSavedInfo > &CSI)
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.
static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset)
.cfi_def_cfa_offset modifies a rule for computing CFA.
Definition: MCDwarf.h:494
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))
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
unsigned getSpillAlignment(const TargetRegisterClass &RC) const
Return the minimum required alignment in bytes for a spill slot for a register of this class...
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:411
static const char * load_funclet_name[]
Context object for machine code objects.
Definition: MCContext.h:65
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...
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:1165
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:432
This file declares the machine register scavenger class.
unsigned const MachineRegisterInfo * MRI
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")
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...
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...
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI) const override
restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee saved registers and returns...
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.
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI) const override
spillCalleeSavedRegisters - Issues instruction(s) to spill all callee saved registers and returns tru...
int64_t getImm() const
const Function & getFunction() const
Return the LLVM function that this machine code represents.
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:64
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
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:58
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:320
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:416
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.
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)