LLVM 20.0.0git
RISCVFrameLowering.cpp
Go to the documentation of this file.
1//===-- RISCVFrameLowering.cpp - RISC-V Frame Information -----------------===//
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 the RISC-V implementation of TargetFrameLowering class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "RISCVFrameLowering.h"
15#include "RISCVSubtarget.h"
24#include "llvm/MC/MCDwarf.h"
25#include "llvm/Support/LEB128.h"
26
27#include <algorithm>
28
29using namespace llvm;
30
31namespace {
32
33class CFISaveRegisterEmitter {
36
37public:
38 CFISaveRegisterEmitter(MachineFunction &MF)
39 : MF{MF}, MFI{MF.getFrameInfo()} {};
40
42 const RISCVRegisterInfo &RI, const RISCVInstrInfo &TII,
43 const DebugLoc &DL, const CalleeSavedInfo &CS) const {
44 int FrameIdx = CS.getFrameIdx();
45 int64_t Offset = MFI.getObjectOffset(FrameIdx);
46 Register Reg = CS.getReg();
47 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
48 nullptr, RI.getDwarfRegNum(Reg, true), Offset));
49 BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
50 .addCFIIndex(CFIIndex)
52 }
53};
54
55class CFIRestoreRegisterEmitter {
57
58public:
59 CFIRestoreRegisterEmitter(MachineFunction &MF) : MF{MF} {};
60
62 const RISCVRegisterInfo &RI, const RISCVInstrInfo &TII,
63 const DebugLoc &DL, const CalleeSavedInfo &CS) const {
64 Register Reg = CS.getReg();
65 unsigned CFIIndex = MF.addFrameInst(
66 MCCFIInstruction::createRestore(nullptr, RI.getDwarfRegNum(Reg, true)));
67 BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
68 .addCFIIndex(CFIIndex)
70 }
71};
72
73} // namespace
74
75template <typename Emitter>
76void RISCVFrameLowering::emitCFIForCSI(
78 const SmallVector<CalleeSavedInfo, 8> &CSI) const {
83
84 Emitter E{*MF};
85 for (const auto &CS : CSI)
86 E.emit(MBB, MBBI, *RI, *TII, DL, CS);
87}
88
90 if (ABI == RISCVABI::ABI_ILP32E)
91 return Align(4);
92 if (ABI == RISCVABI::ABI_LP64E)
93 return Align(8);
94 return Align(16);
95}
96
99 StackGrowsDown, getABIStackAlignment(STI.getTargetABI()),
100 /*LocalAreaOffset=*/0,
101 /*TransientStackAlignment=*/getABIStackAlignment(STI.getTargetABI())),
102 STI(STI) {}
103
104// The register used to hold the frame pointer.
105static constexpr Register FPReg = RISCV::X8;
106
107// The register used to hold the stack pointer.
108static constexpr Register SPReg = RISCV::X2;
109
110// The register used to hold the return address.
111static constexpr Register RAReg = RISCV::X1;
112
113// Offsets which need to be scale by XLen representing locations of CSRs which
114// are given a fixed location by save/restore libcalls or Zcmp Push/Pop.
115static const std::pair<MCPhysReg, int8_t> FixedCSRFIMap[] = {
116 {/*ra*/ RAReg, -1}, {/*s0*/ FPReg, -2},
117 {/*s1*/ RISCV::X9, -3}, {/*s2*/ RISCV::X18, -4},
118 {/*s3*/ RISCV::X19, -5}, {/*s4*/ RISCV::X20, -6},
119 {/*s5*/ RISCV::X21, -7}, {/*s6*/ RISCV::X22, -8},
120 {/*s7*/ RISCV::X23, -9}, {/*s8*/ RISCV::X24, -10},
121 {/*s9*/ RISCV::X25, -11}, {/*s10*/ RISCV::X26, -12},
122 {/*s11*/ RISCV::X27, -13}};
123
124// For now we use x3, a.k.a gp, as pointer to shadow call stack.
125// User should not use x3 in their asm.
128 const DebugLoc &DL) {
129 const auto &STI = MF.getSubtarget<RISCVSubtarget>();
130 bool HasHWShadowStack = MF.getFunction().hasFnAttribute("hw-shadow-stack") &&
131 STI.hasStdExtZicfiss();
132 bool HasSWShadowStack =
133 MF.getFunction().hasFnAttribute(Attribute::ShadowCallStack);
134 if (!HasHWShadowStack && !HasSWShadowStack)
135 return;
136
137 const llvm::RISCVRegisterInfo *TRI = STI.getRegisterInfo();
138 Register RAReg = TRI->getRARegister();
139
140 // Do not save RA to the SCS if it's not saved to the regular stack,
141 // i.e. RA is not at risk of being overwritten.
142 std::vector<CalleeSavedInfo> &CSI = MF.getFrameInfo().getCalleeSavedInfo();
143 if (llvm::none_of(
144 CSI, [&](CalleeSavedInfo &CSR) { return CSR.getReg() == RAReg; }))
145 return;
146
147 const RISCVInstrInfo *TII = STI.getInstrInfo();
148 if (HasHWShadowStack) {
149 BuildMI(MBB, MI, DL, TII->get(RISCV::SSPUSH)).addReg(RAReg);
150 return;
151 }
152
153 Register SCSPReg = RISCVABI::getSCSPReg();
154
155 bool IsRV64 = STI.is64Bit();
156 int64_t SlotSize = STI.getXLen() / 8;
157 // Store return address to shadow call stack
158 // addi gp, gp, [4|8]
159 // s[w|d] ra, -[4|8](gp)
160 BuildMI(MBB, MI, DL, TII->get(RISCV::ADDI))
161 .addReg(SCSPReg, RegState::Define)
162 .addReg(SCSPReg)
163 .addImm(SlotSize)
165 BuildMI(MBB, MI, DL, TII->get(IsRV64 ? RISCV::SD : RISCV::SW))
166 .addReg(RAReg)
167 .addReg(SCSPReg)
168 .addImm(-SlotSize)
170
171 // Emit a CFI instruction that causes SlotSize to be subtracted from the value
172 // of the shadow stack pointer when unwinding past this frame.
173 char DwarfSCSReg = TRI->getDwarfRegNum(SCSPReg, /*IsEH*/ true);
174 assert(DwarfSCSReg < 32 && "SCS Register should be < 32 (X3).");
175
176 char Offset = static_cast<char>(-SlotSize) & 0x7f;
177 const char CFIInst[] = {
178 dwarf::DW_CFA_val_expression,
179 DwarfSCSReg, // register
180 2, // length
181 static_cast<char>(unsigned(dwarf::DW_OP_breg0 + DwarfSCSReg)),
182 Offset, // addend (sleb128)
183 };
184
185 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createEscape(
186 nullptr, StringRef(CFIInst, sizeof(CFIInst))));
187 BuildMI(MBB, MI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
188 .addCFIIndex(CFIIndex)
190}
191
194 const DebugLoc &DL) {
195 const auto &STI = MF.getSubtarget<RISCVSubtarget>();
196 bool HasHWShadowStack = MF.getFunction().hasFnAttribute("hw-shadow-stack") &&
197 STI.hasStdExtZicfiss();
198 bool HasSWShadowStack =
199 MF.getFunction().hasFnAttribute(Attribute::ShadowCallStack);
200 if (!HasHWShadowStack && !HasSWShadowStack)
201 return;
202
203 Register RAReg = STI.getRegisterInfo()->getRARegister();
204
205 // See emitSCSPrologue() above.
206 std::vector<CalleeSavedInfo> &CSI = MF.getFrameInfo().getCalleeSavedInfo();
207 if (llvm::none_of(
208 CSI, [&](CalleeSavedInfo &CSR) { return CSR.getReg() == RAReg; }))
209 return;
210
211 const RISCVInstrInfo *TII = STI.getInstrInfo();
212 if (HasHWShadowStack) {
213 BuildMI(MBB, MI, DL, TII->get(RISCV::SSPOPCHK)).addReg(RAReg);
214 return;
215 }
216
217 Register SCSPReg = RISCVABI::getSCSPReg();
218
219 bool IsRV64 = STI.is64Bit();
220 int64_t SlotSize = STI.getXLen() / 8;
221 // Load return address from shadow call stack
222 // l[w|d] ra, -[4|8](gp)
223 // addi gp, gp, -[4|8]
224 BuildMI(MBB, MI, DL, TII->get(IsRV64 ? RISCV::LD : RISCV::LW))
226 .addReg(SCSPReg)
227 .addImm(-SlotSize)
229 BuildMI(MBB, MI, DL, TII->get(RISCV::ADDI))
230 .addReg(SCSPReg, RegState::Define)
231 .addReg(SCSPReg)
232 .addImm(-SlotSize)
234 // Restore the SCS pointer
235 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore(
236 nullptr, STI.getRegisterInfo()->getDwarfRegNum(SCSPReg, /*IsEH*/ true)));
237 BuildMI(MBB, MI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
238 .addCFIIndex(CFIIndex)
240}
241
242// Get the ID of the libcall used for spilling and restoring callee saved
243// registers. The ID is representative of the number of registers saved or
244// restored by the libcall, except it is zero-indexed - ID 0 corresponds to a
245// single register.
246static int getLibCallID(const MachineFunction &MF,
247 const std::vector<CalleeSavedInfo> &CSI) {
248 const auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
249
250 if (CSI.empty() || !RVFI->useSaveRestoreLibCalls(MF))
251 return -1;
252
253 Register MaxReg = RISCV::NoRegister;
254 for (auto &CS : CSI)
255 // assignCalleeSavedSpillSlots assigns negative frame indexes to
256 // registers which can be saved by libcall.
257 if (CS.getFrameIdx() < 0)
258 MaxReg = std::max(MaxReg.id(), CS.getReg().id());
259
260 if (MaxReg == RISCV::NoRegister)
261 return -1;
262
263 switch (MaxReg) {
264 default:
265 llvm_unreachable("Something has gone wrong!");
266 // clang-format off
267 case /*s11*/ RISCV::X27: return 12;
268 case /*s10*/ RISCV::X26: return 11;
269 case /*s9*/ RISCV::X25: return 10;
270 case /*s8*/ RISCV::X24: return 9;
271 case /*s7*/ RISCV::X23: return 8;
272 case /*s6*/ RISCV::X22: return 7;
273 case /*s5*/ RISCV::X21: return 6;
274 case /*s4*/ RISCV::X20: return 5;
275 case /*s3*/ RISCV::X19: return 4;
276 case /*s2*/ RISCV::X18: return 3;
277 case /*s1*/ RISCV::X9: return 2;
278 case /*s0*/ FPReg: return 1;
279 case /*ra*/ RAReg: return 0;
280 // clang-format on
281 }
282}
283
284// Get the name of the libcall used for spilling callee saved registers.
285// If this function will not use save/restore libcalls, then return a nullptr.
286static const char *
288 const std::vector<CalleeSavedInfo> &CSI) {
289 static const char *const SpillLibCalls[] = {
290 "__riscv_save_0",
291 "__riscv_save_1",
292 "__riscv_save_2",
293 "__riscv_save_3",
294 "__riscv_save_4",
295 "__riscv_save_5",
296 "__riscv_save_6",
297 "__riscv_save_7",
298 "__riscv_save_8",
299 "__riscv_save_9",
300 "__riscv_save_10",
301 "__riscv_save_11",
302 "__riscv_save_12"
303 };
304
305 int LibCallID = getLibCallID(MF, CSI);
306 if (LibCallID == -1)
307 return nullptr;
308 return SpillLibCalls[LibCallID];
309}
310
311// Get the name of the libcall used for restoring callee saved registers.
312// If this function will not use save/restore libcalls, then return a nullptr.
313static const char *
315 const std::vector<CalleeSavedInfo> &CSI) {
316 static const char *const RestoreLibCalls[] = {
317 "__riscv_restore_0",
318 "__riscv_restore_1",
319 "__riscv_restore_2",
320 "__riscv_restore_3",
321 "__riscv_restore_4",
322 "__riscv_restore_5",
323 "__riscv_restore_6",
324 "__riscv_restore_7",
325 "__riscv_restore_8",
326 "__riscv_restore_9",
327 "__riscv_restore_10",
328 "__riscv_restore_11",
329 "__riscv_restore_12"
330 };
331
332 int LibCallID = getLibCallID(MF, CSI);
333 if (LibCallID == -1)
334 return nullptr;
335 return RestoreLibCalls[LibCallID];
336}
337
338// Return encoded value and register count for PUSH/POP instruction,
339// representing registers to store/load.
340static std::pair<unsigned, unsigned>
342 switch (MaxReg) {
343 default:
344 llvm_unreachable("Unexpected Reg for Push/Pop Inst");
345 case RISCV::X27: /*s11*/
346 return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S11, 13);
347 case RISCV::X25: /*s9*/
348 return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S9, 11);
349 case RISCV::X24: /*s8*/
350 return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S8, 10);
351 case RISCV::X23: /*s7*/
352 return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S7, 9);
353 case RISCV::X22: /*s6*/
354 return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S6, 8);
355 case RISCV::X21: /*s5*/
356 return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S5, 7);
357 case RISCV::X20: /*s4*/
358 return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S4, 6);
359 case RISCV::X19: /*s3*/
360 return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S3, 5);
361 case RISCV::X18: /*s2*/
362 return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S2, 4);
363 case RISCV::X9: /*s1*/
364 return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S1, 3);
365 case FPReg: /*s0*/
366 return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0, 2);
367 case RAReg: /*ra*/
368 return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA, 1);
369 }
370}
371
372// Get the max reg of Push/Pop for restoring callee saved registers.
374 const std::vector<CalleeSavedInfo> &CSI) {
375 Register MaxPushPopReg = RISCV::NoRegister;
376 for (auto &CS : CSI) {
377 if (llvm::find_if(FixedCSRFIMap, [&](auto P) {
378 return P.first == CS.getReg();
379 }) != std::end(FixedCSRFIMap))
380 MaxPushPopReg = std::max(MaxPushPopReg.id(), CS.getReg().id());
381 }
382 assert(MaxPushPopReg != RISCV::X26 && "x26 requires x27 to also be pushed");
383 return MaxPushPopReg;
384}
385
386// Return true if the specified function should have a dedicated frame
387// pointer register. This is true if frame pointer elimination is
388// disabled, if it needs dynamic stack realignment, if the function has
389// variable sized allocas, or if the frame address is taken.
391 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
392
393 const MachineFrameInfo &MFI = MF.getFrameInfo();
394 return MF.getTarget().Options.DisableFramePointerElim(MF) ||
395 RegInfo->hasStackRealignment(MF) || MFI.hasVarSizedObjects() ||
397}
398
400 const MachineFrameInfo &MFI = MF.getFrameInfo();
402
403 // If we do not reserve stack space for outgoing arguments in prologue,
404 // we will adjust the stack pointer before call instruction. After the
405 // adjustment, we can not use SP to access the stack objects for the
406 // arguments. Instead, use BP to access these stack objects.
407 return (MFI.hasVarSizedObjects() ||
409 MFI.getMaxCallFrameSize() != 0))) &&
410 TRI->hasStackRealignment(MF);
411}
412
413// Determines the size of the frame and maximum call frame size.
414void RISCVFrameLowering::determineFrameLayout(MachineFunction &MF) const {
415 MachineFrameInfo &MFI = MF.getFrameInfo();
416 auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
417
418 // Get the number of bytes to allocate from the FrameInfo.
419 uint64_t FrameSize = MFI.getStackSize();
420
421 // Get the alignment.
422 Align StackAlign = getStackAlign();
423
424 // Make sure the frame is aligned.
425 FrameSize = alignTo(FrameSize, StackAlign);
426
427 // Update frame info.
428 MFI.setStackSize(FrameSize);
429
430 // When using SP or BP to access stack objects, we may require extra padding
431 // to ensure the bottom of the RVV stack is correctly aligned within the main
432 // stack. We calculate this as the amount required to align the scalar local
433 // variable section up to the RVV alignment.
435 if (RVFI->getRVVStackSize() && (!hasFP(MF) || TRI->hasStackRealignment(MF))) {
436 int ScalarLocalVarSize = FrameSize - RVFI->getCalleeSavedStackSize() -
437 RVFI->getVarArgsSaveSize();
438 if (auto RVVPadding =
439 offsetToAlignment(ScalarLocalVarSize, RVFI->getRVVStackAlign()))
440 RVFI->setRVVPadding(RVVPadding);
441 }
442}
443
444// Returns the stack size including RVV padding (when required), rounded back
445// up to the required stack alignment.
447 const MachineFunction &MF) const {
448 const MachineFrameInfo &MFI = MF.getFrameInfo();
449 auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
450 return alignTo(MFI.getStackSize() + RVFI->getRVVPadding(), getStackAlign());
451}
452
455 const std::vector<CalleeSavedInfo> &CSI) {
456 const MachineFrameInfo &MFI = MF.getFrameInfo();
458
459 for (auto &CS : CSI) {
460 int FI = CS.getFrameIdx();
461 if (FI >= 0 && MFI.getStackID(FI) == TargetStackID::Default)
462 NonLibcallCSI.push_back(CS);
463 }
464
465 return NonLibcallCSI;
466}
467
470 const std::vector<CalleeSavedInfo> &CSI) {
471 const MachineFrameInfo &MFI = MF.getFrameInfo();
473
474 for (auto &CS : CSI) {
475 int FI = CS.getFrameIdx();
476 if (FI >= 0 && MFI.getStackID(FI) == TargetStackID::ScalableVector)
477 RVVCSI.push_back(CS);
478 }
479
480 return RVVCSI;
481}
482
485 const std::vector<CalleeSavedInfo> &CSI) {
486 auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
487
488 SmallVector<CalleeSavedInfo, 8> PushOrLibCallsCSI;
489 if (!RVFI->useSaveRestoreLibCalls(MF) && !RVFI->isPushable(MF))
490 return PushOrLibCallsCSI;
491
492 for (const auto &CS : CSI) {
493 const auto *FII = llvm::find_if(
494 FixedCSRFIMap, [&](auto P) { return P.first == CS.getReg(); });
495 if (FII != std::end(FixedCSRFIMap))
496 PushOrLibCallsCSI.push_back(CS);
497 }
498
499 return PushOrLibCallsCSI;
500}
501
502void RISCVFrameLowering::allocateAndProbeStackForRVV(
504 MachineBasicBlock::iterator MBBI, const DebugLoc &DL, int64_t Amount,
505 MachineInstr::MIFlag Flag, bool EmitCFI, bool DynAllocation) const {
506 assert(Amount != 0 && "Did not need to adjust stack pointer for RVV.");
507
508 // Emit a variable-length allocation probing loop.
509
510 // Get VLEN in TargetReg
512 Register TargetReg = RISCV::X6;
513 uint32_t NumOfVReg = Amount / (RISCV::RVVBitsPerBlock / 8);
514 BuildMI(MBB, MBBI, DL, TII->get(RISCV::PseudoReadVLENB), TargetReg)
515 .setMIFlag(Flag);
516 TII->mulImm(MF, MBB, MBBI, DL, TargetReg, NumOfVReg, Flag);
517
518 if (EmitCFI) {
519 // Set the CFA register to TargetReg.
520 unsigned Reg = STI.getRegisterInfo()->getDwarfRegNum(TargetReg, true);
521 unsigned CFIIndex =
522 MF.addFrameInst(MCCFIInstruction::cfiDefCfa(nullptr, Reg, -Amount));
523 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
524 .addCFIIndex(CFIIndex)
526 }
527
528 // It will be expanded to a probe loop in `inlineStackProbe`.
529 BuildMI(MBB, MBBI, DL, TII->get(RISCV::PROBED_STACKALLOC_RVV))
530 .addReg(SPReg)
531 .addReg(TargetReg);
532
533 if (EmitCFI) {
534 // Set the CFA register back to SP.
535 unsigned Reg = STI.getRegisterInfo()->getDwarfRegNum(SPReg, true);
536 unsigned CFIIndex =
538 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
539 .addCFIIndex(CFIIndex)
541 }
542
543 // SUB SP, SP, T1
544 BuildMI(MBB, MBBI, DL, TII->get(RISCV::SUB), SPReg)
545 .addReg(SPReg)
546 .addReg(TargetReg)
547 .setMIFlag(Flag);
548
549 // If we have a dynamic allocation later we need to probe any residuals.
550 if (DynAllocation) {
551 BuildMI(MBB, MBBI, DL, TII->get(STI.is64Bit() ? RISCV::SD : RISCV::SW))
552 .addReg(RISCV::X0)
553 .addReg(SPReg)
554 .addImm(0)
556 }
557}
558
561 int FixedOffset, int ScalableOffset,
562 llvm::raw_string_ostream &Comment) {
563 unsigned DwarfVLenB = TRI.getDwarfRegNum(RISCV::VLENB, true);
564 uint8_t Buffer[16];
565 if (FixedOffset) {
566 Expr.push_back(dwarf::DW_OP_consts);
567 Expr.append(Buffer, Buffer + encodeSLEB128(FixedOffset, Buffer));
568 Expr.push_back((uint8_t)dwarf::DW_OP_plus);
569 Comment << (FixedOffset < 0 ? " - " : " + ") << std::abs(FixedOffset);
570 }
571
572 Expr.push_back((uint8_t)dwarf::DW_OP_consts);
573 Expr.append(Buffer, Buffer + encodeSLEB128(ScalableOffset, Buffer));
574
575 Expr.push_back((uint8_t)dwarf::DW_OP_bregx);
576 Expr.append(Buffer, Buffer + encodeULEB128(DwarfVLenB, Buffer));
577 Expr.push_back(0);
578
579 Expr.push_back((uint8_t)dwarf::DW_OP_mul);
580 Expr.push_back((uint8_t)dwarf::DW_OP_plus);
581
582 Comment << (ScalableOffset < 0 ? " - " : " + ") << std::abs(ScalableOffset)
583 << " * vlenb";
584}
585
587 Register Reg,
588 uint64_t FixedOffset,
589 uint64_t ScalableOffset) {
590 assert(ScalableOffset != 0 && "Did not need to adjust CFA for RVV");
591 SmallString<64> Expr;
592 std::string CommentBuffer;
593 llvm::raw_string_ostream Comment(CommentBuffer);
594 // Build up the expression (Reg + FixedOffset + ScalableOffset * VLENB).
595 unsigned DwarfReg = TRI.getDwarfRegNum(Reg, true);
596 Expr.push_back((uint8_t)(dwarf::DW_OP_breg0 + DwarfReg));
597 Expr.push_back(0);
598 if (Reg == SPReg)
599 Comment << "sp";
600 else
601 Comment << printReg(Reg, &TRI);
602
603 appendScalableVectorExpression(TRI, Expr, FixedOffset, ScalableOffset,
604 Comment);
605
606 SmallString<64> DefCfaExpr;
607 uint8_t Buffer[16];
608 DefCfaExpr.push_back(dwarf::DW_CFA_def_cfa_expression);
609 DefCfaExpr.append(Buffer, Buffer + encodeULEB128(Expr.size(), Buffer));
610 DefCfaExpr.append(Expr.str());
611
612 return MCCFIInstruction::createEscape(nullptr, DefCfaExpr.str(), SMLoc(),
613 Comment.str());
614}
615
617 Register Reg, uint64_t FixedOffset,
618 uint64_t ScalableOffset) {
619 assert(ScalableOffset != 0 && "Did not need to adjust CFA for RVV");
620 SmallString<64> Expr;
621 std::string CommentBuffer;
622 llvm::raw_string_ostream Comment(CommentBuffer);
623 Comment << printReg(Reg, &TRI) << " @ cfa";
624
625 // Build up the expression (FixedOffset + ScalableOffset * VLENB).
626 appendScalableVectorExpression(TRI, Expr, FixedOffset, ScalableOffset,
627 Comment);
628
629 SmallString<64> DefCfaExpr;
630 uint8_t Buffer[16];
631 unsigned DwarfReg = TRI.getDwarfRegNum(Reg, true);
632 DefCfaExpr.push_back(dwarf::DW_CFA_expression);
633 DefCfaExpr.append(Buffer, Buffer + encodeULEB128(DwarfReg, Buffer));
634 DefCfaExpr.append(Buffer, Buffer + encodeULEB128(Expr.size(), Buffer));
635 DefCfaExpr.append(Expr.str());
636
637 return MCCFIInstruction::createEscape(nullptr, DefCfaExpr.str(), SMLoc(),
638 Comment.str());
639}
640
641// Allocate stack space and probe it if necessary.
645 uint64_t RealStackSize, bool EmitCFI,
646 bool NeedProbe, uint64_t ProbeSize,
647 bool DynAllocation) const {
648 DebugLoc DL;
651 bool IsRV64 = STI.is64Bit();
652
653 // Simply allocate the stack if it's not big enough to require a probe.
654 if (!NeedProbe || Offset <= ProbeSize) {
657
658 if (EmitCFI) {
659 // Emit ".cfi_def_cfa_offset RealStackSize"
660 unsigned CFIIndex = MF.addFrameInst(
661 MCCFIInstruction::cfiDefCfaOffset(nullptr, RealStackSize));
662 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
663 .addCFIIndex(CFIIndex)
665 }
666
667 if (NeedProbe && DynAllocation) {
668 // s[d|w] zero, 0(sp)
669 BuildMI(MBB, MBBI, DL, TII->get(IsRV64 ? RISCV::SD : RISCV::SW))
670 .addReg(RISCV::X0)
671 .addReg(SPReg)
672 .addImm(0)
674 }
675
676 return;
677 }
678
679 // Unroll the probe loop depending on the number of iterations.
680 if (Offset < ProbeSize * 5) {
681 uint64_t CurrentOffset = 0;
682 while (CurrentOffset + ProbeSize <= Offset) {
683 RI->adjustReg(MBB, MBBI, DL, SPReg, SPReg,
685 getStackAlign());
686 // s[d|w] zero, 0(sp)
687 BuildMI(MBB, MBBI, DL, TII->get(IsRV64 ? RISCV::SD : RISCV::SW))
688 .addReg(RISCV::X0)
689 .addReg(SPReg)
690 .addImm(0)
692
693 CurrentOffset += ProbeSize;
694 if (EmitCFI) {
695 // Emit ".cfi_def_cfa_offset CurrentOffset"
696 unsigned CFIIndex = MF.addFrameInst(
697 MCCFIInstruction::cfiDefCfaOffset(nullptr, CurrentOffset));
698 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
699 .addCFIIndex(CFIIndex)
701 }
702 }
703
704 uint64_t Residual = Offset - CurrentOffset;
705 if (Residual) {
706 RI->adjustReg(MBB, MBBI, DL, SPReg, SPReg,
708 getStackAlign());
709 if (EmitCFI) {
710 // Emit ".cfi_def_cfa_offset Offset"
711 unsigned CFIIndex =
713 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
714 .addCFIIndex(CFIIndex)
716 }
717
718 if (DynAllocation) {
719 // s[d|w] zero, 0(sp)
720 BuildMI(MBB, MBBI, DL, TII->get(IsRV64 ? RISCV::SD : RISCV::SW))
721 .addReg(RISCV::X0)
722 .addReg(SPReg)
723 .addImm(0)
725 }
726 }
727
728 return;
729 }
730
731 // Emit a variable-length allocation probing loop.
732 uint64_t RoundedSize = alignDown(Offset, ProbeSize);
733 uint64_t Residual = Offset - RoundedSize;
734
735 Register TargetReg = RISCV::X6;
736 // SUB TargetReg, SP, RoundedSize
737 RI->adjustReg(MBB, MBBI, DL, TargetReg, SPReg,
739 getStackAlign());
740
741 if (EmitCFI) {
742 // Set the CFA register to TargetReg.
743 unsigned Reg = STI.getRegisterInfo()->getDwarfRegNum(TargetReg, true);
744 unsigned CFIIndex =
745 MF.addFrameInst(MCCFIInstruction::cfiDefCfa(nullptr, Reg, RoundedSize));
746 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
747 .addCFIIndex(CFIIndex)
749 }
750
751 // It will be expanded to a probe loop in `inlineStackProbe`.
752 BuildMI(MBB, MBBI, DL, TII->get(RISCV::PROBED_STACKALLOC))
753 .addReg(SPReg)
754 .addReg(TargetReg);
755
756 if (EmitCFI) {
757 // Set the CFA register back to SP.
758 unsigned Reg = STI.getRegisterInfo()->getDwarfRegNum(SPReg, true);
759 unsigned CFIIndex =
761 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
762 .addCFIIndex(CFIIndex)
764 }
765
766 if (Residual) {
769 if (DynAllocation) {
770 // s[d|w] zero, 0(sp)
771 BuildMI(MBB, MBBI, DL, TII->get(IsRV64 ? RISCV::SD : RISCV::SW))
772 .addReg(RISCV::X0)
773 .addReg(SPReg)
774 .addImm(0)
776 }
777 }
778
779 if (EmitCFI) {
780 // Emit ".cfi_def_cfa_offset Offset"
781 unsigned CFIIndex =
783 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
784 .addCFIIndex(CFIIndex)
786 }
787}
788
790 MachineBasicBlock &MBB) const {
791 MachineFrameInfo &MFI = MF.getFrameInfo();
792 auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
796
798
799 // Debug location must be unknown since the first debug location is used
800 // to determine the end of the prologue.
801 DebugLoc DL;
802
803 // All calls are tail calls in GHC calling conv, and functions have no
804 // prologue/epilogue.
806 return;
807
808 // Emit prologue for shadow call stack.
809 emitSCSPrologue(MF, MBB, MBBI, DL);
810
811 auto FirstFrameSetup = MBBI;
812
813 // Since spillCalleeSavedRegisters may have inserted a libcall, skip past
814 // any instructions marked as FrameSetup
815 while (MBBI != MBB.end() && MBBI->getFlag(MachineInstr::FrameSetup))
816 ++MBBI;
817
818 // Determine the correct frame layout
819 determineFrameLayout(MF);
820
821 const auto &CSI = MFI.getCalleeSavedInfo();
822
823 // If libcalls are used to spill and restore callee-saved registers, the frame
824 // has two sections; the opaque section managed by the libcalls, and the
825 // section managed by MachineFrameInfo which can also hold callee saved
826 // registers in fixed stack slots, both of which have negative frame indices.
827 // This gets even more complicated when incoming arguments are passed via the
828 // stack, as these too have negative frame indices. An example is detailed
829 // below:
830 //
831 // | incoming arg | <- FI[-3]
832 // | libcallspill |
833 // | calleespill | <- FI[-2]
834 // | calleespill | <- FI[-1]
835 // | this_frame | <- FI[0]
836 //
837 // For negative frame indices, the offset from the frame pointer will differ
838 // depending on which of these groups the frame index applies to.
839 // The following calculates the correct offset knowing the number of callee
840 // saved registers spilt by the two methods.
841 if (int LibCallRegs = getLibCallID(MF, MFI.getCalleeSavedInfo()) + 1) {
842 // Calculate the size of the frame managed by the libcall. The stack
843 // alignment of these libcalls should be the same as how we set it in
844 // getABIStackAlignment.
845 unsigned LibCallFrameSize =
846 alignTo((STI.getXLen() / 8) * LibCallRegs, getStackAlign());
847 RVFI->setLibCallStackSize(LibCallFrameSize);
848
849 unsigned CFIIndex = MF.addFrameInst(
850 MCCFIInstruction::cfiDefCfaOffset(nullptr, LibCallFrameSize));
851 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
852 .addCFIIndex(CFIIndex)
854
855 emitCFIForCSI<CFISaveRegisterEmitter>(MBB, MBBI,
857 }
858
859 // FIXME (note copied from Lanai): This appears to be overallocating. Needs
860 // investigation. Get the number of bytes to allocate from the FrameInfo.
861 uint64_t RealStackSize = getStackSizeWithRVVPadding(MF);
862 uint64_t StackSize = RealStackSize - RVFI->getReservedSpillsSize();
863 uint64_t RVVStackSize = RVFI->getRVVStackSize();
864
865 // Early exit if there is no need to allocate on the stack
866 if (RealStackSize == 0 && !MFI.adjustsStack() && RVVStackSize == 0)
867 return;
868
869 // If the stack pointer has been marked as reserved, then produce an error if
870 // the frame requires stack allocation
873 MF.getFunction(), "Stack pointer required, but has been reserved."});
874
875 uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF);
876 // Split the SP adjustment to reduce the offsets of callee saved spill.
877 if (FirstSPAdjustAmount) {
878 StackSize = FirstSPAdjustAmount;
879 RealStackSize = FirstSPAdjustAmount;
880 }
881
882 if (RVFI->isPushable(MF) && FirstFrameSetup != MBB.end() &&
883 FirstFrameSetup->getOpcode() == RISCV::CM_PUSH) {
884 // Use available stack adjustment in push instruction to allocate additional
885 // stack space. Align the stack size down to a multiple of 16. This is
886 // needed for RVE.
887 // FIXME: Can we increase the stack size to a multiple of 16 instead?
888 uint64_t Spimm =
889 std::min(alignDown(StackSize, 16), static_cast<uint64_t>(48));
890 FirstFrameSetup->getOperand(1).setImm(Spimm);
891 StackSize -= Spimm;
892
893 unsigned CFIIndex = MF.addFrameInst(
894 MCCFIInstruction::cfiDefCfaOffset(nullptr, RealStackSize - StackSize));
895 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
896 .addCFIIndex(CFIIndex)
898
899 emitCFIForCSI<CFISaveRegisterEmitter>(MBB, MBBI,
901 }
902
903 // Allocate space on the stack if necessary.
904 auto &Subtarget = MF.getSubtarget<RISCVSubtarget>();
905 const RISCVTargetLowering *TLI = Subtarget.getTargetLowering();
906 bool NeedProbe = TLI->hasInlineStackProbe(MF);
907 uint64_t ProbeSize = TLI->getStackProbeSize(MF, getStackAlign());
908 bool DynAllocation =
909 MF.getInfo<RISCVMachineFunctionInfo>()->hasDynamicAllocation();
910 if (StackSize != 0)
911 allocateStack(MBB, MBBI, MF, StackSize, RealStackSize, /*EmitCFI=*/true,
912 NeedProbe, ProbeSize, DynAllocation);
913
914 // The frame pointer is callee-saved, and code has been generated for us to
915 // save it to the stack. We need to skip over the storing of callee-saved
916 // registers as the frame pointer must be modified after it has been saved
917 // to the stack, not before.
918 // FIXME: assumes exactly one instruction is used to save each callee-saved
919 // register.
920 std::advance(MBBI, getUnmanagedCSI(MF, CSI).size());
921
922 // Iterate over list of callee-saved registers and emit .cfi_offset
923 // directives.
924 emitCFIForCSI<CFISaveRegisterEmitter>(MBB, MBBI, getUnmanagedCSI(MF, CSI));
925
926 // Generate new FP.
927 if (hasFP(MF)) {
930 MF.getFunction(), "Frame pointer required, but has been reserved."});
931 // The frame pointer does need to be reserved from register allocation.
932 assert(MF.getRegInfo().isReserved(FPReg) && "FP not reserved");
933
934 RI->adjustReg(MBB, MBBI, DL, FPReg, SPReg,
935 StackOffset::getFixed(RealStackSize - RVFI->getVarArgsSaveSize()),
937
938 // Emit ".cfi_def_cfa $fp, RVFI->getVarArgsSaveSize()"
939 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::cfiDefCfa(
940 nullptr, RI->getDwarfRegNum(FPReg, true), RVFI->getVarArgsSaveSize()));
941 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
942 .addCFIIndex(CFIIndex)
944 }
945
946 uint64_t SecondSPAdjustAmount = 0;
947 // Emit the second SP adjustment after saving callee saved registers.
948 if (FirstSPAdjustAmount) {
949 SecondSPAdjustAmount = getStackSizeWithRVVPadding(MF) - FirstSPAdjustAmount;
950 assert(SecondSPAdjustAmount > 0 &&
951 "SecondSPAdjustAmount should be greater than zero");
952
953 allocateStack(MBB, MBBI, MF, SecondSPAdjustAmount,
954 getStackSizeWithRVVPadding(MF), !hasFP(MF), NeedProbe,
955 ProbeSize, DynAllocation);
956 }
957
958 if (RVVStackSize) {
959 if (NeedProbe) {
960 allocateAndProbeStackForRVV(MF, MBB, MBBI, DL, RVVStackSize,
962 DynAllocation);
963 } else {
964 // We must keep the stack pointer aligned through any intermediate
965 // updates.
966 RI->adjustReg(MBB, MBBI, DL, SPReg, SPReg,
967 StackOffset::getScalable(-RVVStackSize),
969 }
970
971 if (!hasFP(MF)) {
972 // Emit .cfi_def_cfa_expression "sp + StackSize + RVVStackSize * vlenb".
973 unsigned CFIIndex = MF.addFrameInst(createDefCFAExpression(
974 *RI, SPReg, getStackSizeWithRVVPadding(MF), RVVStackSize / 8));
975 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
976 .addCFIIndex(CFIIndex)
978 }
979
980 std::advance(MBBI, getRVVCalleeSavedInfo(MF, CSI).size());
981 emitCalleeSavedRVVPrologCFI(MBB, MBBI, hasFP(MF));
982 }
983
984 if (hasFP(MF)) {
985 // Realign Stack
987 if (RI->hasStackRealignment(MF)) {
988 Align MaxAlignment = MFI.getMaxAlign();
989
991 if (isInt<12>(-(int)MaxAlignment.value())) {
992 BuildMI(MBB, MBBI, DL, TII->get(RISCV::ANDI), SPReg)
993 .addReg(SPReg)
994 .addImm(-(int)MaxAlignment.value())
996 } else {
997 unsigned ShiftAmount = Log2(MaxAlignment);
998 Register VR =
999 MF.getRegInfo().createVirtualRegister(&RISCV::GPRRegClass);
1000 BuildMI(MBB, MBBI, DL, TII->get(RISCV::SRLI), VR)
1001 .addReg(SPReg)
1002 .addImm(ShiftAmount)
1004 BuildMI(MBB, MBBI, DL, TII->get(RISCV::SLLI), SPReg)
1005 .addReg(VR)
1006 .addImm(ShiftAmount)
1008 }
1009 if (NeedProbe && RVVStackSize == 0) {
1010 // Do a probe if the align + size allocated just passed the probe size
1011 // and was not yet probed.
1012 if (SecondSPAdjustAmount < ProbeSize &&
1013 SecondSPAdjustAmount + MaxAlignment.value() >= ProbeSize) {
1014 bool IsRV64 = STI.is64Bit();
1015 BuildMI(MBB, MBBI, DL, TII->get(IsRV64 ? RISCV::SD : RISCV::SW))
1016 .addReg(RISCV::X0)
1017 .addReg(SPReg)
1018 .addImm(0)
1020 }
1021 }
1022 // FP will be used to restore the frame in the epilogue, so we need
1023 // another base register BP to record SP after re-alignment. SP will
1024 // track the current stack after allocating variable sized objects.
1025 if (hasBP(MF)) {
1026 // move BP, SP
1027 BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADDI), BPReg)
1028 .addReg(SPReg)
1029 .addImm(0)
1031 }
1032 }
1033 }
1034}
1035
1036void RISCVFrameLowering::deallocateStack(MachineFunction &MF,
1039 const DebugLoc &DL,
1040 uint64_t &StackSize,
1041 int64_t CFAOffset) const {
1044
1045 RI->adjustReg(MBB, MBBI, DL, SPReg, SPReg, StackOffset::getFixed(StackSize),
1047 StackSize = 0;
1048
1049 unsigned CFIIndex =
1050 MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, CFAOffset));
1051 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
1052 .addCFIIndex(CFIIndex)
1054}
1055
1057 MachineBasicBlock &MBB) const {
1059 MachineFrameInfo &MFI = MF.getFrameInfo();
1060 auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
1062
1063 // All calls are tail calls in GHC calling conv, and functions have no
1064 // prologue/epilogue.
1066 return;
1067
1068 // Get the insert location for the epilogue. If there were no terminators in
1069 // the block, get the last instruction.
1071 DebugLoc DL;
1072 if (!MBB.empty()) {
1074 if (MBBI != MBB.end())
1075 DL = MBBI->getDebugLoc();
1076
1078
1079 // If callee-saved registers are saved via libcall, place stack adjustment
1080 // before this call.
1081 while (MBBI != MBB.begin() &&
1082 std::prev(MBBI)->getFlag(MachineInstr::FrameDestroy))
1083 --MBBI;
1084 }
1085
1086 const auto &CSI = MFI.getCalleeSavedInfo();
1087
1088 // Skip to before the restores of scalar callee-saved registers
1089 // FIXME: assumes exactly one instruction is used to restore each
1090 // callee-saved register.
1091 auto LastFrameDestroy = std::prev(MBBI, getUnmanagedCSI(MF, CSI).size());
1092
1093 uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF);
1094 uint64_t RealStackSize = FirstSPAdjustAmount ? FirstSPAdjustAmount
1096 uint64_t StackSize = FirstSPAdjustAmount ? FirstSPAdjustAmount
1098 RVFI->getReservedSpillsSize();
1099 uint64_t FPOffset = RealStackSize - RVFI->getVarArgsSaveSize();
1100 uint64_t RVVStackSize = RVFI->getRVVStackSize();
1101
1102 bool RestoreSPFromFP = RI->hasStackRealignment(MF) ||
1104 if (RVVStackSize) {
1105 // If RestoreSPFromFP the stack pointer will be restored using the frame
1106 // pointer value.
1107 if (!RestoreSPFromFP)
1108 RI->adjustReg(MBB, LastFrameDestroy, DL, SPReg, SPReg,
1109 StackOffset::getScalable(RVVStackSize),
1111
1112 if (!hasFP(MF)) {
1113 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::cfiDefCfa(
1114 nullptr, RI->getDwarfRegNum(SPReg, true), RealStackSize));
1115 BuildMI(MBB, LastFrameDestroy, DL,
1116 TII->get(TargetOpcode::CFI_INSTRUCTION))
1117 .addCFIIndex(CFIIndex)
1119 }
1120
1121 emitCalleeSavedRVVEpilogCFI(MBB, LastFrameDestroy);
1122 }
1123
1124 if (FirstSPAdjustAmount) {
1125 uint64_t SecondSPAdjustAmount =
1126 getStackSizeWithRVVPadding(MF) - FirstSPAdjustAmount;
1127 assert(SecondSPAdjustAmount > 0 &&
1128 "SecondSPAdjustAmount should be greater than zero");
1129
1130 // If RestoreSPFromFP the stack pointer will be restored using the frame
1131 // pointer value.
1132 if (!RestoreSPFromFP)
1133 RI->adjustReg(MBB, LastFrameDestroy, DL, SPReg, SPReg,
1134 StackOffset::getFixed(SecondSPAdjustAmount),
1136
1137 if (!hasFP(MF)) {
1138 unsigned CFIIndex = MF.addFrameInst(
1139 MCCFIInstruction::cfiDefCfaOffset(nullptr, FirstSPAdjustAmount));
1140 BuildMI(MBB, LastFrameDestroy, DL,
1141 TII->get(TargetOpcode::CFI_INSTRUCTION))
1142 .addCFIIndex(CFIIndex)
1144 }
1145 }
1146
1147 // Restore the stack pointer using the value of the frame pointer. Only
1148 // necessary if the stack pointer was modified, meaning the stack size is
1149 // unknown.
1150 //
1151 // In order to make sure the stack point is right through the EH region,
1152 // we also need to restore stack pointer from the frame pointer if we
1153 // don't preserve stack space within prologue/epilogue for outgoing variables,
1154 // normally it's just checking the variable sized object is present or not
1155 // is enough, but we also don't preserve that at prologue/epilogue when
1156 // have vector objects in stack.
1157 if (RestoreSPFromFP) {
1158 assert(hasFP(MF) && "frame pointer should not have been eliminated");
1159 RI->adjustReg(MBB, LastFrameDestroy, DL, SPReg, FPReg,
1161 getStackAlign());
1162 }
1163
1164 if (hasFP(MF)) {
1165 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::cfiDefCfa(
1166 nullptr, RI->getDwarfRegNum(SPReg, true), RealStackSize));
1167 BuildMI(MBB, LastFrameDestroy, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
1168 .addCFIIndex(CFIIndex)
1170 }
1171
1172 if (getLibCallID(MF, CSI) != -1) {
1173 // tail __riscv_restore_[0-12] instruction is considered as a terminator,
1174 // therefor it is unnecessary to place any CFI instructions after it. Just
1175 // deallocate stack if needed and return.
1176 if (StackSize != 0)
1177 deallocateStack(MF, MBB, MBBI, DL, StackSize,
1178 RVFI->getLibCallStackSize());
1179
1180 // Emit epilogue for shadow call stack.
1181 emitSCSEpilogue(MF, MBB, MBBI, DL);
1182 return;
1183 }
1184
1185 // Recover callee-saved registers.
1186 emitCFIForCSI<CFIRestoreRegisterEmitter>(MBB, MBBI, getUnmanagedCSI(MF, CSI));
1187
1188 bool ApplyPop = RVFI->isPushable(MF) && MBBI != MBB.end() &&
1189 MBBI->getOpcode() == RISCV::CM_POP;
1190 if (ApplyPop) {
1191 // Use available stack adjustment in pop instruction to deallocate stack
1192 // space. Align the stack size down to a multiple of 16. This is needed for
1193 // RVE.
1194 // FIXME: Can we increase the stack size to a multiple of 16 instead?
1195 uint64_t Spimm =
1196 std::min(alignDown(StackSize, 16), static_cast<uint64_t>(48));
1197 MBBI->getOperand(1).setImm(Spimm);
1198 StackSize -= Spimm;
1199
1200 if (StackSize != 0)
1201 deallocateStack(MF, MBB, MBBI, DL, StackSize,
1202 /*stack_adj of cm.pop instr*/ RealStackSize - StackSize);
1203
1204 auto NextI = next_nodbg(MBBI, MBB.end());
1205 if (NextI == MBB.end() || NextI->getOpcode() != RISCV::PseudoRET) {
1206 ++MBBI;
1207
1208 emitCFIForCSI<CFIRestoreRegisterEmitter>(
1210
1211 // Update CFA offset. After CM_POP SP should be equal to CFA, so CFA
1212 // offset should be a zero.
1213 unsigned CFIIndex =
1215 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
1216 .addCFIIndex(CFIIndex)
1218 }
1219 }
1220
1221 // Deallocate stack if StackSize isn't a zero yet
1222 if (StackSize != 0)
1223 deallocateStack(MF, MBB, MBBI, DL, StackSize, 0);
1224
1225 // Emit epilogue for shadow call stack.
1226 emitSCSEpilogue(MF, MBB, MBBI, DL);
1227}
1228
1231 Register &FrameReg) const {
1232 const MachineFrameInfo &MFI = MF.getFrameInfo();
1234 const auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
1235
1236 // Callee-saved registers should be referenced relative to the stack
1237 // pointer (positive offset), otherwise use the frame pointer (negative
1238 // offset).
1239 const auto &CSI = getUnmanagedCSI(MF, MFI.getCalleeSavedInfo());
1240 int MinCSFI = 0;
1241 int MaxCSFI = -1;
1243 auto StackID = MFI.getStackID(FI);
1244
1245 assert((StackID == TargetStackID::Default ||
1246 StackID == TargetStackID::ScalableVector) &&
1247 "Unexpected stack ID for the frame object.");
1248 if (StackID == TargetStackID::Default) {
1249 assert(getOffsetOfLocalArea() == 0 && "LocalAreaOffset is not 0!");
1251 MFI.getOffsetAdjustment());
1252 } else if (StackID == TargetStackID::ScalableVector) {
1254 }
1255
1256 uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF);
1257
1258 if (CSI.size()) {
1259 MinCSFI = CSI[0].getFrameIdx();
1260 MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();
1261 }
1262
1263 if (FI >= MinCSFI && FI <= MaxCSFI) {
1264 FrameReg = SPReg;
1265
1266 if (FirstSPAdjustAmount)
1267 Offset += StackOffset::getFixed(FirstSPAdjustAmount);
1268 else
1270 return Offset;
1271 }
1272
1273 if (RI->hasStackRealignment(MF) && !MFI.isFixedObjectIndex(FI)) {
1274 // If the stack was realigned, the frame pointer is set in order to allow
1275 // SP to be restored, so we need another base register to record the stack
1276 // after realignment.
1277 // |--------------------------| -- <-- FP
1278 // | callee-allocated save | | <----|
1279 // | area for register varargs| | |
1280 // |--------------------------| | |
1281 // | callee-saved registers | | |
1282 // |--------------------------| -- |
1283 // | realignment (the size of | | |
1284 // | this area is not counted | | |
1285 // | in MFI.getStackSize()) | | |
1286 // |--------------------------| -- |-- MFI.getStackSize()
1287 // | RVV alignment padding | | |
1288 // | (not counted in | | |
1289 // | MFI.getStackSize() but | | |
1290 // | counted in | | |
1291 // | RVFI.getRVVStackSize()) | | |
1292 // |--------------------------| -- |
1293 // | RVV objects | | |
1294 // | (not counted in | | |
1295 // | MFI.getStackSize()) | | |
1296 // |--------------------------| -- |
1297 // | padding before RVV | | |
1298 // | (not counted in | | |
1299 // | MFI.getStackSize() or in | | |
1300 // | RVFI.getRVVStackSize()) | | |
1301 // |--------------------------| -- |
1302 // | scalar local variables | | <----'
1303 // |--------------------------| -- <-- BP (if var sized objects present)
1304 // | VarSize objects | |
1305 // |--------------------------| -- <-- SP
1306 if (hasBP(MF)) {
1307 FrameReg = RISCVABI::getBPReg();
1308 } else {
1309 // VarSize objects must be empty in this case!
1310 assert(!MFI.hasVarSizedObjects());
1311 FrameReg = SPReg;
1312 }
1313 } else {
1314 FrameReg = RI->getFrameRegister(MF);
1315 }
1316
1317 if (FrameReg == FPReg) {
1318 Offset += StackOffset::getFixed(RVFI->getVarArgsSaveSize());
1319 // When using FP to access scalable vector objects, we need to minus
1320 // the frame size.
1321 //
1322 // |--------------------------| -- <-- FP
1323 // | callee-allocated save | |
1324 // | area for register varargs| |
1325 // |--------------------------| |
1326 // | callee-saved registers | |
1327 // |--------------------------| | MFI.getStackSize()
1328 // | scalar local variables | |
1329 // |--------------------------| -- (Offset of RVV objects is from here.)
1330 // | RVV objects |
1331 // |--------------------------|
1332 // | VarSize objects |
1333 // |--------------------------| <-- SP
1335 assert(!RI->hasStackRealignment(MF) &&
1336 "Can't index across variable sized realign");
1337 // We don't expect any extra RVV alignment padding, as the stack size
1338 // and RVV object sections should be correct aligned in their own
1339 // right.
1341 "Inconsistent stack layout");
1343 }
1344 return Offset;
1345 }
1346
1347 // This case handles indexing off both SP and BP.
1348 // If indexing off SP, there must not be any var sized objects
1349 assert(FrameReg == RISCVABI::getBPReg() || !MFI.hasVarSizedObjects());
1350
1351 // When using SP to access frame objects, we need to add RVV stack size.
1352 //
1353 // |--------------------------| -- <-- FP
1354 // | callee-allocated save | | <----|
1355 // | area for register varargs| | |
1356 // |--------------------------| | |
1357 // | callee-saved registers | | |
1358 // |--------------------------| -- |
1359 // | RVV alignment padding | | |
1360 // | (not counted in | | |
1361 // | MFI.getStackSize() but | | |
1362 // | counted in | | |
1363 // | RVFI.getRVVStackSize()) | | |
1364 // |--------------------------| -- |
1365 // | RVV objects | | |-- MFI.getStackSize()
1366 // | (not counted in | | |
1367 // | MFI.getStackSize()) | | |
1368 // |--------------------------| -- |
1369 // | padding before RVV | | |
1370 // | (not counted in | | |
1371 // | MFI.getStackSize()) | | |
1372 // |--------------------------| -- |
1373 // | scalar local variables | | <----'
1374 // |--------------------------| -- <-- BP (if var sized objects present)
1375 // | VarSize objects | |
1376 // |--------------------------| -- <-- SP
1377 //
1378 // The total amount of padding surrounding RVV objects is described by
1379 // RVV->getRVVPadding() and it can be zero. It allows us to align the RVV
1380 // objects to the required alignment.
1381 if (MFI.getStackID(FI) == TargetStackID::Default) {
1382 if (MFI.isFixedObjectIndex(FI)) {
1383 assert(!RI->hasStackRealignment(MF) &&
1384 "Can't index across variable sized realign");
1386 RVFI->getRVVStackSize());
1387 } else {
1389 }
1390 } else if (MFI.getStackID(FI) == TargetStackID::ScalableVector) {
1391 // Ensure the base of the RVV stack is correctly aligned: add on the
1392 // alignment padding.
1393 int ScalarLocalVarSize = MFI.getStackSize() -
1394 RVFI->getCalleeSavedStackSize() -
1395 RVFI->getVarArgsSaveSize() + RVFI->getRVVPadding();
1396 Offset += StackOffset::get(ScalarLocalVarSize, RVFI->getRVVStackSize());
1397 }
1398 return Offset;
1399}
1400
1402 BitVector &SavedRegs,
1403 RegScavenger *RS) const {
1405 // Unconditionally spill RA and FP only if the function uses a frame
1406 // pointer.
1407 if (hasFP(MF)) {
1408 SavedRegs.set(RAReg);
1409 SavedRegs.set(FPReg);
1410 }
1411 // Mark BP as used if function has dedicated base pointer.
1412 if (hasBP(MF))
1413 SavedRegs.set(RISCVABI::getBPReg());
1414
1415 // When using cm.push/pop we must save X27 if we save X26.
1416 auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
1417 if (RVFI->isPushable(MF) && SavedRegs.test(RISCV::X26))
1418 SavedRegs.set(RISCV::X27);
1419}
1420
1421std::pair<int64_t, Align>
1422RISCVFrameLowering::assignRVVStackObjectOffsets(MachineFunction &MF) const {
1423 MachineFrameInfo &MFI = MF.getFrameInfo();
1424 // Create a buffer of RVV objects to allocate.
1425 SmallVector<int, 8> ObjectsToAllocate;
1426 auto pushRVVObjects = [&](int FIBegin, int FIEnd) {
1427 for (int I = FIBegin, E = FIEnd; I != E; ++I) {
1428 unsigned StackID = MFI.getStackID(I);
1429 if (StackID != TargetStackID::ScalableVector)
1430 continue;
1431 if (MFI.isDeadObjectIndex(I))
1432 continue;
1433
1434 ObjectsToAllocate.push_back(I);
1435 }
1436 };
1437 // First push RVV Callee Saved object, then push RVV stack object
1438 std::vector<CalleeSavedInfo> &CSI = MF.getFrameInfo().getCalleeSavedInfo();
1439 const auto &RVVCSI = getRVVCalleeSavedInfo(MF, CSI);
1440 if (!RVVCSI.empty())
1441 pushRVVObjects(RVVCSI[0].getFrameIdx(),
1442 RVVCSI[RVVCSI.size() - 1].getFrameIdx() + 1);
1443 pushRVVObjects(0, MFI.getObjectIndexEnd() - RVVCSI.size());
1444
1445 // The minimum alignment is 16 bytes.
1446 Align RVVStackAlign(16);
1447 const auto &ST = MF.getSubtarget<RISCVSubtarget>();
1448
1449 if (!ST.hasVInstructions()) {
1450 assert(ObjectsToAllocate.empty() &&
1451 "Can't allocate scalable-vector objects without V instructions");
1452 return std::make_pair(0, RVVStackAlign);
1453 }
1454
1455 // Allocate all RVV locals and spills
1456 int64_t Offset = 0;
1457 for (int FI : ObjectsToAllocate) {
1458 // ObjectSize in bytes.
1459 int64_t ObjectSize = MFI.getObjectSize(FI);
1460 auto ObjectAlign =
1461 std::max(Align(RISCV::RVVBitsPerBlock / 8), MFI.getObjectAlign(FI));
1462 // If the data type is the fractional vector type, reserve one vector
1463 // register for it.
1464 if (ObjectSize < (RISCV::RVVBitsPerBlock / 8))
1465 ObjectSize = (RISCV::RVVBitsPerBlock / 8);
1466 Offset = alignTo(Offset + ObjectSize, ObjectAlign);
1467 MFI.setObjectOffset(FI, -Offset);
1468 // Update the maximum alignment of the RVV stack section
1469 RVVStackAlign = std::max(RVVStackAlign, ObjectAlign);
1470 }
1471
1472 uint64_t StackSize = Offset;
1473
1474 // Ensure the alignment of the RVV stack. Since we want the most-aligned
1475 // object right at the bottom (i.e., any padding at the top of the frame),
1476 // readjust all RVV objects down by the alignment padding.
1477 // Stack size and offsets are multiples of vscale, stack alignment is in
1478 // bytes, we can divide stack alignment by minimum vscale to get a maximum
1479 // stack alignment multiple of vscale.
1480 auto VScale =
1481 std::max<uint64_t>(ST.getRealMinVLen() / RISCV::RVVBitsPerBlock, 1);
1482 if (auto RVVStackAlignVScale = RVVStackAlign.value() / VScale) {
1483 if (auto AlignmentPadding =
1484 offsetToAlignment(StackSize, Align(RVVStackAlignVScale))) {
1485 StackSize += AlignmentPadding;
1486 for (int FI : ObjectsToAllocate)
1487 MFI.setObjectOffset(FI, MFI.getObjectOffset(FI) - AlignmentPadding);
1488 }
1489 }
1490
1491 return std::make_pair(StackSize, RVVStackAlign);
1492}
1493
1495 // For RVV spill, scalable stack offsets computing requires up to two scratch
1496 // registers
1497 static constexpr unsigned ScavSlotsNumRVVSpillScalableObject = 2;
1498
1499 // For RVV spill, non-scalable stack offsets computing requires up to one
1500 // scratch register.
1501 static constexpr unsigned ScavSlotsNumRVVSpillNonScalableObject = 1;
1502
1503 // ADDI instruction's destination register can be used for computing
1504 // offsets. So Scalable stack offsets require up to one scratch register.
1505 static constexpr unsigned ScavSlotsADDIScalableObject = 1;
1506
1507 static constexpr unsigned MaxScavSlotsNumKnown =
1508 std::max({ScavSlotsADDIScalableObject, ScavSlotsNumRVVSpillScalableObject,
1509 ScavSlotsNumRVVSpillNonScalableObject});
1510
1511 unsigned MaxScavSlotsNum = 0;
1513 return false;
1514 for (const MachineBasicBlock &MBB : MF)
1515 for (const MachineInstr &MI : MBB) {
1516 bool IsRVVSpill = RISCV::isRVVSpill(MI);
1517 for (auto &MO : MI.operands()) {
1518 if (!MO.isFI())
1519 continue;
1520 bool IsScalableVectorID = MF.getFrameInfo().getStackID(MO.getIndex()) ==
1522 if (IsRVVSpill) {
1523 MaxScavSlotsNum = std::max(
1524 MaxScavSlotsNum, IsScalableVectorID
1525 ? ScavSlotsNumRVVSpillScalableObject
1526 : ScavSlotsNumRVVSpillNonScalableObject);
1527 } else if (MI.getOpcode() == RISCV::ADDI && IsScalableVectorID) {
1528 MaxScavSlotsNum =
1529 std::max(MaxScavSlotsNum, ScavSlotsADDIScalableObject);
1530 }
1531 }
1532 if (MaxScavSlotsNum == MaxScavSlotsNumKnown)
1533 return MaxScavSlotsNumKnown;
1534 }
1535 return MaxScavSlotsNum;
1536}
1537
1538static bool hasRVVFrameObject(const MachineFunction &MF) {
1539 // Originally, the function will scan all the stack objects to check whether
1540 // if there is any scalable vector object on the stack or not. However, it
1541 // causes errors in the register allocator. In issue 53016, it returns false
1542 // before RA because there is no RVV stack objects. After RA, it returns true
1543 // because there are spilling slots for RVV values during RA. It will not
1544 // reserve BP during register allocation and generate BP access in the PEI
1545 // pass due to the inconsistent behavior of the function.
1546 //
1547 // The function is changed to use hasVInstructions() as the return value. It
1548 // is not precise, but it can make the register allocation correct.
1549 //
1550 // FIXME: Find a better way to make the decision or revisit the solution in
1551 // D103622.
1552 //
1553 // Refer to https://github.com/llvm/llvm-project/issues/53016.
1554 return MF.getSubtarget<RISCVSubtarget>().hasVInstructions();
1555}
1556
1558 const RISCVInstrInfo &TII) {
1559 unsigned FnSize = 0;
1560 for (auto &MBB : MF) {
1561 for (auto &MI : MBB) {
1562 // Far branches over 20-bit offset will be relaxed in branch relaxation
1563 // pass. In the worst case, conditional branches will be relaxed into
1564 // the following instruction sequence. Unconditional branches are
1565 // relaxed in the same way, with the exception that there is no first
1566 // branch instruction.
1567 //
1568 // foo
1569 // bne t5, t6, .rev_cond # `TII->getInstSizeInBytes(MI)` bytes
1570 // sd s11, 0(sp) # 4 bytes, or 2 bytes in RVC
1571 // jump .restore, s11 # 8 bytes
1572 // .rev_cond
1573 // bar
1574 // j .dest_bb # 4 bytes, or 2 bytes in RVC
1575 // .restore:
1576 // ld s11, 0(sp) # 4 bytes, or 2 bytes in RVC
1577 // .dest:
1578 // baz
1579 if (MI.isConditionalBranch())
1580 FnSize += TII.getInstSizeInBytes(MI);
1581 if (MI.isConditionalBranch() || MI.isUnconditionalBranch()) {
1583 FnSize += 2 + 8 + 2 + 2;
1584 else
1585 FnSize += 4 + 8 + 4 + 4;
1586 continue;
1587 }
1588
1589 FnSize += TII.getInstSizeInBytes(MI);
1590 }
1591 }
1592 return FnSize;
1593}
1594
1596 MachineFunction &MF, RegScavenger *RS) const {
1597 const RISCVRegisterInfo *RegInfo =
1598 MF.getSubtarget<RISCVSubtarget>().getRegisterInfo();
1599 const RISCVInstrInfo *TII = MF.getSubtarget<RISCVSubtarget>().getInstrInfo();
1600 MachineFrameInfo &MFI = MF.getFrameInfo();
1601 const TargetRegisterClass *RC = &RISCV::GPRRegClass;
1602 auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
1603
1604 int64_t RVVStackSize;
1605 Align RVVStackAlign;
1606 std::tie(RVVStackSize, RVVStackAlign) = assignRVVStackObjectOffsets(MF);
1607
1608 RVFI->setRVVStackSize(RVVStackSize);
1609 RVFI->setRVVStackAlign(RVVStackAlign);
1610
1611 if (hasRVVFrameObject(MF)) {
1612 // Ensure the entire stack is aligned to at least the RVV requirement: some
1613 // scalable-vector object alignments are not considered by the
1614 // target-independent code.
1615 MFI.ensureMaxAlignment(RVVStackAlign);
1616 }
1617
1618 unsigned ScavSlotsNum = 0;
1619
1620 // estimateStackSize has been observed to under-estimate the final stack
1621 // size, so give ourselves wiggle-room by checking for stack size
1622 // representable an 11-bit signed field rather than 12-bits.
1623 if (!isInt<11>(MFI.estimateStackSize(MF)))
1624 ScavSlotsNum = 1;
1625
1626 // Far branches over 20-bit offset require a spill slot for scratch register.
1627 bool IsLargeFunction = !isInt<20>(estimateFunctionSizeInBytes(MF, *TII));
1628 if (IsLargeFunction)
1629 ScavSlotsNum = std::max(ScavSlotsNum, 1u);
1630
1631 // RVV loads & stores have no capacity to hold the immediate address offsets
1632 // so we must always reserve an emergency spill slot if the MachineFunction
1633 // contains any RVV spills.
1634 ScavSlotsNum = std::max(ScavSlotsNum, getScavSlotsNumForRVV(MF));
1635
1636 for (unsigned I = 0; I < ScavSlotsNum; I++) {
1637 int FI = MFI.CreateSpillStackObject(RegInfo->getSpillSize(*RC),
1638 RegInfo->getSpillAlign(*RC));
1640
1641 if (IsLargeFunction && RVFI->getBranchRelaxationScratchFrameIndex() == -1)
1642 RVFI->setBranchRelaxationScratchFrameIndex(FI);
1643 }
1644
1645 unsigned Size = RVFI->getReservedSpillsSize();
1646 for (const auto &Info : MFI.getCalleeSavedInfo()) {
1647 int FrameIdx = Info.getFrameIdx();
1648 if (FrameIdx < 0 || MFI.getStackID(FrameIdx) != TargetStackID::Default)
1649 continue;
1650
1651 Size += MFI.getObjectSize(FrameIdx);
1652 }
1653 RVFI->setCalleeSavedStackSize(Size);
1654}
1655
1656// Not preserve stack space within prologue for outgoing variables when the
1657// function contains variable size objects or there are vector objects accessed
1658// by the frame pointer.
1659// Let eliminateCallFramePseudoInstr preserve stack space for it.
1661 return !MF.getFrameInfo().hasVarSizedObjects() &&
1662 !(hasFP(MF) && hasRVVFrameObject(MF));
1663}
1664
1665// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions.
1669 DebugLoc DL = MI->getDebugLoc();
1670
1671 if (!hasReservedCallFrame(MF)) {
1672 // If space has not been reserved for a call frame, ADJCALLSTACKDOWN and
1673 // ADJCALLSTACKUP must be converted to instructions manipulating the stack
1674 // pointer. This is necessary when there is a variable length stack
1675 // allocation (e.g. alloca), which means it's not possible to allocate
1676 // space for outgoing arguments from within the function prologue.
1677 int64_t Amount = MI->getOperand(0).getImm();
1678
1679 if (Amount != 0) {
1680 // Ensure the stack remains aligned after adjustment.
1681 Amount = alignSPAdjust(Amount);
1682
1683 if (MI->getOpcode() == RISCV::ADJCALLSTACKDOWN)
1684 Amount = -Amount;
1685
1686 const RISCVRegisterInfo &RI = *STI.getRegisterInfo();
1689 }
1690 }
1691
1692 return MBB.erase(MI);
1693}
1694
1695// We would like to split the SP adjustment to reduce prologue/epilogue
1696// as following instructions. In this way, the offset of the callee saved
1697// register could fit in a single store. Supposed that the first sp adjust
1698// amount is 2032.
1699// add sp,sp,-2032
1700// sw ra,2028(sp)
1701// sw s0,2024(sp)
1702// sw s1,2020(sp)
1703// sw s3,2012(sp)
1704// sw s4,2008(sp)
1705// add sp,sp,-64
1708 const auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
1709 const MachineFrameInfo &MFI = MF.getFrameInfo();
1710 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
1711 uint64_t StackSize = getStackSizeWithRVVPadding(MF);
1712
1713 // Disable SplitSPAdjust if save-restore libcall is used. The callee-saved
1714 // registers will be pushed by the save-restore libcalls, so we don't have to
1715 // split the SP adjustment in this case.
1716 if (RVFI->getReservedSpillsSize())
1717 return 0;
1718
1719 // Return the FirstSPAdjustAmount if the StackSize can not fit in a signed
1720 // 12-bit and there exists a callee-saved register needing to be pushed.
1721 if (!isInt<12>(StackSize) && (CSI.size() > 0)) {
1722 // FirstSPAdjustAmount is chosen at most as (2048 - StackAlign) because
1723 // 2048 will cause sp = sp + 2048 in the epilogue to be split into multiple
1724 // instructions. Offsets smaller than 2048 can fit in a single load/store
1725 // instruction, and we have to stick with the stack alignment. 2048 has
1726 // 16-byte alignment. The stack alignment for RV32 and RV64 is 16 and for
1727 // RV32E it is 4. So (2048 - StackAlign) will satisfy the stack alignment.
1728 const uint64_t StackAlign = getStackAlign().value();
1729
1730 // Amount of (2048 - StackAlign) will prevent callee saved and restored
1731 // instructions be compressed, so try to adjust the amount to the largest
1732 // offset that stack compression instructions accept when target supports
1733 // compression instructions.
1734 if (STI.hasStdExtCOrZca()) {
1735 // The compression extensions may support the following instructions:
1736 // riscv32: c.lwsp rd, offset[7:2] => 2^(6 + 2)
1737 // c.swsp rs2, offset[7:2] => 2^(6 + 2)
1738 // c.flwsp rd, offset[7:2] => 2^(6 + 2)
1739 // c.fswsp rs2, offset[7:2] => 2^(6 + 2)
1740 // riscv64: c.ldsp rd, offset[8:3] => 2^(6 + 3)
1741 // c.sdsp rs2, offset[8:3] => 2^(6 + 3)
1742 // c.fldsp rd, offset[8:3] => 2^(6 + 3)
1743 // c.fsdsp rs2, offset[8:3] => 2^(6 + 3)
1744 const uint64_t RVCompressLen = STI.getXLen() * 8;
1745 // Compared with amount (2048 - StackAlign), StackSize needs to
1746 // satisfy the following conditions to avoid using more instructions
1747 // to adjust the sp after adjusting the amount, such as
1748 // StackSize meets the condition (StackSize <= 2048 + RVCompressLen),
1749 // case1: Amount is 2048 - StackAlign: use addi + addi to adjust sp.
1750 // case2: Amount is RVCompressLen: use addi + addi to adjust sp.
1751 auto CanCompress = [&](uint64_t CompressLen) -> bool {
1752 if (StackSize <= 2047 + CompressLen ||
1753 (StackSize > 2048 * 2 - StackAlign &&
1754 StackSize <= 2047 * 2 + CompressLen) ||
1755 StackSize > 2048 * 3 - StackAlign)
1756 return true;
1757
1758 return false;
1759 };
1760 // In the epilogue, addi sp, sp, 496 is used to recover the sp and it
1761 // can be compressed(C.ADDI16SP, offset can be [-512, 496]), but
1762 // addi sp, sp, 512 can not be compressed. So try to use 496 first.
1763 const uint64_t ADDI16SPCompressLen = 496;
1764 if (STI.is64Bit() && CanCompress(ADDI16SPCompressLen))
1765 return ADDI16SPCompressLen;
1766 if (CanCompress(RVCompressLen))
1767 return RVCompressLen;
1768 }
1769 return 2048 - StackAlign;
1770 }
1771 return 0;
1772}
1773
1776 std::vector<CalleeSavedInfo> &CSI, unsigned &MinCSFrameIndex,
1777 unsigned &MaxCSFrameIndex) const {
1778 // Early exit if no callee saved registers are modified!
1779 if (CSI.empty())
1780 return true;
1781
1782 auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
1783
1784 if (RVFI->isPushable(MF)) {
1785 // Determine how many GPRs we need to push and save it to RVFI.
1786 Register MaxReg = getMaxPushPopReg(MF, CSI);
1787 if (MaxReg != RISCV::NoRegister) {
1788 auto [RegEnc, PushedRegNum] = getPushPopEncodingAndNum(MaxReg);
1789 RVFI->setRVPushRegs(PushedRegNum);
1790 RVFI->setRVPushStackSize(alignTo((STI.getXLen() / 8) * PushedRegNum, 16));
1791
1792 // Use encoded number to represent registers to spill.
1793 RVFI->setRVPushRlist(RegEnc);
1794 }
1795 }
1796
1797 MachineFrameInfo &MFI = MF.getFrameInfo();
1798 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
1799
1800 for (auto &CS : CSI) {
1801 unsigned Reg = CS.getReg();
1802 const TargetRegisterClass *RC = RegInfo->getMinimalPhysRegClass(Reg);
1803 unsigned Size = RegInfo->getSpillSize(*RC);
1804
1805 // This might need a fixed stack slot.
1806 if (RVFI->useSaveRestoreLibCalls(MF) || RVFI->isPushable(MF)) {
1807 const auto *FII = llvm::find_if(
1808 FixedCSRFIMap, [&](auto P) { return P.first == CS.getReg(); });
1809 if (FII != std::end(FixedCSRFIMap)) {
1810 int64_t Offset;
1811 if (RVFI->isPushable(MF))
1812 Offset = -((FII->second + RVFI->getRVPushRegs() + 1) * (int64_t)Size);
1813 else
1814 Offset = FII->second * (int64_t)Size;
1815
1816 int FrameIdx = MFI.CreateFixedSpillStackObject(Size, Offset);
1817 assert(FrameIdx < 0);
1818 CS.setFrameIdx(FrameIdx);
1819 continue;
1820 }
1821 }
1822
1823 // Not a fixed slot.
1824 Align Alignment = RegInfo->getSpillAlign(*RC);
1825 // We may not be able to satisfy the desired alignment specification of
1826 // the TargetRegisterClass if the stack alignment is smaller. Use the
1827 // min.
1828 Alignment = std::min(Alignment, getStackAlign());
1829 int FrameIdx = MFI.CreateStackObject(Size, Alignment, true);
1830 if ((unsigned)FrameIdx < MinCSFrameIndex)
1831 MinCSFrameIndex = FrameIdx;
1832 if ((unsigned)FrameIdx > MaxCSFrameIndex)
1833 MaxCSFrameIndex = FrameIdx;
1834 CS.setFrameIdx(FrameIdx);
1837 }
1838
1839 // Allocate a fixed object that covers the full push or libcall size.
1840 if (RVFI->isPushable(MF)) {
1841 if (int64_t PushSize = RVFI->getRVPushStackSize())
1842 MFI.CreateFixedSpillStackObject(PushSize, -PushSize);
1843 } else if (int LibCallRegs = getLibCallID(MF, CSI) + 1) {
1844 int64_t LibCallFrameSize =
1845 alignTo((STI.getXLen() / 8) * LibCallRegs, getStackAlign());
1846 MFI.CreateFixedSpillStackObject(LibCallFrameSize, -LibCallFrameSize);
1847 }
1848
1849 return true;
1850}
1851
1855 if (CSI.empty())
1856 return true;
1857
1859 const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
1860 DebugLoc DL;
1861 if (MI != MBB.end() && !MI->isDebugInstr())
1862 DL = MI->getDebugLoc();
1863
1864 // Emit CM.PUSH with base SPimm & evaluate Push stack
1866 if (RVFI->isPushable(*MF)) {
1867 unsigned PushedRegNum = RVFI->getRVPushRegs();
1868 if (PushedRegNum > 0) {
1869 // Use encoded number to represent registers to spill.
1870 int RegEnc = RVFI->getRVPushRlist();
1871 MachineInstrBuilder PushBuilder =
1872 BuildMI(MBB, MI, DL, TII.get(RISCV::CM_PUSH))
1874 PushBuilder.addImm((int64_t)RegEnc);
1875 PushBuilder.addImm(0);
1876
1877 for (unsigned i = 0; i < PushedRegNum; i++)
1878 PushBuilder.addUse(FixedCSRFIMap[i].first, RegState::Implicit);
1879 }
1880 } else if (const char *SpillLibCall = getSpillLibCallName(*MF, CSI)) {
1881 // Add spill libcall via non-callee-saved register t0.
1882 BuildMI(MBB, MI, DL, TII.get(RISCV::PseudoCALLReg), RISCV::X5)
1883 .addExternalSymbol(SpillLibCall, RISCVII::MO_CALL)
1885
1886 // Add registers spilled in libcall as liveins.
1887 for (auto &CS : CSI)
1888 MBB.addLiveIn(CS.getReg());
1889 }
1890
1891 // Manually spill values not spilled by libcall & Push/Pop.
1892 const auto &UnmanagedCSI = getUnmanagedCSI(*MF, CSI);
1893 const auto &RVVCSI = getRVVCalleeSavedInfo(*MF, CSI);
1894
1895 auto storeRegsToStackSlots = [&](decltype(UnmanagedCSI) CSInfo) {
1896 for (auto &CS : CSInfo) {
1897 // Insert the spill to the stack frame.
1898 Register Reg = CS.getReg();
1899 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
1901 CS.getFrameIdx(), RC, TRI, Register());
1902 }
1903 };
1904 storeRegsToStackSlots(UnmanagedCSI);
1905 storeRegsToStackSlots(RVVCSI);
1906
1907 return true;
1908}
1909
1910static unsigned getCalleeSavedRVVNumRegs(const Register &BaseReg) {
1911 return RISCV::VRRegClass.contains(BaseReg) ? 1
1912 : RISCV::VRM2RegClass.contains(BaseReg) ? 2
1913 : RISCV::VRM4RegClass.contains(BaseReg) ? 4
1914 : 8;
1915}
1916
1918 const Register &Reg) {
1919 MCRegister BaseReg = TRI.getSubReg(Reg, RISCV::sub_vrm1_0);
1920 // If it's not a grouped vector register, it doesn't have subregister, so
1921 // the base register is just itself.
1922 if (BaseReg == RISCV::NoRegister)
1923 BaseReg = Reg;
1924 return BaseReg;
1925}
1926
1927void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI(
1930 const MachineFrameInfo &MFI = MF->getFrameInfo();
1932 const TargetInstrInfo &TII = *STI.getInstrInfo();
1935
1936 const auto &RVVCSI = getRVVCalleeSavedInfo(*MF, MFI.getCalleeSavedInfo());
1937 if (RVVCSI.empty())
1938 return;
1939
1940 uint64_t FixedSize = getStackSizeWithRVVPadding(*MF);
1941 if (!HasFP) {
1942 uint64_t ScalarLocalVarSize =
1943 MFI.getStackSize() - RVFI->getCalleeSavedStackSize() -
1944 RVFI->getVarArgsSaveSize() + RVFI->getRVVPadding();
1945 FixedSize -= ScalarLocalVarSize;
1946 }
1947
1948 for (auto &CS : RVVCSI) {
1949 // Insert the spill to the stack frame.
1950 int FI = CS.getFrameIdx();
1951 MCRegister BaseReg = getRVVBaseRegister(TRI, CS.getReg());
1952 unsigned NumRegs = getCalleeSavedRVVNumRegs(CS.getReg());
1953 for (unsigned i = 0; i < NumRegs; ++i) {
1954 unsigned CFIIndex = MF->addFrameInst(createDefCFAOffset(
1955 TRI, BaseReg + i, -FixedSize, MFI.getObjectOffset(FI) / 8 + i));
1956 BuildMI(MBB, MI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
1957 .addCFIIndex(CFIIndex)
1959 }
1960 }
1961}
1962
1963void RISCVFrameLowering::emitCalleeSavedRVVEpilogCFI(
1966 const MachineFrameInfo &MFI = MF->getFrameInfo();
1968 const TargetInstrInfo &TII = *STI.getInstrInfo();
1971
1972 const auto &RVVCSI = getRVVCalleeSavedInfo(*MF, MFI.getCalleeSavedInfo());
1973 for (auto &CS : RVVCSI) {
1974 MCRegister BaseReg = getRVVBaseRegister(TRI, CS.getReg());
1975 unsigned NumRegs = getCalleeSavedRVVNumRegs(CS.getReg());
1976 for (unsigned i = 0; i < NumRegs; ++i) {
1977 unsigned CFIIndex = MF->addFrameInst(MCCFIInstruction::createRestore(
1978 nullptr, RI->getDwarfRegNum(BaseReg + i, true)));
1979 BuildMI(MBB, MI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
1980 .addCFIIndex(CFIIndex)
1982 }
1983 }
1984}
1985
1989 if (CSI.empty())
1990 return true;
1991
1993 const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
1994 DebugLoc DL;
1995 if (MI != MBB.end() && !MI->isDebugInstr())
1996 DL = MI->getDebugLoc();
1997
1998 // Manually restore values not restored by libcall & Push/Pop.
1999 // Reverse the restore order in epilog. In addition, the return
2000 // address will be restored first in the epilogue. It increases
2001 // the opportunity to avoid the load-to-use data hazard between
2002 // loading RA and return by RA. loadRegFromStackSlot can insert
2003 // multiple instructions.
2004 const auto &UnmanagedCSI = getUnmanagedCSI(*MF, CSI);
2005 const auto &RVVCSI = getRVVCalleeSavedInfo(*MF, CSI);
2006
2007 auto loadRegFromStackSlot = [&](decltype(UnmanagedCSI) CSInfo) {
2008 for (auto &CS : CSInfo) {
2009 Register Reg = CS.getReg();
2010 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
2011 TII.loadRegFromStackSlot(MBB, MI, Reg, CS.getFrameIdx(), RC, TRI,
2012 Register());
2013 assert(MI != MBB.begin() &&
2014 "loadRegFromStackSlot didn't insert any code!");
2015 }
2016 };
2017 loadRegFromStackSlot(RVVCSI);
2018 loadRegFromStackSlot(UnmanagedCSI);
2019
2021 if (RVFI->isPushable(*MF)) {
2022 int RegEnc = RVFI->getRVPushRlist();
2024 MachineInstrBuilder PopBuilder =
2025 BuildMI(MBB, MI, DL, TII.get(RISCV::CM_POP))
2027 // Use encoded number to represent registers to restore.
2028 PopBuilder.addImm(RegEnc);
2029 PopBuilder.addImm(0);
2030
2031 for (unsigned i = 0; i < RVFI->getRVPushRegs(); i++)
2032 PopBuilder.addDef(FixedCSRFIMap[i].first, RegState::ImplicitDefine);
2033 }
2034 } else {
2035 const char *RestoreLibCall = getRestoreLibCallName(*MF, CSI);
2036 if (RestoreLibCall) {
2037 // Add restore libcall via tail call.
2039 BuildMI(MBB, MI, DL, TII.get(RISCV::PseudoTAIL))
2040 .addExternalSymbol(RestoreLibCall, RISCVII::MO_CALL)
2042
2043 // Remove trailing returns, since the terminator is now a tail call to the
2044 // restore function.
2045 if (MI != MBB.end() && MI->getOpcode() == RISCV::PseudoRET) {
2046 NewMI->copyImplicitOps(*MF, *MI);
2047 MI->eraseFromParent();
2048 }
2049 }
2050 }
2051 return true;
2052}
2053
2055 // Keep the conventional code flow when not optimizing.
2056 if (MF.getFunction().hasOptNone())
2057 return false;
2058
2059 return true;
2060}
2061
2063 MachineBasicBlock *TmpMBB = const_cast<MachineBasicBlock *>(&MBB);
2064 const MachineFunction *MF = MBB.getParent();
2065 const auto *RVFI = MF->getInfo<RISCVMachineFunctionInfo>();
2066
2067 if (!RVFI->useSaveRestoreLibCalls(*MF))
2068 return true;
2069
2070 // Inserting a call to a __riscv_save libcall requires the use of the register
2071 // t0 (X5) to hold the return address. Therefore if this register is already
2072 // used we can't insert the call.
2073
2074 RegScavenger RS;
2075 RS.enterBasicBlock(*TmpMBB);
2076 return !RS.isRegUsed(RISCV::X5);
2077}
2078
2080 const MachineFunction *MF = MBB.getParent();
2081 MachineBasicBlock *TmpMBB = const_cast<MachineBasicBlock *>(&MBB);
2082 const auto *RVFI = MF->getInfo<RISCVMachineFunctionInfo>();
2083
2084 if (!RVFI->useSaveRestoreLibCalls(*MF))
2085 return true;
2086
2087 // Using the __riscv_restore libcalls to restore CSRs requires a tail call.
2088 // This means if we still need to continue executing code within this function
2089 // the restore cannot take place in this basic block.
2090
2091 if (MBB.succ_size() > 1)
2092 return false;
2093
2094 MachineBasicBlock *SuccMBB =
2095 MBB.succ_empty() ? TmpMBB->getFallThrough() : *MBB.succ_begin();
2096
2097 // Doing a tail call should be safe if there are no successors, because either
2098 // we have a returning block or the end of the block is unreachable, so the
2099 // restore will be eliminated regardless.
2100 if (!SuccMBB)
2101 return true;
2102
2103 // The successor can only contain a return, since we would effectively be
2104 // replacing the successor with our own tail return at the end of our block.
2105 return SuccMBB->isReturnBlock() && SuccMBB->size() == 1;
2106}
2107
2109 switch (ID) {
2112 return true;
2116 return false;
2117 }
2118 llvm_unreachable("Invalid TargetStackID::Value");
2119}
2120
2123}
2124
2125// Synthesize the probe loop.
2128 Register TargetReg, bool IsRVV) {
2129 assert(TargetReg != RISCV::X2 && "New top of stack cannot already be in SP");
2130
2131 auto &Subtarget = MF.getSubtarget<RISCVSubtarget>();
2132 const RISCVInstrInfo *TII = Subtarget.getInstrInfo();
2133 bool IsRV64 = Subtarget.is64Bit();
2134 Align StackAlign = Subtarget.getFrameLowering()->getStackAlign();
2135 const RISCVTargetLowering *TLI = Subtarget.getTargetLowering();
2136 uint64_t ProbeSize = TLI->getStackProbeSize(MF, StackAlign);
2137
2138 MachineFunction::iterator MBBInsertPoint = std::next(MBB.getIterator());
2139 MachineBasicBlock *LoopTestMBB =
2141 MF.insert(MBBInsertPoint, LoopTestMBB);
2143 MF.insert(MBBInsertPoint, ExitMBB);
2145 Register ScratchReg = RISCV::X7;
2146
2147 // ScratchReg = ProbeSize
2148 TII->movImm(MBB, MBBI, DL, ScratchReg, ProbeSize, Flags);
2149
2150 // LoopTest:
2151 // SUB SP, SP, ProbeSize
2152 BuildMI(*LoopTestMBB, LoopTestMBB->end(), DL, TII->get(RISCV::SUB), SPReg)
2153 .addReg(SPReg)
2154 .addReg(ScratchReg)
2155 .setMIFlags(Flags);
2156
2157 // s[d|w] zero, 0(sp)
2158 BuildMI(*LoopTestMBB, LoopTestMBB->end(), DL,
2159 TII->get(IsRV64 ? RISCV::SD : RISCV::SW))
2160 .addReg(RISCV::X0)
2161 .addReg(SPReg)
2162 .addImm(0)
2163 .setMIFlags(Flags);
2164
2165 if (IsRVV) {
2166 // SUB TargetReg, TargetReg, ProbeSize
2167 BuildMI(*LoopTestMBB, LoopTestMBB->end(), DL, TII->get(RISCV::SUB),
2168 TargetReg)
2169 .addReg(TargetReg)
2170 .addReg(ScratchReg)
2171 .setMIFlags(Flags);
2172
2173 // BGE TargetReg, ProbeSize, LoopTest
2174 BuildMI(*LoopTestMBB, LoopTestMBB->end(), DL, TII->get(RISCV::BGE))
2175 .addReg(TargetReg)
2176 .addReg(ScratchReg)
2177 .addMBB(LoopTestMBB)
2178 .setMIFlags(Flags);
2179
2180 } else {
2181 // BNE SP, TargetReg, LoopTest
2182 BuildMI(*LoopTestMBB, LoopTestMBB->end(), DL, TII->get(RISCV::BNE))
2183 .addReg(SPReg)
2184 .addReg(TargetReg)
2185 .addMBB(LoopTestMBB)
2186 .setMIFlags(Flags);
2187 }
2188
2189 ExitMBB->splice(ExitMBB->end(), &MBB, std::next(MBBI), MBB.end());
2191
2192 LoopTestMBB->addSuccessor(ExitMBB);
2193 LoopTestMBB->addSuccessor(LoopTestMBB);
2194 MBB.addSuccessor(LoopTestMBB);
2195 // Update liveins.
2196 fullyRecomputeLiveIns({ExitMBB, LoopTestMBB});
2197}
2198
2199void RISCVFrameLowering::inlineStackProbe(MachineFunction &MF,
2200 MachineBasicBlock &MBB) const {
2201 // Get the instructions that need to be replaced. We emit at most two of
2202 // these. Remember them in order to avoid complications coming from the need
2203 // to traverse the block while potentially creating more blocks.
2205 for (MachineInstr &MI : MBB) {
2206 unsigned Opc = MI.getOpcode();
2207 if (Opc == RISCV::PROBED_STACKALLOC ||
2208 Opc == RISCV::PROBED_STACKALLOC_RVV) {
2209 ToReplace.push_back(&MI);
2210 }
2211 }
2212
2213 for (MachineInstr *MI : ToReplace) {
2214 if (MI->getOpcode() == RISCV::PROBED_STACKALLOC ||
2215 MI->getOpcode() == RISCV::PROBED_STACKALLOC_RVV) {
2216 MachineBasicBlock::iterator MBBI = MI->getIterator();
2218 Register TargetReg = MI->getOperand(1).getReg();
2219 emitStackProbeInline(MF, MBB, MBBI, DL, TargetReg,
2220 (MI->getOpcode() == RISCV::PROBED_STACKALLOC_RVV));
2222 }
2223 }
2224}
static MCCFIInstruction createDefCFAExpression(const TargetRegisterInfo &TRI, unsigned Reg, const StackOffset &Offset)
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
dxil DXContainer Global Emitter
This file contains constants used for implementing Dwarf debug support.
uint64_t Size
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
static uint64_t estimateFunctionSizeInBytes(const LoongArchInstrInfo *TII, const MachineFunction &MF)
#define I(x, y, z)
Definition: MD5.cpp:58
unsigned const TargetRegisterInfo * TRI
#define P(N)
static constexpr Register SPReg
static constexpr Register FPReg
static MCRegister getRVVBaseRegister(const RISCVRegisterInfo &TRI, const Register &Reg)
static void emitStackProbeInline(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc DL, Register TargetReg, bool IsRVV)
static const char * getRestoreLibCallName(const MachineFunction &MF, const std::vector< CalleeSavedInfo > &CSI)
static const char * getSpillLibCallName(const MachineFunction &MF, const std::vector< CalleeSavedInfo > &CSI)
static bool hasRVVFrameObject(const MachineFunction &MF)
static std::pair< unsigned, unsigned > getPushPopEncodingAndNum(const Register MaxReg)
static const std::pair< MCPhysReg, int8_t > FixedCSRFIMap[]
static SmallVector< CalleeSavedInfo, 8 > getRVVCalleeSavedInfo(const MachineFunction &MF, const std::vector< CalleeSavedInfo > &CSI)
static void appendScalableVectorExpression(const TargetRegisterInfo &TRI, SmallVectorImpl< char > &Expr, int FixedOffset, int ScalableOffset, llvm::raw_string_ostream &Comment)
static unsigned getCalleeSavedRVVNumRegs(const Register &BaseReg)
static Align getABIStackAlignment(RISCVABI::ABI ABI)
static SmallVector< CalleeSavedInfo, 8 > getPushOrLibCallsSavedInfo(const MachineFunction &MF, const std::vector< CalleeSavedInfo > &CSI)
static int getLibCallID(const MachineFunction &MF, const std::vector< CalleeSavedInfo > &CSI)
static void emitSCSPrologue(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL)
static constexpr Register RAReg
static void emitSCSEpilogue(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL)
static SmallVector< CalleeSavedInfo, 8 > getUnmanagedCSI(const MachineFunction &MF, const std::vector< CalleeSavedInfo > &CSI)
static Register getMaxPushPopReg(const MachineFunction &MF, const std::vector< CalleeSavedInfo > &CSI)
static unsigned getScavSlotsNumForRVV(MachineFunction &MF)
static MCCFIInstruction createDefCFAOffset(const TargetRegisterInfo &TRI, Register Reg, uint64_t FixedOffset, uint64_t ScalableOffset)
This file declares the machine register scavenger class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:163
bool test(unsigned Idx) const
Definition: BitVector.h:461
BitVector & set()
Definition: BitVector.h:351
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
Register getReg() const
A debug info location.
Definition: DebugLoc.h:33
Diagnostic information for unsupported feature in backend.
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition: Function.h:277
bool hasOptNone() const
Do not optimize this function (-O0).
Definition: Function.h:701
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition: Function.cpp:369
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.cpp:731
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
Store the specified register of the given register class to the specified stack frame index.
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
Load the specified register of the given register class from the specified stack frame index.
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register, SMLoc Loc={})
.cfi_def_cfa_register modifies a rule for computing CFA.
Definition: MCDwarf.h:582
static MCCFIInstruction createRestore(MCSymbol *L, unsigned Register, SMLoc Loc={})
.cfi_restore says that the rule for Register is now the same as it was at the beginning of the functi...
Definition: MCDwarf.h:656
static MCCFIInstruction cfiDefCfa(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})
.cfi_def_cfa defines a rule for computing CFA as: take address from Register and add Offset to it.
Definition: MCDwarf.h:575
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:617
static MCCFIInstruction cfiDefCfaOffset(MCSymbol *L, int64_t Offset, SMLoc Loc={})
.cfi_def_cfa_offset modifies a rule for computing CFA.
Definition: MCDwarf.h:590
static MCCFIInstruction createEscape(MCSymbol *L, StringRef Vals, SMLoc Loc={}, StringRef Comment="")
.cfi_escape Allows the user to add arbitrary bytes to the unwind info.
Definition: MCDwarf.h:687
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
MachineBasicBlock * getFallThrough(bool JumpToFallThrough=true)
Return the fallthrough block if the block can implicitly transfer control to the block after it by fa...
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
unsigned succ_size() const
bool isReturnBlock() const
Convenience function that returns true if the block ends in a return instruction.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.
iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
void eraseFromParent()
This method unlinks 'this' from the containing function and deletes it.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
bool isLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
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.
bool adjustsStack() const
Return true if this function adjusts the stack – e.g., when calling another function.
int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
void ensureMaxAlignment(Align Alignment)
Make sure the function is at least Align bytes aligned.
bool isFrameAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
Align getMaxAlign() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
void setObjectOffset(int ObjectIdx, int64_t SPOffset)
Set the stack frame offset of the specified object.
uint64_t getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
int64_t getOffsetAdjustment() const
Return the correction for frame offsets.
int CreateSpillStackObject(uint64_t Size, Align Alignment)
Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...
uint64_t estimateStackSize(const MachineFunction &MF) const
Estimate and return the size of the stack frame.
void setStackID(int ObjectIdx, uint8_t ID)
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.
bool isMaxCallFrameSizeComputed() const
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
int getObjectIndexEnd() const
Return one past the maximum frame object index.
int CreateFixedSpillStackObject(uint64_t Size, int64_t SPOffset, bool IsImmutable=false)
Create a spill slot at a fixed location on the stack.
uint8_t getStackID(int ObjectIdx) const
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
void setStackSize(uint64_t Size)
Set the size of the stack.
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
bool isDeadObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a dead object.
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.
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...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
const MachineInstrBuilder & addCFIIndex(unsigned CFIIndex) const
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
Definition: MachineInstr.h:69
bool isReserved(MCRegister PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition: ArrayRef.h:310
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
uint64_t getFirstSPAdjustAmount(const MachineFunction &MF) const
bool enableShrinkWrapping(const MachineFunction &MF) const override
Returns true if the target will correctly handle shrink wrapping.
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...
bool hasBP(const MachineFunction &MF) const
bool canUseAsEpilogue(const MachineBasicBlock &MBB) const override
Check whether or not the given MBB can be used as a epilogue for the target.
bool assignCalleeSavedSpillSlots(MachineFunction &MF, const TargetRegisterInfo *TRI, std::vector< CalleeSavedInfo > &CSI, unsigned &MinCSFrameIndex, unsigned &MaxCSFrameIndex) const override
assignCalleeSavedSpillSlots - Allows target to override spill slot assignment logic.
bool hasFPImpl(const MachineFunction &MF) const override
void allocateStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, MachineFunction &MF, uint64_t Offset, uint64_t RealStackSize, bool EmitCFI, bool NeedProbe, uint64_t ProbeSize, bool DynAllocation) const
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...
bool hasReservedCallFrame(const MachineFunction &MF) const override
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
const RISCVSubtarget & STI
StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const override
getFrameIndexReference - This method should return the base register and offset used to reference a f...
bool isSupportedStackID(TargetStackID::Value ID) const override
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
TargetStackID::Value getStackIDForScalableVectors() const override
Returns the StackID that scalable vectors should be associated with.
void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS) const override
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const override
This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy p...
bool canUseAsPrologue(const MachineBasicBlock &MBB) const override
Check whether or not the given MBB can be used as a prologue for the target.
RISCVFrameLowering(const RISCVSubtarget &STI)
uint64_t getStackSizeWithRVVPadding(const MachineFunction &MF) const
RISCVMachineFunctionInfo - This class is derived from MachineFunctionInfo and contains private RISCV-...
bool isPushable(const MachineFunction &MF) const
bool useSaveRestoreLibCalls(const MachineFunction &MF) const
bool hasStdExtCOrZca() const
unsigned getXLen() const
bool hasVInstructions() const
bool isRegisterReservedByUser(Register i) const override
const RISCVRegisterInfo * getRegisterInfo() const override
const RISCVInstrInfo * getInstrInfo() const override
bool hasInlineStackProbe(const MachineFunction &MF) const override
True if stack clash protection is enabled for this functions.
unsigned getStackProbeSize(const MachineFunction &MF, Align StackAlign) const
bool isRegUsed(Register Reg, bool includeReserved=true) const
Return if a specific register is currently used.
void enterBasicBlock(MachineBasicBlock &MBB)
Start tracking liveness from the begin of basic block MBB.
void addScavengingFrameIndex(int FI)
Add a scavenging frame index.
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
constexpr unsigned id() const
Definition: Register.h:103
Represents a location in source code.
Definition: SMLoc.h:23
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
void append(StringRef RHS)
Append from a StringRef.
Definition: SmallString.h:68
StringRef str() const
Explicit conversion to StringRef.
Definition: SmallString.h:254
bool empty() const
Definition: SmallVector.h:81
size_t size() const
Definition: SmallVector.h:78
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:683
void push_back(const T &Elt)
Definition: SmallVector.h:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
StackOffset holds a fixed and a scalable offset in bytes.
Definition: TypeSize.h:33
int64_t getFixed() const
Returns the fixed component of the stack.
Definition: TypeSize.h:49
int64_t getScalable() const
Returns the scalable component of the stack.
Definition: TypeSize.h:52
static StackOffset get(int64_t Fixed, int64_t Scalable)
Definition: TypeSize.h:44
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
Information about stack frame layout on the target.
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
int getOffsetOfLocalArea() const
getOffsetOfLocalArea - This method returns the offset of the local area from the stack pointer on ent...
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
int alignSPAdjust(int SPAdj) const
alignSPAdjust - This method aligns the stack adjustment to the correct alignment.
TargetInstrInfo - Interface to description of machine instruction set.
TargetOptions Options
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...
const TargetRegisterClass * getMinimalPhysRegClass(MCRegister Reg, MVT VT=MVT::Other) const
Returns the Register Class of a physical register of the given type, picking the most sub register cl...
Align getSpillAlign(const TargetRegisterClass &RC) const
Return the minimum required alignment in bytes for a spill slot for a register of this class.
bool hasStackRealignment(const MachineFunction &MF) const
True if stack realignment is required and still possible.
unsigned getSpillSize(const TargetRegisterClass &RC) const
Return the size in bytes of the stack slot allocated to hold a spilled copy of a register from class ...
virtual Register getFrameRegister(const MachineFunction &MF) const =0
Debug information queries.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual const TargetInstrInfo * getInstrInfo() const
self_iterator getIterator()
Definition: ilist_node.h:132
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:661
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
Definition: CallingConv.h:50
MCRegister getBPReg()
MCRegister getSCSPReg()
static constexpr unsigned RVVBitsPerBlock
bool isRVVSpill(const MachineInstr &MI)
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Define
Register definition.
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
IterT next_nodbg(IterT It, IterT End, bool SkipPseudoOp=true)
Increment It, then continue incrementing it while it points to a debug instruction.
@ Offset
Definition: DWP.cpp:480
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition: STLExtras.h:1697
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr T alignDown(U Value, V Align, W Skew=0)
Returns the largest unsigned integer less than or equal to Value and is Skew mod Align.
Definition: MathExtras.h:557
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1753
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
Definition: Alignment.h:197
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
unsigned encodeSLEB128(int64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a SLEB128 value to an output stream.
Definition: LEB128.h:23
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1766
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
Definition: LEB128.h:80
unsigned Log2(Align A)
Returns the log2 of the alignment.
Definition: Alignment.h:208
void fullyRecomputeLiveIns(ArrayRef< MachineBasicBlock * > MBBs)
Convenience function for recomputing live-in's for a set of MBBs until the computation converges.
Definition: LivePhysRegs.h:215
Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85
static bool isRVVRegClass(const TargetRegisterClass *RC)
void adjustReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator II, const DebugLoc &DL, Register DestReg, Register SrcReg, StackOffset Offset, MachineInstr::MIFlag Flag, MaybeAlign RequiredAlign) const