LLVM 24.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 "XCoreInstrInfo.h"
17#include "XCoreSubtarget.h"
25#include "llvm/IR/Function.h"
27#include <algorithm>
28
29using namespace llvm;
30
31static const unsigned FramePtr = XCore::R10;
32static const int MaxImmU16 = (1<<16) - 1;
33
34// helper functions. FIXME: Eliminate.
35static inline bool isImmU6(unsigned val) {
36 return val < (1 << 6);
37}
38
39static inline bool isImmU16(unsigned val) {
40 return val < (1 << 16);
41}
42
43// Helper structure with compare function for handling stack slots.
44namespace {
45struct StackSlotInfo {
46 int FI;
47 int Offset;
48 unsigned Reg;
49 StackSlotInfo(int f, int o, int r) : FI(f), Offset(o), Reg(r){};
50};
51} // end anonymous namespace
52
53static bool CompareSSIOffset(const StackSlotInfo& a, const StackSlotInfo& b) {
54 return a.Offset < b.Offset;
55}
56
59 const DebugLoc &dl, const TargetInstrInfo &TII,
60 MachineFunction &MF, unsigned DRegNum) {
61 unsigned CFIIndex = MF.addFrameInst(
63 BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
64 .addCFIIndex(CFIIndex);
65}
66
69 const DebugLoc &dl, const TargetInstrInfo &TII,
70 int Offset) {
71 MachineFunction &MF = *MBB.getParent();
72 unsigned CFIIndex =
74 BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
75 .addCFIIndex(CFIIndex);
76}
77
80 const TargetInstrInfo &TII, unsigned DRegNum,
81 int Offset) {
82 MachineFunction &MF = *MBB.getParent();
83 unsigned CFIIndex = MF.addFrameInst(
84 MCCFIInstruction::createOffset(nullptr, DRegNum, Offset));
85 BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
86 .addCFIIndex(CFIIndex);
87}
88
89/// The SP register is moved in steps of 'MaxImmU16' towards the bottom of the
90/// frame. During these steps, it may be necessary to spill registers.
91/// IfNeededExtSP emits the necessary EXTSP instructions to move the SP only
92/// as far as to make 'OffsetFromBottom' reachable using an STWSP_lru6.
93/// \param OffsetFromTop the spill offset from the top of the frame.
94/// \param [in,out] Adjusted the current SP offset from the top of the frame.
97 const TargetInstrInfo &TII, int OffsetFromTop,
98 int &Adjusted, int FrameSize, bool emitFrameMoves) {
99 while (OffsetFromTop > Adjusted) {
100 assert(Adjusted < FrameSize && "OffsetFromTop is beyond FrameSize");
101 int remaining = FrameSize - Adjusted;
102 int OpImm = (remaining > MaxImmU16) ? MaxImmU16 : remaining;
103 int Opcode = isImmU6(OpImm) ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
104 BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(OpImm);
105 Adjusted += OpImm;
106 if (emitFrameMoves)
107 EmitDefCfaOffset(MBB, MBBI, dl, TII, Adjusted*4);
108 }
109}
110
111/// The SP register is moved in steps of 'MaxImmU16' towards the top of the
112/// frame. During these steps, it may be necessary to re-load registers.
113/// IfNeededLDAWSP emits the necessary LDAWSP instructions to move the SP only
114/// as far as to make 'OffsetFromTop' reachable using an LDAWSP_lru6.
115/// \param OffsetFromTop the spill offset from the top of the frame.
116/// \param [in,out] RemainingAdj the current SP offset from the top of the
117/// frame.
120 const TargetInstrInfo &TII, int OffsetFromTop,
121 int &RemainingAdj) {
122 while (OffsetFromTop < RemainingAdj - MaxImmU16) {
123 assert(RemainingAdj && "OffsetFromTop is beyond FrameSize");
124 int OpImm = (RemainingAdj > MaxImmU16) ? MaxImmU16 : RemainingAdj;
125 int Opcode = isImmU6(OpImm) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
126 BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(OpImm);
127 RemainingAdj -= OpImm;
128 }
129}
130
131/// Creates an ordered list of registers that are spilled
132/// during the emitPrologue/emitEpilogue.
133/// Registers are ordered according to their frame offset.
134/// As offsets are negative, the largest offsets will be first.
137 bool fetchLR, bool fetchFP) {
138 if (fetchLR) {
139 int Offset = MFI.getObjectOffset(XFI->getLRSpillSlot());
140 SpillList.push_back(StackSlotInfo(XFI->getLRSpillSlot(),
141 Offset,
142 XCore::LR));
143 }
144 if (fetchFP) {
145 int Offset = MFI.getObjectOffset(XFI->getFPSpillSlot());
146 SpillList.push_back(StackSlotInfo(XFI->getFPSpillSlot(),
147 Offset,
148 FramePtr));
149 }
150 llvm::sort(SpillList, CompareSSIOffset);
151}
152
153/// Creates an ordered list of EH info register 'spills'.
154/// These slots are only used by the unwinder and calls to llvm.eh.return().
155/// Registers are ordered according to their frame offset.
156/// As offsets are negative, the largest offsets will be first.
159 const Constant *PersonalityFn,
160 const TargetLowering *TL) {
161 assert(XFI->hasEHSpillSlot() && "There are no EH register spill slots");
162 const int *EHSlot = XFI->getEHSpillSlot();
164 SpillList.push_back(
165 StackSlotInfo(EHSlot[0], MFI.getObjectOffset(EHSlot[0]),
166 TL->getExceptionPointerRegister(EH, PersonalityFn)));
167 SpillList.push_back(
168 StackSlotInfo(EHSlot[0], MFI.getObjectOffset(EHSlot[1]),
169 TL->getExceptionSelectorRegister(EH, PersonalityFn)));
170 llvm::sort(SpillList, CompareSSIOffset);
171}
172
174 int FrameIndex,
176 MachineFunction *MF = MBB.getParent();
177 const MachineFrameInfo &MFI = MF->getFrameInfo();
179 MachinePointerInfo::getFixedStack(*MF, FrameIndex), flags,
180 MFI.getObjectSize(FrameIndex), MFI.getObjectAlign(FrameIndex));
181 return MMO;
182}
183
184
185/// Restore clobbered registers with their spill slot value.
186/// The SP will be adjusted at the same time, thus the SpillList must be ordered
187/// with the largest (negative) offsets first.
190 const DebugLoc &dl, const TargetInstrInfo &TII,
191 int &RemainingAdj,
193 for (unsigned i = 0, e = SpillList.size(); i != e; ++i) {
194 assert(SpillList[i].Offset % 4 == 0 && "Misaligned stack offset");
195 assert(SpillList[i].Offset <= 0 && "Unexpected positive stack offset");
196 int OffsetFromTop = - SpillList[i].Offset/4;
197 IfNeededLDAWSP(MBB, MBBI, dl, TII, OffsetFromTop, RemainingAdj);
198 int Offset = RemainingAdj - OffsetFromTop;
199 int Opcode = isImmU6(Offset) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6;
200 BuildMI(MBB, MBBI, dl, TII.get(Opcode), SpillList[i].Reg)
201 .addImm(Offset)
202 .addMemOperand(getFrameIndexMMO(MBB, SpillList[i].FI,
204 }
205}
206
207//===----------------------------------------------------------------------===//
208// XCoreFrameLowering:
209//===----------------------------------------------------------------------===//
210
215
219
221 MachineBasicBlock &MBB) const {
222 assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
224 MachineFrameInfo &MFI = MF.getFrameInfo();
225 const MCRegisterInfo *MRI = MF.getContext().getRegisterInfo();
226 const XCoreInstrInfo &TII = *MF.getSubtarget<XCoreSubtarget>().getInstrInfo();
228 // Debug location must be unknown since the first debug location is used
229 // to determine the end of the prologue.
230 DebugLoc dl;
231
232 if (MFI.getMaxAlign() > getStackAlign())
233 report_fatal_error("emitPrologue unsupported alignment: " +
234 Twine(MFI.getMaxAlign().value()));
235
236 const AttributeList &PAL = MF.getFunction().getAttributes();
237 if (PAL.hasAttrSomewhere(Attribute::Nest))
238 BuildMI(MBB, MBBI, dl, TII.get(XCore::LDWSP_ru6), XCore::R11).addImm(0);
239 // FIX: Needs addMemOperand() but can't use getFixedStack() or getStack().
240
241 // Work out frame sizes.
242 // We will adjust the SP in stages towards the final FrameSize.
243 assert(MFI.getStackSize()%4 == 0 && "Misaligned frame size");
244 const int FrameSize = MFI.getStackSize() / 4;
245 int Adjusted = 0;
246
247 bool saveLR = XFI->hasLRSpillSlot();
248 bool UseENTSP = saveLR && FrameSize
249 && (MFI.getObjectOffset(XFI->getLRSpillSlot()) == 0);
250 if (UseENTSP)
251 saveLR = false;
252 bool FP = hasFP(MF);
253 bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(MF);
254
255 if (UseENTSP) {
256 // Allocate space on the stack at the same time as saving LR.
257 Adjusted = (FrameSize > MaxImmU16) ? MaxImmU16 : FrameSize;
258 int Opcode = isImmU6(Adjusted) ? XCore::ENTSP_u6 : XCore::ENTSP_lu6;
259 MBB.addLiveIn(XCore::LR);
260 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode));
261 MIB.addImm(Adjusted);
262 MIB->addRegisterKilled(XCore::LR, MF.getSubtarget().getRegisterInfo(),
263 true);
264 if (emitFrameMoves) {
265 EmitDefCfaOffset(MBB, MBBI, dl, TII, Adjusted*4);
266 unsigned DRegNum = MRI->getDwarfRegNum(XCore::LR, true);
267 EmitCfiOffset(MBB, MBBI, dl, TII, DRegNum, 0);
268 }
269 }
270
271 // If necessary, save LR and FP to the stack, as we EXTSP.
273 GetSpillList(SpillList, MFI, XFI, saveLR, FP);
274 // We want the nearest (negative) offsets first, so reverse list.
275 std::reverse(SpillList.begin(), SpillList.end());
276 for (unsigned i = 0, e = SpillList.size(); i != e; ++i) {
277 assert(SpillList[i].Offset % 4 == 0 && "Misaligned stack offset");
278 assert(SpillList[i].Offset <= 0 && "Unexpected positive stack offset");
279 int OffsetFromTop = - SpillList[i].Offset/4;
280 IfNeededExtSP(MBB, MBBI, dl, TII, OffsetFromTop, Adjusted, FrameSize,
281 emitFrameMoves);
282 int Offset = Adjusted - OffsetFromTop;
283 int Opcode = isImmU6(Offset) ? XCore::STWSP_ru6 : XCore::STWSP_lru6;
284 MBB.addLiveIn(SpillList[i].Reg);
285 BuildMI(MBB, MBBI, dl, TII.get(Opcode))
286 .addReg(SpillList[i].Reg, RegState::Kill)
287 .addImm(Offset)
288 .addMemOperand(getFrameIndexMMO(MBB, SpillList[i].FI,
290 if (emitFrameMoves) {
291 unsigned DRegNum = MRI->getDwarfRegNum(SpillList[i].Reg, true);
292 EmitCfiOffset(MBB, MBBI, dl, TII, DRegNum, SpillList[i].Offset);
293 }
294 }
295
296 // Complete any remaining Stack adjustment.
297 IfNeededExtSP(MBB, MBBI, dl, TII, FrameSize, Adjusted, FrameSize,
298 emitFrameMoves);
299 assert(Adjusted==FrameSize && "IfNeededExtSP has not completed adjustment");
300
301 if (FP) {
302 // Set the FP from the SP.
303 BuildMI(MBB, MBBI, dl, TII.get(XCore::LDAWSP_ru6), FramePtr).addImm(0);
304 if (emitFrameMoves)
305 EmitDefCfaRegister(MBB, MBBI, dl, TII, MF,
306 MRI->getDwarfRegNum(FramePtr, true));
307 }
308
309 if (emitFrameMoves) {
310 // Frame moves for callee saved.
311 for (const auto &SpillLabel : XFI->getSpillLabels()) {
312 MachineBasicBlock::iterator Pos = SpillLabel.first;
313 ++Pos;
314 const CalleeSavedInfo &CSI = SpillLabel.second;
315 int Offset = MFI.getObjectOffset(CSI.getFrameIdx());
316 unsigned DRegNum = MRI->getDwarfRegNum(CSI.getReg(), true);
317 EmitCfiOffset(MBB, Pos, dl, TII, DRegNum, Offset);
318 }
319 if (XFI->hasEHSpillSlot()) {
320 // The unwinder requires stack slot & CFI offsets for the exception info.
321 // We do not save/spill these registers.
322 const Function *Fn = &MF.getFunction();
323 const Constant *PersonalityFn =
324 Fn->hasPersonalityFn() ? Fn->getPersonalityFn() : nullptr;
326 GetEHSpillList(SpillList, MFI, XFI, PersonalityFn,
328 assert(SpillList.size()==2 && "Unexpected SpillList size");
330 MRI->getDwarfRegNum(SpillList[0].Reg, true),
331 SpillList[0].Offset);
333 MRI->getDwarfRegNum(SpillList[1].Reg, true),
334 SpillList[1].Offset);
335 }
336 }
337}
338
340 MachineBasicBlock &MBB) const {
341 MachineFrameInfo &MFI = MF.getFrameInfo();
342 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
343 const XCoreInstrInfo &TII = *MF.getSubtarget<XCoreSubtarget>().getInstrInfo();
345 DebugLoc dl = MBBI->getDebugLoc();
346 unsigned RetOpcode = MBBI->getOpcode();
347
348 // Work out frame sizes.
349 // We will adjust the SP in stages towards the final FrameSize.
350 int RemainingAdj = MFI.getStackSize();
351 assert(RemainingAdj%4 == 0 && "Misaligned frame size");
352 RemainingAdj /= 4;
353
354 if (RetOpcode == XCore::EH_RETURN) {
355 // 'Restore' the exception info the unwinder has placed into the stack
356 // slots.
357 const Function *Fn = &MF.getFunction();
358 const Constant *PersonalityFn =
359 Fn->hasPersonalityFn() ? Fn->getPersonalityFn() : nullptr;
361 GetEHSpillList(SpillList, MFI, XFI, PersonalityFn,
363 RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList);
364
365 // Return to the landing pad.
366 Register EhStackReg = MBBI->getOperand(0).getReg();
367 Register EhHandlerReg = MBBI->getOperand(1).getReg();
368 BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(EhStackReg);
369 BuildMI(MBB, MBBI, dl, TII.get(XCore::BAU_1r)).addReg(EhHandlerReg);
370 MBB.erase(MBBI); // Erase the previous return instruction.
371 return;
372 }
373
374 bool restoreLR = XFI->hasLRSpillSlot();
375 bool UseRETSP = restoreLR && RemainingAdj
376 && (MFI.getObjectOffset(XFI->getLRSpillSlot()) == 0);
377 if (UseRETSP)
378 restoreLR = false;
379 bool FP = hasFP(MF);
380
381 if (FP) // Restore the stack pointer.
382 BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(FramePtr);
383
384 // If necessary, restore LR and FP from the stack, as we EXTSP.
386 GetSpillList(SpillList, MFI, XFI, restoreLR, FP);
387 RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList);
388
389 if (RemainingAdj) {
390 // Complete all but one of the remaining Stack adjustments.
391 IfNeededLDAWSP(MBB, MBBI, dl, TII, 0, RemainingAdj);
392 if (UseRETSP) {
393 // Fold prologue into return instruction
394 assert(RetOpcode == XCore::RETSP_u6
395 || RetOpcode == XCore::RETSP_lu6);
396 int Opcode = isImmU6(RemainingAdj) ? XCore::RETSP_u6 : XCore::RETSP_lu6;
397 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode))
398 .addImm(RemainingAdj);
399 for (unsigned i = 3, e = MBBI->getNumOperands(); i < e; ++i)
400 MIB->addOperand(MBBI->getOperand(i)); // copy any variadic operands
401 MBB.erase(MBBI); // Erase the previous return instruction.
402 } else {
403 int Opcode = isImmU6(RemainingAdj) ? XCore::LDAWSP_ru6 :
404 XCore::LDAWSP_lru6;
405 BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(RemainingAdj);
406 // Don't erase the return instruction.
407 }
408 } // else Don't erase the return instruction.
409}
410
414 if (CSI.empty())
415 return true;
416
417 MachineFunction *MF = MBB.getParent();
420 bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(*MF);
421
422 DebugLoc DL;
423 if (MI != MBB.end() && !MI->isDebugInstr())
424 DL = MI->getDebugLoc();
425
426 for (const CalleeSavedInfo &I : CSI) {
427 MCRegister Reg = I.getReg();
428 assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) &&
429 "LR & FP are always handled in emitPrologue");
430
431 // Add the callee-saved register as live-in. It's killed at the spill.
432 MBB.addLiveIn(Reg);
433 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
434 TII.storeRegToStackSlot(MBB, MI, Reg, true, I.getFrameIdx(), RC,
435 Register());
436 if (emitFrameMoves) {
437 auto Store = MI;
438 --Store;
439 XFI->getSpillLabels().push_back(std::make_pair(Store, I));
440 }
441 }
442 return true;
443}
444
448 MachineFunction *MF = MBB.getParent();
450 bool AtStart = MI == MBB.begin();
452 if (!AtStart)
453 --BeforeI;
454 for (const CalleeSavedInfo &CSR : CSI) {
455 MCRegister Reg = CSR.getReg();
456 assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) &&
457 "LR & FP are always handled in emitEpilogue");
458
459 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
460 TII.loadRegFromStackSlot(MBB, MI, Reg, CSR.getFrameIdx(), RC, Register());
461 assert(MI != MBB.begin() &&
462 "loadRegFromStackSlot didn't insert any code!");
463 // Insert in reverse order. loadRegFromStackSlot can insert multiple
464 // instructions.
465 if (AtStart)
466 MI = MBB.begin();
467 else {
468 MI = BeforeI;
469 ++MI;
470 }
471 }
472 return true;
473}
474
475// This function eliminates ADJCALLSTACKDOWN,
476// ADJCALLSTACKUP pseudo instructions
480 const XCoreInstrInfo &TII = *MF.getSubtarget<XCoreSubtarget>().getInstrInfo();
481 if (!hasReservedCallFrame(MF)) {
482 // Turn the adjcallstackdown instruction into 'extsp <amt>' and the
483 // adjcallstackup instruction into 'ldaw sp, sp[<amt>]'
484 MachineInstr &Old = *I;
485 uint64_t Amount = Old.getOperand(0).getImm();
486 if (Amount != 0) {
487 // We need to keep the stack aligned properly. To do this, we round the
488 // amount of space needed for the outgoing arguments up to the next
489 // alignment boundary.
490 Amount = alignTo(Amount, getStackAlign());
491
492 assert(Amount%4 == 0);
493 Amount /= 4;
494
495 bool isU6 = isImmU6(Amount);
496 if (!isU6 && !isImmU16(Amount)) {
497 // FIX could emit multiple instructions in this case.
498#ifndef NDEBUG
499 errs() << "eliminateCallFramePseudoInstr size too big: "
500 << Amount << "\n";
501#endif
502 llvm_unreachable(nullptr);
503 }
504
505 MachineInstr *New;
506 if (Old.getOpcode() == XCore::ADJCALLSTACKDOWN) {
507 int Opcode = isU6 ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
508 New = BuildMI(MF, Old.getDebugLoc(), TII.get(Opcode)).addImm(Amount);
509 } else {
510 assert(Old.getOpcode() == XCore::ADJCALLSTACKUP);
511 int Opcode = isU6 ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
512 New = BuildMI(MF, Old.getDebugLoc(), TII.get(Opcode), XCore::SP)
513 .addImm(Amount);
514 }
515
516 // Replace the pseudo instruction with a new instruction...
517 MBB.insert(I, New);
518 }
519 }
520
521 return MBB.erase(I);
522}
523
525 BitVector &SavedRegs,
526 RegScavenger *RS) const {
528
530
531 const MachineRegisterInfo &MRI = MF.getRegInfo();
532 bool LRUsed = MRI.isPhysRegModified(XCore::LR);
533
534 if (!LRUsed && !MF.getFunction().isVarArg() &&
536 // If we need to extend the stack it is more efficient to use entsp / retsp.
537 // We force the LR to be saved so these instructions are used.
538 LRUsed = true;
539
540 if (MF.callsUnwindInit() || MF.callsEHReturn()) {
541 // The unwinder expects to find spill slots for the exception info regs R0
542 // & R1. These are used during llvm.eh.return() to 'restore' the exception
543 // info. N.B. we do not spill or restore R0, R1 during normal operation.
544 XFI->createEHSpillSlot(MF);
545 // As we will have a stack, we force the LR to be saved.
546 LRUsed = true;
547 }
548
549 if (LRUsed) {
550 // We will handle the LR in the prologue/epilogue
551 // and allocate space on the stack ourselves.
552 SavedRegs.reset(XCore::LR);
553 XFI->createLRSpillSlot(MF);
554 }
555
556 if (hasFP(MF))
557 // A callee save register is used to hold the FP.
558 // This needs saving / restoring in the epilogue / prologue.
559 XFI->createFPSpillSlot(MF);
560}
561
564 RegScavenger *RS) const {
565 assert(RS && "requiresRegisterScavenging failed");
566 MachineFrameInfo &MFI = MF.getFrameInfo();
567 const TargetRegisterClass &RC = XCore::GRRegsRegClass;
570 // Reserve slots close to SP or frame pointer for Scavenging spills.
571 // When using SP for small frames, we don't need any scratch registers.
572 // When using SP for large frames, we may need 2 scratch registers.
573 // When using FP, for large or small frames, we may need 1 scratch register.
574 unsigned Size = TRI.getSpillSize(RC);
575 Align Alignment = TRI.getSpillAlign(RC);
576 if (XFI->isLargeFrame(MF) || hasFP(MF))
577 RS->addScavengingFrameIndex(MFI.CreateSpillStackObject(Size, Alignment));
578 if (XFI->isLargeFrame(MF) && !hasFP(MF))
579 RS->addScavengingFrameIndex(MFI.CreateSpillStackObject(Size, Alignment));
580}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:57
Register const TargetRegisterInfo * TRI
This file declares the machine register scavenger class.
This file describes how to lower LLVM code to machine code.
static MachineMemOperand * getFrameIndexMMO(MachineBasicBlock &MBB, int FrameIndex, MachineMemOperand::Flags flags)
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 'MaxImmU16' towards the bottom of the frame.
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.
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.
static bool isImmU16(unsigned val)
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 'MaxImmU16' towards the top of the frame.
static const unsigned FramePtr
static void EmitCfiOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &dl, const TargetInstrInfo &TII, unsigned DRegNum, int Offset)
static void EmitDefCfaOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &dl, const TargetInstrInfo &TII, int Offset)
static bool CompareSSIOffset(const StackSlotInfo &a, const StackSlotInfo &b)
static const int MaxImmU16
static bool isImmU6(unsigned val)
static void EmitDefCfaRegister(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &dl, const TargetInstrInfo &TII, MachineFunction &MF, unsigned DRegNum)
static void GetEHSpillList(SmallVectorImpl< StackSlotInfo > &SpillList, MachineFrameInfo &MFI, XCoreFunctionInfo *XFI, const Constant *PersonalityFn, const TargetLowering *TL)
Creates an ordered list of EH info register 'spills'.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
BitVector & reset()
Reset all bits in the bitvector.
Definition BitVector.h:409
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
MCRegister getReg() const
This is an important base class in LLVM.
Definition Constant.h:43
A debug info location.
Definition DebugLoc.h:126
bool hasPersonalityFn() const
Check whether this function has a personality function.
Definition Function.h:890
Constant * getPersonalityFn() const
Get the personality function associated with this function.
AttributeList getAttributes() const
Return the attribute list for this Function.
Definition Function.h:329
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition Function.h:230
static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register, SMLoc Loc={})
.cfi_def_cfa_register modifies a rule for computing CFA.
Definition MCDwarf.h:635
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
Definition MCDwarf.h:670
static MCCFIInstruction cfiDefCfaOffset(MCSymbol *L, int64_t Offset, SMLoc Loc={})
.cfi_def_cfa_offset modifies a rule for computing CFA.
Definition MCDwarf.h:643
const MCRegisterInfo * getRegisterInfo() const
Definition MCContext.h:411
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
virtual int64_t getDwarfRegNum(MCRegister Reg, bool isEH) const
Map a target register to an equivalent dwarf register number.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
MachineInstrBundleIterator< MachineInstr > iterator
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 ...
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
Align getMaxAlign() const
Return alignment of this function's frame.
LLVM_ABI uint64_t estimateStackSize(const MachineFunction &MF) const
Estimate and return the size of the stack frame.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
LLVM_ABI int CreateSpillStackObject(uint64_t Size, Align Alignment, TargetStackID::Value StackID=TargetStackID::Default)
Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
unsigned addFrameInst(const MCCFIInstruction &Inst)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MCContext & getContext() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
LLVM_ABI bool disableFramePointerElim() const
Returns true if frame pointer elimination should be disabled for this function.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineBasicBlock & front() const
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
const MachineInstrBuilder & addCFIIndex(unsigned CFIIndex) const
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
LLVM_ABI void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
LLVM_ABI bool addRegisterKilled(Register IncomingReg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
We have determined MI kills a register.
const MachineOperand & getOperand(unsigned i) const
A description of a memory reference used in the backend.
Flags
Flags values. These may be or'd together.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
int64_t getImm() const
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI bool isPhysRegModified(MCRegister PhysReg, bool SkipNoReturnDef=false) const
Return true if the specified register is modified in this function.
Represent a mutable reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:294
Wrapper class representing virtual and physical registers.
Definition Register.h:20
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
virtual bool hasReservedCallFrame(const MachineFunction &MF) const
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
TargetFrameLowering(StackDirection D, Align StackAl, int LAO, Align TransAl=Align(1), bool StackReal=true)
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
TargetInstrInfo - Interface to description of machine instruction set.
const TargetMachine & getTargetMachine() const
virtual Register getExceptionSelectorRegister(ExceptionHandling EH, const Constant *PersonalityFn) const
If a physical register, this returns the register that receives the exception typeid on entry to a la...
virtual Register getExceptionPointerRegister(ExceptionHandling EH, const Constant *PersonalityFn) const
If a physical register, this returns the register that receives the exception address on entry to an ...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
ExceptionHandling getExceptionModel() const
Return the ExceptionHandling to use, considering TargetOptions and the Triple's default.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
virtual const TargetLowering * getTargetLowering() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
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...
XCoreFrameLowering(const XCoreSubtarget &STI)
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
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...
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
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...
void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS=nullptr) const override
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
bool hasFPImpl(const MachineFunction &MF) const override
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
XCoreFunctionInfo - This class is derived from MachineFunction private XCore target-specific informat...
const int * createEHSpillSlot(MachineFunction &MF)
bool isLargeFrame(const MachineFunction &MF) const
int createLRSpillSlot(MachineFunction &MF)
int createFPSpillSlot(MachineFunction &MF)
std::vector< std::pair< MachineBasicBlock::iterator, CalleeSavedInfo > > & getSpillLabels()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
@ Kill
The last use of a register.
@ Store
The extracted value is stored (ExtractElement only).
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1636
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
ExceptionHandling
Definition CodeGen.h:54
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:77
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
static bool needsFrameMoves(const MachineFunction &MF)
Return whether to emit frame moves.