LLVM  6.0.0svn
ARCFrameLowering.cpp
Go to the documentation of this file.
1 //===- ARCFrameLowering.cpp - ARC Frame Information -------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains the ARC implementation of the TargetFrameLowering class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "ARCFrameLowering.h"
15 #include "ARCMachineFunctionInfo.h"
16 #include "ARCSubtarget.h"
21 #include "llvm/IR/Function.h"
22 #include "llvm/Support/Debug.h"
23 
24 #define DEBUG_TYPE "arc-frame-lowering"
25 
26 using namespace llvm;
27 
28 static cl::opt<bool>
29  UseSaveRestoreFunclet("arc-save-restore-funclet", cl::Hidden,
30  cl::desc("Use arc callee save/restore functions"),
31  cl::init(true));
32 
33 static const char *store_funclet_name[] = {
34  "__st_r13_to_r15", "__st_r13_to_r16", "__st_r13_to_r17", "__st_r13_to_r18",
35  "__st_r13_to_r19", "__st_r13_to_r20", "__st_r13_to_r21", "__st_r13_to_r22",
36  "__st_r13_to_r23", "__st_r13_to_r24", "__st_r13_to_r25",
37 };
38 
39 static const char *load_funclet_name[] = {
40  "__ld_r13_to_r15", "__ld_r13_to_r16", "__ld_r13_to_r17", "__ld_r13_to_r18",
41  "__ld_r13_to_r19", "__ld_r13_to_r20", "__ld_r13_to_r21", "__ld_r13_to_r22",
42  "__ld_r13_to_r23", "__ld_r13_to_r24", "__ld_r13_to_r25",
43 };
44 
47  const ARCInstrInfo &TII, DebugLoc dl,
48  int Amount, int StackPtr) {
49  unsigned AdjOp;
50  if (!Amount)
51  return;
52  bool Positive;
53  unsigned AbsAmount;
54  if (Amount < 0) {
55  AbsAmount = -Amount;
56  Positive = false;
57  } else {
58  AbsAmount = Amount;
59  Positive = true;
60  }
61 
62  DEBUG(dbgs() << "Internal: adjust stack by: " << Amount << "," << AbsAmount
63  << "\n");
64 
65  assert((AbsAmount % 4 == 0) && "Stack adjustments must be 4-byte aligned.");
66  if (isUInt<6>(AbsAmount))
67  AdjOp = Positive ? ARC::ADD_rru6 : ARC::SUB_rru6;
68  else
69  AdjOp = Positive ? ARC::ADD_rrlimm : ARC::SUB_rrlimm;
70 
71  BuildMI(MBB, MBBI, dl, TII.get(AdjOp), StackPtr)
72  .addReg(StackPtr)
73  .addImm(AbsAmount);
74 }
75 
76 static unsigned
77 determineLastCalleeSave(const std::vector<CalleeSavedInfo> &CSI) {
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  DEBUG(dbgs() << "Determine Callee Saves: " << MF.getFunction()->getName()
92  << "\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  DEBUG(dbgs() << "Emit Prologue: " << MF.getFunction()->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  DEBUG(dbgs() << "Varargs\n");
137  unsigned VarArgsBytes = MFI.getObjectSize(AFI->getVarArgsFrameIndex());
138  BuildMI(MBB, MBBI, dl, TII->get(ARC::SUB_rru6))
139  .addReg(ARC::SP)
140  .addReg(ARC::SP)
141  .addImm(VarArgsBytes);
142  }
143  if (hasFP(MF)) {
144  DEBUG(dbgs() << "Saving FP\n");
145  BuildMI(MBB, MBBI, dl, TII->get(ARC::ST_AW_rs9))
146  .addReg(ARC::SP, RegState::Define)
147  .addReg(ARC::FP)
148  .addReg(ARC::SP)
149  .addImm(-4);
150  AlreadyAdjusted += 4;
151  }
152  if (UseSaveRestoreFunclet && Last > ARC::R14) {
153  DEBUG(dbgs() << "Creating store funclet.\n");
154  // BL to __save_r13_to_<TRI->getRegAsmName()>
155  StackSlotsUsedByFunclet = Last - ARC::R12;
156  BuildMI(MBB, MBBI, dl, TII->get(ARC::PUSH_S_BLINK));
157  BuildMI(MBB, MBBI, dl, TII->get(ARC::SUB_rru6))
158  .addReg(ARC::SP)
159  .addReg(ARC::SP)
160  .addImm(4 * StackSlotsUsedByFunclet);
161  BuildMI(MBB, MBBI, dl, TII->get(ARC::BL))
162  .addExternalSymbol(store_funclet_name[Last - ARC::R15])
163  .addReg(ARC::BLINK, RegState::Implicit | RegState::Kill);
164  AlreadyAdjusted += 4 * (StackSlotsUsedByFunclet + 1);
165  SavedBlink = true;
166  }
167  // If we haven't saved BLINK, but we need to...do that now.
168  if (MFI.hasCalls() && !SavedBlink) {
169  DEBUG(dbgs() << "Creating save blink.\n");
170  BuildMI(MBB, MBBI, dl, TII->get(ARC::PUSH_S_BLINK));
171  AlreadyAdjusted += 4;
172  }
173  if (AFI->MaxCallStackReq > 0)
174  MFI.setStackSize(MFI.getStackSize() + AFI->MaxCallStackReq);
175  // We have already saved some of the stack...
176  DEBUG(dbgs() << "Adjusting stack by: "
177  << (MFI.getStackSize() - AlreadyAdjusted) << "\n");
178  generateStackAdjustment(MBB, MBBI, *ST.getInstrInfo(), dl,
179  -(MFI.getStackSize() - AlreadyAdjusted), ARC::SP);
180 
181  if (hasFP(MF)) {
182  DEBUG(dbgs() << "Setting FP from SP.\n");
183  BuildMI(MBB, MBBI, dl,
184  TII->get(isUInt<6>(MFI.getStackSize()) ? ARC::ADD_rru6
185  : ARC::ADD_rrlimm),
186  ARC::FP)
187  .addReg(ARC::SP)
188  .addImm(MFI.getStackSize());
189  }
190 
191  // Emit CFI records:
192  // .cfi_def_cfa_offset StackSize
193  // .cfi_offset fp, -StackSize
194  // .cfi_offset blink, -StackSize+4
195  unsigned CFIIndex = MF.addFrameInst(
197  BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
198  .addCFIIndex(CFIIndex)
200 
201  int CurOffset = -4;
202  if (hasFP(MF)) {
204  nullptr, MRI->getDwarfRegNum(ARC::FP, true), CurOffset));
205  BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
206  .addCFIIndex(CFIIndex)
208  CurOffset -= 4;
209  }
210 
211  if (MFI.hasCalls()) {
213  nullptr, MRI->getDwarfRegNum(ARC::BLINK, true), CurOffset));
214  BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
215  .addCFIIndex(CFIIndex)
217  }
218  // CFI for the rest of the registers.
219  for (const auto &Entry : CSI) {
220  unsigned Reg = Entry.getReg();
221  int FI = Entry.getFrameIdx();
222  // Skip BLINK and FP.
223  if ((hasFP(MF) && Reg == ARC::FP) || (MFI.hasCalls() && Reg == ARC::BLINK))
224  continue;
226  nullptr, MRI->getDwarfRegNum(Reg, true), MFI.getObjectOffset(FI)));
227  BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
228  .addCFIIndex(CFIIndex)
230  }
231 }
232 
233 /// Insert epilog code into the function.
234 /// For ARC, this inserts a call to a function that restores callee saved
235 /// registers onto the stack, when enough callee saved registers are required.
237  MachineBasicBlock &MBB) const {
238  DEBUG(dbgs() << "Emit Epilogue: " << MF.getFunction()->getName() << "\n");
239  auto *AFI = MF.getInfo<ARCFunctionInfo>();
240  const ARCInstrInfo *TII = MF.getSubtarget<ARCSubtarget>().getInstrInfo();
242  MachineFrameInfo &MFI = MF.getFrameInfo();
243  uint64_t StackSize = MF.getFrameInfo().getStackSize();
244  bool SavedBlink = false;
245  unsigned AmountAboveFunclet = 0;
246  // If we have variable sized frame objects, then we have to move
247  // the stack pointer to a known spot (fp - StackSize).
248  // Then, replace the frame pointer by (new) [sp,StackSize-4].
249  // Then, move the stack pointer the rest of the way (sp = sp + StackSize).
250  if (hasFP(MF)) {
251  BuildMI(MBB, MBBI, DebugLoc(), TII->get(ARC::SUB_rru6), 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 (UseSaveRestoreFunclet && 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 (StackSize - AmountAboveFunclet) {
276  BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::ADD_rru6))
277  .addReg(ARC::SP)
278  .addReg(ARC::SP)
279  .addImm(StackSize - AmountAboveFunclet);
280  }
281 
282  if (StackSlotsUsedByFunclet) {
283  BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::BL))
284  .addExternalSymbol(load_funclet_name[Last - ARC::R15])
285  .addReg(ARC::BLINK, RegState::Implicit | RegState::Kill);
286  BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::ADD_rru6))
287  .addReg(ARC::SP)
288  .addReg(ARC::SP)
289  .addImm(4 * (StackSlotsUsedByFunclet));
290  }
291  // Now, pop blink if necessary.
292  if (SavedBlink) {
293  BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::POP_S_BLINK));
294  }
295  // Now, pop fp if necessary.
296  if (hasFP(MF)) {
297  BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::LD_AB_rs9))
298  .addReg(ARC::SP, RegState::Define)
299  .addReg(ARC::FP, RegState::Define)
300  .addReg(ARC::SP)
301  .addImm(4);
302  }
303 
304  // Relieve the varargs area if necessary.
305  if (MF.getFunction()->isVarArg()) {
306  // Add in the varargs area here first.
307  DEBUG(dbgs() << "Varargs\n");
308  unsigned VarArgsBytes = MFI.getObjectSize(AFI->getVarArgsFrameIndex());
309  BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::ADD_rru6))
310  .addReg(ARC::SP)
311  .addReg(ARC::SP)
312  .addImm(VarArgsBytes);
313  }
314 }
315 
316 static std::vector<CalleeSavedInfo>::iterator
317 getSavedReg(std::vector<CalleeSavedInfo> &V, unsigned reg) {
318  for (auto I = V.begin(), E = V.end(); I != E; ++I) {
319  if (reg == I->getReg())
320  return I;
321  }
322  return V.end();
323 }
324 
326  MachineFunction &MF, const TargetRegisterInfo *TRI,
327  std::vector<CalleeSavedInfo> &CSI) const {
328  // Use this opportunity to assign the spill slots for all of the potential
329  // callee save registers (blink, fp, r13->r25) that we care about the
330  // placement for. We can calculate all of that data here.
331  int CurOffset = -4;
332  unsigned Last = determineLastCalleeSave(CSI);
333  MachineFrameInfo &MFI = MF.getFrameInfo();
334  if (hasFP(MF)) {
335  // Create a fixed slot at for FP
336  int StackObj = MFI.CreateFixedSpillStackObject(4, CurOffset, true);
337  DEBUG(dbgs() << "Creating fixed object (" << StackObj << ") for FP at "
338  << CurOffset << "\n");
339  (void)StackObj;
340  CurOffset -= 4;
341  }
342  if (MFI.hasCalls() || (UseSaveRestoreFunclet && Last > ARC::R14)) {
343  // Create a fixed slot for BLINK.
344  int StackObj = MFI.CreateFixedSpillStackObject(4, CurOffset, true);
345  DEBUG(dbgs() << "Creating fixed object (" << StackObj << ") for BLINK at "
346  << CurOffset << "\n");
347  (void)StackObj;
348  CurOffset -= 4;
349  }
350 
351  // Create slots for last down to r13.
352  for (unsigned Which = Last; Which > ARC::R12; Which--) {
353  auto RegI = getSavedReg(CSI, Which);
354  if (RegI == CSI.end() || RegI->getFrameIdx() == 0) {
355  // Always create the stack slot. If for some reason the register isn't in
356  // the save list, then don't worry about it.
357  int FI = MFI.CreateFixedSpillStackObject(4, CurOffset, true);
358  if (RegI != CSI.end())
359  RegI->setFrameIdx(FI);
360  } else
361  MFI.setObjectOffset(RegI->getFrameIdx(), CurOffset);
362  CurOffset -= 4;
363  }
364  for (auto &I : CSI) {
365  if (I.getReg() > ARC::R12)
366  continue;
367  if (I.getFrameIdx() == 0) {
368  I.setFrameIdx(MFI.CreateFixedSpillStackObject(4, CurOffset, true));
369  DEBUG(dbgs() << "Creating fixed object (" << I.getFrameIdx()
370  << ") for other register at " << CurOffset << "\n");
371  } else {
372  MFI.setObjectOffset(I.getFrameIdx(), CurOffset);
373  DEBUG(dbgs() << "Updating fixed object (" << I.getFrameIdx()
374  << ") for other register at " << CurOffset << "\n");
375  }
376  CurOffset -= 4;
377  }
378  return true;
379 }
380 
383  const std::vector<CalleeSavedInfo> &CSI,
384  const TargetRegisterInfo *TRI) const {
385  DEBUG(dbgs() << "Spill callee saved registers: "
386  << MBB.getParent()->getFunction()->getName() << "\n");
387  // There are routines for saving at least 3 registers (r13 to r15, etc.)
388  unsigned Last = determineLastCalleeSave(CSI);
389  if (UseSaveRestoreFunclet && Last > ARC::R14) {
390  // Use setObjectOffset for these registers.
391  // Needs to be in or before processFunctionBeforeFrameFinalized.
392  // Or, do assignCalleeSaveSpillSlots?
393  // Will be handled in prolog.
394  return true;
395  }
396  return false;
397 }
398 
401  std::vector<CalleeSavedInfo> &CSI, const TargetRegisterInfo *TRI) const {
402  DEBUG(dbgs() << "Restore callee saved registers: "
403  << MBB.getParent()->getFunction()->getName() << "\n");
404  // There are routines for saving at least 3 registers (r13 to r15, etc.)
405  unsigned Last = determineLastCalleeSave(CSI);
406  if (UseSaveRestoreFunclet && Last > ARC::R14) {
407  // Will be handled in epilog.
408  return true;
409  }
410  return false;
411 }
412 
413 // Adjust local variables that are 4-bytes or larger to 4-byte boundary
415  MachineFunction &MF, RegScavenger *RS) const {
416  const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
417  DEBUG(dbgs() << "Process function before frame finalized: "
418  << MF.getFunction()->getName() << "\n");
419  MachineFrameInfo &MFI = MF.getFrameInfo();
420  DEBUG(dbgs() << "Current stack size: " << MFI.getStackSize() << "\n");
421  const TargetRegisterClass *RC = &ARC::GPR32RegClass;
422  if (MFI.hasStackObjects()) {
423  int RegScavFI = MFI.CreateStackObject(
424  RegInfo->getSpillSize(*RC), RegInfo->getSpillAlignment(*RC), false);
425  RS->addScavengingFrameIndex(RegScavFI);
426  DEBUG(dbgs() << "Created scavenging index RegScavFI=" << RegScavFI << "\n");
427  }
428 }
429 
432  unsigned Reg, int NumBytes, bool IsAdd,
433  const ARCInstrInfo *TII) {
434  unsigned Opc = IsAdd ? ARC::ADD_rru6 : ARC::SUB_rru6;
435  BuildMI(MBB, MBBI, dl, TII->get(Opc), Reg)
436  .addReg(Reg, RegState::Kill)
437  .addImm(NumBytes);
438 }
439 
443  DEBUG(dbgs() << "EmitCallFramePseudo: " << MF.getFunction()->getName()
444  << "\n");
445  const ARCInstrInfo *TII = MF.getSubtarget<ARCSubtarget>().getInstrInfo();
446  MachineInstr &Old = *I;
447  DebugLoc dl = Old.getDebugLoc();
448  unsigned Amt = Old.getOperand(0).getImm();
449  auto *AFI = MF.getInfo<ARCFunctionInfo>();
450  if (!hasFP(MF)) {
451  if (Amt > AFI->MaxCallStackReq && Old.getOpcode() == ARC::ADJCALLSTACKDOWN)
452  AFI->MaxCallStackReq = Amt;
453  } else {
454  if (Amt != 0) {
455  assert((Old.getOpcode() == ARC::ADJCALLSTACKDOWN ||
456  Old.getOpcode() == ARC::ADJCALLSTACKUP) &&
457  "Unknown Frame Pseudo.");
458  bool IsAdd = (Old.getOpcode() == ARC::ADJCALLSTACKUP);
459  emitRegUpdate(MBB, I, dl, ARC::SP, Amt, IsAdd, TII);
460  }
461  }
462  return MBB.erase(I);
463 }
464 
466  const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
467  bool HasFP = MF.getTarget().Options.DisableFramePointerElim(MF) ||
470  RegInfo->needsStackRealignment(MF);
471  return HasFP;
472 }
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition: Function.h:158
ARCFunctionInfo - This class is derived from MachineFunction private ARC target-specific information ...
BitVector & set()
Definition: BitVector.h:398
LLVMContext & Context
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
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:268
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:404
static unsigned determineLastCalleeSave(const std::vector< CalleeSavedInfo > &CSI)
A debug info location.
Definition: DebugLoc.h:34
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:391
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
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
Reg
All possible values of the reg field in the ModR/M byte.
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:290
int getDwarfRegNum(unsigned RegNum, bool isEH) const
Map a target register to an equivalent dwarf register number.
LLVM_NODISCARD unsigned addFrameInst(const MCCFIInstruction &Inst)
int CreateFixedSpillStackObject(uint64_t Size, int64_t SPOffset, bool Immutable=false)
Create a spill slot at a fixed location on the stack.
static const char * load_funclet_name[]
Context object for machine code objects.
Definition: MCContext.h:59
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[]
const ARCInstrInfo * getInstrInfo() const override
Definition: ARCSubtarget.h:49
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:1164
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:406
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 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)
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
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:59
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.
StringRef getName() const
Return a constant reference to the value&#39;s name.
Definition: Value.cpp:220
TargetOptions Options
Definition: TargetMachine.h:96
#define I(x, y, z)
Definition: MD5.cpp:58
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const MCRegisterInfo * getRegisterInfo() const
Definition: MCContext.h:285
bool needsStackRealignment(const MachineFunction &MF) const
True if storage within the function requires the stack pointer to be aligned more than the normal cal...
#define DEBUG(X)
Definition: Debug.h:118
void setObjectOffset(int ObjectIdx, int64_t SPOffset)
Set the stack frame offset of the specified object.
IRTranslator LLVM IR MI
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:295
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...
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)