1 //===-- RISCVFrameLowering.cpp - RISCV 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 RISCV implementation of TargetFrameLowering class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "RISCVFrameLowering.h"
14 #include "RISCVMachineFunctionInfo.h"
15 #include "RISCVSubtarget.h"
16 #include "llvm/CodeGen/MachineFrameInfo.h"
17 #include "llvm/CodeGen/MachineFunction.h"
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
19 #include "llvm/CodeGen/MachineRegisterInfo.h"
20 #include "llvm/CodeGen/RegisterScavenging.h"
21 #include "llvm/IR/DiagnosticInfo.h"
22 #include "llvm/MC/MCDwarf.h"
23
24 using namespace llvm;
25
hasFP(const MachineFunction & MF) const26 bool RISCVFrameLowering::hasFP(const MachineFunction &MF) const {
27 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
28
29 const MachineFrameInfo &MFI = MF.getFrameInfo();
30 return MF.getTarget().Options.DisableFramePointerElim(MF) ||
31 RegInfo->needsStackRealignment(MF) || MFI.hasVarSizedObjects() ||
32 MFI.isFrameAddressTaken();
33 }
34
hasBP(const MachineFunction & MF) const35 bool RISCVFrameLowering::hasBP(const MachineFunction &MF) const {
36 const MachineFrameInfo &MFI = MF.getFrameInfo();
37 const TargetRegisterInfo *TRI = STI.getRegisterInfo();
38
39 return MFI.hasVarSizedObjects() && TRI->needsStackRealignment(MF);
40 }
41
42 // Determines the size of the frame and maximum call frame size.
determineFrameLayout(MachineFunction & MF) const43 void RISCVFrameLowering::determineFrameLayout(MachineFunction &MF) const {
44 MachineFrameInfo &MFI = MF.getFrameInfo();
45 const RISCVRegisterInfo *RI = STI.getRegisterInfo();
46
47 // Get the number of bytes to allocate from the FrameInfo.
48 uint64_t FrameSize = MFI.getStackSize();
49
50 // Get the alignment.
51 unsigned StackAlign = getStackAlignment();
52 if (RI->needsStackRealignment(MF)) {
53 unsigned MaxStackAlign = std::max(StackAlign, MFI.getMaxAlignment());
54 FrameSize += (MaxStackAlign - StackAlign);
55 StackAlign = MaxStackAlign;
56 }
57
58 // Set Max Call Frame Size
59 uint64_t MaxCallSize = alignTo(MFI.getMaxCallFrameSize(), StackAlign);
60 MFI.setMaxCallFrameSize(MaxCallSize);
61
62 // Make sure the frame is aligned.
63 FrameSize = alignTo(FrameSize, StackAlign);
64
65 // Update frame info.
66 MFI.setStackSize(FrameSize);
67 }
68
adjustReg(MachineBasicBlock & MBB,MachineBasicBlock::iterator MBBI,const DebugLoc & DL,Register DestReg,Register SrcReg,int64_t Val,MachineInstr::MIFlag Flag) const69 void RISCVFrameLowering::adjustReg(MachineBasicBlock &MBB,
70 MachineBasicBlock::iterator MBBI,
71 const DebugLoc &DL, Register DestReg,
72 Register SrcReg, int64_t Val,
73 MachineInstr::MIFlag Flag) const {
74 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
75 const RISCVInstrInfo *TII = STI.getInstrInfo();
76
77 if (DestReg == SrcReg && Val == 0)
78 return;
79
80 if (isInt<12>(Val)) {
81 BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADDI), DestReg)
82 .addReg(SrcReg)
83 .addImm(Val)
84 .setMIFlag(Flag);
85 } else {
86 unsigned Opc = RISCV::ADD;
87 bool isSub = Val < 0;
88 if (isSub) {
89 Val = -Val;
90 Opc = RISCV::SUB;
91 }
92
93 Register ScratchReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
94 TII->movImm(MBB, MBBI, DL, ScratchReg, Val, Flag);
95 BuildMI(MBB, MBBI, DL, TII->get(Opc), DestReg)
96 .addReg(SrcReg)
97 .addReg(ScratchReg, RegState::Kill)
98 .setMIFlag(Flag);
99 }
100 }
101
102 // Returns the register used to hold the frame pointer.
getFPReg(const RISCVSubtarget & STI)103 static Register getFPReg(const RISCVSubtarget &STI) { return RISCV::X8; }
104
105 // Returns the register used to hold the stack pointer.
getSPReg(const RISCVSubtarget & STI)106 static Register getSPReg(const RISCVSubtarget &STI) { return RISCV::X2; }
107
emitPrologue(MachineFunction & MF,MachineBasicBlock & MBB) const108 void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
109 MachineBasicBlock &MBB) const {
110 MachineFrameInfo &MFI = MF.getFrameInfo();
111 auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
112 const RISCVRegisterInfo *RI = STI.getRegisterInfo();
113 const RISCVInstrInfo *TII = STI.getInstrInfo();
114 MachineBasicBlock::iterator MBBI = MBB.begin();
115
116 Register FPReg = getFPReg(STI);
117 Register SPReg = getSPReg(STI);
118 Register BPReg = RISCVABI::getBPReg();
119
120 // Debug location must be unknown since the first debug location is used
121 // to determine the end of the prologue.
122 DebugLoc DL;
123
124 // Determine the correct frame layout
125 determineFrameLayout(MF);
126
127 // FIXME (note copied from Lanai): This appears to be overallocating. Needs
128 // investigation. Get the number of bytes to allocate from the FrameInfo.
129 uint64_t StackSize = MFI.getStackSize();
130
131 // Early exit if there is no need to allocate on the stack
132 if (StackSize == 0 && !MFI.adjustsStack())
133 return;
134
135 // If the stack pointer has been marked as reserved, then produce an error if
136 // the frame requires stack allocation
137 if (STI.isRegisterReservedByUser(SPReg))
138 MF.getFunction().getContext().diagnose(DiagnosticInfoUnsupported{
139 MF.getFunction(), "Stack pointer required, but has been reserved."});
140
141 uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF);
142 // Split the SP adjustment to reduce the offsets of callee saved spill.
143 if (FirstSPAdjustAmount)
144 StackSize = FirstSPAdjustAmount;
145
146 // Allocate space on the stack if necessary.
147 adjustReg(MBB, MBBI, DL, SPReg, SPReg, -StackSize, MachineInstr::FrameSetup);
148
149 // Emit ".cfi_def_cfa_offset StackSize"
150 unsigned CFIIndex = MF.addFrameInst(
151 MCCFIInstruction::createDefCfaOffset(nullptr, -StackSize));
152 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
153 .addCFIIndex(CFIIndex);
154
155 // The frame pointer is callee-saved, and code has been generated for us to
156 // save it to the stack. We need to skip over the storing of callee-saved
157 // registers as the frame pointer must be modified after it has been saved
158 // to the stack, not before.
159 // FIXME: assumes exactly one instruction is used to save each callee-saved
160 // register.
161 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
162 std::advance(MBBI, CSI.size());
163
164 // Iterate over list of callee-saved registers and emit .cfi_offset
165 // directives.
166 for (const auto &Entry : CSI) {
167 int64_t Offset = MFI.getObjectOffset(Entry.getFrameIdx());
168 Register Reg = Entry.getReg();
169 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
170 nullptr, RI->getDwarfRegNum(Reg, true), Offset));
171 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
172 .addCFIIndex(CFIIndex);
173 }
174
175 // Generate new FP.
176 if (hasFP(MF)) {
177 if (STI.isRegisterReservedByUser(FPReg))
178 MF.getFunction().getContext().diagnose(DiagnosticInfoUnsupported{
179 MF.getFunction(), "Frame pointer required, but has been reserved."});
180
181 adjustReg(MBB, MBBI, DL, FPReg, SPReg,
182 StackSize - RVFI->getVarArgsSaveSize(), MachineInstr::FrameSetup);
183
184 // Emit ".cfi_def_cfa $fp, -RVFI->getVarArgsSaveSize()"
185 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createDefCfa(
186 nullptr, RI->getDwarfRegNum(FPReg, true), -RVFI->getVarArgsSaveSize()));
187 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
188 .addCFIIndex(CFIIndex);
189 }
190
191 // Emit the second SP adjustment after saving callee saved registers.
192 if (FirstSPAdjustAmount) {
193 uint64_t SecondSPAdjustAmount = MFI.getStackSize() - FirstSPAdjustAmount;
194 assert(SecondSPAdjustAmount > 0 &&
195 "SecondSPAdjustAmount should be greater than zero");
196 adjustReg(MBB, MBBI, DL, SPReg, SPReg, -SecondSPAdjustAmount,
197 MachineInstr::FrameSetup);
198
199 // If we are using a frame-pointer, and thus emitted ".cfi_def_cfa fp, 0",
200 // don't emit an sp-based .cfi_def_cfa_offset
201 if (!hasFP(MF)) {
202 // Emit ".cfi_def_cfa_offset StackSize"
203 unsigned CFIIndex = MF.addFrameInst(
204 MCCFIInstruction::createDefCfaOffset(nullptr, -MFI.getStackSize()));
205 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
206 .addCFIIndex(CFIIndex);
207 }
208 }
209
210 if (hasFP(MF)) {
211 // Realign Stack
212 const RISCVRegisterInfo *RI = STI.getRegisterInfo();
213 if (RI->needsStackRealignment(MF)) {
214 unsigned MaxAlignment = MFI.getMaxAlignment();
215
216 const RISCVInstrInfo *TII = STI.getInstrInfo();
217 if (isInt<12>(-(int)MaxAlignment)) {
218 BuildMI(MBB, MBBI, DL, TII->get(RISCV::ANDI), SPReg)
219 .addReg(SPReg)
220 .addImm(-(int)MaxAlignment);
221 } else {
222 unsigned ShiftAmount = countTrailingZeros(MaxAlignment);
223 Register VR =
224 MF.getRegInfo().createVirtualRegister(&RISCV::GPRRegClass);
225 BuildMI(MBB, MBBI, DL, TII->get(RISCV::SRLI), VR)
226 .addReg(SPReg)
227 .addImm(ShiftAmount);
228 BuildMI(MBB, MBBI, DL, TII->get(RISCV::SLLI), SPReg)
229 .addReg(VR)
230 .addImm(ShiftAmount);
231 }
232 // FP will be used to restore the frame in the epilogue, so we need
233 // another base register BP to record SP after re-alignment. SP will
234 // track the current stack after allocating variable sized objects.
235 if (hasBP(MF)) {
236 // move BP, SP
237 BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADDI), BPReg)
238 .addReg(SPReg)
239 .addImm(0);
240 }
241 }
242 }
243 }
244
emitEpilogue(MachineFunction & MF,MachineBasicBlock & MBB) const245 void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
246 MachineBasicBlock &MBB) const {
247 const RISCVRegisterInfo *RI = STI.getRegisterInfo();
248 MachineFrameInfo &MFI = MF.getFrameInfo();
249 auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
250 Register FPReg = getFPReg(STI);
251 Register SPReg = getSPReg(STI);
252
253 // Get the insert location for the epilogue. If there were no terminators in
254 // the block, get the last instruction.
255 MachineBasicBlock::iterator MBBI = MBB.end();
256 DebugLoc DL;
257 if (!MBB.empty()) {
258 MBBI = MBB.getFirstTerminator();
259 if (MBBI == MBB.end())
260 MBBI = MBB.getLastNonDebugInstr();
261 DL = MBBI->getDebugLoc();
262
263 // If this is not a terminator, the actual insert location should be after the
264 // last instruction.
265 if (!MBBI->isTerminator())
266 MBBI = std::next(MBBI);
267 }
268
269 // Skip to before the restores of callee-saved registers
270 // FIXME: assumes exactly one instruction is used to restore each
271 // callee-saved register.
272 auto LastFrameDestroy = std::prev(MBBI, MFI.getCalleeSavedInfo().size());
273
274 uint64_t StackSize = MFI.getStackSize();
275 uint64_t FPOffset = StackSize - RVFI->getVarArgsSaveSize();
276
277 // Restore the stack pointer using the value of the frame pointer. Only
278 // necessary if the stack pointer was modified, meaning the stack size is
279 // unknown.
280 if (RI->needsStackRealignment(MF) || MFI.hasVarSizedObjects()) {
281 assert(hasFP(MF) && "frame pointer should not have been eliminated");
282 adjustReg(MBB, LastFrameDestroy, DL, SPReg, FPReg, -FPOffset,
283 MachineInstr::FrameDestroy);
284 }
285
286 uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF);
287 if (FirstSPAdjustAmount) {
288 uint64_t SecondSPAdjustAmount = MFI.getStackSize() - FirstSPAdjustAmount;
289 assert(SecondSPAdjustAmount > 0 &&
290 "SecondSPAdjustAmount should be greater than zero");
291
292 adjustReg(MBB, LastFrameDestroy, DL, SPReg, SPReg, SecondSPAdjustAmount,
293 MachineInstr::FrameDestroy);
294 }
295
296 if (FirstSPAdjustAmount)
297 StackSize = FirstSPAdjustAmount;
298
299 // Deallocate stack
300 adjustReg(MBB, MBBI, DL, SPReg, SPReg, StackSize, MachineInstr::FrameDestroy);
301 }
302
getFrameIndexReference(const MachineFunction & MF,int FI,unsigned & FrameReg) const303 int RISCVFrameLowering::getFrameIndexReference(const MachineFunction &MF,
304 int FI,
305 unsigned &FrameReg) const {
306 const MachineFrameInfo &MFI = MF.getFrameInfo();
307 const TargetRegisterInfo *RI = MF.getSubtarget().getRegisterInfo();
308 const auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
309
310 // Callee-saved registers should be referenced relative to the stack
311 // pointer (positive offset), otherwise use the frame pointer (negative
312 // offset).
313 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
314 int MinCSFI = 0;
315 int MaxCSFI = -1;
316
317 int Offset = MFI.getObjectOffset(FI) - getOffsetOfLocalArea() +
318 MFI.getOffsetAdjustment();
319
320 uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF);
321
322 if (CSI.size()) {
323 MinCSFI = CSI[0].getFrameIdx();
324 MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();
325 }
326
327 if (FI >= MinCSFI && FI <= MaxCSFI) {
328 FrameReg = RISCV::X2;
329
330 if (FirstSPAdjustAmount)
331 Offset += FirstSPAdjustAmount;
332 else
333 Offset += MF.getFrameInfo().getStackSize();
334 } else if (RI->needsStackRealignment(MF) && !MFI.isFixedObjectIndex(FI)) {
335 // If the stack was realigned, the frame pointer is set in order to allow
336 // SP to be restored, so we need another base register to record the stack
337 // after realignment.
338 if (hasBP(MF))
339 FrameReg = RISCVABI::getBPReg();
340 else
341 FrameReg = RISCV::X2;
342 Offset += MF.getFrameInfo().getStackSize();
343 } else {
344 FrameReg = RI->getFrameRegister(MF);
345 if (hasFP(MF))
346 Offset += RVFI->getVarArgsSaveSize();
347 else
348 Offset += MF.getFrameInfo().getStackSize();
349 }
350 return Offset;
351 }
352
determineCalleeSaves(MachineFunction & MF,BitVector & SavedRegs,RegScavenger * RS) const353 void RISCVFrameLowering::determineCalleeSaves(MachineFunction &MF,
354 BitVector &SavedRegs,
355 RegScavenger *RS) const {
356 TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
357 // Unconditionally spill RA and FP only if the function uses a frame
358 // pointer.
359 if (hasFP(MF)) {
360 SavedRegs.set(RISCV::X1);
361 SavedRegs.set(RISCV::X8);
362 }
363 // Mark BP as used if function has dedicated base pointer.
364 if (hasBP(MF))
365 SavedRegs.set(RISCVABI::getBPReg());
366
367 // If interrupt is enabled and there are calls in the handler,
368 // unconditionally save all Caller-saved registers and
369 // all FP registers, regardless whether they are used.
370 MachineFrameInfo &MFI = MF.getFrameInfo();
371
372 if (MF.getFunction().hasFnAttribute("interrupt") && MFI.hasCalls()) {
373
374 static const MCPhysReg CSRegs[] = { RISCV::X1, /* ra */
375 RISCV::X5, RISCV::X6, RISCV::X7, /* t0-t2 */
376 RISCV::X10, RISCV::X11, /* a0-a1, a2-a7 */
377 RISCV::X12, RISCV::X13, RISCV::X14, RISCV::X15, RISCV::X16, RISCV::X17,
378 RISCV::X28, RISCV::X29, RISCV::X30, RISCV::X31, 0 /* t3-t6 */
379 };
380
381 for (unsigned i = 0; CSRegs[i]; ++i)
382 SavedRegs.set(CSRegs[i]);
383
384 if (MF.getSubtarget<RISCVSubtarget>().hasStdExtD() ||
385 MF.getSubtarget<RISCVSubtarget>().hasStdExtF()) {
386
387 // If interrupt is enabled, this list contains all FP registers.
388 const MCPhysReg * Regs = MF.getRegInfo().getCalleeSavedRegs();
389
390 for (unsigned i = 0; Regs[i]; ++i)
391 if (RISCV::FPR32RegClass.contains(Regs[i]) ||
392 RISCV::FPR64RegClass.contains(Regs[i]))
393 SavedRegs.set(Regs[i]);
394 }
395 }
396 }
397
processFunctionBeforeFrameFinalized(MachineFunction & MF,RegScavenger * RS) const398 void RISCVFrameLowering::processFunctionBeforeFrameFinalized(
399 MachineFunction &MF, RegScavenger *RS) const {
400 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
401 MachineFrameInfo &MFI = MF.getFrameInfo();
402 const TargetRegisterClass *RC = &RISCV::GPRRegClass;
403 // estimateStackSize has been observed to under-estimate the final stack
404 // size, so give ourselves wiggle-room by checking for stack size
405 // representable an 11-bit signed field rather than 12-bits.
406 // FIXME: It may be possible to craft a function with a small stack that
407 // still needs an emergency spill slot for branch relaxation. This case
408 // would currently be missed.
409 if (!isInt<11>(MFI.estimateStackSize(MF))) {
410 int RegScavFI = MFI.CreateStackObject(
411 RegInfo->getSpillSize(*RC), RegInfo->getSpillAlignment(*RC), false);
412 RS->addScavengingFrameIndex(RegScavFI);
413 }
414 }
415
416 // Not preserve stack space within prologue for outgoing variables when the
417 // function contains variable size objects and let eliminateCallFramePseudoInstr
418 // preserve stack space for it.
hasReservedCallFrame(const MachineFunction & MF) const419 bool RISCVFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
420 return !MF.getFrameInfo().hasVarSizedObjects();
421 }
422
423 // Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions.
eliminateCallFramePseudoInstr(MachineFunction & MF,MachineBasicBlock & MBB,MachineBasicBlock::iterator MI) const424 MachineBasicBlock::iterator RISCVFrameLowering::eliminateCallFramePseudoInstr(
425 MachineFunction &MF, MachineBasicBlock &MBB,
426 MachineBasicBlock::iterator MI) const {
427 Register SPReg = RISCV::X2;
428 DebugLoc DL = MI->getDebugLoc();
429
430 if (!hasReservedCallFrame(MF)) {
431 // If space has not been reserved for a call frame, ADJCALLSTACKDOWN and
432 // ADJCALLSTACKUP must be converted to instructions manipulating the stack
433 // pointer. This is necessary when there is a variable length stack
434 // allocation (e.g. alloca), which means it's not possible to allocate
435 // space for outgoing arguments from within the function prologue.
436 int64_t Amount = MI->getOperand(0).getImm();
437
438 if (Amount != 0) {
439 // Ensure the stack remains aligned after adjustment.
440 Amount = alignSPAdjust(Amount);
441
442 if (MI->getOpcode() == RISCV::ADJCALLSTACKDOWN)
443 Amount = -Amount;
444
445 adjustReg(MBB, MI, DL, SPReg, SPReg, Amount, MachineInstr::NoFlags);
446 }
447 }
448
449 return MBB.erase(MI);
450 }
451
452 // We would like to split the SP adjustment to reduce prologue/epilogue
453 // as following instructions. In this way, the offset of the callee saved
454 // register could fit in a single store.
455 // add sp,sp,-2032
456 // sw ra,2028(sp)
457 // sw s0,2024(sp)
458 // sw s1,2020(sp)
459 // sw s3,2012(sp)
460 // sw s4,2008(sp)
461 // add sp,sp,-64
462 uint64_t
getFirstSPAdjustAmount(const MachineFunction & MF) const463 RISCVFrameLowering::getFirstSPAdjustAmount(const MachineFunction &MF) const {
464 const MachineFrameInfo &MFI = MF.getFrameInfo();
465 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
466 uint64_t StackSize = MFI.getStackSize();
467 uint64_t StackAlign = getStackAlignment();
468
469 // FIXME: Disable SplitSPAdjust if save-restore libcall enabled when the patch
470 // landing. The callee saved registers will be pushed by the
471 // save-restore libcalls, so we don't have to split the SP adjustment
472 // in this case.
473 //
474 // Return the FirstSPAdjustAmount if the StackSize can not fit in signed
475 // 12-bit and there exists a callee saved register need to be pushed.
476 if (!isInt<12>(StackSize) && (CSI.size() > 0)) {
477 // FirstSPAdjustAmount is choosed as (2048 - StackAlign)
478 // because 2048 will cause sp = sp + 2048 in epilogue split into
479 // multi-instructions. The offset smaller than 2048 can fit in signle
480 // load/store instruction and we have to stick with the stack alignment.
481 // 2048 is 16-byte alignment. The stack alignment for RV32 and RV64 is 16,
482 // for RV32E is 4. So (2048 - StackAlign) will satisfy the stack alignment.
483 return 2048 - StackAlign;
484 }
485 return 0;
486 }
487