LLVM  12.0.0git
XCoreFrameLowering.cpp
Go to the documentation of this file.
1 //===-- XCoreFrameLowering.cpp - Frame info for XCore Target --------------===//
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 XCore frame information that doesn't fit anywhere else
10 // cleanly...
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "XCoreFrameLowering.h"
15 #include "XCore.h"
16 #include "XCoreInstrInfo.h"
18 #include "XCoreSubtarget.h"
26 #include "llvm/IR/DataLayout.h"
27 #include "llvm/IR/Function.h"
30 #include <algorithm> // std::sort
31 
32 using namespace llvm;
33 
34 static const unsigned FramePtr = XCore::R10;
35 static const int MaxImmU16 = (1<<16) - 1;
36 
37 // helper functions. FIXME: Eliminate.
38 static inline bool isImmU6(unsigned val) {
39  return val < (1 << 6);
40 }
41 
42 static inline bool isImmU16(unsigned val) {
43  return val < (1 << 16);
44 }
45 
46 // Helper structure with compare function for handling stack slots.
47 namespace {
48 struct StackSlotInfo {
49  int FI;
50  int Offset;
51  unsigned Reg;
52  StackSlotInfo(int f, int o, int r) : FI(f), Offset(o), Reg(r){};
53 };
54 } // end anonymous namespace
55 
56 static bool CompareSSIOffset(const StackSlotInfo& a, const StackSlotInfo& b) {
57  return a.Offset < b.Offset;
58 }
59 
62  const DebugLoc &dl, const TargetInstrInfo &TII,
63  MachineFunction &MF, unsigned DRegNum) {
64  unsigned CFIIndex = MF.addFrameInst(
65  MCCFIInstruction::createDefCfaRegister(nullptr, DRegNum));
66  BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
67  .addCFIIndex(CFIIndex);
68 }
69 
72  const DebugLoc &dl, const TargetInstrInfo &TII,
73  int Offset) {
74  MachineFunction &MF = *MBB.getParent();
75  unsigned CFIIndex =
77  BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
78  .addCFIIndex(CFIIndex);
79 }
80 
83  const TargetInstrInfo &TII, unsigned DRegNum,
84  int Offset) {
85  MachineFunction &MF = *MBB.getParent();
86  unsigned CFIIndex = MF.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.
100  const TargetInstrInfo &TII, int OffsetFromTop,
101  int &Adjusted, int FrameSize, bool emitFrameMoves) {
102  while (OffsetFromTop > Adjusted) {
103  assert(Adjusted < FrameSize && "OffsetFromTop is beyond FrameSize");
104  int remaining = FrameSize - Adjusted;
105  int OpImm = (remaining > MaxImmU16) ? MaxImmU16 : remaining;
106  int Opcode = isImmU6(OpImm) ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
107  BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(OpImm);
108  Adjusted += OpImm;
109  if (emitFrameMoves)
110  EmitDefCfaOffset(MBB, MBBI, dl, TII, Adjusted*4);
111  }
112 }
113 
114 /// The SP register is moved in steps of 'MaxImmU16' towards the top of the
115 /// frame. During these steps, it may be necessary to re-load registers.
116 /// IfNeededLDAWSP emits the necessary LDAWSP instructions to move the SP only
117 /// as far as to make 'OffsetFromTop' reachable using an LDAWSP_lru6.
118 /// \param OffsetFromTop the spill offset from the top of the frame.
119 /// \param [in,out] RemainingAdj the current SP offset from the top of the
120 /// frame.
123  const TargetInstrInfo &TII, int OffsetFromTop,
124  int &RemainingAdj) {
125  while (OffsetFromTop < RemainingAdj - MaxImmU16) {
126  assert(RemainingAdj && "OffsetFromTop is beyond FrameSize");
127  int OpImm = (RemainingAdj > MaxImmU16) ? MaxImmU16 : RemainingAdj;
128  int Opcode = isImmU6(OpImm) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
129  BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(OpImm);
130  RemainingAdj -= OpImm;
131  }
132 }
133 
134 /// Creates an ordered list of registers that are spilled
135 /// during the emitPrologue/emitEpilogue.
136 /// Registers are ordered according to their frame offset.
137 /// As offsets are negative, the largest offsets will be first.
140  bool fetchLR, bool fetchFP) {
141  if (fetchLR) {
142  int Offset = MFI.getObjectOffset(XFI->getLRSpillSlot());
143  SpillList.push_back(StackSlotInfo(XFI->getLRSpillSlot(),
144  Offset,
145  XCore::LR));
146  }
147  if (fetchFP) {
148  int Offset = MFI.getObjectOffset(XFI->getFPSpillSlot());
149  SpillList.push_back(StackSlotInfo(XFI->getFPSpillSlot(),
150  Offset,
151  FramePtr));
152  }
153  llvm::sort(SpillList, CompareSSIOffset);
154 }
155 
156 /// Creates an ordered list of EH info register 'spills'.
157 /// These slots are only used by the unwinder and calls to llvm.eh.return().
158 /// Registers are ordered according to their frame offset.
159 /// As offsets are negative, the largest offsets will be first.
162  const Constant *PersonalityFn,
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(
167  StackSlotInfo(EHSlot[0], MFI.getObjectOffset(EHSlot[0]),
168  TL->getExceptionPointerRegister(PersonalityFn)));
169  SpillList.push_back(
170  StackSlotInfo(EHSlot[0], MFI.getObjectOffset(EHSlot[1]),
171  TL->getExceptionSelectorRegister(PersonalityFn)));
172  llvm::sort(SpillList, CompareSSIOffset);
173 }
174 
176  int FrameIndex,
177  MachineMemOperand::Flags flags) {
178  MachineFunction *MF = MBB.getParent();
179  const MachineFrameInfo &MFI = MF->getFrameInfo();
181  MachinePointerInfo::getFixedStack(*MF, FrameIndex), flags,
182  MFI.getObjectSize(FrameIndex), MFI.getObjectAlign(FrameIndex));
183  return MMO;
184 }
185 
186 
187 /// Restore clobbered registers with their spill slot value.
188 /// The SP will be adjusted at the same time, thus the SpillList must be ordered
189 /// with the largest (negative) offsets first.
192  const DebugLoc &dl, const TargetInstrInfo &TII,
193  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, Align(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");
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.getMaxAlign() > getStackAlign())
237  report_fatal_error("emitPrologue unsupported alignment: " +
238  Twine(MFI.getMaxAlign().value()));
239 
240  const AttributeList &PAL = MF.getFunction().getAttributes();
241  if (PAL.hasAttrSomewhere(Attribute::Nest))
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, Adjusted*4);
270  unsigned DRegNum = MRI->getDwarfRegNum(XCore::LR, true);
271  EmitCfiOffset(MBB, MBBI, dl, TII, 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, 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, DRegNum, SpillList[i].Offset);
297  }
298  }
299 
300  // Complete any remaining Stack adjustment.
301  IfNeededExtSP(MBB, MBBI, dl, TII, 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, MF,
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, 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.
326  const Function *Fn = &MF.getFunction();
327  const Constant *PersonalityFn =
328  Fn->hasPersonalityFn() ? Fn->getPersonalityFn() : nullptr;
330  GetEHSpillList(SpillList, MFI, XFI, PersonalityFn,
332  assert(SpillList.size()==2 && "Unexpected SpillList size");
333  EmitCfiOffset(MBB, MBBI, dl, TII,
334  MRI->getDwarfRegNum(SpillList[0].Reg, true),
335  SpillList[0].Offset);
336  EmitCfiOffset(MBB, MBBI, dl, TII,
337  MRI->getDwarfRegNum(SpillList[1].Reg, true),
338  SpillList[1].Offset);
339  }
340  }
341 }
342 
344  MachineBasicBlock &MBB) const {
345  MachineFrameInfo &MFI = MF.getFrameInfo();
347  const XCoreInstrInfo &TII = *MF.getSubtarget<XCoreSubtarget>().getInstrInfo();
349  DebugLoc dl = MBBI->getDebugLoc();
350  unsigned RetOpcode = MBBI->getOpcode();
351 
352  // Work out frame sizes.
353  // We will adjust the SP in stages towards the final FrameSize.
354  int RemainingAdj = MFI.getStackSize();
355  assert(RemainingAdj%4 == 0 && "Misaligned frame size");
356  RemainingAdj /= 4;
357 
358  if (RetOpcode == XCore::EH_RETURN) {
359  // 'Restore' the exception info the unwinder has placed into the stack
360  // slots.
361  const Function *Fn = &MF.getFunction();
362  const Constant *PersonalityFn =
363  Fn->hasPersonalityFn() ? Fn->getPersonalityFn() : nullptr;
365  GetEHSpillList(SpillList, MFI, XFI, PersonalityFn,
367  RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList);
368 
369  // Return to the landing pad.
370  Register EhStackReg = MBBI->getOperand(0).getReg();
371  Register EhHandlerReg = MBBI->getOperand(1).getReg();
372  BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(EhStackReg);
373  BuildMI(MBB, MBBI, dl, TII.get(XCore::BAU_1r)).addReg(EhHandlerReg);
374  MBB.erase(MBBI); // Erase the previous return instruction.
375  return;
376  }
377 
378  bool restoreLR = XFI->hasLRSpillSlot();
379  bool UseRETSP = restoreLR && RemainingAdj
380  && (MFI.getObjectOffset(XFI->getLRSpillSlot()) == 0);
381  if (UseRETSP)
382  restoreLR = false;
383  bool FP = hasFP(MF);
384 
385  if (FP) // Restore the stack pointer.
386  BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(FramePtr);
387 
388  // If necessary, restore LR and FP from the stack, as we EXTSP.
390  GetSpillList(SpillList, MFI, XFI, restoreLR, FP);
391  RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList);
392 
393  if (RemainingAdj) {
394  // Complete all but one of the remaining Stack adjustments.
395  IfNeededLDAWSP(MBB, MBBI, dl, TII, 0, RemainingAdj);
396  if (UseRETSP) {
397  // Fold prologue into return instruction
398  assert(RetOpcode == XCore::RETSP_u6
399  || RetOpcode == XCore::RETSP_lu6);
400  int Opcode = isImmU6(RemainingAdj) ? XCore::RETSP_u6 : XCore::RETSP_lu6;
401  MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode))
402  .addImm(RemainingAdj);
403  for (unsigned i = 3, e = MBBI->getNumOperands(); i < e; ++i)
404  MIB->addOperand(MBBI->getOperand(i)); // copy any variadic operands
405  MBB.erase(MBBI); // Erase the previous return instruction.
406  } else {
407  int Opcode = isImmU6(RemainingAdj) ? XCore::LDAWSP_ru6 :
408  XCore::LDAWSP_lru6;
409  BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(RemainingAdj);
410  // Don't erase the return instruction.
411  }
412  } // else Don't erase the return instruction.
413 }
414 
418  if (CSI.empty())
419  return true;
420 
421  MachineFunction *MF = MBB.getParent();
422  const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
424  bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(*MF);
425 
426  DebugLoc DL;
427  if (MI != MBB.end() && !MI->isDebugInstr())
428  DL = MI->getDebugLoc();
429 
430  for (auto it = CSI.begin(); it != CSI.end(); ++it) {
431  unsigned Reg = it->getReg();
432  assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) &&
433  "LR & FP are always handled in emitPrologue");
434 
435  // Add the callee-saved register as live-in. It's killed at the spill.
436  MBB.addLiveIn(Reg);
437  const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
438  TII.storeRegToStackSlot(MBB, MI, Reg, true, it->getFrameIdx(), RC, TRI);
439  if (emitFrameMoves) {
440  auto Store = MI;
441  --Store;
442  XFI->getSpillLabels().push_back(std::make_pair(Store, *it));
443  }
444  }
445  return true;
446 }
447 
451  MachineFunction *MF = MBB.getParent();
452  const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
453  bool AtStart = MI == MBB.begin();
455  if (!AtStart)
456  --BeforeI;
457  for (const CalleeSavedInfo &CSR : CSI) {
458  unsigned Reg = CSR.getReg();
459  assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) &&
460  "LR & FP are always handled in emitEpilogue");
461 
462  const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
463  TII.loadRegFromStackSlot(MBB, MI, Reg, CSR.getFrameIdx(), RC, TRI);
464  assert(MI != MBB.begin() &&
465  "loadRegFromStackSlot didn't insert any code!");
466  // Insert in reverse order. loadRegFromStackSlot can insert multiple
467  // instructions.
468  if (AtStart)
469  MI = MBB.begin();
470  else {
471  MI = BeforeI;
472  ++MI;
473  }
474  }
475  return true;
476 }
477 
478 // This function eliminates ADJCALLSTACKDOWN,
479 // ADJCALLSTACKUP pseudo instructions
483  const XCoreInstrInfo &TII = *MF.getSubtarget<XCoreSubtarget>().getInstrInfo();
484  if (!hasReservedCallFrame(MF)) {
485  // Turn the adjcallstackdown instruction into 'extsp <amt>' and the
486  // adjcallstackup instruction into 'ldaw sp, sp[<amt>]'
487  MachineInstr &Old = *I;
488  uint64_t Amount = Old.getOperand(0).getImm();
489  if (Amount != 0) {
490  // We need to keep the stack aligned properly. To do this, we round the
491  // amount of space needed for the outgoing arguments up to the next
492  // alignment boundary.
493  Amount = alignTo(Amount, getStackAlign());
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)).addImm(Amount);
512  } else {
513  assert(Old.getOpcode() == XCore::ADJCALLSTACKUP);
514  int Opcode = isU6 ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
515  New = BuildMI(MF, Old.getDebugLoc(), TII.get(Opcode), XCore::SP)
516  .addImm(Amount);
517  }
518 
519  // Replace the pseudo instruction with a new instruction...
520  MBB.insert(I, New);
521  }
522  }
523 
524  return MBB.erase(I);
525 }
526 
528  BitVector &SavedRegs,
529  RegScavenger *RS) const {
531 
533 
534  const MachineRegisterInfo &MRI = MF.getRegInfo();
535  bool LRUsed = MRI.isPhysRegModified(XCore::LR);
536 
537  if (!LRUsed && !MF.getFunction().isVarArg() &&
539  // If we need to extend the stack it is more efficient to use entsp / retsp.
540  // We force the LR to be saved so these instructions are used.
541  LRUsed = true;
542 
543  if (MF.callsUnwindInit() || MF.callsEHReturn()) {
544  // The unwinder expects to find spill slots for the exception info regs R0
545  // & R1. These are used during llvm.eh.return() to 'restore' the exception
546  // info. N.B. we do not spill or restore R0, R1 during normal operation.
547  XFI->createEHSpillSlot(MF);
548  // As we will have a stack, we force the LR to be saved.
549  LRUsed = true;
550  }
551 
552  if (LRUsed) {
553  // We will handle the LR in the prologue/epilogue
554  // and allocate space on the stack ourselves.
555  SavedRegs.reset(XCore::LR);
556  XFI->createLRSpillSlot(MF);
557  }
558 
559  if (hasFP(MF))
560  // A callee save register is used to hold the FP.
561  // This needs saving / restoring in the epilogue / prologue.
562  XFI->createFPSpillSlot(MF);
563 }
564 
567  RegScavenger *RS) const {
568  assert(RS && "requiresRegisterScavenging failed");
569  MachineFrameInfo &MFI = MF.getFrameInfo();
570  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  unsigned Size = TRI.getSpillSize(RC);
578  Align Alignment = TRI.getSpillAlign(RC);
579  if (XFI->isLargeFrame(MF) || hasFP(MF))
580  RS->addScavengingFrameIndex(MFI.CreateStackObject(Size, Alignment, false));
581  if (XFI->isLargeFrame(MF) && !hasFP(MF))
582  RS->addScavengingFrameIndex(MFI.CreateStackObject(Size, Alignment, false));
583 }
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition: Function.h:178
int createLRSpillSlot(MachineFunction &MF)
static const int MaxImmU16
static bool isImmU16(unsigned val)
virtual void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register 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...
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:140
This class represents lattice values for constants.
Definition: AllocatorList.h:23
Align getMaxAlign() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
iterator begin() const
Definition: ArrayRef.h:144
XCoreFrameLowering(const XCoreSubtarget &STI)
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
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 DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:409
LLVM_NODISCARD unsigned addFrameInst(const MCCFIInstruction &Inst)
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
virtual const TargetLowering * getTargetLowering() const
std::vector< std::pair< MachineBasicBlock::iterator, CalleeSavedInfo > > & getSpillLabels()
unsigned const TargetRegisterInfo * TRI
A debug info location.
Definition: DebugLoc.h:33
MachineModuleInfo & getMMI() const
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 MachineMemOperand * getFrameIndexMMO(MachineBasicBlock &MBB, int FrameIndex, MachineMemOperand::Flags flags)
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
A description of a memory reference used in the backend.
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:80
const HexagonInstrInfo * TII
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:43
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
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
int getDwarfRegNum(MCRegister RegNum, bool isEH) const
Map a target register to an equivalent dwarf register number.
static bool needsFrameMoves(const MachineFunction &MF)
Return whether to emit frame moves.
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...
static void GetEHSpillList(SmallVectorImpl< StackSlotInfo > &SpillList, MachineFrameInfo &MFI, XCoreFunctionInfo *XFI, const Constant *PersonalityFn, const TargetLowering *TL)
Creates an ordered list of EH info register &#39;spills&#39;.
bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
bool addRegisterKilled(Register IncomingReg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
We have determined MI kills a register.
const MCContext & getContext() const
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:32
iterator getLastNonDebugInstr()
Returns an iterator to the last non-debug instruction in the basic block, or end().
AttributeList getAttributes() const
Return the attribute list for this Function.
Definition: Function.h:230
bool hasPersonalityFn() const
Check whether this function has a personality function.
Definition: Function.h:757
virtual const TargetInstrInfo * getInstrInfo() const
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
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.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
bool hasAttrSomewhere(Attribute::AttrKind Kind, unsigned *Index=nullptr) const
Return true if the specified attribute is set for at least one parameter or for the return value...
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
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.
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
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register)
.cfi_def_cfa_register modifies a rule for computing CFA.
Definition: MCDwarf.h:492
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
static void EmitCfiOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &dl, const TargetInstrInfo &TII, unsigned DRegNum, int Offset)
Align getSpillAlign(const TargetRegisterClass &RC) const
Return the minimum required alignment in bytes for a spill slot for a register of this class...
This is an important base class in LLVM.
Definition: Constant.h:41
virtual void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register 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:439
constexpr double e
Definition: MathExtras.h:58
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.
const int * createEHSpillSlot(MachineFunction &MF)
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1433
bool isPhysRegModified(MCRegister PhysReg, bool SkipNoReturnDef=false) const
Return true if the specified register is modified in this function.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
XCoreFunctionInfo - This class is derived from MachineFunction private XCore target-specific informat...
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
const MachineBasicBlock & front() const
static void EmitDefCfaRegister(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &dl, const TargetInstrInfo &TII, MachineFunction &MF, unsigned DRegNum)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
The memory access writes data.
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
const TargetRegisterClass * getMinimalPhysRegClass(MCRegister Reg, MVT VT=MVT::Other) const
Returns the Register Class of a physical register of the given type, picking the most sub register cl...
void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
static void EmitDefCfaOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &dl, const TargetInstrInfo &TII, int Offset)
void addScavengingFrameIndex(int FI)
Add a scavenging frame index.
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:883
iterator end() const
Definition: ArrayRef.h:145
virtual Register getExceptionPointerRegister(const Constant *PersonalityFn) const
If a physical register, this returns the register that receives the exception address on entry to an ...
Information about stack frame layout on the target.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
bool callsUnwindInit() const
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 getImm() const
static bool isImmU6(unsigned val)
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
bool callsEHReturn() const
void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS=nullptr) const override
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
Flags
Flags values. These may be or&#39;d together.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
The memory access reads data.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
const int * getEHSpillSlot() const
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
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:158
uint64_t estimateStackSize(const MachineFunction &MF) const
Estimate and return the size of the stack frame.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
static void RestoreSpillList(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &dl, const TargetInstrInfo &TII, int &RemainingAdj, SmallVectorImpl< StackSlotInfo > &SpillList)
Restore clobbered registers with their spill slot value.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
Definition: MCInstrInfo.h:62
TargetOptions Options
#define I(x, y, z)
Definition: MD5.cpp:59
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
uint32_t Size
Definition: Profile.cpp:46
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) - This node represents &#39;eh_return&#39; gcc dwarf builtin...
Definition: ISDOpcodes.h:119
bool isLargeFrame(const MachineFunction &MF) const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it...
const MCRegisterInfo * getRegisterInfo() const
Definition: MCContext.h:365
Constant * getPersonalityFn() const
Get the personality function associated with this function.
Definition: Function.cpp:1543
static void IfNeededExtSP(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &dl, const TargetInstrInfo &TII, int OffsetFromTop, int &Adjusted, int FrameSize, bool emitFrameMoves)
The SP register is moved in steps of &#39;MaxImmU16&#39; towards the bottom of the frame. ...
static const unsigned FramePtr
virtual Register getExceptionSelectorRegister(const Constant *PersonalityFn) const
If a physical register, this returns the register that receives the exception typeid on entry to a la...
static void IfNeededLDAWSP(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &dl, const TargetInstrInfo &TII, int OffsetFromTop, int &RemainingAdj)
The SP register is moved in steps of &#39;MaxImmU16&#39; towards the top of the frame.
IRTranslator LLVM IR MI
auto reverse(ContainerTy &&C, std::enable_if_t< has_rbegin< ContainerTy >::value > *=nullptr)
Definition: STLExtras.h:341
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:466
unsigned getReg() const
static bool CompareSSIOffset(const StackSlotInfo &a, const StackSlotInfo &b)
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...
MachineBasicBlock MachineBasicBlock::iterator MBBI
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:151
This class contains meta information specific to a module.
This file describes how to lower LLVM code to machine code.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL