LLVM 19.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"
23#include "llvm/MC/MCDwarf.h"
24#include "llvm/Support/LEB128.h"
25
26#include <algorithm>
27
28using namespace llvm;
29
31 if (ABI == RISCVABI::ABI_ILP32E)
32 return Align(4);
33 if (ABI == RISCVABI::ABI_LP64E)
34 return Align(8);
35 return Align(16);
36}
37
40 StackGrowsDown, getABIStackAlignment(STI.getTargetABI()),
41 /*LocalAreaOffset=*/0,
42 /*TransientStackAlignment=*/getABIStackAlignment(STI.getTargetABI())),
43 STI(STI) {}
44
45// Offsets which need to be scale by XLen representing locations of CSRs which
46// are given a fixed location by save/restore libcalls or Zcmp Push/Pop.
47static const std::pair<MCPhysReg, int8_t> FixedCSRFIMap[] = {
48 {/*ra*/ RISCV::X1, -1}, {/*s0*/ RISCV::X8, -2},
49 {/*s1*/ RISCV::X9, -3}, {/*s2*/ RISCV::X18, -4},
50 {/*s3*/ RISCV::X19, -5}, {/*s4*/ RISCV::X20, -6},
51 {/*s5*/ RISCV::X21, -7}, {/*s6*/ RISCV::X22, -8},
52 {/*s7*/ RISCV::X23, -9}, {/*s8*/ RISCV::X24, -10},
53 {/*s9*/ RISCV::X25, -11}, {/*s10*/ RISCV::X26, -12},
54 {/*s11*/ RISCV::X27, -13}};
55
56// For now we use x3, a.k.a gp, as pointer to shadow call stack.
57// User should not use x3 in their asm.
60 const DebugLoc &DL) {
61 if (!MF.getFunction().hasFnAttribute(Attribute::ShadowCallStack))
62 return;
63
64 const auto &STI = MF.getSubtarget<RISCVSubtarget>();
65 const llvm::RISCVRegisterInfo *TRI = STI.getRegisterInfo();
66 Register RAReg = TRI->getRARegister();
67
68 // Do not save RA to the SCS if it's not saved to the regular stack,
69 // i.e. RA is not at risk of being overwritten.
70 std::vector<CalleeSavedInfo> &CSI = MF.getFrameInfo().getCalleeSavedInfo();
71 if (llvm::none_of(
72 CSI, [&](CalleeSavedInfo &CSR) { return CSR.getReg() == RAReg; }))
73 return;
74
75 const RISCVInstrInfo *TII = STI.getInstrInfo();
76 if (!STI.hasForcedSWShadowStack() && STI.hasStdExtZicfiss()) {
77 BuildMI(MBB, MI, DL, TII->get(RISCV::SSPUSH)).addReg(RAReg);
78 return;
79 }
80
82
83 bool IsRV64 = STI.hasFeature(RISCV::Feature64Bit);
84 int64_t SlotSize = STI.getXLen() / 8;
85 // Store return address to shadow call stack
86 // addi gp, gp, [4|8]
87 // s[w|d] ra, -[4|8](gp)
88 BuildMI(MBB, MI, DL, TII->get(RISCV::ADDI))
89 .addReg(SCSPReg, RegState::Define)
90 .addReg(SCSPReg)
91 .addImm(SlotSize)
93 BuildMI(MBB, MI, DL, TII->get(IsRV64 ? RISCV::SD : RISCV::SW))
94 .addReg(RAReg)
95 .addReg(SCSPReg)
96 .addImm(-SlotSize)
98
99 // Emit a CFI instruction that causes SlotSize to be subtracted from the value
100 // of the shadow stack pointer when unwinding past this frame.
101 char DwarfSCSReg = TRI->getDwarfRegNum(SCSPReg, /*IsEH*/ true);
102 assert(DwarfSCSReg < 32 && "SCS Register should be < 32 (X3).");
103
104 char Offset = static_cast<char>(-SlotSize) & 0x7f;
105 const char CFIInst[] = {
106 dwarf::DW_CFA_val_expression,
107 DwarfSCSReg, // register
108 2, // length
109 static_cast<char>(unsigned(dwarf::DW_OP_breg0 + DwarfSCSReg)),
110 Offset, // addend (sleb128)
111 };
112
113 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createEscape(
114 nullptr, StringRef(CFIInst, sizeof(CFIInst))));
115 BuildMI(MBB, MI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
116 .addCFIIndex(CFIIndex)
118}
119
122 const DebugLoc &DL) {
123 if (!MF.getFunction().hasFnAttribute(Attribute::ShadowCallStack))
124 return;
125
126 const auto &STI = MF.getSubtarget<RISCVSubtarget>();
127 Register RAReg = STI.getRegisterInfo()->getRARegister();
128
129 // See emitSCSPrologue() above.
130 std::vector<CalleeSavedInfo> &CSI = MF.getFrameInfo().getCalleeSavedInfo();
131 if (llvm::none_of(
132 CSI, [&](CalleeSavedInfo &CSR) { return CSR.getReg() == RAReg; }))
133 return;
134
135 const RISCVInstrInfo *TII = STI.getInstrInfo();
136 if (!STI.hasForcedSWShadowStack() && STI.hasStdExtZicfiss()) {
137 BuildMI(MBB, MI, DL, TII->get(RISCV::SSPOPCHK)).addReg(RAReg);
138 return;
139 }
140
141 Register SCSPReg = RISCVABI::getSCSPReg();
142
143 bool IsRV64 = STI.hasFeature(RISCV::Feature64Bit);
144 int64_t SlotSize = STI.getXLen() / 8;
145 // Load return address from shadow call stack
146 // l[w|d] ra, -[4|8](gp)
147 // addi gp, gp, -[4|8]
148 BuildMI(MBB, MI, DL, TII->get(IsRV64 ? RISCV::LD : RISCV::LW))
149 .addReg(RAReg, RegState::Define)
150 .addReg(SCSPReg)
151 .addImm(-SlotSize)
153 BuildMI(MBB, MI, DL, TII->get(RISCV::ADDI))
154 .addReg(SCSPReg, RegState::Define)
155 .addReg(SCSPReg)
156 .addImm(-SlotSize)
158 // Restore the SCS pointer
159 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore(
160 nullptr, STI.getRegisterInfo()->getDwarfRegNum(SCSPReg, /*IsEH*/ true)));
161 BuildMI(MBB, MI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
162 .addCFIIndex(CFIIndex)
164}
165
166// Get the ID of the libcall used for spilling and restoring callee saved
167// registers. The ID is representative of the number of registers saved or
168// restored by the libcall, except it is zero-indexed - ID 0 corresponds to a
169// single register.
170static int getLibCallID(const MachineFunction &MF,
171 const std::vector<CalleeSavedInfo> &CSI) {
172 const auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
173
174 if (CSI.empty() || !RVFI->useSaveRestoreLibCalls(MF))
175 return -1;
176
177 Register MaxReg = RISCV::NoRegister;
178 for (auto &CS : CSI)
179 // assignCalleeSavedSpillSlots assigns negative frame indexes to
180 // registers which can be saved by libcall.
181 if (CS.getFrameIdx() < 0)
182 MaxReg = std::max(MaxReg.id(), CS.getReg().id());
183
184 if (MaxReg == RISCV::NoRegister)
185 return -1;
186
187 switch (MaxReg) {
188 default:
189 llvm_unreachable("Something has gone wrong!");
190 case /*s11*/ RISCV::X27: return 12;
191 case /*s10*/ RISCV::X26: return 11;
192 case /*s9*/ RISCV::X25: return 10;
193 case /*s8*/ RISCV::X24: return 9;
194 case /*s7*/ RISCV::X23: return 8;
195 case /*s6*/ RISCV::X22: return 7;
196 case /*s5*/ RISCV::X21: return 6;
197 case /*s4*/ RISCV::X20: return 5;
198 case /*s3*/ RISCV::X19: return 4;
199 case /*s2*/ RISCV::X18: return 3;
200 case /*s1*/ RISCV::X9: return 2;
201 case /*s0*/ RISCV::X8: return 1;
202 case /*ra*/ RISCV::X1: return 0;
203 }
204}
205
206// Get the name of the libcall used for spilling callee saved registers.
207// If this function will not use save/restore libcalls, then return a nullptr.
208static const char *
210 const std::vector<CalleeSavedInfo> &CSI) {
211 static const char *const SpillLibCalls[] = {
212 "__riscv_save_0",
213 "__riscv_save_1",
214 "__riscv_save_2",
215 "__riscv_save_3",
216 "__riscv_save_4",
217 "__riscv_save_5",
218 "__riscv_save_6",
219 "__riscv_save_7",
220 "__riscv_save_8",
221 "__riscv_save_9",
222 "__riscv_save_10",
223 "__riscv_save_11",
224 "__riscv_save_12"
225 };
226
227 int LibCallID = getLibCallID(MF, CSI);
228 if (LibCallID == -1)
229 return nullptr;
230 return SpillLibCalls[LibCallID];
231}
232
233// Get the name of the libcall used for restoring callee saved registers.
234// If this function will not use save/restore libcalls, then return a nullptr.
235static const char *
237 const std::vector<CalleeSavedInfo> &CSI) {
238 static const char *const RestoreLibCalls[] = {
239 "__riscv_restore_0",
240 "__riscv_restore_1",
241 "__riscv_restore_2",
242 "__riscv_restore_3",
243 "__riscv_restore_4",
244 "__riscv_restore_5",
245 "__riscv_restore_6",
246 "__riscv_restore_7",
247 "__riscv_restore_8",
248 "__riscv_restore_9",
249 "__riscv_restore_10",
250 "__riscv_restore_11",
251 "__riscv_restore_12"
252 };
253
254 int LibCallID = getLibCallID(MF, CSI);
255 if (LibCallID == -1)
256 return nullptr;
257 return RestoreLibCalls[LibCallID];
258}
259
260// Return encoded value and register count for PUSH/POP instruction,
261// representing registers to store/load.
262static std::pair<unsigned, unsigned>
264 switch (MaxReg) {
265 default:
266 llvm_unreachable("Unexpected Reg for Push/Pop Inst");
267 case RISCV::X27: /*s11*/
268 return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S11, 13);
269 case RISCV::X25: /*s9*/
270 return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S9, 11);
271 case RISCV::X24: /*s8*/
272 return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S8, 10);
273 case RISCV::X23: /*s7*/
274 return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S7, 9);
275 case RISCV::X22: /*s6*/
276 return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S6, 8);
277 case RISCV::X21: /*s5*/
278 return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S5, 7);
279 case RISCV::X20: /*s4*/
280 return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S4, 6);
281 case RISCV::X19: /*s3*/
282 return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S3, 5);
283 case RISCV::X18: /*s2*/
284 return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S2, 4);
285 case RISCV::X9: /*s1*/
286 return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S1, 3);
287 case RISCV::X8: /*s0*/
288 return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0, 2);
289 case RISCV::X1: /*ra*/
290 return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA, 1);
291 }
292}
293
294// Get the max reg of Push/Pop for restoring callee saved registers.
296 const std::vector<CalleeSavedInfo> &CSI) {
297 Register MaxPushPopReg = RISCV::NoRegister;
298 for (auto &CS : CSI) {
299 if (llvm::find_if(FixedCSRFIMap, [&](auto P) {
300 return P.first == CS.getReg();
301 }) != std::end(FixedCSRFIMap))
302 MaxPushPopReg = std::max(MaxPushPopReg.id(), CS.getReg().id());
303 }
304 assert(MaxPushPopReg != RISCV::X26 && "x26 requires x27 to also be pushed");
305 return MaxPushPopReg;
306}
307
308// Return true if the specified function should have a dedicated frame
309// pointer register. This is true if frame pointer elimination is
310// disabled, if it needs dynamic stack realignment, if the function has
311// variable sized allocas, or if the frame address is taken.
313 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
314
315 const MachineFrameInfo &MFI = MF.getFrameInfo();
316 return MF.getTarget().Options.DisableFramePointerElim(MF) ||
317 RegInfo->hasStackRealignment(MF) || MFI.hasVarSizedObjects() ||
319}
320
322 const MachineFrameInfo &MFI = MF.getFrameInfo();
324
325 // If we do not reserve stack space for outgoing arguments in prologue,
326 // we will adjust the stack pointer before call instruction. After the
327 // adjustment, we can not use SP to access the stack objects for the
328 // arguments. Instead, use BP to access these stack objects.
329 return (MFI.hasVarSizedObjects() ||
331 MFI.getMaxCallFrameSize() != 0))) &&
332 TRI->hasStackRealignment(MF);
333}
334
335// Determines the size of the frame and maximum call frame size.
336void RISCVFrameLowering::determineFrameLayout(MachineFunction &MF) const {
337 MachineFrameInfo &MFI = MF.getFrameInfo();
338 auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
339
340 // Get the number of bytes to allocate from the FrameInfo.
341 uint64_t FrameSize = MFI.getStackSize();
342
343 // Get the alignment.
344 Align StackAlign = getStackAlign();
345
346 // Make sure the frame is aligned.
347 FrameSize = alignTo(FrameSize, StackAlign);
348
349 // Update frame info.
350 MFI.setStackSize(FrameSize);
351
352 // When using SP or BP to access stack objects, we may require extra padding
353 // to ensure the bottom of the RVV stack is correctly aligned within the main
354 // stack. We calculate this as the amount required to align the scalar local
355 // variable section up to the RVV alignment.
357 if (RVFI->getRVVStackSize() && (!hasFP(MF) || TRI->hasStackRealignment(MF))) {
358 int ScalarLocalVarSize = FrameSize - RVFI->getCalleeSavedStackSize() -
359 RVFI->getVarArgsSaveSize();
360 if (auto RVVPadding =
361 offsetToAlignment(ScalarLocalVarSize, RVFI->getRVVStackAlign()))
362 RVFI->setRVVPadding(RVVPadding);
363 }
364}
365
366// Returns the stack size including RVV padding (when required), rounded back
367// up to the required stack alignment.
369 const MachineFunction &MF) const {
370 const MachineFrameInfo &MFI = MF.getFrameInfo();
371 auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
372 return alignTo(MFI.getStackSize() + RVFI->getRVVPadding(), getStackAlign());
373}
374
375// Returns the register used to hold the frame pointer.
376static Register getFPReg(const RISCVSubtarget &STI) { return RISCV::X8; }
377
378// Returns the register used to hold the stack pointer.
379static Register getSPReg(const RISCVSubtarget &STI) { return RISCV::X2; }
380
383 const std::vector<CalleeSavedInfo> &CSI) {
384 const MachineFrameInfo &MFI = MF.getFrameInfo();
386
387 for (auto &CS : CSI) {
388 int FI = CS.getFrameIdx();
389 if (FI >= 0 && MFI.getStackID(FI) == TargetStackID::Default)
390 NonLibcallCSI.push_back(CS);
391 }
392
393 return NonLibcallCSI;
394}
395
398 const std::vector<CalleeSavedInfo> &CSI) {
399 const MachineFrameInfo &MFI = MF.getFrameInfo();
401
402 for (auto &CS : CSI) {
403 int FI = CS.getFrameIdx();
404 if (FI >= 0 && MFI.getStackID(FI) == TargetStackID::ScalableVector)
405 RVVCSI.push_back(CS);
406 }
407
408 return RVVCSI;
409}
410
411void RISCVFrameLowering::adjustStackForRVV(MachineFunction &MF,
414 const DebugLoc &DL, int64_t Amount,
415 MachineInstr::MIFlag Flag) const {
416 assert(Amount != 0 && "Did not need to adjust stack pointer for RVV.");
417
418 const Register SPReg = getSPReg(STI);
419
420 // Optimize compile time offset case
422 if (auto VLEN = STI.getRealVLen()) {
423 // 1. Multiply the number of v-slots by the (constant) length of register
424 const int64_t VLENB = *VLEN / 8;
425 assert(Amount % 8 == 0 &&
426 "Reserve the stack by the multiple of one vector size.");
427 const int64_t NumOfVReg = Amount / 8;
428 const int64_t FixedOffset = NumOfVReg * VLENB;
429 if (!isInt<32>(FixedOffset)) {
431 "Frame size outside of the signed 32-bit range not supported");
432 }
433 Offset = StackOffset::getFixed(FixedOffset);
434 }
435
437 // We must keep the stack pointer aligned through any intermediate
438 // updates.
439 RI.adjustReg(MBB, MBBI, DL, SPReg, SPReg, Offset,
440 Flag, getStackAlign());
441}
442
445 int FixedOffset, int ScalableOffset,
446 llvm::raw_string_ostream &Comment) {
447 unsigned DwarfVLenB = TRI.getDwarfRegNum(RISCV::VLENB, true);
448 uint8_t Buffer[16];
449 if (FixedOffset) {
450 Expr.push_back(dwarf::DW_OP_consts);
451 Expr.append(Buffer, Buffer + encodeSLEB128(FixedOffset, Buffer));
452 Expr.push_back((uint8_t)dwarf::DW_OP_plus);
453 Comment << (FixedOffset < 0 ? " - " : " + ") << std::abs(FixedOffset);
454 }
455
456 Expr.push_back((uint8_t)dwarf::DW_OP_consts);
457 Expr.append(Buffer, Buffer + encodeSLEB128(ScalableOffset, Buffer));
458
459 Expr.push_back((uint8_t)dwarf::DW_OP_bregx);
460 Expr.append(Buffer, Buffer + encodeULEB128(DwarfVLenB, Buffer));
461 Expr.push_back(0);
462
463 Expr.push_back((uint8_t)dwarf::DW_OP_mul);
464 Expr.push_back((uint8_t)dwarf::DW_OP_plus);
465
466 Comment << (ScalableOffset < 0 ? " - " : " + ") << std::abs(ScalableOffset)
467 << " * vlenb";
468}
469
471 Register Reg,
472 uint64_t FixedOffset,
473 uint64_t ScalableOffset) {
474 assert(ScalableOffset != 0 && "Did not need to adjust CFA for RVV");
475 SmallString<64> Expr;
476 std::string CommentBuffer;
477 llvm::raw_string_ostream Comment(CommentBuffer);
478 // Build up the expression (Reg + FixedOffset + ScalableOffset * VLENB).
479 unsigned DwarfReg = TRI.getDwarfRegNum(Reg, true);
480 Expr.push_back((uint8_t)(dwarf::DW_OP_breg0 + DwarfReg));
481 Expr.push_back(0);
482 if (Reg == RISCV::X2)
483 Comment << "sp";
484 else
485 Comment << printReg(Reg, &TRI);
486
487 appendScalableVectorExpression(TRI, Expr, FixedOffset, ScalableOffset,
488 Comment);
489
490 SmallString<64> DefCfaExpr;
491 uint8_t Buffer[16];
492 DefCfaExpr.push_back(dwarf::DW_CFA_def_cfa_expression);
493 DefCfaExpr.append(Buffer, Buffer + encodeULEB128(Expr.size(), Buffer));
494 DefCfaExpr.append(Expr.str());
495
496 return MCCFIInstruction::createEscape(nullptr, DefCfaExpr.str(), SMLoc(),
497 Comment.str());
498}
499
501 Register Reg, uint64_t FixedOffset,
502 uint64_t ScalableOffset) {
503 assert(ScalableOffset != 0 && "Did not need to adjust CFA for RVV");
504 SmallString<64> Expr;
505 std::string CommentBuffer;
506 llvm::raw_string_ostream Comment(CommentBuffer);
507 Comment << printReg(Reg, &TRI) << " @ cfa";
508
509 // Build up the expression (FixedOffset + ScalableOffset * VLENB).
510 appendScalableVectorExpression(TRI, Expr, FixedOffset, ScalableOffset,
511 Comment);
512
513 SmallString<64> DefCfaExpr;
514 uint8_t Buffer[16];
515 unsigned DwarfReg = TRI.getDwarfRegNum(Reg, true);
516 DefCfaExpr.push_back(dwarf::DW_CFA_expression);
517 DefCfaExpr.append(Buffer, Buffer + encodeULEB128(DwarfReg, Buffer));
518 DefCfaExpr.append(Buffer, Buffer + encodeULEB128(Expr.size(), Buffer));
519 DefCfaExpr.append(Expr.str());
520
521 return MCCFIInstruction::createEscape(nullptr, DefCfaExpr.str(), SMLoc(),
522 Comment.str());
523}
524
526 MachineBasicBlock &MBB) const {
527 MachineFrameInfo &MFI = MF.getFrameInfo();
528 auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
532
533 Register FPReg = getFPReg(STI);
534 Register SPReg = getSPReg(STI);
536
537 // Debug location must be unknown since the first debug location is used
538 // to determine the end of the prologue.
539 DebugLoc DL;
540
541 // All calls are tail calls in GHC calling conv, and functions have no
542 // prologue/epilogue.
544 return;
545
546 // Emit prologue for shadow call stack.
547 emitSCSPrologue(MF, MBB, MBBI, DL);
548
549 auto FirstFrameSetup = MBBI;
550
551 // Since spillCalleeSavedRegisters may have inserted a libcall, skip past
552 // any instructions marked as FrameSetup
553 while (MBBI != MBB.end() && MBBI->getFlag(MachineInstr::FrameSetup))
554 ++MBBI;
555
556 // Determine the correct frame layout
557 determineFrameLayout(MF);
558
559 // If libcalls are used to spill and restore callee-saved registers, the frame
560 // has two sections; the opaque section managed by the libcalls, and the
561 // section managed by MachineFrameInfo which can also hold callee saved
562 // registers in fixed stack slots, both of which have negative frame indices.
563 // This gets even more complicated when incoming arguments are passed via the
564 // stack, as these too have negative frame indices. An example is detailed
565 // below:
566 //
567 // | incoming arg | <- FI[-3]
568 // | libcallspill |
569 // | calleespill | <- FI[-2]
570 // | calleespill | <- FI[-1]
571 // | this_frame | <- FI[0]
572 //
573 // For negative frame indices, the offset from the frame pointer will differ
574 // depending on which of these groups the frame index applies to.
575 // The following calculates the correct offset knowing the number of callee
576 // saved registers spilt by the two methods.
577 if (int LibCallRegs = getLibCallID(MF, MFI.getCalleeSavedInfo()) + 1) {
578 // Calculate the size of the frame managed by the libcall. The stack
579 // alignment of these libcalls should be the same as how we set it in
580 // getABIStackAlignment.
581 unsigned LibCallFrameSize =
582 alignTo((STI.getXLen() / 8) * LibCallRegs, getStackAlign());
583 RVFI->setLibCallStackSize(LibCallFrameSize);
584 }
585
586 // FIXME (note copied from Lanai): This appears to be overallocating. Needs
587 // investigation. Get the number of bytes to allocate from the FrameInfo.
588 uint64_t RealStackSize = getStackSizeWithRVVPadding(MF);
589 uint64_t StackSize = RealStackSize - RVFI->getReservedSpillsSize();
590 uint64_t RVVStackSize = RVFI->getRVVStackSize();
591
592 // Early exit if there is no need to allocate on the stack
593 if (RealStackSize == 0 && !MFI.adjustsStack() && RVVStackSize == 0)
594 return;
595
596 // If the stack pointer has been marked as reserved, then produce an error if
597 // the frame requires stack allocation
598 if (STI.isRegisterReservedByUser(SPReg))
600 MF.getFunction(), "Stack pointer required, but has been reserved."});
601
602 uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF);
603 // Split the SP adjustment to reduce the offsets of callee saved spill.
604 if (FirstSPAdjustAmount) {
605 StackSize = FirstSPAdjustAmount;
606 RealStackSize = FirstSPAdjustAmount;
607 }
608
609 if (RVFI->isPushable(MF) && FirstFrameSetup != MBB.end() &&
610 FirstFrameSetup->getOpcode() == RISCV::CM_PUSH) {
611 // Use available stack adjustment in push instruction to allocate additional
612 // stack space. Align the stack size down to a multiple of 16. This is
613 // needed for RVE.
614 // FIXME: Can we increase the stack size to a multiple of 16 instead?
615 uint64_t Spimm = std::min(alignDown(StackSize, 16), (uint64_t)48);
616 FirstFrameSetup->getOperand(1).setImm(Spimm);
617 StackSize -= Spimm;
618 }
619
620 if (StackSize != 0) {
621 // Allocate space on the stack if necessary.
622 RI->adjustReg(MBB, MBBI, DL, SPReg, SPReg,
624 getStackAlign());
625 }
626
627 // Emit ".cfi_def_cfa_offset RealStackSize"
628 unsigned CFIIndex = MF.addFrameInst(
629 MCCFIInstruction::cfiDefCfaOffset(nullptr, RealStackSize));
630 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
631 .addCFIIndex(CFIIndex)
633
634 const auto &CSI = MFI.getCalleeSavedInfo();
635
636 // The frame pointer is callee-saved, and code has been generated for us to
637 // save it to the stack. We need to skip over the storing of callee-saved
638 // registers as the frame pointer must be modified after it has been saved
639 // to the stack, not before.
640 // FIXME: assumes exactly one instruction is used to save each callee-saved
641 // register.
642 std::advance(MBBI, getUnmanagedCSI(MF, CSI).size());
643
644 // Iterate over list of callee-saved registers and emit .cfi_offset
645 // directives.
646 for (const auto &Entry : CSI) {
647 int FrameIdx = Entry.getFrameIdx();
648 if (FrameIdx >= 0 &&
650 continue;
651
652 int64_t Offset = MFI.getObjectOffset(FrameIdx);
653 Register Reg = Entry.getReg();
654 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
655 nullptr, RI->getDwarfRegNum(Reg, true), Offset));
656 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
657 .addCFIIndex(CFIIndex)
659 }
660
661 // Generate new FP.
662 if (hasFP(MF)) {
663 if (STI.isRegisterReservedByUser(FPReg))
665 MF.getFunction(), "Frame pointer required, but has been reserved."});
666 // The frame pointer does need to be reserved from register allocation.
667 assert(MF.getRegInfo().isReserved(FPReg) && "FP not reserved");
668
669 RI->adjustReg(MBB, MBBI, DL, FPReg, SPReg,
670 StackOffset::getFixed(RealStackSize - RVFI->getVarArgsSaveSize()),
672
673 // Emit ".cfi_def_cfa $fp, RVFI->getVarArgsSaveSize()"
674 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::cfiDefCfa(
675 nullptr, RI->getDwarfRegNum(FPReg, true), RVFI->getVarArgsSaveSize()));
676 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
677 .addCFIIndex(CFIIndex)
679 }
680
681 // Emit the second SP adjustment after saving callee saved registers.
682 if (FirstSPAdjustAmount) {
683 uint64_t SecondSPAdjustAmount =
684 getStackSizeWithRVVPadding(MF) - FirstSPAdjustAmount;
685 assert(SecondSPAdjustAmount > 0 &&
686 "SecondSPAdjustAmount should be greater than zero");
687 RI->adjustReg(MBB, MBBI, DL, SPReg, SPReg,
688 StackOffset::getFixed(-SecondSPAdjustAmount),
690
691 // If we are using a frame-pointer, and thus emitted ".cfi_def_cfa fp, 0",
692 // don't emit an sp-based .cfi_def_cfa_offset
693 if (!hasFP(MF)) {
694 // Emit ".cfi_def_cfa_offset StackSize"
695 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(
696 nullptr, getStackSizeWithRVVPadding(MF)));
697 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
698 .addCFIIndex(CFIIndex)
700 }
701 }
702
703 if (RVVStackSize) {
704 adjustStackForRVV(MF, MBB, MBBI, DL, -RVVStackSize,
706 if (!hasFP(MF)) {
707 // Emit .cfi_def_cfa_expression "sp + StackSize + RVVStackSize * vlenb".
708 unsigned CFIIndex = MF.addFrameInst(createDefCFAExpression(
709 *RI, SPReg, getStackSizeWithRVVPadding(MF), RVVStackSize / 8));
710 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
711 .addCFIIndex(CFIIndex)
713 }
714
715 std::advance(MBBI, getRVVCalleeSavedInfo(MF, CSI).size());
716 emitCalleeSavedRVVPrologCFI(MBB, MBBI, hasFP(MF));
717 }
718
719 if (hasFP(MF)) {
720 // Realign Stack
722 if (RI->hasStackRealignment(MF)) {
723 Align MaxAlignment = MFI.getMaxAlign();
724
726 if (isInt<12>(-(int)MaxAlignment.value())) {
727 BuildMI(MBB, MBBI, DL, TII->get(RISCV::ANDI), SPReg)
728 .addReg(SPReg)
729 .addImm(-(int)MaxAlignment.value())
731 } else {
732 unsigned ShiftAmount = Log2(MaxAlignment);
733 Register VR =
734 MF.getRegInfo().createVirtualRegister(&RISCV::GPRRegClass);
735 BuildMI(MBB, MBBI, DL, TII->get(RISCV::SRLI), VR)
736 .addReg(SPReg)
737 .addImm(ShiftAmount)
739 BuildMI(MBB, MBBI, DL, TII->get(RISCV::SLLI), SPReg)
740 .addReg(VR)
741 .addImm(ShiftAmount)
743 }
744 // FP will be used to restore the frame in the epilogue, so we need
745 // another base register BP to record SP after re-alignment. SP will
746 // track the current stack after allocating variable sized objects.
747 if (hasBP(MF)) {
748 // move BP, SP
749 BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADDI), BPReg)
750 .addReg(SPReg)
751 .addImm(0)
753 }
754 }
755 }
756}
757
759 MachineBasicBlock &MBB) const {
761 MachineFrameInfo &MFI = MF.getFrameInfo();
762 auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
763 Register FPReg = getFPReg(STI);
764 Register SPReg = getSPReg(STI);
765
766 // All calls are tail calls in GHC calling conv, and functions have no
767 // prologue/epilogue.
769 return;
770
771 // Get the insert location for the epilogue. If there were no terminators in
772 // the block, get the last instruction.
774 DebugLoc DL;
775 if (!MBB.empty()) {
777 if (MBBI != MBB.end())
778 DL = MBBI->getDebugLoc();
779
781
782 // If callee-saved registers are saved via libcall, place stack adjustment
783 // before this call.
784 while (MBBI != MBB.begin() &&
785 std::prev(MBBI)->getFlag(MachineInstr::FrameDestroy))
786 --MBBI;
787 }
788
789 const auto &CSI = getUnmanagedCSI(MF, MFI.getCalleeSavedInfo());
790
791 // Skip to before the restores of scalar callee-saved registers
792 // FIXME: assumes exactly one instruction is used to restore each
793 // callee-saved register.
794 auto LastFrameDestroy = MBBI;
795 if (!CSI.empty())
796 LastFrameDestroy = std::prev(MBBI, CSI.size());
797
798 uint64_t RealStackSize = getStackSizeWithRVVPadding(MF);
799 uint64_t StackSize = RealStackSize - RVFI->getReservedSpillsSize();
800 uint64_t FPOffset = RealStackSize - RVFI->getVarArgsSaveSize();
801 uint64_t RVVStackSize = RVFI->getRVVStackSize();
802
803 // Restore the stack pointer using the value of the frame pointer. Only
804 // necessary if the stack pointer was modified, meaning the stack size is
805 // unknown.
806 //
807 // In order to make sure the stack point is right through the EH region,
808 // we also need to restore stack pointer from the frame pointer if we
809 // don't preserve stack space within prologue/epilogue for outgoing variables,
810 // normally it's just checking the variable sized object is present or not
811 // is enough, but we also don't preserve that at prologue/epilogue when
812 // have vector objects in stack.
813 if (RI->hasStackRealignment(MF) || MFI.hasVarSizedObjects() ||
815 assert(hasFP(MF) && "frame pointer should not have been eliminated");
816 RI->adjustReg(MBB, LastFrameDestroy, DL, SPReg, FPReg,
817 StackOffset::getFixed(-FPOffset),
819 } else {
820 if (RVVStackSize)
821 adjustStackForRVV(MF, MBB, LastFrameDestroy, DL, RVVStackSize,
823 }
824
825 uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF);
826 if (FirstSPAdjustAmount) {
827 uint64_t SecondSPAdjustAmount =
828 getStackSizeWithRVVPadding(MF) - FirstSPAdjustAmount;
829 assert(SecondSPAdjustAmount > 0 &&
830 "SecondSPAdjustAmount should be greater than zero");
831
832 RI->adjustReg(MBB, LastFrameDestroy, DL, SPReg, SPReg,
833 StackOffset::getFixed(SecondSPAdjustAmount),
835 }
836
837 if (FirstSPAdjustAmount)
838 StackSize = FirstSPAdjustAmount;
839
840 if (RVFI->isPushable(MF) && MBBI != MBB.end() &&
841 MBBI->getOpcode() == RISCV::CM_POP) {
842 // Use available stack adjustment in pop instruction to deallocate stack
843 // space. Align the stack size down to a multiple of 16. This is needed for
844 // RVE.
845 // FIXME: Can we increase the stack size to a multiple of 16 instead?
846 uint64_t Spimm = std::min(alignDown(StackSize, 16), (uint64_t)48);
847 MBBI->getOperand(1).setImm(Spimm);
848 StackSize -= Spimm;
849 }
850
851 // Deallocate stack
852 if (StackSize != 0) {
853 RI->adjustReg(MBB, MBBI, DL, SPReg, SPReg, StackOffset::getFixed(StackSize),
855 }
856
857 // Emit epilogue for shadow call stack.
858 emitSCSEpilogue(MF, MBB, MBBI, DL);
859}
860
863 Register &FrameReg) const {
864 const MachineFrameInfo &MFI = MF.getFrameInfo();
866 const auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
867
868 // Callee-saved registers should be referenced relative to the stack
869 // pointer (positive offset), otherwise use the frame pointer (negative
870 // offset).
871 const auto &CSI = getUnmanagedCSI(MF, MFI.getCalleeSavedInfo());
872 int MinCSFI = 0;
873 int MaxCSFI = -1;
875 auto StackID = MFI.getStackID(FI);
876
877 assert((StackID == TargetStackID::Default ||
878 StackID == TargetStackID::ScalableVector) &&
879 "Unexpected stack ID for the frame object.");
880 if (StackID == TargetStackID::Default) {
881 Offset =
883 MFI.getOffsetAdjustment());
884 } else if (StackID == TargetStackID::ScalableVector) {
886 }
887
888 uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF);
889
890 if (CSI.size()) {
891 MinCSFI = CSI[0].getFrameIdx();
892 MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();
893 }
894
895 if (FI >= MinCSFI && FI <= MaxCSFI) {
896 FrameReg = RISCV::X2;
897
898 if (FirstSPAdjustAmount)
899 Offset += StackOffset::getFixed(FirstSPAdjustAmount);
900 else
902 return Offset;
903 }
904
905 if (RI->hasStackRealignment(MF) && !MFI.isFixedObjectIndex(FI)) {
906 // If the stack was realigned, the frame pointer is set in order to allow
907 // SP to be restored, so we need another base register to record the stack
908 // after realignment.
909 // |--------------------------| -- <-- FP
910 // | callee-allocated save | | <----|
911 // | area for register varargs| | |
912 // |--------------------------| | |
913 // | callee-saved registers | | |
914 // |--------------------------| -- |
915 // | realignment (the size of | | |
916 // | this area is not counted | | |
917 // | in MFI.getStackSize()) | | |
918 // |--------------------------| -- |-- MFI.getStackSize()
919 // | RVV alignment padding | | |
920 // | (not counted in | | |
921 // | MFI.getStackSize() but | | |
922 // | counted in | | |
923 // | RVFI.getRVVStackSize()) | | |
924 // |--------------------------| -- |
925 // | RVV objects | | |
926 // | (not counted in | | |
927 // | MFI.getStackSize()) | | |
928 // |--------------------------| -- |
929 // | padding before RVV | | |
930 // | (not counted in | | |
931 // | MFI.getStackSize() or in | | |
932 // | RVFI.getRVVStackSize()) | | |
933 // |--------------------------| -- |
934 // | scalar local variables | | <----'
935 // |--------------------------| -- <-- BP (if var sized objects present)
936 // | VarSize objects | |
937 // |--------------------------| -- <-- SP
938 if (hasBP(MF)) {
939 FrameReg = RISCVABI::getBPReg();
940 } else {
941 // VarSize objects must be empty in this case!
943 FrameReg = RISCV::X2;
944 }
945 } else {
946 FrameReg = RI->getFrameRegister(MF);
947 }
948
949 if (FrameReg == getFPReg(STI)) {
950 Offset += StackOffset::getFixed(RVFI->getVarArgsSaveSize());
951 // When using FP to access scalable vector objects, we need to minus
952 // the frame size.
953 //
954 // |--------------------------| -- <-- FP
955 // | callee-allocated save | |
956 // | area for register varargs| |
957 // |--------------------------| |
958 // | callee-saved registers | |
959 // |--------------------------| | MFI.getStackSize()
960 // | scalar local variables | |
961 // |--------------------------| -- (Offset of RVV objects is from here.)
962 // | RVV objects |
963 // |--------------------------|
964 // | VarSize objects |
965 // |--------------------------| <-- SP
967 assert(!RI->hasStackRealignment(MF) &&
968 "Can't index across variable sized realign");
969 // We don't expect any extra RVV alignment padding, as the stack size
970 // and RVV object sections should be correct aligned in their own
971 // right.
973 "Inconsistent stack layout");
975 }
976 return Offset;
977 }
978
979 // This case handles indexing off both SP and BP.
980 // If indexing off SP, there must not be any var sized objects
981 assert(FrameReg == RISCVABI::getBPReg() || !MFI.hasVarSizedObjects());
982
983 // When using SP to access frame objects, we need to add RVV stack size.
984 //
985 // |--------------------------| -- <-- FP
986 // | callee-allocated save | | <----|
987 // | area for register varargs| | |
988 // |--------------------------| | |
989 // | callee-saved registers | | |
990 // |--------------------------| -- |
991 // | RVV alignment padding | | |
992 // | (not counted in | | |
993 // | MFI.getStackSize() but | | |
994 // | counted in | | |
995 // | RVFI.getRVVStackSize()) | | |
996 // |--------------------------| -- |
997 // | RVV objects | | |-- MFI.getStackSize()
998 // | (not counted in | | |
999 // | MFI.getStackSize()) | | |
1000 // |--------------------------| -- |
1001 // | padding before RVV | | |
1002 // | (not counted in | | |
1003 // | MFI.getStackSize()) | | |
1004 // |--------------------------| -- |
1005 // | scalar local variables | | <----'
1006 // |--------------------------| -- <-- BP (if var sized objects present)
1007 // | VarSize objects | |
1008 // |--------------------------| -- <-- SP
1009 //
1010 // The total amount of padding surrounding RVV objects is described by
1011 // RVV->getRVVPadding() and it can be zero. It allows us to align the RVV
1012 // objects to the required alignment.
1013 if (MFI.getStackID(FI) == TargetStackID::Default) {
1014 if (MFI.isFixedObjectIndex(FI)) {
1015 assert(!RI->hasStackRealignment(MF) &&
1016 "Can't index across variable sized realign");
1018 RVFI->getRVVStackSize());
1019 } else {
1021 }
1022 } else if (MFI.getStackID(FI) == TargetStackID::ScalableVector) {
1023 // Ensure the base of the RVV stack is correctly aligned: add on the
1024 // alignment padding.
1025 int ScalarLocalVarSize = MFI.getStackSize() -
1026 RVFI->getCalleeSavedStackSize() -
1027 RVFI->getRVPushStackSize() -
1028 RVFI->getVarArgsSaveSize() + RVFI->getRVVPadding();
1029 Offset += StackOffset::get(ScalarLocalVarSize, RVFI->getRVVStackSize());
1030 }
1031 return Offset;
1032}
1033
1035 BitVector &SavedRegs,
1036 RegScavenger *RS) const {
1038 // Unconditionally spill RA and FP only if the function uses a frame
1039 // pointer.
1040 if (hasFP(MF)) {
1041 SavedRegs.set(RISCV::X1);
1042 SavedRegs.set(RISCV::X8);
1043 }
1044 // Mark BP as used if function has dedicated base pointer.
1045 if (hasBP(MF))
1046 SavedRegs.set(RISCVABI::getBPReg());
1047
1048 // When using cm.push/pop we must save X27 if we save X26.
1049 auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
1050 if (RVFI->isPushable(MF) && SavedRegs.test(RISCV::X26))
1051 SavedRegs.set(RISCV::X27);
1052}
1053
1054std::pair<int64_t, Align>
1055RISCVFrameLowering::assignRVVStackObjectOffsets(MachineFunction &MF) const {
1056 MachineFrameInfo &MFI = MF.getFrameInfo();
1057 // Create a buffer of RVV objects to allocate.
1058 SmallVector<int, 8> ObjectsToAllocate;
1059 auto pushRVVObjects = [&](int FIBegin, int FIEnd) {
1060 for (int I = FIBegin, E = FIEnd; I != E; ++I) {
1061 unsigned StackID = MFI.getStackID(I);
1062 if (StackID != TargetStackID::ScalableVector)
1063 continue;
1064 if (MFI.isDeadObjectIndex(I))
1065 continue;
1066
1067 ObjectsToAllocate.push_back(I);
1068 }
1069 };
1070 // First push RVV Callee Saved object, then push RVV stack object
1071 std::vector<CalleeSavedInfo> &CSI = MF.getFrameInfo().getCalleeSavedInfo();
1072 const auto &RVVCSI = getRVVCalleeSavedInfo(MF, CSI);
1073 if (!RVVCSI.empty())
1074 pushRVVObjects(RVVCSI[0].getFrameIdx(),
1075 RVVCSI[RVVCSI.size() - 1].getFrameIdx() + 1);
1076 pushRVVObjects(0, MFI.getObjectIndexEnd() - RVVCSI.size());
1077
1078 // The minimum alignment is 16 bytes.
1079 Align RVVStackAlign(16);
1080 const auto &ST = MF.getSubtarget<RISCVSubtarget>();
1081
1082 if (!ST.hasVInstructions()) {
1083 assert(ObjectsToAllocate.empty() &&
1084 "Can't allocate scalable-vector objects without V instructions");
1085 return std::make_pair(0, RVVStackAlign);
1086 }
1087
1088 // Allocate all RVV locals and spills
1089 int64_t Offset = 0;
1090 for (int FI : ObjectsToAllocate) {
1091 // ObjectSize in bytes.
1092 int64_t ObjectSize = MFI.getObjectSize(FI);
1093 auto ObjectAlign = std::max(Align(8), MFI.getObjectAlign(FI));
1094 // If the data type is the fractional vector type, reserve one vector
1095 // register for it.
1096 if (ObjectSize < 8)
1097 ObjectSize = 8;
1098 Offset = alignTo(Offset + ObjectSize, ObjectAlign);
1099 MFI.setObjectOffset(FI, -Offset);
1100 // Update the maximum alignment of the RVV stack section
1101 RVVStackAlign = std::max(RVVStackAlign, ObjectAlign);
1102 }
1103
1104 // Ensure the alignment of the RVV stack. Since we want the most-aligned
1105 // object right at the bottom (i.e., any padding at the top of the frame),
1106 // readjust all RVV objects down by the alignment padding.
1107 uint64_t StackSize = Offset;
1108 if (auto AlignmentPadding = offsetToAlignment(StackSize, RVVStackAlign)) {
1109 StackSize += AlignmentPadding;
1110 for (int FI : ObjectsToAllocate)
1111 MFI.setObjectOffset(FI, MFI.getObjectOffset(FI) - AlignmentPadding);
1112 }
1113
1114 return std::make_pair(StackSize, RVVStackAlign);
1115}
1116
1118 // For RVV spill, scalable stack offsets computing requires up to two scratch
1119 // registers
1120 static constexpr unsigned ScavSlotsNumRVVSpillScalableObject = 2;
1121
1122 // For RVV spill, non-scalable stack offsets computing requires up to one
1123 // scratch register.
1124 static constexpr unsigned ScavSlotsNumRVVSpillNonScalableObject = 1;
1125
1126 // ADDI instruction's destination register can be used for computing
1127 // offsets. So Scalable stack offsets require up to one scratch register.
1128 static constexpr unsigned ScavSlotsADDIScalableObject = 1;
1129
1130 static constexpr unsigned MaxScavSlotsNumKnown =
1131 std::max({ScavSlotsADDIScalableObject, ScavSlotsNumRVVSpillScalableObject,
1132 ScavSlotsNumRVVSpillNonScalableObject});
1133
1134 unsigned MaxScavSlotsNum = 0;
1136 return false;
1137 for (const MachineBasicBlock &MBB : MF)
1138 for (const MachineInstr &MI : MBB) {
1139 bool IsRVVSpill = RISCV::isRVVSpill(MI);
1140 for (auto &MO : MI.operands()) {
1141 if (!MO.isFI())
1142 continue;
1143 bool IsScalableVectorID = MF.getFrameInfo().getStackID(MO.getIndex()) ==
1145 if (IsRVVSpill) {
1146 MaxScavSlotsNum = std::max(
1147 MaxScavSlotsNum, IsScalableVectorID
1148 ? ScavSlotsNumRVVSpillScalableObject
1149 : ScavSlotsNumRVVSpillNonScalableObject);
1150 } else if (MI.getOpcode() == RISCV::ADDI && IsScalableVectorID) {
1151 MaxScavSlotsNum =
1152 std::max(MaxScavSlotsNum, ScavSlotsADDIScalableObject);
1153 }
1154 }
1155 if (MaxScavSlotsNum == MaxScavSlotsNumKnown)
1156 return MaxScavSlotsNumKnown;
1157 }
1158 return MaxScavSlotsNum;
1159}
1160
1161static bool hasRVVFrameObject(const MachineFunction &MF) {
1162 // Originally, the function will scan all the stack objects to check whether
1163 // if there is any scalable vector object on the stack or not. However, it
1164 // causes errors in the register allocator. In issue 53016, it returns false
1165 // before RA because there is no RVV stack objects. After RA, it returns true
1166 // because there are spilling slots for RVV values during RA. It will not
1167 // reserve BP during register allocation and generate BP access in the PEI
1168 // pass due to the inconsistent behavior of the function.
1169 //
1170 // The function is changed to use hasVInstructions() as the return value. It
1171 // is not precise, but it can make the register allocation correct.
1172 //
1173 // FIXME: Find a better way to make the decision or revisit the solution in
1174 // D103622.
1175 //
1176 // Refer to https://github.com/llvm/llvm-project/issues/53016.
1177 return MF.getSubtarget<RISCVSubtarget>().hasVInstructions();
1178}
1179
1181 const RISCVInstrInfo &TII) {
1182 unsigned FnSize = 0;
1183 for (auto &MBB : MF) {
1184 for (auto &MI : MBB) {
1185 // Far branches over 20-bit offset will be relaxed in branch relaxation
1186 // pass. In the worst case, conditional branches will be relaxed into
1187 // the following instruction sequence. Unconditional branches are
1188 // relaxed in the same way, with the exception that there is no first
1189 // branch instruction.
1190 //
1191 // foo
1192 // bne t5, t6, .rev_cond # `TII->getInstSizeInBytes(MI)` bytes
1193 // sd s11, 0(sp) # 4 bytes, or 2 bytes in RVC
1194 // jump .restore, s11 # 8 bytes
1195 // .rev_cond
1196 // bar
1197 // j .dest_bb # 4 bytes, or 2 bytes in RVC
1198 // .restore:
1199 // ld s11, 0(sp) # 4 bytes, or 2 bytes in RVC
1200 // .dest:
1201 // baz
1202 if (MI.isConditionalBranch())
1203 FnSize += TII.getInstSizeInBytes(MI);
1204 if (MI.isConditionalBranch() || MI.isUnconditionalBranch()) {
1206 FnSize += 2 + 8 + 2 + 2;
1207 else
1208 FnSize += 4 + 8 + 4 + 4;
1209 continue;
1210 }
1211
1212 FnSize += TII.getInstSizeInBytes(MI);
1213 }
1214 }
1215 return FnSize;
1216}
1217
1219 MachineFunction &MF, RegScavenger *RS) const {
1220 const RISCVRegisterInfo *RegInfo =
1221 MF.getSubtarget<RISCVSubtarget>().getRegisterInfo();
1222 const RISCVInstrInfo *TII = MF.getSubtarget<RISCVSubtarget>().getInstrInfo();
1223 MachineFrameInfo &MFI = MF.getFrameInfo();
1224 const TargetRegisterClass *RC = &RISCV::GPRRegClass;
1225 auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
1226
1227 int64_t RVVStackSize;
1228 Align RVVStackAlign;
1229 std::tie(RVVStackSize, RVVStackAlign) = assignRVVStackObjectOffsets(MF);
1230
1231 RVFI->setRVVStackSize(RVVStackSize);
1232 RVFI->setRVVStackAlign(RVVStackAlign);
1233
1234 if (hasRVVFrameObject(MF)) {
1235 // Ensure the entire stack is aligned to at least the RVV requirement: some
1236 // scalable-vector object alignments are not considered by the
1237 // target-independent code.
1238 MFI.ensureMaxAlignment(RVVStackAlign);
1239 }
1240
1241 unsigned ScavSlotsNum = 0;
1242
1243 // estimateStackSize has been observed to under-estimate the final stack
1244 // size, so give ourselves wiggle-room by checking for stack size
1245 // representable an 11-bit signed field rather than 12-bits.
1246 if (!isInt<11>(MFI.estimateStackSize(MF)))
1247 ScavSlotsNum = 1;
1248
1249 // Far branches over 20-bit offset require a spill slot for scratch register.
1250 bool IsLargeFunction = !isInt<20>(estimateFunctionSizeInBytes(MF, *TII));
1251 if (IsLargeFunction)
1252 ScavSlotsNum = std::max(ScavSlotsNum, 1u);
1253
1254 // RVV loads & stores have no capacity to hold the immediate address offsets
1255 // so we must always reserve an emergency spill slot if the MachineFunction
1256 // contains any RVV spills.
1257 ScavSlotsNum = std::max(ScavSlotsNum, getScavSlotsNumForRVV(MF));
1258
1259 for (unsigned I = 0; I < ScavSlotsNum; I++) {
1260 int FI = MFI.CreateStackObject(RegInfo->getSpillSize(*RC),
1261 RegInfo->getSpillAlign(*RC), false);
1263
1264 if (IsLargeFunction && RVFI->getBranchRelaxationScratchFrameIndex() == -1)
1265 RVFI->setBranchRelaxationScratchFrameIndex(FI);
1266 }
1267
1268 unsigned Size = RVFI->getReservedSpillsSize();
1269 for (const auto &Info : MFI.getCalleeSavedInfo()) {
1270 int FrameIdx = Info.getFrameIdx();
1271 if (FrameIdx < 0 || MFI.getStackID(FrameIdx) != TargetStackID::Default)
1272 continue;
1273
1274 Size += MFI.getObjectSize(FrameIdx);
1275 }
1276 RVFI->setCalleeSavedStackSize(Size);
1277}
1278
1279// Not preserve stack space within prologue for outgoing variables when the
1280// function contains variable size objects or there are vector objects accessed
1281// by the frame pointer.
1282// Let eliminateCallFramePseudoInstr preserve stack space for it.
1284 return !MF.getFrameInfo().hasVarSizedObjects() &&
1285 !(hasFP(MF) && hasRVVFrameObject(MF));
1286}
1287
1288// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions.
1292 Register SPReg = RISCV::X2;
1293 DebugLoc DL = MI->getDebugLoc();
1294
1295 if (!hasReservedCallFrame(MF)) {
1296 // If space has not been reserved for a call frame, ADJCALLSTACKDOWN and
1297 // ADJCALLSTACKUP must be converted to instructions manipulating the stack
1298 // pointer. This is necessary when there is a variable length stack
1299 // allocation (e.g. alloca), which means it's not possible to allocate
1300 // space for outgoing arguments from within the function prologue.
1301 int64_t Amount = MI->getOperand(0).getImm();
1302
1303 if (Amount != 0) {
1304 // Ensure the stack remains aligned after adjustment.
1305 Amount = alignSPAdjust(Amount);
1306
1307 if (MI->getOpcode() == RISCV::ADJCALLSTACKDOWN)
1308 Amount = -Amount;
1309
1310 const RISCVRegisterInfo &RI = *STI.getRegisterInfo();
1311 RI.adjustReg(MBB, MI, DL, SPReg, SPReg, StackOffset::getFixed(Amount),
1313 }
1314 }
1315
1316 return MBB.erase(MI);
1317}
1318
1319// We would like to split the SP adjustment to reduce prologue/epilogue
1320// as following instructions. In this way, the offset of the callee saved
1321// register could fit in a single store. Supposed that the first sp adjust
1322// amount is 2032.
1323// add sp,sp,-2032
1324// sw ra,2028(sp)
1325// sw s0,2024(sp)
1326// sw s1,2020(sp)
1327// sw s3,2012(sp)
1328// sw s4,2008(sp)
1329// add sp,sp,-64
1332 const auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
1333 const MachineFrameInfo &MFI = MF.getFrameInfo();
1334 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
1335 uint64_t StackSize = getStackSizeWithRVVPadding(MF);
1336
1337 // Disable SplitSPAdjust if save-restore libcall is used. The callee-saved
1338 // registers will be pushed by the save-restore libcalls, so we don't have to
1339 // split the SP adjustment in this case.
1340 if (RVFI->getReservedSpillsSize())
1341 return 0;
1342
1343 // Return the FirstSPAdjustAmount if the StackSize can not fit in a signed
1344 // 12-bit and there exists a callee-saved register needing to be pushed.
1345 if (!isInt<12>(StackSize) && (CSI.size() > 0)) {
1346 // FirstSPAdjustAmount is chosen at most as (2048 - StackAlign) because
1347 // 2048 will cause sp = sp + 2048 in the epilogue to be split into multiple
1348 // instructions. Offsets smaller than 2048 can fit in a single load/store
1349 // instruction, and we have to stick with the stack alignment. 2048 has
1350 // 16-byte alignment. The stack alignment for RV32 and RV64 is 16 and for
1351 // RV32E it is 4. So (2048 - StackAlign) will satisfy the stack alignment.
1352 const uint64_t StackAlign = getStackAlign().value();
1353
1354 // Amount of (2048 - StackAlign) will prevent callee saved and restored
1355 // instructions be compressed, so try to adjust the amount to the largest
1356 // offset that stack compression instructions accept when target supports
1357 // compression instructions.
1358 if (STI.hasStdExtCOrZca()) {
1359 // The compression extensions may support the following instructions:
1360 // riscv32: c.lwsp rd, offset[7:2] => 2^(6 + 2)
1361 // c.swsp rs2, offset[7:2] => 2^(6 + 2)
1362 // c.flwsp rd, offset[7:2] => 2^(6 + 2)
1363 // c.fswsp rs2, offset[7:2] => 2^(6 + 2)
1364 // riscv64: c.ldsp rd, offset[8:3] => 2^(6 + 3)
1365 // c.sdsp rs2, offset[8:3] => 2^(6 + 3)
1366 // c.fldsp rd, offset[8:3] => 2^(6 + 3)
1367 // c.fsdsp rs2, offset[8:3] => 2^(6 + 3)
1368 const uint64_t RVCompressLen = STI.getXLen() * 8;
1369 // Compared with amount (2048 - StackAlign), StackSize needs to
1370 // satisfy the following conditions to avoid using more instructions
1371 // to adjust the sp after adjusting the amount, such as
1372 // StackSize meets the condition (StackSize <= 2048 + RVCompressLen),
1373 // case1: Amount is 2048 - StackAlign: use addi + addi to adjust sp.
1374 // case2: Amount is RVCompressLen: use addi + addi to adjust sp.
1375 auto CanCompress = [&](uint64_t CompressLen) -> bool {
1376 if (StackSize <= 2047 + CompressLen ||
1377 (StackSize > 2048 * 2 - StackAlign &&
1378 StackSize <= 2047 * 2 + CompressLen) ||
1379 StackSize > 2048 * 3 - StackAlign)
1380 return true;
1381
1382 return false;
1383 };
1384 // In the epilogue, addi sp, sp, 496 is used to recover the sp and it
1385 // can be compressed(C.ADDI16SP, offset can be [-512, 496]), but
1386 // addi sp, sp, 512 can not be compressed. So try to use 496 first.
1387 const uint64_t ADDI16SPCompressLen = 496;
1388 if (STI.is64Bit() && CanCompress(ADDI16SPCompressLen))
1389 return ADDI16SPCompressLen;
1390 if (CanCompress(RVCompressLen))
1391 return RVCompressLen;
1392 }
1393 return 2048 - StackAlign;
1394 }
1395 return 0;
1396}
1397
1400 std::vector<CalleeSavedInfo> &CSI, unsigned &MinCSFrameIndex,
1401 unsigned &MaxCSFrameIndex) const {
1402 // Early exit if no callee saved registers are modified!
1403 if (CSI.empty())
1404 return true;
1405
1406 auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
1407
1408 if (RVFI->isPushable(MF)) {
1409 // Determine how many GPRs we need to push and save it to RVFI.
1410 Register MaxReg = getMaxPushPopReg(MF, CSI);
1411 if (MaxReg != RISCV::NoRegister) {
1412 auto [RegEnc, PushedRegNum] = getPushPopEncodingAndNum(MaxReg);
1413 RVFI->setRVPushRegs(PushedRegNum);
1414 RVFI->setRVPushStackSize(alignTo((STI.getXLen() / 8) * PushedRegNum, 16));
1415
1416 // Use encoded number to represent registers to spill.
1417 RVFI->setRVPushRlist(RegEnc);
1418 }
1419 }
1420
1421 MachineFrameInfo &MFI = MF.getFrameInfo();
1422 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
1423
1424 for (auto &CS : CSI) {
1425 unsigned Reg = CS.getReg();
1426 const TargetRegisterClass *RC = RegInfo->getMinimalPhysRegClass(Reg);
1427 unsigned Size = RegInfo->getSpillSize(*RC);
1428
1429 // This might need a fixed stack slot.
1430 if (RVFI->useSaveRestoreLibCalls(MF) || RVFI->isPushable(MF)) {
1431 const auto *FII = llvm::find_if(
1432 FixedCSRFIMap, [&](auto P) { return P.first == CS.getReg(); });
1433 if (FII != std::end(FixedCSRFIMap)) {
1434 int64_t Offset;
1435 if (RVFI->isPushable(MF))
1436 Offset = -((FII->second + RVFI->getRVPushRegs() + 1) * (int64_t)Size);
1437 else
1438 Offset = FII->second * (int64_t)Size;
1439
1440 int FrameIdx = MFI.CreateFixedSpillStackObject(Size, Offset);
1441 assert(FrameIdx < 0);
1442 CS.setFrameIdx(FrameIdx);
1443 continue;
1444 }
1445 }
1446
1447 // Not a fixed slot.
1448 Align Alignment = RegInfo->getSpillAlign(*RC);
1449 // We may not be able to satisfy the desired alignment specification of
1450 // the TargetRegisterClass if the stack alignment is smaller. Use the
1451 // min.
1452 Alignment = std::min(Alignment, getStackAlign());
1453 int FrameIdx = MFI.CreateStackObject(Size, Alignment, true);
1454 if ((unsigned)FrameIdx < MinCSFrameIndex)
1455 MinCSFrameIndex = FrameIdx;
1456 if ((unsigned)FrameIdx > MaxCSFrameIndex)
1457 MaxCSFrameIndex = FrameIdx;
1458 CS.setFrameIdx(FrameIdx);
1459 }
1460
1461 // Allocate a fixed object that covers the full push or libcall size.
1462 if (RVFI->isPushable(MF)) {
1463 if (int64_t PushSize = RVFI->getRVPushStackSize())
1464 MFI.CreateFixedSpillStackObject(PushSize, -PushSize);
1465 } else if (int LibCallRegs = getLibCallID(MF, CSI) + 1) {
1466 int64_t LibCallFrameSize =
1467 alignTo((STI.getXLen() / 8) * LibCallRegs, getStackAlign());
1468 MFI.CreateFixedSpillStackObject(LibCallFrameSize, -LibCallFrameSize);
1469 }
1470
1471 return true;
1472}
1473
1477 if (CSI.empty())
1478 return true;
1479
1481 const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
1482 DebugLoc DL;
1483 if (MI != MBB.end() && !MI->isDebugInstr())
1484 DL = MI->getDebugLoc();
1485
1486 // Emit CM.PUSH with base SPimm & evaluate Push stack
1488 if (RVFI->isPushable(*MF)) {
1489 unsigned PushedRegNum = RVFI->getRVPushRegs();
1490 if (PushedRegNum > 0) {
1491 // Use encoded number to represent registers to spill.
1492 int RegEnc = RVFI->getRVPushRlist();
1493 MachineInstrBuilder PushBuilder =
1494 BuildMI(MBB, MI, DL, TII.get(RISCV::CM_PUSH))
1496 PushBuilder.addImm((int64_t)RegEnc);
1497 PushBuilder.addImm(0);
1498
1499 for (unsigned i = 0; i < PushedRegNum; i++)
1500 PushBuilder.addUse(FixedCSRFIMap[i].first, RegState::Implicit);
1501 }
1502 } else if (const char *SpillLibCall = getSpillLibCallName(*MF, CSI)) {
1503 // Add spill libcall via non-callee-saved register t0.
1504 BuildMI(MBB, MI, DL, TII.get(RISCV::PseudoCALLReg), RISCV::X5)
1505 .addExternalSymbol(SpillLibCall, RISCVII::MO_CALL)
1507
1508 // Add registers spilled in libcall as liveins.
1509 for (auto &CS : CSI)
1510 MBB.addLiveIn(CS.getReg());
1511 }
1512
1513 // Manually spill values not spilled by libcall & Push/Pop.
1514 const auto &UnmanagedCSI = getUnmanagedCSI(*MF, CSI);
1515 const auto &RVVCSI = getRVVCalleeSavedInfo(*MF, CSI);
1516
1517 auto storeRegToStackSlot = [&](decltype(UnmanagedCSI) CSInfo) {
1518 for (auto &CS : CSInfo) {
1519 // Insert the spill to the stack frame.
1520 Register Reg = CS.getReg();
1521 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
1523 CS.getFrameIdx(), RC, TRI, Register());
1524 }
1525 };
1526 storeRegToStackSlot(UnmanagedCSI);
1527 storeRegToStackSlot(RVVCSI);
1528
1529 return true;
1530}
1531
1532void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI(
1535 const MachineFrameInfo &MFI = MF->getFrameInfo();
1537 const TargetInstrInfo &TII = *STI.getInstrInfo();
1539
1540 const auto &RVVCSI = getRVVCalleeSavedInfo(*MF, MFI.getCalleeSavedInfo());
1541 if (RVVCSI.empty())
1542 return;
1543
1544 uint64_t FixedSize = getStackSizeWithRVVPadding(*MF);
1545 if (!HasFP) {
1546 uint64_t ScalarLocalVarSize =
1547 MFI.getStackSize() - RVFI->getCalleeSavedStackSize() -
1548 RVFI->getRVPushStackSize() - RVFI->getVarArgsSaveSize() +
1549 RVFI->getRVVPadding();
1550 FixedSize -= ScalarLocalVarSize;
1551 }
1552
1553 for (auto &CS : RVVCSI) {
1554 // Insert the spill to the stack frame.
1555 int FI = CS.getFrameIdx();
1556 if (FI >= 0 && MFI.getStackID(FI) == TargetStackID::ScalableVector) {
1557 unsigned CFIIndex = MF->addFrameInst(
1558 createDefCFAOffset(*STI.getRegisterInfo(), CS.getReg(), -FixedSize,
1559 MFI.getObjectOffset(FI) / 8));
1560 BuildMI(MBB, MI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
1561 .addCFIIndex(CFIIndex)
1563 }
1564 }
1565}
1566
1570 if (CSI.empty())
1571 return true;
1572
1574 const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
1575 DebugLoc DL;
1576 if (MI != MBB.end() && !MI->isDebugInstr())
1577 DL = MI->getDebugLoc();
1578
1579 // Manually restore values not restored by libcall & Push/Pop.
1580 // Reverse the restore order in epilog. In addition, the return
1581 // address will be restored first in the epilogue. It increases
1582 // the opportunity to avoid the load-to-use data hazard between
1583 // loading RA and return by RA. loadRegFromStackSlot can insert
1584 // multiple instructions.
1585 const auto &UnmanagedCSI = getUnmanagedCSI(*MF, CSI);
1586 const auto &RVVCSI = getRVVCalleeSavedInfo(*MF, CSI);
1587
1588 auto loadRegFromStackSlot = [&](decltype(UnmanagedCSI) CSInfo) {
1589 for (auto &CS : CSInfo) {
1590 Register Reg = CS.getReg();
1591 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
1592 TII.loadRegFromStackSlot(MBB, MI, Reg, CS.getFrameIdx(), RC, TRI,
1593 Register());
1594 assert(MI != MBB.begin() &&
1595 "loadRegFromStackSlot didn't insert any code!");
1596 }
1597 };
1598 loadRegFromStackSlot(RVVCSI);
1599 loadRegFromStackSlot(UnmanagedCSI);
1600
1602 if (RVFI->isPushable(*MF)) {
1603 int RegEnc = RVFI->getRVPushRlist();
1605 MachineInstrBuilder PopBuilder =
1606 BuildMI(MBB, MI, DL, TII.get(RISCV::CM_POP))
1608 // Use encoded number to represent registers to restore.
1609 PopBuilder.addImm(RegEnc);
1610 PopBuilder.addImm(0);
1611
1612 for (unsigned i = 0; i < RVFI->getRVPushRegs(); i++)
1613 PopBuilder.addDef(FixedCSRFIMap[i].first, RegState::ImplicitDefine);
1614 }
1615 } else {
1616 const char *RestoreLibCall = getRestoreLibCallName(*MF, CSI);
1617 if (RestoreLibCall) {
1618 // Add restore libcall via tail call.
1620 BuildMI(MBB, MI, DL, TII.get(RISCV::PseudoTAIL))
1621 .addExternalSymbol(RestoreLibCall, RISCVII::MO_CALL)
1623
1624 // Remove trailing returns, since the terminator is now a tail call to the
1625 // restore function.
1626 if (MI != MBB.end() && MI->getOpcode() == RISCV::PseudoRET) {
1627 NewMI->copyImplicitOps(*MF, *MI);
1628 MI->eraseFromParent();
1629 }
1630 }
1631 }
1632 return true;
1633}
1634
1636 // Keep the conventional code flow when not optimizing.
1637 if (MF.getFunction().hasOptNone())
1638 return false;
1639
1640 return true;
1641}
1642
1644 MachineBasicBlock *TmpMBB = const_cast<MachineBasicBlock *>(&MBB);
1645 const MachineFunction *MF = MBB.getParent();
1646 const auto *RVFI = MF->getInfo<RISCVMachineFunctionInfo>();
1647
1648 if (!RVFI->useSaveRestoreLibCalls(*MF))
1649 return true;
1650
1651 // Inserting a call to a __riscv_save libcall requires the use of the register
1652 // t0 (X5) to hold the return address. Therefore if this register is already
1653 // used we can't insert the call.
1654
1655 RegScavenger RS;
1656 RS.enterBasicBlock(*TmpMBB);
1657 return !RS.isRegUsed(RISCV::X5);
1658}
1659
1661 const MachineFunction *MF = MBB.getParent();
1662 MachineBasicBlock *TmpMBB = const_cast<MachineBasicBlock *>(&MBB);
1663 const auto *RVFI = MF->getInfo<RISCVMachineFunctionInfo>();
1664
1665 if (!RVFI->useSaveRestoreLibCalls(*MF))
1666 return true;
1667
1668 // Using the __riscv_restore libcalls to restore CSRs requires a tail call.
1669 // This means if we still need to continue executing code within this function
1670 // the restore cannot take place in this basic block.
1671
1672 if (MBB.succ_size() > 1)
1673 return false;
1674
1675 MachineBasicBlock *SuccMBB =
1676 MBB.succ_empty() ? TmpMBB->getFallThrough() : *MBB.succ_begin();
1677
1678 // Doing a tail call should be safe if there are no successors, because either
1679 // we have a returning block or the end of the block is unreachable, so the
1680 // restore will be eliminated regardless.
1681 if (!SuccMBB)
1682 return true;
1683
1684 // The successor can only contain a return, since we would effectively be
1685 // replacing the successor with our own tail return at the end of our block.
1686 return SuccMBB->isReturnBlock() && SuccMBB->size() == 1;
1687}
1688
1690 switch (ID) {
1693 return true;
1697 return false;
1698 }
1699 llvm_unreachable("Invalid TargetStackID::Value");
1700}
1701
1704}
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
static Register getFPReg(const CSKYSubtarget &STI)
This file contains constants used for implementing Dwarf debug support.
uint64_t Size
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
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 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 Align getABIStackAlignment(RISCVABI::ABI ABI)
static int getLibCallID(const MachineFunction &MF, const std::vector< CalleeSavedInfo > &CSI)
static Register getSPReg(const RISCVSubtarget &STI)
static void emitSCSPrologue(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL)
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:160
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:264
bool hasOptNone() const
Do not optimize this function (-O0).
Definition: Function.h:679
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition: Function.cpp:356
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.cpp:675
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 createOffset(MCSymbol *L, unsigned Register, int Offset, SMLoc Loc={})
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
Definition: MCDwarf.h:583
static MCCFIInstruction cfiDefCfaOffset(MCSymbol *L, int Offset, SMLoc Loc={})
.cfi_def_cfa_offset modifies a rule for computing CFA.
Definition: MCDwarf.h:556
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:616
static MCCFIInstruction cfiDefCfa(MCSymbol *L, unsigned Register, int 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:541
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:647
MachineBasicBlock * getFallThrough(bool JumpToFallThrough=true)
Return the fallthrough block if the block can implicitly transfer control to the block after it by fa...
bool isLiveIn(MCPhysReg Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
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.
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 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.
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 estimateStackSize(const MachineFunction &MF) const
Estimate and return the size of the stack frame.
int getOffsetAdjustment() const
Return the correction for frame offsets.
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.
unsigned getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
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.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
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 & 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:307
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 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,...
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register.
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 isRegisterReservedByUser(Register i) const
bool hasVInstructions() const
std::optional< unsigned > getRealVLen() const
const RISCVRegisterInfo * getRegisterInfo() const override
const RISCVInstrInfo * getInstrInfo() const override
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:94
size_t size() const
Definition: SmallVector.h:91
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:586
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:696
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
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:50
Information about stack frame layout on the target.
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
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:660
#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()
bool isRVVSpill(const MachineInstr &MI)
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Define
Register definition.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:456
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:1680
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
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:1736
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:156
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:1749
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
uint64_t alignDown(uint64_t Value, uint64_t Align, uint64_t Skew=0)
Returns the largest uint64_t less than or equal to Value and is Skew mod Align.
Definition: MathExtras.h:439
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
void adjustReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator II, const DebugLoc &DL, Register DestReg, Register SrcReg, StackOffset Offset, MachineInstr::MIFlag Flag, MaybeAlign RequiredAlign) const