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 #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 
82  MachineBasicBlock::iterator MBBI, const DebugLoc &dl,
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.
99  MachineBasicBlock::iterator MBBI, const DebugLoc &dl,
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.
122  MachineBasicBlock::iterator MBBI, const DebugLoc &dl,
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.getObjectAlignment(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, 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 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  unsigned EhStackReg = MBBI->getOperand(0).getReg();
371  unsigned 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  const std::vector<CalleeSavedInfo> &CSI,
419  const TargetRegisterInfo *TRI) const {
420  if (CSI.empty())
421  return true;
422 
423  MachineFunction *MF = MBB.getParent();
424  const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
426  bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(*MF);
427 
428  DebugLoc DL;
429  if (MI != MBB.end() && !MI->isDebugInstr())
430  DL = MI->getDebugLoc();
431 
432  for (std::vector<CalleeSavedInfo>::const_iterator it = CSI.begin();
433  it != CSI.end(); ++it) {
434  unsigned Reg = it->getReg();
435  assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) &&
436  "LR & FP are always handled in emitPrologue");
437 
438  // Add the callee-saved register as live-in. It's killed at the spill.
439  MBB.addLiveIn(Reg);
440  const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
441  TII.storeRegToStackSlot(MBB, MI, Reg, true, it->getFrameIdx(), RC, TRI);
442  if (emitFrameMoves) {
443  auto Store = MI;
444  --Store;
445  XFI->getSpillLabels().push_back(std::make_pair(Store, *it));
446  }
447  }
448  return true;
449 }
450 
454  std::vector<CalleeSavedInfo> &CSI,
455  const TargetRegisterInfo *TRI) const{
456  MachineFunction *MF = MBB.getParent();
457  const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
458  bool AtStart = MI == MBB.begin();
460  if (!AtStart)
461  --BeforeI;
462  for (std::vector<CalleeSavedInfo>::const_iterator it = CSI.begin();
463  it != CSI.end(); ++it) {
464  unsigned Reg = it->getReg();
465  assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) &&
466  "LR & FP are always handled in emitEpilogue");
467 
468  const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
469  TII.loadRegFromStackSlot(MBB, MI, Reg, it->getFrameIdx(), RC, TRI);
470  assert(MI != MBB.begin() &&
471  "loadRegFromStackSlot didn't insert any code!");
472  // Insert in reverse order. loadRegFromStackSlot can insert multiple
473  // instructions.
474  if (AtStart)
475  MI = MBB.begin();
476  else {
477  MI = BeforeI;
478  ++MI;
479  }
480  }
481  return true;
482 }
483 
484 // This function eliminates ADJCALLSTACKDOWN,
485 // ADJCALLSTACKUP pseudo instructions
489  const XCoreInstrInfo &TII = *MF.getSubtarget<XCoreSubtarget>().getInstrInfo();
490  if (!hasReservedCallFrame(MF)) {
491  // Turn the adjcallstackdown instruction into 'extsp <amt>' and the
492  // adjcallstackup instruction into 'ldaw sp, sp[<amt>]'
493  MachineInstr &Old = *I;
494  uint64_t Amount = Old.getOperand(0).getImm();
495  if (Amount != 0) {
496  // We need to keep the stack aligned properly. To do this, we round the
497  // amount of space needed for the outgoing arguments up to the next
498  // alignment boundary.
499  unsigned Align = getStackAlignment();
500  Amount = (Amount+Align-1)/Align*Align;
501 
502  assert(Amount%4 == 0);
503  Amount /= 4;
504 
505  bool isU6 = isImmU6(Amount);
506  if (!isU6 && !isImmU16(Amount)) {
507  // FIX could emit multiple instructions in this case.
508 #ifndef NDEBUG
509  errs() << "eliminateCallFramePseudoInstr size too big: "
510  << Amount << "\n";
511 #endif
512  llvm_unreachable(nullptr);
513  }
514 
515  MachineInstr *New;
516  if (Old.getOpcode() == XCore::ADJCALLSTACKDOWN) {
517  int Opcode = isU6 ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
518  New = BuildMI(MF, Old.getDebugLoc(), TII.get(Opcode)).addImm(Amount);
519  } else {
520  assert(Old.getOpcode() == XCore::ADJCALLSTACKUP);
521  int Opcode = isU6 ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
522  New = BuildMI(MF, Old.getDebugLoc(), TII.get(Opcode), XCore::SP)
523  .addImm(Amount);
524  }
525 
526  // Replace the pseudo instruction with a new instruction...
527  MBB.insert(I, New);
528  }
529  }
530 
531  return MBB.erase(I);
532 }
533 
535  BitVector &SavedRegs,
536  RegScavenger *RS) const {
538 
540 
541  const MachineRegisterInfo &MRI = MF.getRegInfo();
542  bool LRUsed = MRI.isPhysRegModified(XCore::LR);
543 
544  if (!LRUsed && !MF.getFunction().isVarArg() &&
546  // If we need to extend the stack it is more efficient to use entsp / retsp.
547  // We force the LR to be saved so these instructions are used.
548  LRUsed = true;
549 
550  if (MF.callsUnwindInit() || MF.callsEHReturn()) {
551  // The unwinder expects to find spill slots for the exception info regs R0
552  // & R1. These are used during llvm.eh.return() to 'restore' the exception
553  // info. N.B. we do not spill or restore R0, R1 during normal operation.
554  XFI->createEHSpillSlot(MF);
555  // As we will have a stack, we force the LR to be saved.
556  LRUsed = true;
557  }
558 
559  if (LRUsed) {
560  // We will handle the LR in the prologue/epilogue
561  // and allocate space on the stack ourselves.
562  SavedRegs.reset(XCore::LR);
563  XFI->createLRSpillSlot(MF);
564  }
565 
566  if (hasFP(MF))
567  // A callee save register is used to hold the FP.
568  // This needs saving / restoring in the epilogue / prologue.
569  XFI->createFPSpillSlot(MF);
570 }
571 
574  RegScavenger *RS) const {
575  assert(RS && "requiresRegisterScavenging failed");
576  MachineFrameInfo &MFI = MF.getFrameInfo();
577  const TargetRegisterClass &RC = XCore::GRRegsRegClass;
580  // Reserve slots close to SP or frame pointer for Scavenging spills.
581  // When using SP for small frames, we don't need any scratch registers.
582  // When using SP for large frames, we may need 2 scratch registers.
583  // When using FP, for large or small frames, we may need 1 scratch register.
584  unsigned Size = TRI.getSpillSize(RC);
585  unsigned Align = TRI.getSpillAlignment(RC);
586  if (XFI->isLargeFrame(MF) || hasFP(MF))
587  RS->addScavengingFrameIndex(MFI.CreateStackObject(Size, Align, false));
588  if (XFI->isLargeFrame(MF) && !hasFP(MF))
589  RS->addScavengingFrameIndex(MFI.CreateStackObject(Size, Align, false));
590 }
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:704
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:1302
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.