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"
28#include <algorithm>
29
30using namespace llvm;
31
32static const unsigned FramePtr = XCore::R10;
33static const int MaxImmU16 = (1<<16) - 1;
34
35// helper functions. FIXME: Eliminate.
36static inline bool isImmU6(unsigned val) {
37 return val < (1 << 6);
38}
39
40static inline bool isImmU16(unsigned val) {
41 return val < (1 << 16);
42}
43
44// Helper structure with compare function for handling stack slots.
45namespace {
46struct StackSlotInfo {
47 int FI;
48 int Offset;
49 unsigned Reg;
50 StackSlotInfo(int f, int o, int r) : FI(f), Offset(o), Reg(r){};
51};
52} // end anonymous namespace
53
54static bool CompareSSIOffset(const StackSlotInfo& a, const StackSlotInfo& b) {
55 return a.Offset < b.Offset;
56}
57
60 const DebugLoc &dl, const TargetInstrInfo &TII,
61 MachineFunction &MF, unsigned DRegNum) {
62 unsigned CFIIndex = MF.addFrameInst(
64 BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
65 .addCFIIndex(CFIIndex);
66}
67
70 const DebugLoc &dl, const TargetInstrInfo &TII,
71 int Offset) {
72 MachineFunction &MF = *MBB.getParent();
73 unsigned CFIIndex =
75 BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
76 .addCFIIndex(CFIIndex);
77}
78
81 const TargetInstrInfo &TII, unsigned DRegNum,
82 int Offset) {
83 MachineFunction &MF = *MBB.getParent();
84 unsigned CFIIndex = MF.addFrameInst(
85 MCCFIInstruction::createOffset(nullptr, DRegNum, Offset));
86 BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
87 .addCFIIndex(CFIIndex);
88}
89
90/// The SP register is moved in steps of 'MaxImmU16' towards the bottom of the
91/// frame. During these steps, it may be necessary to spill registers.
92/// IfNeededExtSP emits the necessary EXTSP instructions to move the SP only
93/// as far as to make 'OffsetFromBottom' reachable using an STWSP_lru6.
94/// \param OffsetFromTop the spill offset from the top of the frame.
95/// \param [in,out] Adjusted the current SP offset from the top of the frame.
98 const TargetInstrInfo &TII, int OffsetFromTop,
99 int &Adjusted, int FrameSize, bool emitFrameMoves) {
100 while (OffsetFromTop > Adjusted) {
101 assert(Adjusted < FrameSize && "OffsetFromTop is beyond FrameSize");
102 int remaining = FrameSize - Adjusted;
103 int OpImm = (remaining > MaxImmU16) ? MaxImmU16 : remaining;
104 int Opcode = isImmU6(OpImm) ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
105 BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(OpImm);
106 Adjusted += OpImm;
107 if (emitFrameMoves)
108 EmitDefCfaOffset(MBB, MBBI, dl, TII, Adjusted*4);
109 }
110}
111
112/// The SP register is moved in steps of 'MaxImmU16' towards the top of the
113/// frame. During these steps, it may be necessary to re-load registers.
114/// IfNeededLDAWSP emits the necessary LDAWSP instructions to move the SP only
115/// as far as to make 'OffsetFromTop' reachable using an LDAWSP_lru6.
116/// \param OffsetFromTop the spill offset from the top of the frame.
117/// \param [in,out] RemainingAdj the current SP offset from the top of the
118/// frame.
121 const TargetInstrInfo &TII, int OffsetFromTop,
122 int &RemainingAdj) {
123 while (OffsetFromTop < RemainingAdj - MaxImmU16) {
124 assert(RemainingAdj && "OffsetFromTop is beyond FrameSize");
125 int OpImm = (RemainingAdj > MaxImmU16) ? MaxImmU16 : RemainingAdj;
126 int Opcode = isImmU6(OpImm) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
127 BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(OpImm);
128 RemainingAdj -= OpImm;
129 }
130}
131
132/// Creates an ordered list of registers that are spilled
133/// during the emitPrologue/emitEpilogue.
134/// Registers are ordered according to their frame offset.
135/// As offsets are negative, the largest offsets will be first.
138 bool fetchLR, bool fetchFP) {
139 if (fetchLR) {
140 int Offset = MFI.getObjectOffset(XFI->getLRSpillSlot());
141 SpillList.push_back(StackSlotInfo(XFI->getLRSpillSlot(),
142 Offset,
143 XCore::LR));
144 }
145 if (fetchFP) {
146 int Offset = MFI.getObjectOffset(XFI->getFPSpillSlot());
147 SpillList.push_back(StackSlotInfo(XFI->getFPSpillSlot(),
148 Offset,
149 FramePtr));
150 }
151 llvm::sort(SpillList, CompareSSIOffset);
152}
153
154/// Creates an ordered list of EH info register 'spills'.
155/// These slots are only used by the unwinder and calls to llvm.eh.return().
156/// Registers are ordered according to their frame offset.
157/// As offsets are negative, the largest offsets will be first.
160 const Constant *PersonalityFn,
161 const TargetLowering *TL) {
162 assert(XFI->hasEHSpillSlot() && "There are no EH register spill slots");
163 const int *EHSlot = XFI->getEHSpillSlot();
165 SpillList.push_back(
166 StackSlotInfo(EHSlot[0], MFI.getObjectOffset(EHSlot[0]),
167 TL->getExceptionPointerRegister(EH, PersonalityFn)));
168 SpillList.push_back(
169 StackSlotInfo(EHSlot[0], MFI.getObjectOffset(EHSlot[1]),
170 TL->getExceptionSelectorRegister(EH, PersonalityFn)));
171 llvm::sort(SpillList, CompareSSIOffset);
172}
173
175 int FrameIndex,
177 MachineFunction *MF = MBB.getParent();
178 const MachineFrameInfo &MFI = MF->getFrameInfo();
180 MachinePointerInfo::getFixedStack(*MF, FrameIndex), flags,
181 MFI.getObjectSize(FrameIndex), MFI.getObjectAlign(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,
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
216
221
223 MachineBasicBlock &MBB) const {
224 assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
226 MachineFrameInfo &MFI = MF.getFrameInfo();
227 const MCRegisterInfo *MRI = MF.getContext().getRegisterInfo();
228 const XCoreInstrInfo &TII = *MF.getSubtarget<XCoreSubtarget>().getInstrInfo();
230 // Debug location must be unknown since the first debug location is used
231 // to determine the end of the prologue.
232 DebugLoc dl;
233
234 if (MFI.getMaxAlign() > getStackAlign())
235 report_fatal_error("emitPrologue unsupported alignment: " +
236 Twine(MFI.getMaxAlign().value()));
237
238 const AttributeList &PAL = MF.getFunction().getAttributes();
239 if (PAL.hasAttrSomewhere(Attribute::Nest))
240 BuildMI(MBB, MBBI, dl, TII.get(XCore::LDWSP_ru6), XCore::R11).addImm(0);
241 // FIX: Needs addMemOperand() but can't use getFixedStack() or getStack().
242
243 // Work out frame sizes.
244 // We will adjust the SP in stages towards the final FrameSize.
245 assert(MFI.getStackSize()%4 == 0 && "Misaligned frame size");
246 const int FrameSize = MFI.getStackSize() / 4;
247 int Adjusted = 0;
248
249 bool saveLR = XFI->hasLRSpillSlot();
250 bool UseENTSP = saveLR && FrameSize
251 && (MFI.getObjectOffset(XFI->getLRSpillSlot()) == 0);
252 if (UseENTSP)
253 saveLR = false;
254 bool FP = hasFP(MF);
255 bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(MF);
256
257 if (UseENTSP) {
258 // Allocate space on the stack at the same time as saving LR.
259 Adjusted = (FrameSize > MaxImmU16) ? MaxImmU16 : FrameSize;
260 int Opcode = isImmU6(Adjusted) ? XCore::ENTSP_u6 : XCore::ENTSP_lu6;
261 MBB.addLiveIn(XCore::LR);
262 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode));
263 MIB.addImm(Adjusted);
264 MIB->addRegisterKilled(XCore::LR, MF.getSubtarget().getRegisterInfo(),
265 true);
266 if (emitFrameMoves) {
267 EmitDefCfaOffset(MBB, MBBI, dl, TII, Adjusted*4);
268 unsigned DRegNum = MRI->getDwarfRegNum(XCore::LR, true);
269 EmitCfiOffset(MBB, MBBI, dl, TII, DRegNum, 0);
270 }
271 }
272
273 // If necessary, save LR and FP to the stack, as we EXTSP.
275 GetSpillList(SpillList, MFI, XFI, saveLR, FP);
276 // We want the nearest (negative) offsets first, so reverse list.
277 std::reverse(SpillList.begin(), SpillList.end());
278 for (unsigned i = 0, e = SpillList.size(); i != e; ++i) {
279 assert(SpillList[i].Offset % 4 == 0 && "Misaligned stack offset");
280 assert(SpillList[i].Offset <= 0 && "Unexpected positive stack offset");
281 int OffsetFromTop = - SpillList[i].Offset/4;
282 IfNeededExtSP(MBB, MBBI, dl, TII, OffsetFromTop, Adjusted, FrameSize,
283 emitFrameMoves);
284 int Offset = Adjusted - OffsetFromTop;
285 int Opcode = isImmU6(Offset) ? XCore::STWSP_ru6 : XCore::STWSP_lru6;
286 MBB.addLiveIn(SpillList[i].Reg);
287 BuildMI(MBB, MBBI, dl, TII.get(Opcode))
288 .addReg(SpillList[i].Reg, RegState::Kill)
289 .addImm(Offset)
290 .addMemOperand(getFrameIndexMMO(MBB, SpillList[i].FI,
292 if (emitFrameMoves) {
293 unsigned DRegNum = MRI->getDwarfRegNum(SpillList[i].Reg, true);
294 EmitCfiOffset(MBB, MBBI, dl, TII, DRegNum, SpillList[i].Offset);
295 }
296 }
297
298 // Complete any remaining Stack adjustment.
299 IfNeededExtSP(MBB, MBBI, dl, TII, FrameSize, Adjusted, FrameSize,
300 emitFrameMoves);
301 assert(Adjusted==FrameSize && "IfNeededExtSP has not completed adjustment");
302
303 if (FP) {
304 // Set the FP from the SP.
305 BuildMI(MBB, MBBI, dl, TII.get(XCore::LDAWSP_ru6), FramePtr).addImm(0);
306 if (emitFrameMoves)
307 EmitDefCfaRegister(MBB, MBBI, dl, TII, MF,
308 MRI->getDwarfRegNum(FramePtr, true));
309 }
310
311 if (emitFrameMoves) {
312 // Frame moves for callee saved.
313 for (const auto &SpillLabel : XFI->getSpillLabels()) {
314 MachineBasicBlock::iterator Pos = SpillLabel.first;
315 ++Pos;
316 const CalleeSavedInfo &CSI = SpillLabel.second;
317 int Offset = MFI.getObjectOffset(CSI.getFrameIdx());
318 unsigned DRegNum = MRI->getDwarfRegNum(CSI.getReg(), true);
319 EmitCfiOffset(MBB, Pos, dl, TII, DRegNum, Offset);
320 }
321 if (XFI->hasEHSpillSlot()) {
322 // The unwinder requires stack slot & CFI offsets for the exception info.
323 // We do not save/spill these registers.
324 const Function *Fn = &MF.getFunction();
325 const Constant *PersonalityFn =
326 Fn->hasPersonalityFn() ? Fn->getPersonalityFn() : nullptr;
328 GetEHSpillList(SpillList, MFI, XFI, PersonalityFn,
330 assert(SpillList.size()==2 && "Unexpected SpillList size");
332 MRI->getDwarfRegNum(SpillList[0].Reg, true),
333 SpillList[0].Offset);
335 MRI->getDwarfRegNum(SpillList[1].Reg, true),
336 SpillList[1].Offset);
337 }
338 }
339}
340
342 MachineBasicBlock &MBB) const {
343 MachineFrameInfo &MFI = MF.getFrameInfo();
344 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
345 const XCoreInstrInfo &TII = *MF.getSubtarget<XCoreSubtarget>().getInstrInfo();
347 DebugLoc dl = MBBI->getDebugLoc();
348 unsigned RetOpcode = MBBI->getOpcode();
349
350 // Work out frame sizes.
351 // We will adjust the SP in stages towards the final FrameSize.
352 int RemainingAdj = MFI.getStackSize();
353 assert(RemainingAdj%4 == 0 && "Misaligned frame size");
354 RemainingAdj /= 4;
355
356 if (RetOpcode == XCore::EH_RETURN) {
357 // 'Restore' the exception info the unwinder has placed into the stack
358 // slots.
359 const Function *Fn = &MF.getFunction();
360 const Constant *PersonalityFn =
361 Fn->hasPersonalityFn() ? Fn->getPersonalityFn() : nullptr;
363 GetEHSpillList(SpillList, MFI, XFI, PersonalityFn,
365 RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList);
366
367 // Return to the landing pad.
368 Register EhStackReg = MBBI->getOperand(0).getReg();
369 Register EhHandlerReg = MBBI->getOperand(1).getReg();
370 BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(EhStackReg);
371 BuildMI(MBB, MBBI, dl, TII.get(XCore::BAU_1r)).addReg(EhHandlerReg);
372 MBB.erase(MBBI); // Erase the previous return instruction.
373 return;
374 }
375
376 bool restoreLR = XFI->hasLRSpillSlot();
377 bool UseRETSP = restoreLR && RemainingAdj
378 && (MFI.getObjectOffset(XFI->getLRSpillSlot()) == 0);
379 if (UseRETSP)
380 restoreLR = false;
381 bool FP = hasFP(MF);
382
383 if (FP) // Restore the stack pointer.
384 BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(FramePtr);
385
386 // If necessary, restore LR and FP from the stack, as we EXTSP.
388 GetSpillList(SpillList, MFI, XFI, restoreLR, FP);
389 RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList);
390
391 if (RemainingAdj) {
392 // Complete all but one of the remaining Stack adjustments.
393 IfNeededLDAWSP(MBB, MBBI, dl, TII, 0, RemainingAdj);
394 if (UseRETSP) {
395 // Fold prologue into return instruction
396 assert(RetOpcode == XCore::RETSP_u6
397 || RetOpcode == XCore::RETSP_lu6);
398 int Opcode = isImmU6(RemainingAdj) ? XCore::RETSP_u6 : XCore::RETSP_lu6;
399 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode))
400 .addImm(RemainingAdj);
401 for (unsigned i = 3, e = MBBI->getNumOperands(); i < e; ++i)
402 MIB->addOperand(MBBI->getOperand(i)); // copy any variadic operands
403 MBB.erase(MBBI); // Erase the previous return instruction.
404 } else {
405 int Opcode = isImmU6(RemainingAdj) ? XCore::LDAWSP_ru6 :
406 XCore::LDAWSP_lru6;
407 BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(RemainingAdj);
408 // Don't erase the return instruction.
409 }
410 } // else Don't erase the return instruction.
411}
412
416 if (CSI.empty())
417 return true;
418
419 MachineFunction *MF = MBB.getParent();
422 bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(*MF);
423
424 DebugLoc DL;
425 if (MI != MBB.end() && !MI->isDebugInstr())
426 DL = MI->getDebugLoc();
427
428 for (const CalleeSavedInfo &I : CSI) {
429 MCRegister Reg = I.getReg();
430 assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) &&
431 "LR & FP are always handled in emitPrologue");
432
433 // Add the callee-saved register as live-in. It's killed at the spill.
434 MBB.addLiveIn(Reg);
435 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
436 TII.storeRegToStackSlot(MBB, MI, Reg, true, I.getFrameIdx(), RC,
437 Register());
438 if (emitFrameMoves) {
439 auto Store = MI;
440 --Store;
441 XFI->getSpillLabels().push_back(std::make_pair(Store, I));
442 }
443 }
444 return true;
445}
446
450 MachineFunction *MF = MBB.getParent();
452 bool AtStart = MI == MBB.begin();
454 if (!AtStart)
455 --BeforeI;
456 for (const CalleeSavedInfo &CSR : CSI) {
457 MCRegister Reg = CSR.getReg();
458 assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) &&
459 "LR & FP are always handled in emitEpilogue");
460
461 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
462 TII.loadRegFromStackSlot(MBB, MI, Reg, CSR.getFrameIdx(), RC, Register());
463 assert(MI != MBB.begin() &&
464 "loadRegFromStackSlot didn't insert any code!");
465 // Insert in reverse order. loadRegFromStackSlot can insert multiple
466 // instructions.
467 if (AtStart)
468 MI = MBB.begin();
469 else {
470 MI = BeforeI;
471 ++MI;
472 }
473 }
474 return true;
475}
476
477// This function eliminates ADJCALLSTACKDOWN,
478// ADJCALLSTACKUP pseudo instructions
482 const XCoreInstrInfo &TII = *MF.getSubtarget<XCoreSubtarget>().getInstrInfo();
483 if (!hasReservedCallFrame(MF)) {
484 // Turn the adjcallstackdown instruction into 'extsp <amt>' and the
485 // adjcallstackup instruction into 'ldaw sp, sp[<amt>]'
486 MachineInstr &Old = *I;
487 uint64_t Amount = Old.getOperand(0).getImm();
488 if (Amount != 0) {
489 // We need to keep the stack aligned properly. To do this, we round the
490 // amount of space needed for the outgoing arguments up to the next
491 // alignment boundary.
492 Amount = alignTo(Amount, getStackAlign());
493
494 assert(Amount%4 == 0);
495 Amount /= 4;
496
497 bool isU6 = isImmU6(Amount);
498 if (!isU6 && !isImmU16(Amount)) {
499 // FIX could emit multiple instructions in this case.
500#ifndef NDEBUG
501 errs() << "eliminateCallFramePseudoInstr size too big: "
502 << Amount << "\n";
503#endif
504 llvm_unreachable(nullptr);
505 }
506
507 MachineInstr *New;
508 if (Old.getOpcode() == XCore::ADJCALLSTACKDOWN) {
509 int Opcode = isU6 ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
510 New = BuildMI(MF, Old.getDebugLoc(), TII.get(Opcode)).addImm(Amount);
511 } else {
512 assert(Old.getOpcode() == XCore::ADJCALLSTACKUP);
513 int Opcode = isU6 ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
514 New = BuildMI(MF, Old.getDebugLoc(), TII.get(Opcode), XCore::SP)
515 .addImm(Amount);
516 }
517
518 // Replace the pseudo instruction with a new instruction...
519 MBB.insert(I, New);
520 }
521 }
522
523 return MBB.erase(I);
524}
525
527 BitVector &SavedRegs,
528 RegScavenger *RS) const {
530
532
533 const MachineRegisterInfo &MRI = MF.getRegInfo();
534 bool LRUsed = MRI.isPhysRegModified(XCore::LR);
535
536 if (!LRUsed && !MF.getFunction().isVarArg() &&
538 // If we need to extend the stack it is more efficient to use entsp / retsp.
539 // We force the LR to be saved so these instructions are used.
540 LRUsed = true;
541
542 if (MF.callsUnwindInit() || MF.callsEHReturn()) {
543 // The unwinder expects to find spill slots for the exception info regs R0
544 // & R1. These are used during llvm.eh.return() to 'restore' the exception
545 // info. N.B. we do not spill or restore R0, R1 during normal operation.
546 XFI->createEHSpillSlot(MF);
547 // As we will have a stack, we force the LR to be saved.
548 LRUsed = true;
549 }
550
551 if (LRUsed) {
552 // We will handle the LR in the prologue/epilogue
553 // and allocate space on the stack ourselves.
554 SavedRegs.reset(XCore::LR);
555 XFI->createLRSpillSlot(MF);
556 }
557
558 if (hasFP(MF))
559 // A callee save register is used to hold the FP.
560 // This needs saving / restoring in the epilogue / prologue.
561 XFI->createFPSpillSlot(MF);
562}
563
566 RegScavenger *RS) const {
567 assert(RS && "requiresRegisterScavenging failed");
568 MachineFrameInfo &MFI = MF.getFrameInfo();
569 const TargetRegisterClass &RC = XCore::GRRegsRegClass;
572 // Reserve slots close to SP or frame pointer for Scavenging spills.
573 // When using SP for small frames, we don't need any scratch registers.
574 // When using SP for large frames, we may need 2 scratch registers.
575 // When using FP, for large or small frames, we may need 1 scratch register.
576 unsigned Size = TRI.getSpillSize(RC);
577 Align Alignment = TRI.getSpillAlign(RC);
578 if (XFI->isLargeFrame(MF) || hasFP(MF))
579 RS->addScavengingFrameIndex(MFI.CreateSpillStackObject(Size, Alignment));
580 if (XFI->isLargeFrame(MF) && !hasFP(MF))
581 RS->addScavengingFrameIndex(MFI.CreateSpillStackObject(Size, Alignment));
582}
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:889
Constant * getPersonalityFn() const
Get the personality function associated with this function.
AttributeList getAttributes() const
Return the attribute list for this Function.
Definition Function.h:328
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition Function.h:229
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 the alignment in bytes that this function must be aligned to, which is greater than the defaul...
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.
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 TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
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.
TargetOptions Options
LLVM_ABI bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
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:578
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.