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"
26#include "llvm/IR/Module.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 Module &M, const Constant *PersonalityFn,
161 const TargetLowering *TL) {
162 assert(XFI->hasEHSpillSlot() && "There are no EH register spill slots");
163 const int *EHSlot = XFI->getEHSpillSlot();
164 // Prefer the "exception-model" module flag, else the TargetOptions default.
165 ExceptionHandling EH = M.getExceptionModel();
168 SpillList.push_back(
169 StackSlotInfo(EHSlot[0], MFI.getObjectOffset(EHSlot[0]),
170 TL->getExceptionPointerRegister(EH, PersonalityFn)));
171 SpillList.push_back(
172 StackSlotInfo(EHSlot[0], MFI.getObjectOffset(EHSlot[1]),
173 TL->getExceptionSelectorRegister(EH, PersonalityFn)));
174 llvm::sort(SpillList, CompareSSIOffset);
175}
176
178 int FrameIndex,
180 MachineFunction *MF = MBB.getParent();
181 const MachineFrameInfo &MFI = MF->getFrameInfo();
183 MachinePointerInfo::getFixedStack(*MF, FrameIndex), flags,
184 MFI.getObjectSize(FrameIndex), MFI.getObjectAlign(FrameIndex));
185 return MMO;
186}
187
188
189/// Restore clobbered registers with their spill slot value.
190/// The SP will be adjusted at the same time, thus the SpillList must be ordered
191/// with the largest (negative) offsets first.
194 const DebugLoc &dl, const TargetInstrInfo &TII,
195 int &RemainingAdj,
197 for (unsigned i = 0, e = SpillList.size(); i != e; ++i) {
198 assert(SpillList[i].Offset % 4 == 0 && "Misaligned stack offset");
199 assert(SpillList[i].Offset <= 0 && "Unexpected positive stack offset");
200 int OffsetFromTop = - SpillList[i].Offset/4;
201 IfNeededLDAWSP(MBB, MBBI, dl, TII, OffsetFromTop, RemainingAdj);
202 int Offset = RemainingAdj - OffsetFromTop;
203 int Opcode = isImmU6(Offset) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6;
204 BuildMI(MBB, MBBI, dl, TII.get(Opcode), SpillList[i].Reg)
205 .addImm(Offset)
206 .addMemOperand(getFrameIndexMMO(MBB, SpillList[i].FI,
208 }
209}
210
211//===----------------------------------------------------------------------===//
212// XCoreFrameLowering:
213//===----------------------------------------------------------------------===//
214
219
223
225 MachineBasicBlock &MBB) const {
226 assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
228 MachineFrameInfo &MFI = MF.getFrameInfo();
229 const MCRegisterInfo *MRI = MF.getContext().getRegisterInfo();
230 const XCoreInstrInfo &TII = *MF.getSubtarget<XCoreSubtarget>().getInstrInfo();
232 // Debug location must be unknown since the first debug location is used
233 // to determine the end of the prologue.
234 DebugLoc dl;
235
236 if (MFI.getMaxAlign() > getStackAlign())
237 report_fatal_error("emitPrologue unsupported alignment: " +
238 Twine(MFI.getMaxAlign().value()));
239
240 const AttributeList &PAL = MF.getFunction().getAttributes();
241 if (PAL.hasAttrSomewhere(Attribute::Nest))
242 BuildMI(MBB, MBBI, dl, TII.get(XCore::LDWSP_ru6), XCore::R11).addImm(0);
243 // FIX: Needs addMemOperand() but can't use getFixedStack() or getStack().
244
245 // Work out frame sizes.
246 // We will adjust the SP in stages towards the final FrameSize.
247 assert(MFI.getStackSize()%4 == 0 && "Misaligned frame size");
248 const int FrameSize = MFI.getStackSize() / 4;
249 int Adjusted = 0;
250
251 bool saveLR = XFI->hasLRSpillSlot();
252 bool UseENTSP = saveLR && FrameSize
253 && (MFI.getObjectOffset(XFI->getLRSpillSlot()) == 0);
254 if (UseENTSP)
255 saveLR = false;
256 bool FP = hasFP(MF);
257 bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(MF);
258
259 if (UseENTSP) {
260 // Allocate space on the stack at the same time as saving LR.
261 Adjusted = (FrameSize > MaxImmU16) ? MaxImmU16 : FrameSize;
262 int Opcode = isImmU6(Adjusted) ? XCore::ENTSP_u6 : XCore::ENTSP_lu6;
263 MBB.addLiveIn(XCore::LR);
264 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode));
265 MIB.addImm(Adjusted);
266 MIB->addRegisterKilled(XCore::LR, MF.getSubtarget().getRegisterInfo(),
267 true);
268 if (emitFrameMoves) {
269 EmitDefCfaOffset(MBB, MBBI, dl, TII, Adjusted*4);
270 unsigned DRegNum = MRI->getDwarfRegNum(XCore::LR, true);
271 EmitCfiOffset(MBB, MBBI, dl, TII, DRegNum, 0);
272 }
273 }
274
275 // If necessary, save LR and FP to the stack, as we EXTSP.
277 GetSpillList(SpillList, MFI, XFI, saveLR, FP);
278 // We want the nearest (negative) offsets first, so reverse list.
279 std::reverse(SpillList.begin(), SpillList.end());
280 for (unsigned i = 0, e = SpillList.size(); i != e; ++i) {
281 assert(SpillList[i].Offset % 4 == 0 && "Misaligned stack offset");
282 assert(SpillList[i].Offset <= 0 && "Unexpected positive stack offset");
283 int OffsetFromTop = - SpillList[i].Offset/4;
284 IfNeededExtSP(MBB, MBBI, dl, TII, OffsetFromTop, Adjusted, FrameSize,
285 emitFrameMoves);
286 int Offset = Adjusted - OffsetFromTop;
287 int Opcode = isImmU6(Offset) ? XCore::STWSP_ru6 : XCore::STWSP_lru6;
288 MBB.addLiveIn(SpillList[i].Reg);
289 BuildMI(MBB, MBBI, dl, TII.get(Opcode))
290 .addReg(SpillList[i].Reg, RegState::Kill)
291 .addImm(Offset)
292 .addMemOperand(getFrameIndexMMO(MBB, SpillList[i].FI,
294 if (emitFrameMoves) {
295 unsigned DRegNum = MRI->getDwarfRegNum(SpillList[i].Reg, true);
296 EmitCfiOffset(MBB, MBBI, dl, TII, DRegNum, SpillList[i].Offset);
297 }
298 }
299
300 // Complete any remaining Stack adjustment.
301 IfNeededExtSP(MBB, MBBI, dl, TII, FrameSize, Adjusted, FrameSize,
302 emitFrameMoves);
303 assert(Adjusted==FrameSize && "IfNeededExtSP has not completed adjustment");
304
305 if (FP) {
306 // Set the FP from the SP.
307 BuildMI(MBB, MBBI, dl, TII.get(XCore::LDAWSP_ru6), FramePtr).addImm(0);
308 if (emitFrameMoves)
309 EmitDefCfaRegister(MBB, MBBI, dl, TII, MF,
310 MRI->getDwarfRegNum(FramePtr, true));
311 }
312
313 if (emitFrameMoves) {
314 // Frame moves for callee saved.
315 for (const auto &SpillLabel : XFI->getSpillLabels()) {
316 MachineBasicBlock::iterator Pos = SpillLabel.first;
317 ++Pos;
318 const CalleeSavedInfo &CSI = SpillLabel.second;
319 int Offset = MFI.getObjectOffset(CSI.getFrameIdx());
320 unsigned DRegNum = MRI->getDwarfRegNum(CSI.getReg(), true);
321 EmitCfiOffset(MBB, Pos, dl, TII, DRegNum, Offset);
322 }
323 if (XFI->hasEHSpillSlot()) {
324 // The unwinder requires stack slot & CFI offsets for the exception info.
325 // We do not save/spill these registers.
326 const Function *Fn = &MF.getFunction();
327 const Constant *PersonalityFn =
328 Fn->hasPersonalityFn() ? Fn->getPersonalityFn() : nullptr;
330 GetEHSpillList(SpillList, MFI, XFI, *Fn->getParent(), PersonalityFn,
332 assert(SpillList.size()==2 && "Unexpected SpillList size");
334 MRI->getDwarfRegNum(SpillList[0].Reg, true),
335 SpillList[0].Offset);
337 MRI->getDwarfRegNum(SpillList[1].Reg, true),
338 SpillList[1].Offset);
339 }
340 }
341}
342
344 MachineBasicBlock &MBB) const {
345 MachineFrameInfo &MFI = MF.getFrameInfo();
346 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
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, *Fn->getParent(), PersonalityFn,
367 RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList);
368
369 // Return to the landing pad.
370 Register EhStackReg = MBBI->getOperand(0).getReg();
371 Register EhHandlerReg = MBBI->getOperand(1).getReg();
372 BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(EhStackReg);
373 BuildMI(MBB, MBBI, dl, TII.get(XCore::BAU_1r)).addReg(EhHandlerReg);
374 MBB.erase(MBBI); // Erase the previous return instruction.
375 return;
376 }
377
378 bool restoreLR = XFI->hasLRSpillSlot();
379 bool UseRETSP = restoreLR && RemainingAdj
380 && (MFI.getObjectOffset(XFI->getLRSpillSlot()) == 0);
381 if (UseRETSP)
382 restoreLR = false;
383 bool FP = hasFP(MF);
384
385 if (FP) // Restore the stack pointer.
386 BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(FramePtr);
387
388 // If necessary, restore LR and FP from the stack, as we EXTSP.
390 GetSpillList(SpillList, MFI, XFI, restoreLR, FP);
391 RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList);
392
393 if (RemainingAdj) {
394 // Complete all but one of the remaining Stack adjustments.
395 IfNeededLDAWSP(MBB, MBBI, dl, TII, 0, RemainingAdj);
396 if (UseRETSP) {
397 // Fold prologue into return instruction
398 assert(RetOpcode == XCore::RETSP_u6
399 || RetOpcode == XCore::RETSP_lu6);
400 int Opcode = isImmU6(RemainingAdj) ? XCore::RETSP_u6 : XCore::RETSP_lu6;
401 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode))
402 .addImm(RemainingAdj);
403 for (unsigned i = 3, e = MBBI->getNumOperands(); i < e; ++i)
404 MIB->addOperand(MBBI->getOperand(i)); // copy any variadic operands
405 MBB.erase(MBBI); // Erase the previous return instruction.
406 } else {
407 int Opcode = isImmU6(RemainingAdj) ? XCore::LDAWSP_ru6 :
408 XCore::LDAWSP_lru6;
409 BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(RemainingAdj);
410 // Don't erase the return instruction.
411 }
412 } // else Don't erase the return instruction.
413}
414
418 if (CSI.empty())
419 return true;
420
421 MachineFunction *MF = MBB.getParent();
424 bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(*MF);
425
426 DebugLoc DL;
427 if (MI != MBB.end() && !MI->isDebugInstr())
428 DL = MI->getDebugLoc();
429
430 for (const CalleeSavedInfo &I : CSI) {
431 MCRegister Reg = I.getReg();
432 assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) &&
433 "LR & FP are always handled in emitPrologue");
434
435 // Add the callee-saved register as live-in. It's killed at the spill.
436 MBB.addLiveIn(Reg);
437 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
438 TII.storeRegToStackSlot(MBB, MI, Reg, true, I.getFrameIdx(), RC,
439 Register());
440 if (emitFrameMoves) {
441 auto Store = MI;
442 --Store;
443 XFI->getSpillLabels().push_back(std::make_pair(Store, I));
444 }
445 }
446 return true;
447}
448
452 MachineFunction *MF = MBB.getParent();
454 bool AtStart = MI == MBB.begin();
456 if (!AtStart)
457 --BeforeI;
458 for (const CalleeSavedInfo &CSR : CSI) {
459 MCRegister Reg = CSR.getReg();
460 assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) &&
461 "LR & FP are always handled in emitEpilogue");
462
463 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
464 TII.loadRegFromStackSlot(MBB, MI, Reg, CSR.getFrameIdx(), RC, Register());
465 assert(MI != MBB.begin() &&
466 "loadRegFromStackSlot didn't insert any code!");
467 // Insert in reverse order. loadRegFromStackSlot can insert multiple
468 // instructions.
469 if (AtStart)
470 MI = MBB.begin();
471 else {
472 MI = BeforeI;
473 ++MI;
474 }
475 }
476 return true;
477}
478
479// This function eliminates ADJCALLSTACKDOWN,
480// ADJCALLSTACKUP pseudo instructions
484 const XCoreInstrInfo &TII = *MF.getSubtarget<XCoreSubtarget>().getInstrInfo();
485 if (!hasReservedCallFrame(MF)) {
486 // Turn the adjcallstackdown instruction into 'extsp <amt>' and the
487 // adjcallstackup instruction into 'ldaw sp, sp[<amt>]'
488 MachineInstr &Old = *I;
489 uint64_t Amount = Old.getOperand(0).getImm();
490 if (Amount != 0) {
491 // We need to keep the stack aligned properly. To do this, we round the
492 // amount of space needed for the outgoing arguments up to the next
493 // alignment boundary.
494 Amount = alignTo(Amount, getStackAlign());
495
496 assert(Amount%4 == 0);
497 Amount /= 4;
498
499 bool isU6 = isImmU6(Amount);
500 if (!isU6 && !isImmU16(Amount)) {
501 // FIX could emit multiple instructions in this case.
502#ifndef NDEBUG
503 errs() << "eliminateCallFramePseudoInstr size too big: "
504 << Amount << "\n";
505#endif
506 llvm_unreachable(nullptr);
507 }
508
509 MachineInstr *New;
510 if (Old.getOpcode() == XCore::ADJCALLSTACKDOWN) {
511 int Opcode = isU6 ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
512 New = BuildMI(MF, Old.getDebugLoc(), TII.get(Opcode)).addImm(Amount);
513 } else {
514 assert(Old.getOpcode() == XCore::ADJCALLSTACKUP);
515 int Opcode = isU6 ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
516 New = BuildMI(MF, Old.getDebugLoc(), TII.get(Opcode), XCore::SP)
517 .addImm(Amount);
518 }
519
520 // Replace the pseudo instruction with a new instruction...
521 MBB.insert(I, New);
522 }
523 }
524
525 return MBB.erase(I);
526}
527
529 BitVector &SavedRegs,
530 RegScavenger *RS) const {
532
534
535 const MachineRegisterInfo &MRI = MF.getRegInfo();
536 bool LRUsed = MRI.isPhysRegModified(XCore::LR);
537
538 if (!LRUsed && !MF.getFunction().isVarArg() &&
540 // If we need to extend the stack it is more efficient to use entsp / retsp.
541 // We force the LR to be saved so these instructions are used.
542 LRUsed = true;
543
544 if (MF.callsUnwindInit() || MF.callsEHReturn()) {
545 // The unwinder expects to find spill slots for the exception info regs R0
546 // & R1. These are used during llvm.eh.return() to 'restore' the exception
547 // info. N.B. we do not spill or restore R0, R1 during normal operation.
548 XFI->createEHSpillSlot(MF);
549 // As we will have a stack, we force the LR to be saved.
550 LRUsed = true;
551 }
552
553 if (LRUsed) {
554 // We will handle the LR in the prologue/epilogue
555 // and allocate space on the stack ourselves.
556 SavedRegs.reset(XCore::LR);
557 XFI->createLRSpillSlot(MF);
558 }
559
560 if (hasFP(MF))
561 // A callee save register is used to hold the FP.
562 // This needs saving / restoring in the epilogue / prologue.
563 XFI->createFPSpillSlot(MF);
564}
565
568 RegScavenger *RS) const {
569 assert(RS && "requiresRegisterScavenging failed");
570 MachineFrameInfo &MFI = MF.getFrameInfo();
571 const TargetRegisterClass &RC = XCore::GRRegsRegClass;
574 // Reserve slots close to SP or frame pointer for Scavenging spills.
575 // When using SP for small frames, we don't need any scratch registers.
576 // When using SP for large frames, we may need 2 scratch registers.
577 // When using FP, for large or small frames, we may need 1 scratch register.
578 unsigned Size = TRI.getSpillSize(RC);
579 Align Alignment = TRI.getSpillAlign(RC);
580 if (XFI->isLargeFrame(MF) || hasFP(MF))
581 RS->addScavengingFrameIndex(MFI.CreateSpillStackObject(Size, Alignment));
582 if (XFI->isLargeFrame(MF) && !hasFP(MF))
583 RS->addScavengingFrameIndex(MFI.CreateSpillStackObject(Size, Alignment));
584}
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
Module.h This file contains the declarations for the Module class.
#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 GetEHSpillList(SmallVectorImpl< StackSlotInfo > &SpillList, MachineFrameInfo &MFI, XCoreFunctionInfo *XFI, const Module &M, const Constant *PersonalityFn, const TargetLowering *TL)
Creates an ordered list of EH info register 'spills'.
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)
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
Module * getParent()
Get the module that this global value is contained inside of...
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.
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.
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
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.
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:1652
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
@ Default
Not specified; resolve to the target's default model.
Definition CodeGen.h:55
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.