1 //===-- RISCVFrameLowering.cpp - RISCV Frame Information ------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains the RISCV implementation of TargetFrameLowering class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "RISCVFrameLowering.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 
21 using namespace llvm;
22 
23 bool RISCVFrameLowering::hasFP(const MachineFunction &MF) const { return true; }
24 
25 // Determines the size of the frame and maximum call frame size.
26 void RISCVFrameLowering::determineFrameLayout(MachineFunction &MF) const {
27   MachineFrameInfo &MFI = MF.getFrameInfo();
28   const RISCVRegisterInfo *RI = STI.getRegisterInfo();
29 
30   // Get the number of bytes to allocate from the FrameInfo.
31   uint64_t FrameSize = MFI.getStackSize();
32 
33   // Get the alignment.
34   uint64_t StackAlign = RI->needsStackRealignment(MF) ? MFI.getMaxAlignment()
35                                                       : getStackAlignment();
36 
37   // Get the maximum call frame size of all the calls.
38   uint64_t MaxCallFrameSize = MFI.getMaxCallFrameSize();
39 
40   // If we have dynamic alloca then MaxCallFrameSize needs to be aligned so
41   // that allocations will be aligned.
42   if (MFI.hasVarSizedObjects())
43     MaxCallFrameSize = alignTo(MaxCallFrameSize, StackAlign);
44 
45   // Update maximum call frame size.
46   MFI.setMaxCallFrameSize(MaxCallFrameSize);
47 
48   // Include call frame size in total.
49   if (!(hasReservedCallFrame(MF) && MFI.adjustsStack()))
50     FrameSize += MaxCallFrameSize;
51 
52   // Make sure the frame is aligned.
53   FrameSize = alignTo(FrameSize, StackAlign);
54 
55   // Update frame info.
56   MFI.setStackSize(FrameSize);
57 }
58 
59 void RISCVFrameLowering::adjustReg(MachineBasicBlock &MBB,
60                                    MachineBasicBlock::iterator MBBI,
61                                    const DebugLoc &DL, unsigned DestReg,
62                                    unsigned SrcReg, int64_t Val,
63                                    MachineInstr::MIFlag Flag) const {
64   const RISCVInstrInfo *TII = STI.getInstrInfo();
65 
66   if (DestReg == SrcReg && Val == 0)
67     return;
68 
69   if (!isInt<12>(Val))
70     report_fatal_error("adjustReg cannot yet handle adjustments >12 bits");
71 
72   BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADDI), DestReg)
73       .addReg(SrcReg)
74       .addImm(Val)
75       .setMIFlag(Flag);
76 }
77 
78 // Returns the register used to hold the frame pointer.
79 static unsigned getFPReg(const RISCVSubtarget &STI) { return RISCV::X8; }
80 
81 // Returns the register used to hold the stack pointer.
82 static unsigned getSPReg(const RISCVSubtarget &STI) { return RISCV::X2; }
83 
84 void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
85                                       MachineBasicBlock &MBB) const {
86   assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
87 
88   if (!hasFP(MF)) {
89     report_fatal_error(
90         "emitPrologue doesn't support framepointer-less functions");
91   }
92 
93   MachineFrameInfo &MFI = MF.getFrameInfo();
94   MachineBasicBlock::iterator MBBI = MBB.begin();
95 
96   unsigned FPReg = getFPReg(STI);
97   unsigned SPReg = getSPReg(STI);
98 
99   // Debug location must be unknown since the first debug location is used
100   // to determine the end of the prologue.
101   DebugLoc DL;
102 
103   // Determine the correct frame layout
104   determineFrameLayout(MF);
105 
106   // FIXME (note copied from Lanai): This appears to be overallocating.  Needs
107   // investigation. Get the number of bytes to allocate from the FrameInfo.
108   uint64_t StackSize = MFI.getStackSize();
109 
110   // Early exit if there is no need to allocate on the stack
111   if (StackSize == 0 && !MFI.adjustsStack())
112     return;
113 
114   // Allocate space on the stack if necessary.
115   adjustReg(MBB, MBBI, DL, SPReg, SPReg, -StackSize, MachineInstr::FrameSetup);
116 
117   // The frame pointer is callee-saved, and code has been generated for us to
118   // save it to the stack. We need to skip over the storing of callee-saved
119   // registers as the frame pointer must be modified after it has been saved
120   // to the stack, not before.
121   // FIXME: assumes exactly one instruction is used to save each callee-saved
122   // register.
123   const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
124   std::advance(MBBI, CSI.size());
125 
126   // Generate new FP.
127   adjustReg(MBB, MBBI, DL, FPReg, SPReg, StackSize, MachineInstr::FrameSetup);
128 }
129 
130 void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
131                                       MachineBasicBlock &MBB) const {
132   if (!hasFP(MF)) {
133     report_fatal_error(
134         "emitEpilogue doesn't support framepointer-less functions");
135   }
136 
137   MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
138   const RISCVRegisterInfo *RI = STI.getRegisterInfo();
139   MachineFrameInfo &MFI = MF.getFrameInfo();
140   DebugLoc DL = MBBI->getDebugLoc();
141   unsigned FPReg = getFPReg(STI);
142   unsigned SPReg = getSPReg(STI);
143 
144   // Skip to before the restores of callee-saved registers
145   // FIXME: assumes exactly one instruction is used to restore each
146   // callee-saved register.
147   MachineBasicBlock::iterator LastFrameDestroy = MBBI;
148   std::advance(LastFrameDestroy, -MFI.getCalleeSavedInfo().size());
149 
150   uint64_t StackSize = MFI.getStackSize();
151 
152   // Restore the stack pointer using the value of the frame pointer. Only
153   // necessary if the stack pointer was modified, meaning the stack size is
154   // unknown.
155   if (RI->needsStackRealignment(MF) || MFI.hasVarSizedObjects()) {
156     adjustReg(MBB, LastFrameDestroy, DL, SPReg, FPReg, -StackSize,
157               MachineInstr::FrameDestroy);
158   }
159 
160   // Deallocate stack
161   adjustReg(MBB, MBBI, DL, SPReg, SPReg, StackSize, MachineInstr::FrameDestroy);
162 }
163 
164 int RISCVFrameLowering::getFrameIndexReference(const MachineFunction &MF,
165                                                int FI,
166                                                unsigned &FrameReg) const {
167   const MachineFrameInfo &MFI = MF.getFrameInfo();
168   const TargetRegisterInfo *RI = MF.getSubtarget().getRegisterInfo();
169 
170   // Callee-saved registers should be referenced relative to the stack
171   // pointer (positive offset), otherwise use the frame pointer (negative
172   // offset).
173   const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
174   int MinCSFI = 0;
175   int MaxCSFI = -1;
176 
177   int Offset = MFI.getObjectOffset(FI) - getOffsetOfLocalArea() +
178                MFI.getOffsetAdjustment();
179 
180   if (CSI.size()) {
181     MinCSFI = CSI[0].getFrameIdx();
182     MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();
183   }
184 
185   FrameReg = RI->getFrameRegister(MF);
186   if (FI >= MinCSFI && FI <= MaxCSFI) {
187     FrameReg = RISCV::X2;
188     Offset += MF.getFrameInfo().getStackSize();
189   }
190   return Offset;
191 }
192 
193 void RISCVFrameLowering::determineCalleeSaves(MachineFunction &MF,
194                                               BitVector &SavedRegs,
195                                               RegScavenger *RS) const {
196   TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
197   // TODO: Once frame pointer elimination is implemented, don't
198   // unconditionally spill the frame pointer and return address.
199   SavedRegs.set(RISCV::X1);
200   SavedRegs.set(RISCV::X8);
201 }
202