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