LLVM  3.7.0
XCoreFrameLowering.cpp
Go to the documentation of this file.
1 //===-- XCoreFrameLowering.cpp - Frame info for XCore Target --------------===//
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 XCore frame information that doesn't fit anywhere else
11 // cleanly...
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "XCoreFrameLowering.h"
16 #include "XCore.h"
17 #include "XCoreInstrInfo.h"
19 #include "XCoreSubtarget.h"
26 #include "llvm/IR/DataLayout.h"
27 #include "llvm/IR/Function.h"
31 #include <algorithm> // std::sort
32 
33 using namespace llvm;
34 
35 static const unsigned FramePtr = XCore::R10;
36 static const int MaxImmU16 = (1<<16) - 1;
37 
38 // helper functions. FIXME: Eliminate.
39 static inline bool isImmU6(unsigned val) {
40  return val < (1 << 6);
41 }
42 
43 static inline bool isImmU16(unsigned val) {
44  return val < (1 << 16);
45 }
46 
47 // Helper structure with compare function for handling stack slots.
48 namespace {
49 struct StackSlotInfo {
50  int FI;
51  int Offset;
52  unsigned Reg;
53  StackSlotInfo(int f, int o, int r) : FI(f), Offset(o), Reg(r){};
54 };
55 } // end anonymous namespace
56 
57 static bool CompareSSIOffset(const StackSlotInfo& a, const StackSlotInfo& b) {
58  return a.Offset < b.Offset;
59 }
60 
61 
64  const TargetInstrInfo &TII,
65  MachineModuleInfo *MMI, unsigned DRegNum) {
66  unsigned CFIIndex = MMI->addFrameInst(
67  MCCFIInstruction::createDefCfaRegister(nullptr, DRegNum));
68  BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
69  .addCFIIndex(CFIIndex);
70 }
71 
74  const TargetInstrInfo &TII,
75  MachineModuleInfo *MMI, int Offset) {
76  unsigned CFIIndex =
77  MMI->addFrameInst(MCCFIInstruction::createDefCfaOffset(nullptr, -Offset));
78  BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
79  .addCFIIndex(CFIIndex);
80 }
81 
85  unsigned DRegNum, int Offset) {
86  unsigned CFIIndex = MMI->addFrameInst(
87  MCCFIInstruction::createOffset(nullptr, DRegNum, Offset));
88  BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
89  .addCFIIndex(CFIIndex);
90 }
91 
92 /// The SP register is moved in steps of 'MaxImmU16' towards the bottom of the
93 /// frame. During these steps, it may be necessary to spill registers.
94 /// IfNeededExtSP emits the necessary EXTSP instructions to move the SP only
95 /// as far as to make 'OffsetFromBottom' reachable using an STWSP_lru6.
96 /// \param OffsetFromTop the spill offset from the top of the frame.
97 /// \param [in,out] Adjusted the current SP offset from the top of the frame.
101  int OffsetFromTop, int &Adjusted, int FrameSize,
102  bool emitFrameMoves) {
103  while (OffsetFromTop > Adjusted) {
104  assert(Adjusted < FrameSize && "OffsetFromTop is beyond FrameSize");
105  int remaining = FrameSize - Adjusted;
106  int OpImm = (remaining > MaxImmU16) ? MaxImmU16 : remaining;
107  int Opcode = isImmU6(OpImm) ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
108  BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(OpImm);
109  Adjusted += OpImm;
110  if (emitFrameMoves)
111  EmitDefCfaOffset(MBB, MBBI, dl, TII, MMI, Adjusted*4);
112  }
113 }
114 
115 /// The SP register is moved in steps of 'MaxImmU16' towards the top of the
116 /// frame. During these steps, it may be necessary to re-load registers.
117 /// IfNeededLDAWSP emits the necessary LDAWSP instructions to move the SP only
118 /// as far as to make 'OffsetFromTop' reachable using an LDAWSP_lru6.
119 /// \param OffsetFromTop the spill offset from the top of the frame.
120 /// \param [in,out] RemainingAdj the current SP offset from the top of the
121 /// frame.
124  const TargetInstrInfo &TII, int OffsetFromTop,
125  int &RemainingAdj) {
126  while (OffsetFromTop < RemainingAdj - MaxImmU16) {
127  assert(RemainingAdj && "OffsetFromTop is beyond FrameSize");
128  int OpImm = (RemainingAdj > MaxImmU16) ? MaxImmU16 : RemainingAdj;
129  int Opcode = isImmU6(OpImm) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
130  BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(OpImm);
131  RemainingAdj -= OpImm;
132  }
133 }
134 
135 /// Creates an ordered list of registers that are spilled
136 /// during the emitPrologue/emitEpilogue.
137 /// Registers are ordered according to their frame offset.
138 /// As offsets are negative, the largest offsets will be first.
141  bool fetchLR, bool fetchFP) {
142  if (fetchLR) {
143  int Offset = MFI->getObjectOffset(XFI->getLRSpillSlot());
144  SpillList.push_back(StackSlotInfo(XFI->getLRSpillSlot(),
145  Offset,
146  XCore::LR));
147  }
148  if (fetchFP) {
149  int Offset = MFI->getObjectOffset(XFI->getFPSpillSlot());
150  SpillList.push_back(StackSlotInfo(XFI->getFPSpillSlot(),
151  Offset,
152  FramePtr));
153  }
154  std::sort(SpillList.begin(), SpillList.end(), CompareSSIOffset);
155 }
156 
157 /// Creates an ordered list of EH info register 'spills'.
158 /// These slots are only used by the unwinder and calls to llvm.eh.return().
159 /// Registers are ordered according to their frame offset.
160 /// As offsets are negative, the largest offsets will be first.
163  const TargetLowering *TL) {
164  assert(XFI->hasEHSpillSlot() && "There are no EH register spill slots");
165  const int* EHSlot = XFI->getEHSpillSlot();
166  SpillList.push_back(StackSlotInfo(EHSlot[0],
167  MFI->getObjectOffset(EHSlot[0]),
169  SpillList.push_back(StackSlotInfo(EHSlot[0],
170  MFI->getObjectOffset(EHSlot[1]),
172  std::sort(SpillList.begin(), SpillList.end(), CompareSSIOffset);
173 }
174 
175 
176 static MachineMemOperand *
177 getFrameIndexMMO(MachineBasicBlock &MBB, int FrameIndex, unsigned flags) {
178  MachineFunction *MF = MBB.getParent();
179  const MachineFrameInfo &MFI = *MF->getFrameInfo();
180  MachineMemOperand *MMO =
182  flags, MFI.getObjectSize(FrameIndex),
183  MFI.getObjectAlignment(FrameIndex));
184  return MMO;
185 }
186 
187 
188 /// Restore clobbered registers with their spill slot value.
189 /// The SP will be adjusted at the same time, thus the SpillList must be ordered
190 /// with the largest (negative) offsets first.
191 static void
193  DebugLoc dl, const TargetInstrInfo &TII, int &RemainingAdj,
194  SmallVectorImpl<StackSlotInfo> &SpillList) {
195  for (unsigned i = 0, e = SpillList.size(); i != e; ++i) {
196  assert(SpillList[i].Offset % 4 == 0 && "Misaligned stack offset");
197  assert(SpillList[i].Offset <= 0 && "Unexpected positive stack offset");
198  int OffsetFromTop = - SpillList[i].Offset/4;
199  IfNeededLDAWSP(MBB, MBBI, dl, TII, OffsetFromTop, RemainingAdj);
200  int Offset = RemainingAdj - OffsetFromTop;
201  int Opcode = isImmU6(Offset) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6;
202  BuildMI(MBB, MBBI, dl, TII.get(Opcode), SpillList[i].Reg)
203  .addImm(Offset)
204  .addMemOperand(getFrameIndexMMO(MBB, SpillList[i].FI,
206  }
207 }
208 
209 //===----------------------------------------------------------------------===//
210 // XCoreFrameLowering:
211 //===----------------------------------------------------------------------===//
212 
214  : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 4, 0) {
215  // Do nothing
216 }
217 
219  return MF.getTarget().Options.DisableFramePointerElim(MF) ||
221 }
222 
224  MachineBasicBlock &MBB) const {
225  assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
226  MachineBasicBlock::iterator MBBI = MBB.begin();
227  MachineFrameInfo *MFI = MF.getFrameInfo();
228  MachineModuleInfo *MMI = &MF.getMMI();
229  const MCRegisterInfo *MRI = MMI->getContext().getRegisterInfo();
230  const XCoreInstrInfo &TII = *MF.getSubtarget<XCoreSubtarget>().getInstrInfo();
232  // Debug location must be unknown since the first debug location is used
233  // to determine the end of the prologue.
234  DebugLoc dl;
235 
236  if (MFI->getMaxAlignment() > getStackAlignment())
237  report_fatal_error("emitPrologue unsupported alignment: "
238  + Twine(MFI->getMaxAlignment()));
239 
240  const AttributeSet &PAL = MF.getFunction()->getAttributes();
242  BuildMI(MBB, MBBI, dl, TII.get(XCore::LDWSP_ru6), XCore::R11).addImm(0);
243  // FIX: Needs addMemOperand() but can't use getFixedStack() or getStack().
244 
245  // Work out frame sizes.
246  // We will adjust the SP in stages towards the final FrameSize.
247  assert(MFI->getStackSize()%4 == 0 && "Misaligned frame size");
248  const int FrameSize = MFI->getStackSize() / 4;
249  int Adjusted = 0;
250 
251  bool saveLR = XFI->hasLRSpillSlot();
252  bool UseENTSP = saveLR && FrameSize
253  && (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0);
254  if (UseENTSP)
255  saveLR = false;
256  bool FP = hasFP(MF);
257  bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(MF);
258 
259  if (UseENTSP) {
260  // Allocate space on the stack at the same time as saving LR.
261  Adjusted = (FrameSize > MaxImmU16) ? MaxImmU16 : FrameSize;
262  int Opcode = isImmU6(Adjusted) ? XCore::ENTSP_u6 : XCore::ENTSP_lu6;
263  MBB.addLiveIn(XCore::LR);
264  MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode));
265  MIB.addImm(Adjusted);
266  MIB->addRegisterKilled(XCore::LR, MF.getSubtarget().getRegisterInfo(),
267  true);
268  if (emitFrameMoves) {
269  EmitDefCfaOffset(MBB, MBBI, dl, TII, MMI, Adjusted*4);
270  unsigned DRegNum = MRI->getDwarfRegNum(XCore::LR, true);
271  EmitCfiOffset(MBB, MBBI, dl, TII, MMI, DRegNum, 0);
272  }
273  }
274 
275  // If necessary, save LR and FP to the stack, as we EXTSP.
277  GetSpillList(SpillList, MFI, XFI, saveLR, FP);
278  // We want the nearest (negative) offsets first, so reverse list.
279  std::reverse(SpillList.begin(), SpillList.end());
280  for (unsigned i = 0, e = SpillList.size(); i != e; ++i) {
281  assert(SpillList[i].Offset % 4 == 0 && "Misaligned stack offset");
282  assert(SpillList[i].Offset <= 0 && "Unexpected positive stack offset");
283  int OffsetFromTop = - SpillList[i].Offset/4;
284  IfNeededExtSP(MBB, MBBI, dl, TII, MMI, OffsetFromTop, Adjusted, FrameSize,
285  emitFrameMoves);
286  int Offset = Adjusted - OffsetFromTop;
287  int Opcode = isImmU6(Offset) ? XCore::STWSP_ru6 : XCore::STWSP_lru6;
288  MBB.addLiveIn(SpillList[i].Reg);
289  BuildMI(MBB, MBBI, dl, TII.get(Opcode))
290  .addReg(SpillList[i].Reg, RegState::Kill)
291  .addImm(Offset)
292  .addMemOperand(getFrameIndexMMO(MBB, SpillList[i].FI,
294  if (emitFrameMoves) {
295  unsigned DRegNum = MRI->getDwarfRegNum(SpillList[i].Reg, true);
296  EmitCfiOffset(MBB, MBBI, dl, TII, MMI, DRegNum, SpillList[i].Offset);
297  }
298  }
299 
300  // Complete any remaining Stack adjustment.
301  IfNeededExtSP(MBB, MBBI, dl, TII, MMI, FrameSize, Adjusted, FrameSize,
302  emitFrameMoves);
303  assert(Adjusted==FrameSize && "IfNeededExtSP has not completed adjustment");
304 
305  if (FP) {
306  // Set the FP from the SP.
307  BuildMI(MBB, MBBI, dl, TII.get(XCore::LDAWSP_ru6), FramePtr).addImm(0);
308  if (emitFrameMoves)
309  EmitDefCfaRegister(MBB, MBBI, dl, TII, MMI,
310  MRI->getDwarfRegNum(FramePtr, true));
311  }
312 
313  if (emitFrameMoves) {
314  // Frame moves for callee saved.
315  for (const auto &SpillLabel : XFI->getSpillLabels()) {
316  MachineBasicBlock::iterator Pos = SpillLabel.first;
317  ++Pos;
318  const CalleeSavedInfo &CSI = SpillLabel.second;
319  int Offset = MFI->getObjectOffset(CSI.getFrameIdx());
320  unsigned DRegNum = MRI->getDwarfRegNum(CSI.getReg(), true);
321  EmitCfiOffset(MBB, Pos, dl, TII, MMI, DRegNum, Offset);
322  }
323  if (XFI->hasEHSpillSlot()) {
324  // The unwinder requires stack slot & CFI offsets for the exception info.
325  // We do not save/spill these registers.
327  GetEHSpillList(SpillList, MFI, XFI,
329  assert(SpillList.size()==2 && "Unexpected SpillList size");
330  EmitCfiOffset(MBB, MBBI, dl, TII, MMI,
331  MRI->getDwarfRegNum(SpillList[0].Reg, true),
332  SpillList[0].Offset);
333  EmitCfiOffset(MBB, MBBI, dl, TII, MMI,
334  MRI->getDwarfRegNum(SpillList[1].Reg, true),
335  SpillList[1].Offset);
336  }
337  }
338 }
339 
341  MachineBasicBlock &MBB) const {
342  MachineFrameInfo *MFI = MF.getFrameInfo();
344  const XCoreInstrInfo &TII = *MF.getSubtarget<XCoreSubtarget>().getInstrInfo();
346  DebugLoc dl = MBBI->getDebugLoc();
347  unsigned RetOpcode = MBBI->getOpcode();
348 
349  // Work out frame sizes.
350  // We will adjust the SP in stages towards the final FrameSize.
351  int RemainingAdj = MFI->getStackSize();
352  assert(RemainingAdj%4 == 0 && "Misaligned frame size");
353  RemainingAdj /= 4;
354 
355  if (RetOpcode == XCore::EH_RETURN) {
356  // 'Restore' the exception info the unwinder has placed into the stack
357  // slots.
359  GetEHSpillList(SpillList, MFI, XFI, MF.getSubtarget().getTargetLowering());
360  RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList);
361 
362  // Return to the landing pad.
363  unsigned EhStackReg = MBBI->getOperand(0).getReg();
364  unsigned EhHandlerReg = MBBI->getOperand(1).getReg();
365  BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(EhStackReg);
366  BuildMI(MBB, MBBI, dl, TII.get(XCore::BAU_1r)).addReg(EhHandlerReg);
367  MBB.erase(MBBI); // Erase the previous return instruction.
368  return;
369  }
370 
371  bool restoreLR = XFI->hasLRSpillSlot();
372  bool UseRETSP = restoreLR && RemainingAdj
373  && (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0);
374  if (UseRETSP)
375  restoreLR = false;
376  bool FP = hasFP(MF);
377 
378  if (FP) // Restore the stack pointer.
379  BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(FramePtr);
380 
381  // If necessary, restore LR and FP from the stack, as we EXTSP.
383  GetSpillList(SpillList, MFI, XFI, restoreLR, FP);
384  RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList);
385 
386  if (RemainingAdj) {
387  // Complete all but one of the remaining Stack adjustments.
388  IfNeededLDAWSP(MBB, MBBI, dl, TII, 0, RemainingAdj);
389  if (UseRETSP) {
390  // Fold prologue into return instruction
391  assert(RetOpcode == XCore::RETSP_u6
392  || RetOpcode == XCore::RETSP_lu6);
393  int Opcode = isImmU6(RemainingAdj) ? XCore::RETSP_u6 : XCore::RETSP_lu6;
394  MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode))
395  .addImm(RemainingAdj);
396  for (unsigned i = 3, e = MBBI->getNumOperands(); i < e; ++i)
397  MIB->addOperand(MBBI->getOperand(i)); // copy any variadic operands
398  MBB.erase(MBBI); // Erase the previous return instruction.
399  } else {
400  int Opcode = isImmU6(RemainingAdj) ? XCore::LDAWSP_ru6 :
401  XCore::LDAWSP_lru6;
402  BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(RemainingAdj);
403  // Don't erase the return instruction.
404  }
405  } // else Don't erase the return instruction.
406 }
407 
411  const std::vector<CalleeSavedInfo> &CSI,
412  const TargetRegisterInfo *TRI) const {
413  if (CSI.empty())
414  return true;
415 
416  MachineFunction *MF = MBB.getParent();
417  const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
419  bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(*MF);
420 
421  DebugLoc DL;
422  if (MI != MBB.end() && !MI->isDebugValue())
423  DL = MI->getDebugLoc();
424 
425  for (std::vector<CalleeSavedInfo>::const_iterator it = CSI.begin();
426  it != CSI.end(); ++it) {
427  unsigned Reg = it->getReg();
428  assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) &&
429  "LR & FP are always handled in emitPrologue");
430 
431  // Add the callee-saved register as live-in. It's killed at the spill.
432  MBB.addLiveIn(Reg);
433  const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
434  TII.storeRegToStackSlot(MBB, MI, Reg, true, it->getFrameIdx(), RC, TRI);
435  if (emitFrameMoves) {
436  auto Store = MI;
437  --Store;
438  XFI->getSpillLabels().push_back(std::make_pair(Store, *it));
439  }
440  }
441  return true;
442 }
443 
447  const std::vector<CalleeSavedInfo> &CSI,
448  const TargetRegisterInfo *TRI) const{
449  MachineFunction *MF = MBB.getParent();
450  const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
451  bool AtStart = MI == MBB.begin();
453  if (!AtStart)
454  --BeforeI;
455  for (std::vector<CalleeSavedInfo>::const_iterator it = CSI.begin();
456  it != CSI.end(); ++it) {
457  unsigned Reg = it->getReg();
458  assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) &&
459  "LR & FP are always handled in emitEpilogue");
460 
461  const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
462  TII.loadRegFromStackSlot(MBB, MI, Reg, it->getFrameIdx(), RC, TRI);
463  assert(MI != MBB.begin() &&
464  "loadRegFromStackSlot didn't insert any code!");
465  // Insert in reverse order. loadRegFromStackSlot can insert multiple
466  // instructions.
467  if (AtStart)
468  MI = MBB.begin();
469  else {
470  MI = BeforeI;
471  ++MI;
472  }
473  }
474  return true;
475 }
476 
477 // This function eliminates ADJCALLSTACKDOWN,
478 // ADJCALLSTACKUP pseudo instructions
482  const XCoreInstrInfo &TII = *MF.getSubtarget<XCoreSubtarget>().getInstrInfo();
483  if (!hasReservedCallFrame(MF)) {
484  // Turn the adjcallstackdown instruction into 'extsp <amt>' and the
485  // adjcallstackup instruction into 'ldaw sp, sp[<amt>]'
486  MachineInstr *Old = I;
487  uint64_t Amount = Old->getOperand(0).getImm();
488  if (Amount != 0) {
489  // We need to keep the stack aligned properly. To do this, we round the
490  // amount of space needed for the outgoing arguments up to the next
491  // alignment boundary.
492  unsigned Align = getStackAlignment();
493  Amount = (Amount+Align-1)/Align*Align;
494 
495  assert(Amount%4 == 0);
496  Amount /= 4;
497 
498  bool isU6 = isImmU6(Amount);
499  if (!isU6 && !isImmU16(Amount)) {
500  // FIX could emit multiple instructions in this case.
501 #ifndef NDEBUG
502  errs() << "eliminateCallFramePseudoInstr size too big: "
503  << Amount << "\n";
504 #endif
505  llvm_unreachable(nullptr);
506  }
507 
508  MachineInstr *New;
509  if (Old->getOpcode() == XCore::ADJCALLSTACKDOWN) {
510  int Opcode = isU6 ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
511  New=BuildMI(MF, Old->getDebugLoc(), TII.get(Opcode))
512  .addImm(Amount);
513  } else {
514  assert(Old->getOpcode() == XCore::ADJCALLSTACKUP);
515  int Opcode = isU6 ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
516  New=BuildMI(MF, Old->getDebugLoc(), TII.get(Opcode), XCore::SP)
517  .addImm(Amount);
518  }
519 
520  // Replace the pseudo instruction with a new instruction...
521  MBB.insert(I, New);
522  }
523  }
524 
525  MBB.erase(I);
526 }
527 
529  BitVector &SavedRegs,
530  RegScavenger *RS) const {
532 
534 
535  const MachineRegisterInfo &MRI = MF.getRegInfo();
536  bool LRUsed = MRI.isPhysRegModified(XCore::LR);
537 
538  if (!LRUsed && !MF.getFunction()->isVarArg() &&
540  // If we need to extend the stack it is more efficient to use entsp / retsp.
541  // We force the LR to be saved so these instructions are used.
542  LRUsed = true;
543 
544  if (MF.getMMI().callsUnwindInit() || MF.getMMI().callsEHReturn()) {
545  // The unwinder expects to find spill slots for the exception info regs R0
546  // & R1. These are used during llvm.eh.return() to 'restore' the exception
547  // info. N.B. we do not spill or restore R0, R1 during normal operation.
548  XFI->createEHSpillSlot(MF);
549  // As we will have a stack, we force the LR to be saved.
550  LRUsed = true;
551  }
552 
553  if (LRUsed) {
554  // We will handle the LR in the prologue/epilogue
555  // and allocate space on the stack ourselves.
556  SavedRegs.reset(XCore::LR);
557  XFI->createLRSpillSlot(MF);
558  }
559 
560  if (hasFP(MF))
561  // A callee save register is used to hold the FP.
562  // This needs saving / restoring in the epilogue / prologue.
563  XFI->createFPSpillSlot(MF);
564 }
565 
568  RegScavenger *RS) const {
569  assert(RS && "requiresRegisterScavenging failed");
570  MachineFrameInfo *MFI = MF.getFrameInfo();
571  const TargetRegisterClass *RC = &XCore::GRRegsRegClass;
573  // Reserve slots close to SP or frame pointer for Scavenging spills.
574  // When using SP for small frames, we don't need any scratch registers.
575  // When using SP for large frames, we may need 2 scratch registers.
576  // When using FP, for large or small frames, we may need 1 scratch register.
577  if (XFI->isLargeFrame(MF) || hasFP(MF))
579  RC->getAlignment(),
580  false));
581  if (XFI->isLargeFrame(MF) && !hasFP(MF))
583  RC->getAlignment(),
584  false));
585 }
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
int createLRSpillSlot(MachineFunction &MF)
The memory access reads data.
const MachineFunction * getParent() const
getParent - Return the MachineFunction containing this basic block.
static const int MaxImmU16
int getDwarfRegNum(unsigned RegNum, bool isEH) const
Map a target register to an equivalent dwarf register number.
The memory access writes data.
static bool isImmU16(unsigned val)
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
bool isPhysRegModified(unsigned PhysReg) const
Return true if the specified register is modified in this function.
XCoreFrameLowering(const XCoreSubtarget &STI)
Nested function static chain.
Definition: Attributes.h:82
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:381
void addLiveIn(unsigned Reg)
Adds the specified register as a live in.
std::vector< std::pair< MachineBasicBlock::iterator, CalleeSavedInfo > > & getSpillLabels()
static void EmitDefCfaOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc dl, const TargetInstrInfo &TII, MachineModuleInfo *MMI, int Offset)
A debug info location.
Definition: DebugLoc.h:34
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
static void RestoreSpillList(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc dl, const TargetInstrInfo &TII, int &RemainingAdj, SmallVectorImpl< StackSlotInfo > &SpillList)
Restore clobbered registers with their spill slot value.
static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset)
.cfi_def_cfa_offset modifies a rule for computing CFA.
Definition: MCDwarf.h:368
static void GetEHSpillList(SmallVectorImpl< StackSlotInfo > &SpillList, MachineFrameInfo *MFI, XCoreFunctionInfo *XFI, const TargetLowering *TL)
Creates an ordered list of EH info register 'spills'.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, unsigned f, uint64_t s, unsigned base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
getMachineMemOperand - Allocate a new MachineMemOperand.
static void IfNeededLDAWSP(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc dl, const TargetInstrInfo &TII, int OffsetFromTop, int &RemainingAdj)
The SP register is moved in steps of 'MaxImmU16' towards the top of the frame.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
static MachinePointerInfo getFixedStack(int FI, int64_t offset=0)
getFixedStack - Return a MachinePointerInfo record that refers to the the specified FrameIndex...
void eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const override
eliminateCallFramePseudoInstr - This method is called during prolog/epilog code insertion to eliminat...
unsigned getMaxAlignment() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...
unsigned getSize() const
getSize - Return the size of the register in bytes, which is also the size of a stack slot allocated ...
MachineMemOperand - A description of a memory reference used in the backend.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:79
const HexagonInstrInfo * TII
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:98
bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APInt.h:33
Reg
All possible values of the reg field in the ModR/M byte.
static void IfNeededExtSP(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc dl, const TargetInstrInfo &TII, MachineModuleInfo *MMI, int OffsetFromTop, int &Adjusted, int FrameSize, bool emitFrameMoves)
The SP register is moved in steps of 'MaxImmU16' towards the bottom of the frame. ...
static void EmitDefCfaRegister(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc dl, const TargetInstrInfo &TII, MachineModuleInfo *MMI, unsigned DRegNum)
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
const MachineInstrBuilder & addImm(int64_t Val) const
addImm - Add a new immediate operand.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
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...
const MachineBasicBlock & front() const
static bool needsFrameMoves(const MachineFunction &MF)
Return whether to emit frame moves.
const int * getEHSpillSlot() const
unsigned LLVM_ATTRIBUTE_UNUSED_RESULT addFrameInst(const MCCFIInstruction &Inst)
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI) const override
restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee saved registers and returns...
iterator getLastNonDebugInstr()
getLastNonDebugInstr - returns an iterator to the last non-debug instruction in the basic block...
int64_t getImm() const
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
unsigned estimateStackSize(const MachineFunction &MF) const
Estimate and return the size of the stack frame.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:267
int createFPSpillSlot(MachineFunction &MF)
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
TargetInstrInfo - Interface to description of machine instruction set.
bundle_iterator< MachineInstr, instr_iterator > iterator
unsigned getAlignment() const
getAlignment - Return the minimum required alignment for a register of this class.
static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register)
.cfi_def_cfa_register modifies a rule for computing CFA.
Definition: MCDwarf.h:361
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:273
virtual void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const
Load the specified register of the given register class from the specified stack frame index...
BitVector & reset()
Definition: BitVector.h:259
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
static void EmitCfiOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc dl, const TargetInstrInfo &TII, MachineModuleInfo *MMI, unsigned DRegNum, int Offset)
const int * createEHSpillSlot(MachineFunction &MF)
static MachineMemOperand * getFrameIndexMMO(MachineBasicBlock &MBB, int FrameIndex, unsigned flags)
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
BuildMI - Builder interface.
XCoreFunctionInfo - This class is derived from MachineFunction private XCore target-specific informat...
virtual void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const
Store the specified register of the given register class to the specified stack frame index...
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register...
unsigned getExceptionPointerRegister() const
If a physical register, this returns the register that receives the exception address on entry to a l...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
Definition: MCInstrInfo.h:45
virtual bool hasReservedCallFrame(const MachineFunction &MF) const
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required, we reserve argument space for call sites in the function immediately on entry to the current function.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
bool isLargeFrame(const MachineFunction &MF) const
void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
const MCContext & getContext() const
void addScavengingFrameIndex(int FI)
Add a scavenging frame index.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:861
unsigned getObjectAlignment(int ObjectIdx) const
Return the alignment of the specified stack object.
virtual const TargetLowering * getTargetLowering() const
Information about stack frame layout on the target.
MachineFrameInfo * getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(NoStrictAlign), cl::values(clEnumValN(StrictAlign,"aarch64-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"aarch64-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
static bool isImmU6(unsigned val)
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
AttributeSet getAttributes() const
Return the attribute list for this Function.
Definition: Function.h:181
void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS=nullptr) const override
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
const TargetRegisterClass * getMinimalPhysRegClass(unsigned Reg, MVT VT=MVT::Other) const
getMinimalPhysRegClass - Returns the Register Class of a physical register of the given type...
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:238
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
const MCRegisterInfo * getRegisterInfo() const
Definition: MCContext.h:227
Representation of each machine instruction.
Definition: MachineInstr.h:51
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
bool hasAttrSomewhere(Attribute::AttrKind Attr) const
Return true if the specified attribute is set for at least one parameter or for the return value...
Definition: Attributes.cpp:973
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
#define I(x, y, z)
Definition: MD5.cpp:54
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
static void GetSpillList(SmallVectorImpl< StackSlotInfo > &SpillList, MachineFrameInfo *MFI, XCoreFunctionInfo *XFI, bool fetchLR, bool fetchFP)
Creates an ordered list of registers that are spilled during the emitPrologue/emitEpilogue.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS, const AllocaInst *Alloca=nullptr)
Create a new statically sized stack object, returning a nonnegative identifier to represent it...
OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) - This node represents 'eh_return' gcc dwarf builtin...
Definition: ISDOpcodes.h:97
virtual const TargetInstrInfo * getInstrInfo() const
static const unsigned FramePtr
bool addRegisterKilled(unsigned IncomingReg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
We have determined MI kills a register.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
MachineModuleInfo & getMMI() const
unsigned getExceptionSelectorRegister() const
If a physical register, this returns the register that receives the exception typeid on entry to a la...
static bool CompareSSIOffset(const StackSlotInfo &a, const StackSlotInfo &b)
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition: Function.cpp:229
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
MachineModuleInfo - This class contains meta information specific to a module.
This file describes how to lower LLVM code to machine code.
unsigned getReg() const