blob: 0723668c743e10838187c74aaa35913f6a6f6e49 [file] [log] [blame]
Jacques Pienaarfcef3e42016-03-28 13:09:54 +00001//===-- LanaiFrameLowering.cpp - Lanai Frame Information ------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains the Lanai implementation of TargetFrameLowering class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "LanaiFrameLowering.h"
15
16#include "LanaiInstrInfo.h"
17#include "LanaiMachineFunctionInfo.h"
18#include "LanaiSubtarget.h"
19#include "llvm/CodeGen/MachineFrameInfo.h"
20#include "llvm/CodeGen/MachineFunction.h"
21#include "llvm/CodeGen/MachineInstrBuilder.h"
22#include "llvm/CodeGen/MachineRegisterInfo.h"
23#include "llvm/IR/Function.h"
24
25using namespace llvm;
26
27// Determines the size of the frame and maximum call frame size.
28void LanaiFrameLowering::determineFrameLayout(MachineFunction &MF) const {
Matthias Braun941a7052016-07-28 18:40:00 +000029 MachineFrameInfo &MFI = MF.getFrameInfo();
Jacques Pienaarfcef3e42016-03-28 13:09:54 +000030 const LanaiRegisterInfo *LRI = STI.getRegisterInfo();
31
32 // Get the number of bytes to allocate from the FrameInfo.
Matthias Braun941a7052016-07-28 18:40:00 +000033 unsigned FrameSize = MFI.getStackSize();
Jacques Pienaarfcef3e42016-03-28 13:09:54 +000034
35 // Get the alignment.
Matthias Braun941a7052016-07-28 18:40:00 +000036 unsigned StackAlign = LRI->needsStackRealignment(MF) ? MFI.getMaxAlignment()
Jacques Pienaarfcef3e42016-03-28 13:09:54 +000037 : getStackAlignment();
38
39 // Get the maximum call frame size of all the calls.
Matthias Braun941a7052016-07-28 18:40:00 +000040 unsigned MaxCallFrameSize = MFI.getMaxCallFrameSize();
Jacques Pienaarfcef3e42016-03-28 13:09:54 +000041
42 // If we have dynamic alloca then MaxCallFrameSize needs to be aligned so
43 // that allocations will be aligned.
Matthias Braun941a7052016-07-28 18:40:00 +000044 if (MFI.hasVarSizedObjects())
Jacques Pienaarfcef3e42016-03-28 13:09:54 +000045 MaxCallFrameSize = alignTo(MaxCallFrameSize, StackAlign);
46
47 // Update maximum call frame size.
Matthias Braun941a7052016-07-28 18:40:00 +000048 MFI.setMaxCallFrameSize(MaxCallFrameSize);
Jacques Pienaarfcef3e42016-03-28 13:09:54 +000049
50 // Include call frame size in total.
Matthias Braun941a7052016-07-28 18:40:00 +000051 if (!(hasReservedCallFrame(MF) && MFI.adjustsStack()))
Jacques Pienaarfcef3e42016-03-28 13:09:54 +000052 FrameSize += MaxCallFrameSize;
53
54 // Make sure the frame is aligned.
55 FrameSize = alignTo(FrameSize, StackAlign);
56
57 // Update frame info.
Matthias Braun941a7052016-07-28 18:40:00 +000058 MFI.setStackSize(FrameSize);
Jacques Pienaarfcef3e42016-03-28 13:09:54 +000059}
60
61// Iterates through each basic block in a machine function and replaces
62// ADJDYNALLOC pseudo instructions with a Lanai:ADDI with the
63// maximum call frame size as the immediate.
64void LanaiFrameLowering::replaceAdjDynAllocPseudo(MachineFunction &MF) const {
65 const LanaiInstrInfo &LII =
66 *static_cast<const LanaiInstrInfo *>(STI.getInstrInfo());
Matthias Braun941a7052016-07-28 18:40:00 +000067 unsigned MaxCallFrameSize = MF.getFrameInfo().getMaxCallFrameSize();
Jacques Pienaarfcef3e42016-03-28 13:09:54 +000068
69 for (MachineFunction::iterator MBB = MF.begin(), E = MF.end(); MBB != E;
70 ++MBB) {
71 MachineBasicBlock::iterator MBBI = MBB->begin();
72 while (MBBI != MBB->end()) {
Duncan P. N. Exon Smithbe6092d2016-07-08 22:11:30 +000073 MachineInstr &MI = *MBBI++;
74 if (MI.getOpcode() == Lanai::ADJDYNALLOC) {
75 DebugLoc DL = MI.getDebugLoc();
76 unsigned Dst = MI.getOperand(0).getReg();
77 unsigned Src = MI.getOperand(1).getReg();
Jacques Pienaarfcef3e42016-03-28 13:09:54 +000078
79 BuildMI(*MBB, MI, DL, LII.get(Lanai::ADD_I_LO), Dst)
80 .addReg(Src)
81 .addImm(MaxCallFrameSize);
Duncan P. N. Exon Smithbe6092d2016-07-08 22:11:30 +000082 MI.eraseFromParent();
Jacques Pienaarfcef3e42016-03-28 13:09:54 +000083 }
84 }
85 }
86}
87
88// Generates the following sequence for function entry:
89// st %fp,-4[*%sp] !push old FP
90// add %sp,8,%fp !generate new FP
91// sub %sp,0x4,%sp !allocate stack space (as needed)
92void LanaiFrameLowering::emitPrologue(MachineFunction &MF,
93 MachineBasicBlock &MBB) const {
94 assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
95
Matthias Braun941a7052016-07-28 18:40:00 +000096 MachineFrameInfo &MFI = MF.getFrameInfo();
Jacques Pienaarfcef3e42016-03-28 13:09:54 +000097 const LanaiInstrInfo &LII =
98 *static_cast<const LanaiInstrInfo *>(STI.getInstrInfo());
99 MachineBasicBlock::iterator MBBI = MBB.begin();
100
101 // Debug location must be unknown since the first debug location is used
102 // to determine the end of the prologue.
103 DebugLoc DL;
104
105 // Determine the correct frame layout
106 determineFrameLayout(MF);
107
108 // FIXME: This appears to be overallocating. Needs investigation.
109 // Get the number of bytes to allocate from the FrameInfo.
Matthias Braun941a7052016-07-28 18:40:00 +0000110 unsigned StackSize = MFI.getStackSize();
Jacques Pienaarfcef3e42016-03-28 13:09:54 +0000111
112 // Push old FP
113 // st %fp,-4[*%sp]
114 BuildMI(MBB, MBBI, DL, LII.get(Lanai::SW_RI))
115 .addReg(Lanai::FP)
116 .addReg(Lanai::SP)
117 .addImm(-4)
118 .addImm(LPAC::makePreOp(LPAC::ADD))
119 .setMIFlag(MachineInstr::FrameSetup);
120
121 // Generate new FP
122 // add %sp,8,%fp
123 BuildMI(MBB, MBBI, DL, LII.get(Lanai::ADD_I_LO), Lanai::FP)
124 .addReg(Lanai::SP)
125 .addImm(8)
126 .setMIFlag(MachineInstr::FrameSetup);
127
128 // Allocate space on the stack if needed
129 // sub %sp,StackSize,%sp
130 if (StackSize != 0) {
131 BuildMI(MBB, MBBI, DL, LII.get(Lanai::SUB_I_LO), Lanai::SP)
132 .addReg(Lanai::SP)
133 .addImm(StackSize)
134 .setMIFlag(MachineInstr::FrameSetup);
135 }
136
137 // Replace ADJDYNANALLOC
Matthias Braun941a7052016-07-28 18:40:00 +0000138 if (MFI.hasVarSizedObjects())
Jacques Pienaarfcef3e42016-03-28 13:09:54 +0000139 replaceAdjDynAllocPseudo(MF);
140}
141
Hans Wennborge1a2e902016-03-31 18:33:38 +0000142MachineBasicBlock::iterator LanaiFrameLowering::eliminateCallFramePseudoInstr(
Jacques Pienaare2f06992016-07-15 22:38:32 +0000143 MachineFunction & /*MF*/, MachineBasicBlock &MBB,
Jacques Pienaarfcef3e42016-03-28 13:09:54 +0000144 MachineBasicBlock::iterator I) const {
145 // Discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
Hans Wennborge1a2e902016-03-31 18:33:38 +0000146 return MBB.erase(I);
Jacques Pienaarfcef3e42016-03-28 13:09:54 +0000147}
148
149// The function epilogue should not depend on the current stack pointer!
150// It should use the frame pointer only. This is mandatory because
151// of alloca; we also take advantage of it to omit stack adjustments
152// before returning.
153//
154// Note that when we go to restore the preserved register values we must
155// not try to address their slots by using offsets from the stack pointer.
156// That's because the stack pointer may have been moved during the function
157// execution due to a call to alloca(). Rather, we must restore all
158// preserved registers via offsets from the frame pointer value.
159//
160// Note also that when the current frame is being "popped" (by adjusting
161// the value of the stack pointer) on function exit, we must (for the
162// sake of alloca) set the new value of the stack pointer based upon
163// the current value of the frame pointer. We can't just add what we
164// believe to be the (static) frame size to the stack pointer because
165// if we did that, and alloca() had been called during this function,
166// we would end up returning *without* having fully deallocated all of
167// the space grabbed by alloca. If that happened, and a function
168// containing one or more alloca() calls was called over and over again,
169// then the stack would grow without limit!
170//
171// RET is lowered to
172// ld -4[%fp],%pc # modify %pc (two delay slots)
173// as the return address is in the stack frame and mov to pc is allowed.
174// emitEpilogue emits
175// mov %fp,%sp # restore the stack pointer
176// ld -8[%fp],%fp # restore the caller's frame pointer
177// before RET and the delay slot filler will move RET such that these
178// instructions execute in the delay slots of the load to PC.
Jacques Pienaare2f06992016-07-15 22:38:32 +0000179void LanaiFrameLowering::emitEpilogue(MachineFunction & /*MF*/,
Jacques Pienaarfcef3e42016-03-28 13:09:54 +0000180 MachineBasicBlock &MBB) const {
181 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
182 const LanaiInstrInfo &LII =
183 *static_cast<const LanaiInstrInfo *>(STI.getInstrInfo());
184 DebugLoc DL = MBBI->getDebugLoc();
185
186 // Restore the stack pointer using the callee's frame pointer value.
187 BuildMI(MBB, MBBI, DL, LII.get(Lanai::ADD_I_LO), Lanai::SP)
188 .addReg(Lanai::FP)
189 .addImm(0);
190
191 // Restore the frame pointer from the stack.
192 BuildMI(MBB, MBBI, DL, LII.get(Lanai::LDW_RI), Lanai::FP)
193 .addReg(Lanai::FP)
194 .addImm(-8)
195 .addImm(LPAC::ADD);
196}
197
198void LanaiFrameLowering::determineCalleeSaves(MachineFunction &MF,
199 BitVector &SavedRegs,
200 RegScavenger *RS) const {
201 TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
202
Matthias Braun941a7052016-07-28 18:40:00 +0000203 MachineFrameInfo &MFI = MF.getFrameInfo();
Jacques Pienaarfcef3e42016-03-28 13:09:54 +0000204 const LanaiRegisterInfo *LRI =
205 static_cast<const LanaiRegisterInfo *>(STI.getRegisterInfo());
206 int Offset = -4;
207
208 // Reserve 4 bytes for the saved RCA
Matthias Braun941a7052016-07-28 18:40:00 +0000209 MFI.CreateFixedObject(4, Offset, true);
Jacques Pienaarfcef3e42016-03-28 13:09:54 +0000210 Offset -= 4;
211
212 // Reserve 4 bytes for the saved FP
Matthias Braun941a7052016-07-28 18:40:00 +0000213 MFI.CreateFixedObject(4, Offset, true);
Jacques Pienaarfcef3e42016-03-28 13:09:54 +0000214 Offset -= 4;
215
216 if (LRI->hasBasePointer(MF)) {
Matthias Braun941a7052016-07-28 18:40:00 +0000217 MFI.CreateFixedObject(4, Offset, true);
Jacques Pienaarfcef3e42016-03-28 13:09:54 +0000218 SavedRegs.reset(LRI->getBaseRegister());
219 }
220}