1 //===-- LanaiFrameLowering.cpp - Lanai Frame Information ------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file contains the Lanai implementation of TargetFrameLowering class.
11 //===----------------------------------------------------------------------===//
13 #include "LanaiFrameLowering.h"
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 #include "llvm/CodeGen/MachineRegisterInfo.h"
22 #include "llvm/IR/Function.h"
26 // Determines the size of the frame and maximum call frame size.
27 void LanaiFrameLowering::determineFrameLayout(MachineFunction
&MF
) const {
28 MachineFrameInfo
&MFI
= MF
.getFrameInfo();
29 const LanaiRegisterInfo
*LRI
= STI
.getRegisterInfo();
31 // Get the number of bytes to allocate from the FrameInfo.
32 unsigned FrameSize
= MFI
.getStackSize();
35 unsigned StackAlign
= LRI
->needsStackRealignment(MF
) ? MFI
.getMaxAlignment()
36 : getStackAlignment();
38 // Get the maximum call frame size of all the calls.
39 unsigned MaxCallFrameSize
= MFI
.getMaxCallFrameSize();
41 // If we have dynamic alloca then MaxCallFrameSize needs to be aligned so
42 // that allocations will be aligned.
43 if (MFI
.hasVarSizedObjects())
44 MaxCallFrameSize
= alignTo(MaxCallFrameSize
, StackAlign
);
46 // Update maximum call frame size.
47 MFI
.setMaxCallFrameSize(MaxCallFrameSize
);
49 // Include call frame size in total.
50 if (!(hasReservedCallFrame(MF
) && MFI
.adjustsStack()))
51 FrameSize
+= MaxCallFrameSize
;
53 // Make sure the frame is aligned.
54 FrameSize
= alignTo(FrameSize
, StackAlign
);
57 MFI
.setStackSize(FrameSize
);
60 // Iterates through each basic block in a machine function and replaces
61 // ADJDYNALLOC pseudo instructions with a Lanai:ADDI with the
62 // maximum call frame size as the immediate.
63 void LanaiFrameLowering::replaceAdjDynAllocPseudo(MachineFunction
&MF
) const {
64 const LanaiInstrInfo
&LII
=
65 *static_cast<const LanaiInstrInfo
*>(STI
.getInstrInfo());
66 unsigned MaxCallFrameSize
= MF
.getFrameInfo().getMaxCallFrameSize();
68 for (MachineFunction::iterator MBB
= MF
.begin(), E
= MF
.end(); MBB
!= E
;
70 MachineBasicBlock::iterator MBBI
= MBB
->begin();
71 while (MBBI
!= MBB
->end()) {
72 MachineInstr
&MI
= *MBBI
++;
73 if (MI
.getOpcode() == Lanai::ADJDYNALLOC
) {
74 DebugLoc DL
= MI
.getDebugLoc();
75 Register Dst
= MI
.getOperand(0).getReg();
76 Register Src
= MI
.getOperand(1).getReg();
78 BuildMI(*MBB
, MI
, DL
, LII
.get(Lanai::ADD_I_LO
), Dst
)
80 .addImm(MaxCallFrameSize
);
87 // Generates the following sequence for function entry:
88 // st %fp,-4[*%sp] !push old FP
89 // add %sp,8,%fp !generate new FP
90 // sub %sp,0x4,%sp !allocate stack space (as needed)
91 void LanaiFrameLowering::emitPrologue(MachineFunction
&MF
,
92 MachineBasicBlock
&MBB
) const {
93 assert(&MF
.front() == &MBB
&& "Shrink-wrapping not yet supported");
95 MachineFrameInfo
&MFI
= MF
.getFrameInfo();
96 const LanaiInstrInfo
&LII
=
97 *static_cast<const LanaiInstrInfo
*>(STI
.getInstrInfo());
98 MachineBasicBlock::iterator MBBI
= MBB
.begin();
100 // Debug location must be unknown since the first debug location is used
101 // to determine the end of the prologue.
104 // Determine the correct frame layout
105 determineFrameLayout(MF
);
107 // FIXME: This appears to be overallocating. Needs investigation.
108 // Get the number of bytes to allocate from the FrameInfo.
109 unsigned StackSize
= MFI
.getStackSize();
113 BuildMI(MBB
, MBBI
, DL
, LII
.get(Lanai::SW_RI
))
117 .addImm(LPAC::makePreOp(LPAC::ADD
))
118 .setMIFlag(MachineInstr::FrameSetup
);
122 BuildMI(MBB
, MBBI
, DL
, LII
.get(Lanai::ADD_I_LO
), Lanai::FP
)
125 .setMIFlag(MachineInstr::FrameSetup
);
127 // Allocate space on the stack if needed
128 // sub %sp,StackSize,%sp
129 if (StackSize
!= 0) {
130 BuildMI(MBB
, MBBI
, DL
, LII
.get(Lanai::SUB_I_LO
), Lanai::SP
)
133 .setMIFlag(MachineInstr::FrameSetup
);
136 // Replace ADJDYNANALLOC
137 if (MFI
.hasVarSizedObjects())
138 replaceAdjDynAllocPseudo(MF
);
141 MachineBasicBlock::iterator
LanaiFrameLowering::eliminateCallFramePseudoInstr(
142 MachineFunction
& /*MF*/, MachineBasicBlock
&MBB
,
143 MachineBasicBlock::iterator I
) const {
144 // Discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
148 // The function epilogue should not depend on the current stack pointer!
149 // It should use the frame pointer only. This is mandatory because
150 // of alloca; we also take advantage of it to omit stack adjustments
153 // Note that when we go to restore the preserved register values we must
154 // not try to address their slots by using offsets from the stack pointer.
155 // That's because the stack pointer may have been moved during the function
156 // execution due to a call to alloca(). Rather, we must restore all
157 // preserved registers via offsets from the frame pointer value.
159 // Note also that when the current frame is being "popped" (by adjusting
160 // the value of the stack pointer) on function exit, we must (for the
161 // sake of alloca) set the new value of the stack pointer based upon
162 // the current value of the frame pointer. We can't just add what we
163 // believe to be the (static) frame size to the stack pointer because
164 // if we did that, and alloca() had been called during this function,
165 // we would end up returning *without* having fully deallocated all of
166 // the space grabbed by alloca. If that happened, and a function
167 // containing one or more alloca() calls was called over and over again,
168 // then the stack would grow without limit!
171 // ld -4[%fp],%pc # modify %pc (two delay slots)
172 // as the return address is in the stack frame and mov to pc is allowed.
173 // emitEpilogue emits
174 // mov %fp,%sp # restore the stack pointer
175 // ld -8[%fp],%fp # restore the caller's frame pointer
176 // before RET and the delay slot filler will move RET such that these
177 // instructions execute in the delay slots of the load to PC.
178 void LanaiFrameLowering::emitEpilogue(MachineFunction
& /*MF*/,
179 MachineBasicBlock
&MBB
) const {
180 MachineBasicBlock::iterator MBBI
= MBB
.getLastNonDebugInstr();
181 const LanaiInstrInfo
&LII
=
182 *static_cast<const LanaiInstrInfo
*>(STI
.getInstrInfo());
183 DebugLoc DL
= MBBI
->getDebugLoc();
185 // Restore the stack pointer using the callee's frame pointer value.
186 BuildMI(MBB
, MBBI
, DL
, LII
.get(Lanai::ADD_I_LO
), Lanai::SP
)
190 // Restore the frame pointer from the stack.
191 BuildMI(MBB
, MBBI
, DL
, LII
.get(Lanai::LDW_RI
), Lanai::FP
)
197 void LanaiFrameLowering::determineCalleeSaves(MachineFunction
&MF
,
198 BitVector
&SavedRegs
,
199 RegScavenger
*RS
) const {
200 TargetFrameLowering::determineCalleeSaves(MF
, SavedRegs
, RS
);
202 MachineFrameInfo
&MFI
= MF
.getFrameInfo();
203 const LanaiRegisterInfo
*LRI
=
204 static_cast<const LanaiRegisterInfo
*>(STI
.getRegisterInfo());
207 // Reserve 4 bytes for the saved RCA
208 MFI
.CreateFixedObject(4, Offset
, true);
211 // Reserve 4 bytes for the saved FP
212 MFI
.CreateFixedObject(4, Offset
, true);
215 if (LRI
->hasBasePointer(MF
)) {
216 MFI
.CreateFixedObject(4, Offset
, true);
217 SavedRegs
.reset(LRI
->getBaseRegister());