LLVM 22.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 = *STI.getInstrInfo();
63 unsigned MaxCallFrameSize = MF.getFrameInfo().getMaxCallFrameSize();
64
65 for (MachineBasicBlock &MBB : MF) {
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)
86 MachineBasicBlock &MBB) const {
87 assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
88
90 const LanaiInstrInfo &LII = *STI.getInstrInfo();
92
93 // Debug location must be unknown since the first debug location is used
94 // to determine the end of the prologue.
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)
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)
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)
127 }
128
129 // Replace ADJDYNANALLOC
130 if (MFI.hasVarSizedObjects())
131 replaceAdjDynAllocPseudo(MF);
132}
133
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.
172 MachineBasicBlock &MBB) const {
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)
187}
188
190 BitVector &SavedRegs,
191 RegScavenger *RS) const {
193
194 MachineFrameInfo &MFI = MF.getFrameInfo();
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}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
BitVector & reset()
Definition: BitVector.h:392
A debug info location.
Definition: DebugLoc.h:124
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
LLVM_ABI iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
LLVM_ABI 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)
LLVM_ABI 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:72
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:477
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:663
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