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