LLVM 20.0.0git
LanaiFrameLowering.cpp
Go to the documentation of this file.
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"
21
22using namespace llvm;
23
24// Determines the size of the frame and maximum call frame size.
25void LanaiFrameLowering::determineFrameLayout(MachineFunction &MF) const {
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.
61void LanaiFrameLowering::replaceAdjDynAllocPseudo(MachineFunction &MF) const {
62 const LanaiInstrInfo &LII =
63 *static_cast<const LanaiInstrInfo *>(STI.getInstrInfo());
64 unsigned MaxCallFrameSize = MF.getFrameInfo().getMaxCallFrameSize();
65
66 for (MachineBasicBlock &MBB : MF) {
68 if (MI.getOpcode() == Lanai::ADJDYNALLOC) {
69 DebugLoc DL = MI.getDebugLoc();
70 Register Dst = MI.getOperand(0).getReg();
71 Register Src = MI.getOperand(1).getReg();
72
73 BuildMI(MBB, MI, DL, LII.get(Lanai::ADD_I_LO), Dst)
74 .addReg(Src)
75 .addImm(MaxCallFrameSize);
76 MI.eraseFromParent();
77 }
78 }
79 }
80}
81
82// Generates the following sequence for function entry:
83// st %fp,-4[*%sp] !push old FP
84// add %sp,8,%fp !generate new FP
85// sub %sp,0x4,%sp !allocate stack space (as needed)
87 MachineBasicBlock &MBB) const {
88 assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
89
91 const LanaiInstrInfo &LII =
92 *static_cast<const LanaiInstrInfo *>(STI.getInstrInfo());
94
95 // Debug location must be unknown since the first debug location is used
96 // to determine the end of the prologue.
98
99 // Determine the correct frame layout
100 determineFrameLayout(MF);
101
102 // FIXME: This appears to be overallocating. Needs investigation.
103 // Get the number of bytes to allocate from the FrameInfo.
104 unsigned StackSize = MFI.getStackSize();
105
106 // Push old FP
107 // st %fp,-4[*%sp]
108 BuildMI(MBB, MBBI, DL, LII.get(Lanai::SW_RI))
109 .addReg(Lanai::FP)
110 .addReg(Lanai::SP)
111 .addImm(-4)
114
115 // Generate new FP
116 // add %sp,8,%fp
117 BuildMI(MBB, MBBI, DL, LII.get(Lanai::ADD_I_LO), Lanai::FP)
118 .addReg(Lanai::SP)
119 .addImm(8)
121
122 // Allocate space on the stack if needed
123 // sub %sp,StackSize,%sp
124 if (StackSize != 0) {
125 BuildMI(MBB, MBBI, DL, LII.get(Lanai::SUB_I_LO), Lanai::SP)
126 .addReg(Lanai::SP)
127 .addImm(StackSize)
129 }
130
131 // Replace ADJDYNANALLOC
132 if (MFI.hasVarSizedObjects())
133 replaceAdjDynAllocPseudo(MF);
134}
135
139 // Discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
140 return MBB.erase(I);
141}
142
143// The function epilogue should not depend on the current stack pointer!
144// It should use the frame pointer only. This is mandatory because
145// of alloca; we also take advantage of it to omit stack adjustments
146// before returning.
147//
148// Note that when we go to restore the preserved register values we must
149// not try to address their slots by using offsets from the stack pointer.
150// That's because the stack pointer may have been moved during the function
151// execution due to a call to alloca(). Rather, we must restore all
152// preserved registers via offsets from the frame pointer value.
153//
154// Note also that when the current frame is being "popped" (by adjusting
155// the value of the stack pointer) on function exit, we must (for the
156// sake of alloca) set the new value of the stack pointer based upon
157// the current value of the frame pointer. We can't just add what we
158// believe to be the (static) frame size to the stack pointer because
159// if we did that, and alloca() had been called during this function,
160// we would end up returning *without* having fully deallocated all of
161// the space grabbed by alloca. If that happened, and a function
162// containing one or more alloca() calls was called over and over again,
163// then the stack would grow without limit!
164//
165// RET is lowered to
166// ld -4[%fp],%pc # modify %pc (two delay slots)
167// as the return address is in the stack frame and mov to pc is allowed.
168// emitEpilogue emits
169// mov %fp,%sp # restore the stack pointer
170// ld -8[%fp],%fp # restore the caller's frame pointer
171// before RET and the delay slot filler will move RET such that these
172// instructions execute in the delay slots of the load to PC.
174 MachineBasicBlock &MBB) const {
176 const LanaiInstrInfo &LII =
177 *static_cast<const LanaiInstrInfo *>(STI.getInstrInfo());
178 DebugLoc DL = MBBI->getDebugLoc();
179
180 // Restore the stack pointer using the callee's frame pointer value.
181 BuildMI(MBB, MBBI, DL, LII.get(Lanai::ADD_I_LO), Lanai::SP)
182 .addReg(Lanai::FP)
183 .addImm(0);
184
185 // Restore the frame pointer from the stack.
186 BuildMI(MBB, MBBI, DL, LII.get(Lanai::LDW_RI), Lanai::FP)
187 .addReg(Lanai::FP)
188 .addImm(-8)
190}
191
193 BitVector &SavedRegs,
194 RegScavenger *RS) const {
196
197 MachineFrameInfo &MFI = MF.getFrameInfo();
198 const LanaiRegisterInfo *LRI =
199 static_cast<const LanaiRegisterInfo *>(STI.getRegisterInfo());
200 int Offset = -4;
201
202 // Reserve 4 bytes for the saved RCA
203 MFI.CreateFixedObject(4, Offset, true);
204 Offset -= 4;
205
206 // Reserve 4 bytes for the saved FP
207 MFI.CreateFixedObject(4, Offset, true);
208 Offset -= 4;
209
210 if (LRI->hasBasePointer(MF)) {
211 MFI.CreateFixedObject(4, Offset, true);
212 SavedRegs.reset(LRI->getBaseRegister());
213 }
214}
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
BitVector & reset()
Definition: BitVector.h:392
A debug info location.
Definition: DebugLoc.h:33
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
const LanaiSubtarget & STI
MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const override
This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy p...
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
const LanaiRegisterInfo * getRegisterInfo() const override
const LanaiInstrInfo * getInstrInfo() const override
iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
void setMaxCallFrameSize(uint64_t S)
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
bool adjustsStack() const
Return true if this function adjusts the stack – e.g., when calling another function.
Align getMaxAlign() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
uint64_t getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
void setStackSize(uint64_t Size)
Set the size of the stack.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
const MachineBasicBlock & front() const
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Representation of each machine instruction.
Definition: MachineInstr.h:69
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
virtual bool hasReservedCallFrame(const MachineFunction &MF) const
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
static unsigned makePreOp(unsigned AluOp)
Definition: LanaiAluCode.h:61
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition: STLExtras.h:657
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
Register getBaseRegister() const
bool hasBasePointer(const MachineFunction &MF) const