xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Lanai/LanaiFrameLowering.cpp (revision 1ed2ef42e01771f5d8ca9be61e07dcf0fd47feba)
1 //===-- LanaiFrameLowering.cpp - Lanai 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 Lanai implementation of TargetFrameLowering class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "LanaiFrameLowering.h"
14 
15 #include "LanaiAluCode.h"
16 #include "LanaiInstrInfo.h"
17 #include "LanaiSubtarget.h"
18 #include "llvm/CodeGen/MachineFrameInfo.h"
19 #include "llvm/CodeGen/MachineFunction.h"
20 #include "llvm/CodeGen/MachineInstrBuilder.h"
21 
22 using namespace llvm;
23 
24 // Determines the size of the frame and maximum call frame size.
25 void LanaiFrameLowering::determineFrameLayout(MachineFunction &MF) const {
26   MachineFrameInfo &MFI = MF.getFrameInfo();
27   const LanaiRegisterInfo *LRI = STI.getRegisterInfo();
28 
29   // Get the number of bytes to allocate from the FrameInfo.
30   unsigned FrameSize = MFI.getStackSize();
31 
32   // Get the alignment.
33   Align StackAlign =
34       LRI->hasStackRealignment(MF) ? MFI.getMaxAlign() : getStackAlign();
35 
36   // Get the maximum call frame size of all the calls.
37   unsigned MaxCallFrameSize = MFI.getMaxCallFrameSize();
38 
39   // If we have dynamic alloca then MaxCallFrameSize needs to be aligned so
40   // that allocations will be aligned.
41   if (MFI.hasVarSizedObjects())
42     MaxCallFrameSize = alignTo(MaxCallFrameSize, StackAlign);
43 
44   // Update maximum call frame size.
45   MFI.setMaxCallFrameSize(MaxCallFrameSize);
46 
47   // Include call frame size in total.
48   if (!(hasReservedCallFrame(MF) && MFI.adjustsStack()))
49     FrameSize += MaxCallFrameSize;
50 
51   // Make sure the frame is aligned.
52   FrameSize = alignTo(FrameSize, StackAlign);
53 
54   // Update frame info.
55   MFI.setStackSize(FrameSize);
56 }
57 
58 // Iterates through each basic block in a machine function and replaces
59 // ADJDYNALLOC pseudo instructions with a Lanai:ADDI with the
60 // maximum call frame size as the immediate.
61 void LanaiFrameLowering::replaceAdjDynAllocPseudo(MachineFunction &MF) const {
62   const LanaiInstrInfo &LII = *STI.getInstrInfo();
63   unsigned MaxCallFrameSize = MF.getFrameInfo().getMaxCallFrameSize();
64 
65   for (MachineBasicBlock &MBB : MF) {
66     for (MachineInstr &MI : llvm::make_early_inc_range(MBB)) {
67       if (MI.getOpcode() == Lanai::ADJDYNALLOC) {
68         DebugLoc DL = MI.getDebugLoc();
69         Register Dst = MI.getOperand(0).getReg();
70         Register Src = MI.getOperand(1).getReg();
71 
72         BuildMI(MBB, MI, DL, LII.get(Lanai::ADD_I_LO), Dst)
73             .addReg(Src)
74             .addImm(MaxCallFrameSize);
75         MI.eraseFromParent();
76       }
77     }
78   }
79 }
80 
81 // Generates the following sequence for function entry:
82 //   st %fp,-4[*%sp]        !push old FP
83 //   add %sp,8,%fp          !generate new FP
84 //   sub %sp,0x4,%sp        !allocate stack space (as needed)
85 void LanaiFrameLowering::emitPrologue(MachineFunction &MF,
86                                       MachineBasicBlock &MBB) const {
87   assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
88 
89   MachineFrameInfo &MFI = MF.getFrameInfo();
90   const LanaiInstrInfo &LII = *STI.getInstrInfo();
91   MachineBasicBlock::iterator MBBI = MBB.begin();
92 
93   // Debug location must be unknown since the first debug location is used
94   // to determine the end of the prologue.
95   DebugLoc DL;
96 
97   // Determine the correct frame layout
98   determineFrameLayout(MF);
99 
100   // FIXME: This appears to be overallocating.  Needs investigation.
101   // Get the number of bytes to allocate from the FrameInfo.
102   unsigned StackSize = MFI.getStackSize();
103 
104   // Push old FP
105   // st %fp,-4[*%sp]
106   BuildMI(MBB, MBBI, DL, LII.get(Lanai::SW_RI))
107       .addReg(Lanai::FP)
108       .addReg(Lanai::SP)
109       .addImm(-4)
110       .addImm(LPAC::makePreOp(LPAC::ADD))
111       .setMIFlag(MachineInstr::FrameSetup);
112 
113   // Generate new FP
114   // add %sp,8,%fp
115   BuildMI(MBB, MBBI, DL, LII.get(Lanai::ADD_I_LO), Lanai::FP)
116       .addReg(Lanai::SP)
117       .addImm(8)
118       .setMIFlag(MachineInstr::FrameSetup);
119 
120   // Allocate space on the stack if needed
121   // sub %sp,StackSize,%sp
122   if (StackSize != 0) {
123     BuildMI(MBB, MBBI, DL, LII.get(Lanai::SUB_I_LO), Lanai::SP)
124         .addReg(Lanai::SP)
125         .addImm(StackSize)
126         .setMIFlag(MachineInstr::FrameSetup);
127   }
128 
129   // Replace ADJDYNANALLOC
130   if (MFI.hasVarSizedObjects())
131     replaceAdjDynAllocPseudo(MF);
132 }
133 
134 MachineBasicBlock::iterator LanaiFrameLowering::eliminateCallFramePseudoInstr(
135     MachineFunction & /*MF*/, MachineBasicBlock &MBB,
136     MachineBasicBlock::iterator I) const {
137   // Discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
138   return MBB.erase(I);
139 }
140 
141 // The function epilogue should not depend on the current stack pointer!
142 // It should use the frame pointer only.  This is mandatory because
143 // of alloca; we also take advantage of it to omit stack adjustments
144 // before returning.
145 //
146 // Note that when we go to restore the preserved register values we must
147 // not try to address their slots by using offsets from the stack pointer.
148 // That's because the stack pointer may have been moved during the function
149 // execution due to a call to alloca().  Rather, we must restore all
150 // preserved registers via offsets from the frame pointer value.
151 //
152 // Note also that when the current frame is being "popped" (by adjusting
153 // the value of the stack pointer) on function exit, we must (for the
154 // sake of alloca) set the new value of the stack pointer based upon
155 // the current value of the frame pointer.  We can't just add what we
156 // believe to be the (static) frame size to the stack pointer because
157 // if we did that, and alloca() had been called during this function,
158 // we would end up returning *without* having fully deallocated all of
159 // the space grabbed by alloca.  If that happened, and a function
160 // containing one or more alloca() calls was called over and over again,
161 // then the stack would grow without limit!
162 //
163 // RET is lowered to
164 //      ld -4[%fp],%pc  # modify %pc (two delay slots)
165 // as the return address is in the stack frame and mov to pc is allowed.
166 // emitEpilogue emits
167 //      mov %fp,%sp     # restore the stack pointer
168 //      ld -8[%fp],%fp  # restore the caller's frame pointer
169 // before RET and the delay slot filler will move RET such that these
170 // instructions execute in the delay slots of the load to PC.
171 void LanaiFrameLowering::emitEpilogue(MachineFunction & /*MF*/,
172                                       MachineBasicBlock &MBB) const {
173   MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
174   const LanaiInstrInfo &LII = *STI.getInstrInfo();
175   DebugLoc DL = MBBI->getDebugLoc();
176 
177   // Restore the stack pointer using the callee's frame pointer value.
178   BuildMI(MBB, MBBI, DL, LII.get(Lanai::ADD_I_LO), Lanai::SP)
179       .addReg(Lanai::FP)
180       .addImm(0);
181 
182   // Restore the frame pointer from the stack.
183   BuildMI(MBB, MBBI, DL, LII.get(Lanai::LDW_RI), Lanai::FP)
184       .addReg(Lanai::FP)
185       .addImm(-8)
186       .addImm(LPAC::ADD);
187 }
188 
189 void LanaiFrameLowering::determineCalleeSaves(MachineFunction &MF,
190                                               BitVector &SavedRegs,
191                                               RegScavenger *RS) const {
192   TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
193 
194   MachineFrameInfo &MFI = MF.getFrameInfo();
195   const LanaiRegisterInfo *LRI = STI.getRegisterInfo();
196   int Offset = -4;
197 
198   // Reserve 4 bytes for the saved RCA
199   MFI.CreateFixedObject(4, Offset, true);
200   Offset -= 4;
201 
202   // Reserve 4 bytes for the saved FP
203   MFI.CreateFixedObject(4, Offset, true);
204   Offset -= 4;
205 
206   if (LRI->hasBasePointer(MF)) {
207     MFI.CreateFixedObject(4, Offset, true);
208     SavedRegs.reset(LRI->getBaseRegister());
209   }
210 }
211