LLVM  9.0.0svn
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 
31 using namespace llvm;
32 
33 static const unsigned FramePtr = XCore::R10;
34 static const int MaxImmU16 = (1<<16) - 1;
35 
36 // helper functions. FIXME: Eliminate.
37 static inline bool isImmU6(unsigned val) {
38  return val < (1 << 6);
39 }
40 
41 static inline bool isImmU16(unsigned val) {
42  return val < (1 << 16);
43 }
44 
45 // Helper structure with compare function for handling stack slots.
46 namespace {
47 struct StackSlotInfo {
48  int FI;
49  int Offset;
50  unsigned Reg;
51  StackSlotInfo(int f, int o, int r) : FI(f), Offset(o), Reg(r){};
52 };
53 } // end anonymous namespace
54 
55 static bool CompareSSIOffset(const StackSlotInfo& a, const StackSlotInfo& b) {
56  return a.Offset < b.Offset;
57 }
58 
61  const DebugLoc &dl, const TargetInstrInfo &TII,
62  MachineFunction &MF, unsigned DRegNum) {
63  unsigned CFIIndex = MF.addFrameInst(
64  MCCFIInstruction::createDefCfaRegister(nullptr, DRegNum));
65  BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
66  .addCFIIndex(CFIIndex);
67 }
68 
71  const DebugLoc &dl, const TargetInstrInfo &TII,
72  int Offset) {
73  MachineFunction &MF = *MBB.getParent();
74  unsigned CFIIndex =
76  BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
77  .addCFIIndex(CFIIndex);
78 }
79 
81  MachineBasicBlock::iterator MBBI, const DebugLoc &dl,
82  const TargetInstrInfo &TII, unsigned DRegNum,
83  int Offset) {
84  MachineFunction &MF = *MBB.getParent();
85  unsigned CFIIndex = MF.addFrameInst(
86  MCCFIInstruction::createOffset(nullptr, DRegNum, Offset));
87  BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
88  .addCFIIndex(CFIIndex);
89 }
90 
91 /// The SP register is moved in steps of 'MaxImmU16' towards the bottom of the
92 /// frame. During these steps, it may be necessary to spill registers.
93 /// IfNeededExtSP emits the necessary EXTSP instructions to move the SP only
94 /// as far as to make 'OffsetFromBottom' reachable using an STWSP_lru6.
95 /// \param OffsetFromTop the spill offset from the top of the frame.
96 /// \param [in,out] Adjusted the current SP offset from the top of the frame.
98  MachineBasicBlock::iterator MBBI, const DebugLoc &dl,
99  const TargetInstrInfo &TII, int OffsetFromTop,
100  int &Adjusted, int FrameSize, bool emitFrameMoves) {
101  while (OffsetFromTop > Adjusted) {
102  assert(Adjusted < FrameSize && "OffsetFromTop is beyond FrameSize");
103  int remaining = FrameSize - Adjusted;
104  int OpImm = (remaining > MaxImmU16) ? MaxImmU16 : remaining;
105  int Opcode = isImmU6(OpImm) ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
106  BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(OpImm);
107  Adjusted += OpImm;
108  if (emitFrameMoves)
109  EmitDefCfaOffset(MBB, MBBI, dl, TII, Adjusted*4);
110  }
111 }
112 
113 /// The SP register is moved in steps of 'MaxImmU16' towards the top of the
114 /// frame. During these steps, it may be necessary to re-load registers.
115 /// IfNeededLDAWSP emits the necessary LDAWSP instructions to move the SP only
116 /// as far as to make 'OffsetFromTop' reachable using an LDAWSP_lru6.
117 /// \param OffsetFromTop the spill offset from the top of the frame.
118 /// \param [in,out] RemainingAdj the current SP offset from the top of the
119 /// frame.
121  MachineBasicBlock::iterator MBBI, const DebugLoc &dl,
122  const TargetInstrInfo &TII, int OffsetFromTop,
123  int &RemainingAdj) {
124  while (OffsetFromTop < RemainingAdj - MaxImmU16) {
125  assert(RemainingAdj && "OffsetFromTop is beyond FrameSize");
126  int OpImm = (RemainingAdj > MaxImmU16) ? MaxImmU16 : RemainingAdj;
127  int Opcode = isImmU6(OpImm) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
128  BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(OpImm);
129  RemainingAdj -= OpImm;
130  }
131 }
132 
133 /// Creates an ordered list of registers that are spilled
134 /// during the emitPrologue/emitEpilogue.
135 /// Registers are ordered according to their frame offset.
136 /// As offsets are negative, the largest offsets will be first.
139  bool fetchLR, bool fetchFP) {
140  if (fetchLR) {
141  int Offset = MFI.getObjectOffset(XFI->getLRSpillSlot());
142  SpillList.push_back(StackSlotInfo(XFI->getLRSpillSlot(),
143  Offset,
144  XCore::LR));
145  }
146  if (fetchFP) {
147  int Offset = MFI.getObjectOffset(XFI->getFPSpillSlot());
148  SpillList.push_back(StackSlotInfo(XFI->getFPSpillSlot(),
149  Offset,
150  FramePtr));
151  }
152  llvm::sort(SpillList, CompareSSIOffset);
153 }
154 
155 /// Creates an ordered list of EH info register 'spills'.
156 /// These slots are only used by the unwinder and calls to llvm.eh.return().
157 /// Registers are ordered according to their frame offset.
158 /// As offsets are negative, the largest offsets will be first.
161  const Constant *PersonalityFn,
162  const TargetLowering *TL) {
163  assert(XFI->hasEHSpillSlot() && "There are no EH register spill slots");
164  const int *EHSlot = XFI->getEHSpillSlot();
165  SpillList.push_back(
166  StackSlotInfo(EHSlot[0], MFI.getObjectOffset(EHSlot[0]),
167  TL->getExceptionPointerRegister(PersonalityFn)));
168  SpillList.push_back(
169  StackSlotInfo(EHSlot[0], MFI.getObjectOffset(EHSlot[1]),
170  TL->getExceptionSelectorRegister(PersonalityFn)));
171  llvm::sort(SpillList, CompareSSIOffset);
172 }
173 
175  int FrameIndex,
176  MachineMemOperand::Flags flags) {
177  MachineFunction *MF = MBB.getParent();
178  const MachineFrameInfo &MFI = MF->getFrameInfo();
180  MachinePointerInfo::getFixedStack(*MF, FrameIndex), flags,
181  MFI.getObjectSize(FrameIndex), MFI.getObjectAlignment(FrameIndex));
182  return MMO;
183 }
184 
185 
186 /// Restore clobbered registers with their spill slot value.
187 /// The SP will be adjusted at the same time, thus the SpillList must be ordered
188 /// with the largest (negative) offsets first.
191  const DebugLoc &dl, const TargetInstrInfo &TII,
192  int &RemainingAdj,
193  SmallVectorImpl<StackSlotInfo> &SpillList) {
194  for (unsigned i = 0, e = SpillList.size(); i != e; ++i) {
195  assert(SpillList[i].Offset % 4 == 0 && "Misaligned stack offset");
196  assert(SpillList[i].Offset <= 0 && "Unexpected positive stack offset");
197  int OffsetFromTop = - SpillList[i].Offset/4;
198  IfNeededLDAWSP(MBB, MBBI, dl, TII, OffsetFromTop, RemainingAdj);
199  int Offset = RemainingAdj - OffsetFromTop;
200  int Opcode = isImmU6(Offset) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6;
201  BuildMI(MBB, MBBI, dl, TII.get(Opcode), SpillList[i].Reg)
202  .addImm(Offset)
203  .addMemOperand(getFrameIndexMMO(MBB, SpillList[i].FI,
205  }
206 }
207 
208 //===----------------------------------------------------------------------===//
209 // XCoreFrameLowering:
210 //===----------------------------------------------------------------------===//
211 
213  : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 4, 0) {
214  // Do nothing
215 }
216 
218  return MF.getTarget().Options.DisableFramePointerElim(MF) ||
220 }
221 
223  MachineBasicBlock &MBB) const {
224  assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
225  MachineBasicBlock::iterator MBBI = MBB.begin();
226  MachineFrameInfo &MFI = MF.getFrameInfo();
227  MachineModuleInfo *MMI = &MF.getMMI();
228  const MCRegisterInfo *MRI = MMI->getContext().getRegisterInfo();
229  const XCoreInstrInfo &TII = *MF.getSubtarget<XCoreSubtarget>().getInstrInfo();
231  // Debug location must be unknown since the first debug location is used
232  // to determine the end of the prologue.
233  DebugLoc dl;
234 
235  if (MFI.getMaxAlignment() > getStackAlignment())
236  report_fatal_error("emitPrologue unsupported alignment: "
237  + Twine(MFI.getMaxAlignment()));
238 
239  const AttributeList &PAL = MF.getFunction().getAttributes();
240  if (PAL.hasAttrSomewhere(Attribute::Nest))
241  BuildMI(MBB, MBBI, dl, TII.get(XCore::LDWSP_ru6), XCore::R11).addImm(0);
242  // FIX: Needs addMemOperand() but can't use getFixedStack() or getStack().
243 
244  // Work out frame sizes.
245  // We will adjust the SP in stages towards the final FrameSize.
246  assert(MFI.getStackSize()%4 == 0 && "Misaligned frame size");
247  const int FrameSize = MFI.getStackSize() / 4;
248  int Adjusted = 0;
249 
250  bool saveLR = XFI->hasLRSpillSlot();
251  bool UseENTSP = saveLR && FrameSize
252  && (MFI.getObjectOffset(XFI->getLRSpillSlot()) == 0);
253  if (UseENTSP)
254  saveLR = false;
255  bool FP = hasFP(MF);
256  bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(MF);
257 
258  if (UseENTSP) {
259  // Allocate space on the stack at the same time as saving LR.
260  Adjusted = (FrameSize > MaxImmU16) ? MaxImmU16 : FrameSize;
261  int Opcode = isImmU6(Adjusted) ? XCore::ENTSP_u6 : XCore::ENTSP_lu6;
262  MBB.addLiveIn(XCore::LR);
263  MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode));
264  MIB.addImm(Adjusted);
265  MIB->addRegisterKilled(XCore::LR, MF.getSubtarget().getRegisterInfo(),
266  true);
267  if (emitFrameMoves) {
268  EmitDefCfaOffset(MBB, MBBI, dl, TII, Adjusted*4);
269  unsigned DRegNum = MRI->getDwarfRegNum(XCore::LR, true);
270  EmitCfiOffset(MBB, MBBI, dl, TII, DRegNum, 0);
271  }
272  }
273 
274  // If necessary, save LR and FP to the stack, as we EXTSP.
276  GetSpillList(SpillList, MFI, XFI, saveLR, FP);
277  // We want the nearest (negative) offsets first, so reverse list.
278  std::reverse(SpillList.begin(), SpillList.end());
279  for (unsigned i = 0, e = SpillList.size(); i != e; ++i) {
280  assert(SpillList[i].Offset % 4 == 0 && "Misaligned stack offset");
281  assert(SpillList[i].Offset <= 0 && "Unexpected positive stack offset");
282  int OffsetFromTop = - SpillList[i].Offset/4;
283  IfNeededExtSP(MBB, MBBI, dl, TII, OffsetFromTop, Adjusted, FrameSize,
284  emitFrameMoves);
285  int Offset = Adjusted - OffsetFromTop;
286  int Opcode = isImmU6(Offset) ? XCore::STWSP_ru6 : XCore::STWSP_lru6;
287  MBB.addLiveIn(SpillList[i].Reg);
288  BuildMI(MBB, MBBI, dl, TII.get(Opcode))
289  .addReg(SpillList[i].Reg, RegState::Kill)
290  .addImm(Offset)
291  .addMemOperand(getFrameIndexMMO(MBB, SpillList[i].FI,
293  if (emitFrameMoves) {
294  unsigned DRegNum = MRI->getDwarfRegNum(SpillList[i].Reg, true);
295  EmitCfiOffset(MBB, MBBI, dl, TII, DRegNum, SpillList[i].Offset);
296  }
297  }
298 
299  // Complete any remaining Stack adjustment.
300  IfNeededExtSP(MBB, MBBI, dl, TII, FrameSize, Adjusted, FrameSize,
301  emitFrameMoves);
302  assert(Adjusted==FrameSize && "IfNeededExtSP has not completed adjustment");
303 
304  if (FP) {
305  // Set the FP from the SP.
306  BuildMI(MBB, MBBI, dl, TII.get(XCore::LDAWSP_ru6), FramePtr).addImm(0);
307  if (emitFrameMoves)
308  EmitDefCfaRegister(MBB, MBBI, dl, TII, MF,
309  MRI->getDwarfRegNum(FramePtr, true));
310  }
311 
312  if (emitFrameMoves) {
313  // Frame moves for callee saved.
314  for (const auto &SpillLabel : XFI->getSpillLabels()) {
315  MachineBasicBlock::iterator Pos = SpillLabel.first;
316  ++Pos;
317  const CalleeSavedInfo &CSI = SpillLabel.second;
318  int Offset = MFI.getObjectOffset(CSI.getFrameIdx());
319  unsigned DRegNum = MRI->getDwarfRegNum(CSI.getReg(), true);
320  EmitCfiOffset(MBB, Pos, dl, TII, DRegNum, Offset);
321  }
322  if (XFI->hasEHSpillSlot()) {
323  // The unwinder requires stack slot & CFI offsets for the exception info.
324  // We do not save/spill these registers.
325  const Function *Fn = &MF.getFunction();
326  const Constant *PersonalityFn =
327  Fn->hasPersonalityFn() ? Fn->getPersonalityFn() : nullptr;
329  GetEHSpillList(SpillList, MFI, XFI, PersonalityFn,
331  assert(SpillList.size()==2 && "Unexpected SpillList size");
332  EmitCfiOffset(MBB, MBBI, dl, TII,
333  MRI->getDwarfRegNum(SpillList[0].Reg, true),
334  SpillList[0].Offset);
335  EmitCfiOffset(MBB, MBBI, dl, TII,
336  MRI->getDwarfRegNum(SpillList[1].Reg, true),
337  SpillList[1].Offset);
338  }
339  }
340 }
341 
343  MachineBasicBlock &MBB) const {
344  MachineFrameInfo &MFI = MF.getFrameInfo();
346  const XCoreInstrInfo &TII = *MF.getSubtarget<XCoreSubtarget>().getInstrInfo();
348  DebugLoc dl = MBBI->getDebugLoc();
349  unsigned RetOpcode = MBBI->getOpcode();
350 
351  // Work out frame sizes.
352  // We will adjust the SP in stages towards the final FrameSize.
353  int RemainingAdj = MFI.getStackSize();
354  assert(RemainingAdj%4 == 0 && "Misaligned frame size");
355  RemainingAdj /= 4;
356 
357  if (RetOpcode == XCore::EH_RETURN) {
358  // 'Restore' the exception info the unwinder has placed into the stack
359  // slots.
360  const Function *Fn = &MF.getFunction();
361  const Constant *PersonalityFn =
362  Fn->hasPersonalityFn() ? Fn->getPersonalityFn() : nullptr;
364  GetEHSpillList(SpillList, MFI, XFI, PersonalityFn,
366  RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList);
367 
368  // Return to the landing pad.
369  unsigned EhStackReg = MBBI->getOperand(0).getReg();
370  unsigned EhHandlerReg = MBBI->getOperand(1).getReg();
371  BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(EhStackReg);
372  BuildMI(MBB, MBBI, dl, TII.get(XCore::BAU_1r)).addReg(EhHandlerReg);
373  MBB.erase(MBBI); // Erase the previous return instruction.
374  return;
375  }
376 
377  bool restoreLR = XFI->hasLRSpillSlot();
378  bool UseRETSP = restoreLR && RemainingAdj
379  && (MFI.getObjectOffset(XFI->getLRSpillSlot()) == 0);
380  if (UseRETSP)
381  restoreLR = false;
382  bool FP = hasFP(MF);
383 
384  if (FP) // Restore the stack pointer.
385  BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(FramePtr);
386 
387  // If necessary, restore LR and FP from the stack, as we EXTSP.
389  GetSpillList(SpillList, MFI, XFI, restoreLR, FP);
390  RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList);
391 
392  if (RemainingAdj) {
393  // Complete all but one of the remaining Stack adjustments.
394  IfNeededLDAWSP(MBB, MBBI, dl, TII, 0, RemainingAdj);
395  if (UseRETSP) {
396  // Fold prologue into return instruction
397  assert(RetOpcode == XCore::RETSP_u6
398  || RetOpcode == XCore::RETSP_lu6);
399  int Opcode = isImmU6(RemainingAdj) ? XCore::RETSP_u6 : XCore::RETSP_lu6;
400  MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode))
401  .addImm(RemainingAdj);
402  for (unsigned i = 3, e = MBBI->getNumOperands(); i < e; ++i)
403  MIB->addOperand(MBBI->getOperand(i)); // copy any variadic operands
404  MBB.erase(MBBI); // Erase the previous return instruction.
405  } else {
406  int Opcode = isImmU6(RemainingAdj) ? XCore::LDAWSP_ru6 :
407  XCore::LDAWSP_lru6;
408  BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(RemainingAdj);
409  // Don't erase the return instruction.
410  }
411  } // else Don't erase the return instruction.
412 }
413 
417  const std::vector<CalleeSavedInfo> &CSI,
418  const TargetRegisterInfo *TRI) const {
419  if (CSI.empty())
420  return true;
421 
422  MachineFunction *MF = MBB.getParent();
423  const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
425  bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(*MF);
426 
427  DebugLoc DL;
428  if (MI != MBB.end() && !MI->isDebugInstr())
429  DL = MI->getDebugLoc();
430 
431  for (std::vector<CalleeSavedInfo>::const_iterator it = CSI.begin();
432  it != CSI.end(); ++it) {
433  unsigned Reg = it->getReg();
434  assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) &&
435  "LR & FP are always handled in emitPrologue");
436 
437  // Add the callee-saved register as live-in. It's killed at the spill.
438  MBB.addLiveIn(Reg);
439  const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
440  TII.storeRegToStackSlot(MBB, MI, Reg, true, it->getFrameIdx(), RC, TRI);
441  if (emitFrameMoves) {
442  auto Store = MI;
443  --Store;
444  XFI->getSpillLabels().push_back(std::make_pair(Store, *it));
445  }
446  }
447  return true;
448 }
449 
453  std::vector<CalleeSavedInfo> &CSI,
454  const TargetRegisterInfo *TRI) const{
455  MachineFunction *MF = MBB.getParent();
456  const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
457  bool AtStart = MI == MBB.begin();
459  if (!AtStart)
460  --BeforeI;
461  for (std::vector<CalleeSavedInfo>::const_iterator it = CSI.begin();
462  it != CSI.end(); ++it) {
463  unsigned Reg = it->getReg();
464  assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) &&
465  "LR & FP are always handled in emitEpilogue");
466 
467  const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
468  TII.loadRegFromStackSlot(MBB, MI, Reg, it->getFrameIdx(), RC, TRI);
469  assert(MI != MBB.begin() &&
470  "loadRegFromStackSlot didn't insert any code!");
471  // Insert in reverse order. loadRegFromStackSlot can insert multiple
472  // instructions.
473  if (AtStart)
474  MI = MBB.begin();
475  else {
476  MI = BeforeI;
477  ++MI;
478  }
479  }
480  return true;
481 }
482 
483 // This function eliminates ADJCALLSTACKDOWN,
484 // ADJCALLSTACKUP pseudo instructions
488  const XCoreInstrInfo &TII = *MF.getSubtarget<XCoreSubtarget>().getInstrInfo();
489  if (!hasReservedCallFrame(MF)) {
490  // Turn the adjcallstackdown instruction into 'extsp <amt>' and the
491  // adjcallstackup instruction into 'ldaw sp, sp[<amt>]'
492  MachineInstr &Old = *I;
493  uint64_t Amount = Old.getOperand(0).getImm();
494  if (Amount != 0) {
495  // We need to keep the stack aligned properly. To do this, we round the
496  // amount of space needed for the outgoing arguments up to the next
497  // alignment boundary.
498  unsigned Align = getStackAlignment();
499  Amount = (Amount+Align-1)/Align*Align;
500 
501  assert(Amount%4 == 0);
502  Amount /= 4;
503 
504  bool isU6 = isImmU6(Amount);
505  if (!isU6 && !isImmU16(Amount)) {
506  // FIX could emit multiple instructions in this case.
507 #ifndef NDEBUG
508  errs() << "eliminateCallFramePseudoInstr size too big: "
509  << Amount << "\n";
510 #endif
511  llvm_unreachable(nullptr);
512  }
513 
514  MachineInstr *New;
515  if (Old.getOpcode() == XCore::ADJCALLSTACKDOWN) {
516  int Opcode = isU6 ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
517  New = BuildMI(MF, Old.getDebugLoc(), TII.get(Opcode)).addImm(Amount);
518  } else {
519  assert(Old.getOpcode() == XCore::ADJCALLSTACKUP);
520  int Opcode = isU6 ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
521  New = BuildMI(MF, Old.getDebugLoc(), TII.get(Opcode), XCore::SP)
522  .addImm(Amount);
523  }
524 
525  // Replace the pseudo instruction with a new instruction...
526  MBB.insert(I, New);
527  }
528  }
529 
530  return MBB.erase(I);
531 }
532 
534  BitVector &SavedRegs,
535  RegScavenger *RS) const {
537 
539 
540  const MachineRegisterInfo &MRI = MF.getRegInfo();
541  bool LRUsed = MRI.isPhysRegModified(XCore::LR);
542 
543  if (!LRUsed && !MF.getFunction().isVarArg() &&
545  // If we need to extend the stack it is more efficient to use entsp / retsp.
546  // We force the LR to be saved so these instructions are used.
547  LRUsed = true;
548 
549  if (MF.callsUnwindInit() || MF.callsEHReturn()) {
550  // The unwinder expects to find spill slots for the exception info regs R0
551  // & R1. These are used during llvm.eh.return() to 'restore' the exception
552  // info. N.B. we do not spill or restore R0, R1 during normal operation.
553  XFI->createEHSpillSlot(MF);
554  // As we will have a stack, we force the LR to be saved.
555  LRUsed = true;
556  }
557 
558  if (LRUsed) {
559  // We will handle the LR in the prologue/epilogue
560  // and allocate space on the stack ourselves.
561  SavedRegs.reset(XCore::LR);
562  XFI->createLRSpillSlot(MF);
563  }
564 
565  if (hasFP(MF))
566  // A callee save register is used to hold the FP.
567  // This needs saving / restoring in the epilogue / prologue.
568  XFI->createFPSpillSlot(MF);
569 }
570 
573  RegScavenger *RS) const {
574  assert(RS && "requiresRegisterScavenging failed");
575  MachineFrameInfo &MFI = MF.getFrameInfo();
576  const TargetRegisterClass &RC = XCore::GRRegsRegClass;
579  // Reserve slots close to SP or frame pointer for Scavenging spills.
580  // When using SP for small frames, we don't need any scratch registers.
581  // When using SP for large frames, we may need 2 scratch registers.
582  // When using FP, for large or small frames, we may need 1 scratch register.
583  unsigned Size = TRI.getSpillSize(RC);
584  unsigned Align = TRI.getSpillAlignment(RC);
585  if (XFI->isLargeFrame(MF) || hasFP(MF))
586  RS->addScavengingFrameIndex(MFI.CreateStackObject(Size, Align, false));
587  if (XFI->isLargeFrame(MF) && !hasFP(MF))
588  RS->addScavengingFrameIndex(MFI.CreateStackObject(Size, Align, false));
589 }
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition: Function.h:176
int createLRSpillSlot(MachineFunction &MF)
static const int MaxImmU16
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
static bool isImmU16(unsigned val)
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
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:139
This class represents lattice values for constants.
Definition: AllocatorList.h:23
XCoreFrameLowering(const XCoreSubtarget &STI)
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
bool isPhysRegModified(unsigned PhysReg, bool SkipNoReturnDef=false) const
Return true if the specified register is modified in this function.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:382
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:504
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
static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset)
.cfi_def_cfa_offset modifies a rule for computing CFA.
Definition: MCDwarf.h:491
int CreateStackObject(uint64_t Size, unsigned 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...
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)
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...
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:41
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:408
int getDwarfRegNum(unsigned RegNum, bool isEH) const
Map a target register to an equivalent dwarf register number.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, unsigned 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.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
Definition: STLExtras.h:266
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...
static bool needsFrameMoves(const MachineFunction &MF)
Return whether to emit frame moves.
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...
const MCContext & getContext() const
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:223
bool hasPersonalityFn() const
Check whether this function has a personality function.
Definition: Function.h:707
virtual const TargetInstrInfo * getInstrInfo() const
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.
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.
unsigned getObjectAlignment(int ObjectIdx) const
Return the alignment of the specified stack object.
void addLiveIn(MCPhysReg PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
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
virtual unsigned getExceptionPointerRegister(const Constant *PersonalityFn) const
If a physical register, this returns the register that receives the exception address on entry to an ...
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:484
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)
This is an important base class in LLVM.
Definition: Constant.h:41
virtual unsigned getExceptionSelectorRegister(const Constant *PersonalityFn) const
If a physical register, this returns the register that receives the exception typeid on entry to a la...
BitVector & reset()
Definition: BitVector.h:438
unsigned getMaxAlignment() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
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)
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
size_t size() const
Definition: SmallVector.h:52
static void EmitDefCfaRegister(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &dl, const TargetInstrInfo &TII, MachineFunction &MF, unsigned DRegNum)
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
#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.
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1115
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...
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 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:841
unsigned estimateStackSize(const MachineFunction &MF) const
Estimate and return the size of the stack frame.
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)
const Function & getFunction() const
Return the LLVM function that this machine code represents.
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...
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...
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:63
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
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:44
TargetOptions Options
#define I(x, y, z)
Definition: MD5.cpp:58
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
const TargetRegisterClass * getMinimalPhysRegClass(unsigned Reg, MVT VT=MVT::Other) const
Returns the Register Class of a physical register of the given type, picking the most sub register cl...
OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) - This node represents &#39;eh_return&#39; gcc dwarf builtin...
Definition: ISDOpcodes.h:101
bool isLargeFrame(const MachineFunction &MF) const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const MCRegisterInfo * getRegisterInfo() const
Definition: MCContext.h:294
Constant * getPersonalityFn() const
Get the personality function associated with this function.
Definition: Function.cpp:1306
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
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.
bool addRegisterKilled(unsigned IncomingReg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
We have determined MI kills a register.
IRTranslator LLVM IR MI
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:413
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...
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...
This class contains meta information specific to a module.
This file describes how to lower LLVM code to machine code.