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