LLVM 17.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"
22#include "llvm/IR/Function.h"
23
24using namespace llvm;
25
26// Determines the size of the frame and maximum call frame size.
27void LanaiFrameLowering::determineFrameLayout(MachineFunction &MF) const {
30
31 // Get the number of bytes to allocate from the FrameInfo.
32 unsigned FrameSize = MFI.getStackSize();
33
34 // Get the alignment.
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.
63void 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) {
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)
89 MachineBasicBlock &MBB) const {
90 assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
91
93 const LanaiInstrInfo &LII =
94 *static_cast<const LanaiInstrInfo *>(STI.getInstrInfo());
96
97 // Debug location must be unknown since the first debug location is used
98 // to determine the end of the prologue.
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)
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)
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)
131 }
132
133 // Replace ADJDYNANALLOC
134 if (MFI.hasVarSizedObjects())
135 replaceAdjDynAllocPseudo(MF);
136}
137
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.
176 MachineBasicBlock &MBB) const {
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)
192}
193
195 BitVector &SavedRegs,
196 RegScavenger *RS) const {
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}
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:385
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.
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...
unsigned getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
void setMaxCallFrameSize(unsigned S)
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:68
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:62
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:406
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:721
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