File: | build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp |
Warning: | line 938, column 13 Called C++ object pointer is uninitialized |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===-- SystemZFrameLowering.cpp - Frame lowering for SystemZ -------------===// | |||
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 | #include "SystemZFrameLowering.h" | |||
10 | #include "SystemZCallingConv.h" | |||
11 | #include "SystemZInstrBuilder.h" | |||
12 | #include "SystemZInstrInfo.h" | |||
13 | #include "SystemZMachineFunctionInfo.h" | |||
14 | #include "SystemZRegisterInfo.h" | |||
15 | #include "SystemZSubtarget.h" | |||
16 | #include "llvm/CodeGen/LivePhysRegs.h" | |||
17 | #include "llvm/CodeGen/MachineModuleInfo.h" | |||
18 | #include "llvm/CodeGen/MachineRegisterInfo.h" | |||
19 | #include "llvm/CodeGen/RegisterScavenging.h" | |||
20 | #include "llvm/IR/Function.h" | |||
21 | #include "llvm/Target/TargetMachine.h" | |||
22 | ||||
23 | using namespace llvm; | |||
24 | ||||
25 | namespace { | |||
26 | // The ABI-defined register save slots, relative to the CFA (i.e. | |||
27 | // incoming stack pointer + SystemZMC::ELFCallFrameSize). | |||
28 | static const TargetFrameLowering::SpillSlot ELFSpillOffsetTable[] = { | |||
29 | { SystemZ::R2D, 0x10 }, | |||
30 | { SystemZ::R3D, 0x18 }, | |||
31 | { SystemZ::R4D, 0x20 }, | |||
32 | { SystemZ::R5D, 0x28 }, | |||
33 | { SystemZ::R6D, 0x30 }, | |||
34 | { SystemZ::R7D, 0x38 }, | |||
35 | { SystemZ::R8D, 0x40 }, | |||
36 | { SystemZ::R9D, 0x48 }, | |||
37 | { SystemZ::R10D, 0x50 }, | |||
38 | { SystemZ::R11D, 0x58 }, | |||
39 | { SystemZ::R12D, 0x60 }, | |||
40 | { SystemZ::R13D, 0x68 }, | |||
41 | { SystemZ::R14D, 0x70 }, | |||
42 | { SystemZ::R15D, 0x78 }, | |||
43 | { SystemZ::F0D, 0x80 }, | |||
44 | { SystemZ::F2D, 0x88 }, | |||
45 | { SystemZ::F4D, 0x90 }, | |||
46 | { SystemZ::F6D, 0x98 } | |||
47 | }; | |||
48 | ||||
49 | static const TargetFrameLowering::SpillSlot XPLINKSpillOffsetTable[] = { | |||
50 | {SystemZ::R4D, 0x00}, {SystemZ::R5D, 0x08}, {SystemZ::R6D, 0x10}, | |||
51 | {SystemZ::R7D, 0x18}, {SystemZ::R8D, 0x20}, {SystemZ::R9D, 0x28}, | |||
52 | {SystemZ::R10D, 0x30}, {SystemZ::R11D, 0x38}, {SystemZ::R12D, 0x40}, | |||
53 | {SystemZ::R13D, 0x48}, {SystemZ::R14D, 0x50}, {SystemZ::R15D, 0x58}}; | |||
54 | } // end anonymous namespace | |||
55 | ||||
56 | SystemZFrameLowering::SystemZFrameLowering(StackDirection D, Align StackAl, | |||
57 | int LAO, Align TransAl, | |||
58 | bool StackReal) | |||
59 | : TargetFrameLowering(D, StackAl, LAO, TransAl, StackReal) {} | |||
60 | ||||
61 | std::unique_ptr<SystemZFrameLowering> | |||
62 | SystemZFrameLowering::create(const SystemZSubtarget &STI) { | |||
63 | if (STI.isTargetXPLINK64()) | |||
64 | return std::make_unique<SystemZXPLINKFrameLowering>(); | |||
65 | return std::make_unique<SystemZELFFrameLowering>(); | |||
66 | } | |||
67 | ||||
68 | MachineBasicBlock::iterator SystemZFrameLowering::eliminateCallFramePseudoInstr( | |||
69 | MachineFunction &MF, MachineBasicBlock &MBB, | |||
70 | MachineBasicBlock::iterator MI) const { | |||
71 | switch (MI->getOpcode()) { | |||
72 | case SystemZ::ADJCALLSTACKDOWN: | |||
73 | case SystemZ::ADJCALLSTACKUP: | |||
74 | assert(hasReservedCallFrame(MF) &&(static_cast <bool> (hasReservedCallFrame(MF) && "ADJSTACKDOWN and ADJSTACKUP should be no-ops") ? void (0) : __assert_fail ("hasReservedCallFrame(MF) && \"ADJSTACKDOWN and ADJSTACKUP should be no-ops\"" , "llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp", 75, __extension__ __PRETTY_FUNCTION__)) | |||
75 | "ADJSTACKDOWN and ADJSTACKUP should be no-ops")(static_cast <bool> (hasReservedCallFrame(MF) && "ADJSTACKDOWN and ADJSTACKUP should be no-ops") ? void (0) : __assert_fail ("hasReservedCallFrame(MF) && \"ADJSTACKDOWN and ADJSTACKUP should be no-ops\"" , "llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp", 75, __extension__ __PRETTY_FUNCTION__)); | |||
76 | return MBB.erase(MI); | |||
77 | break; | |||
78 | ||||
79 | default: | |||
80 | llvm_unreachable("Unexpected call frame instruction")::llvm::llvm_unreachable_internal("Unexpected call frame instruction" , "llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp", 80); | |||
81 | } | |||
82 | } | |||
83 | ||||
84 | namespace { | |||
85 | struct SZFrameSortingObj { | |||
86 | bool IsValid = false; // True if we care about this Object. | |||
87 | uint32_t ObjectIndex = 0; // Index of Object into MFI list. | |||
88 | uint64_t ObjectSize = 0; // Size of Object in bytes. | |||
89 | uint32_t D12Count = 0; // 12-bit displacement only. | |||
90 | uint32_t DPairCount = 0; // 12 or 20 bit displacement. | |||
91 | }; | |||
92 | typedef std::vector<SZFrameSortingObj> SZFrameObjVec; | |||
93 | } // namespace | |||
94 | ||||
95 | // TODO: Move to base class. | |||
96 | void SystemZELFFrameLowering::orderFrameObjects( | |||
97 | const MachineFunction &MF, SmallVectorImpl<int> &ObjectsToAllocate) const { | |||
98 | const MachineFrameInfo &MFI = MF.getFrameInfo(); | |||
99 | const SystemZInstrInfo *TII = | |||
100 | static_cast<const SystemZInstrInfo *>(MF.getSubtarget().getInstrInfo()); | |||
101 | ||||
102 | // Make a vector of sorting objects to track all MFI objects and mark those | |||
103 | // to be sorted as valid. | |||
104 | if (ObjectsToAllocate.size() <= 1) | |||
105 | return; | |||
106 | SZFrameObjVec SortingObjects(MFI.getObjectIndexEnd()); | |||
107 | for (auto &Obj : ObjectsToAllocate) { | |||
108 | SortingObjects[Obj].IsValid = true; | |||
109 | SortingObjects[Obj].ObjectIndex = Obj; | |||
110 | SortingObjects[Obj].ObjectSize = MFI.getObjectSize(Obj); | |||
111 | } | |||
112 | ||||
113 | // Examine uses for each object and record short (12-bit) and "pair" | |||
114 | // displacement types. | |||
115 | for (auto &MBB : MF) | |||
116 | for (auto &MI : MBB) { | |||
117 | if (MI.isDebugInstr()) | |||
118 | continue; | |||
119 | for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) { | |||
120 | const MachineOperand &MO = MI.getOperand(I); | |||
121 | if (!MO.isFI()) | |||
122 | continue; | |||
123 | int Index = MO.getIndex(); | |||
124 | if (Index >= 0 && Index < MFI.getObjectIndexEnd() && | |||
125 | SortingObjects[Index].IsValid) { | |||
126 | if (TII->hasDisplacementPairInsn(MI.getOpcode())) | |||
127 | SortingObjects[Index].DPairCount++; | |||
128 | else if (!(MI.getDesc().TSFlags & SystemZII::Has20BitOffset)) | |||
129 | SortingObjects[Index].D12Count++; | |||
130 | } | |||
131 | } | |||
132 | } | |||
133 | ||||
134 | // Sort all objects for short/paired displacements, which should be | |||
135 | // sufficient as it seems like all frame objects typically are within the | |||
136 | // long displacement range. Sorting works by computing the "density" as | |||
137 | // Count / ObjectSize. The comparisons of two such fractions are refactored | |||
138 | // by multiplying both sides with A.ObjectSize * B.ObjectSize, in order to | |||
139 | // eliminate the (fp) divisions. A higher density object needs to go after | |||
140 | // in the list in order for it to end up lower on the stack. | |||
141 | auto CmpD12 = [](const SZFrameSortingObj &A, const SZFrameSortingObj &B) { | |||
142 | // Put all invalid and variable sized objects at the end. | |||
143 | if (!A.IsValid || !B.IsValid) | |||
144 | return A.IsValid; | |||
145 | if (!A.ObjectSize || !B.ObjectSize) | |||
146 | return A.ObjectSize > 0; | |||
147 | uint64_t ADensityCmp = A.D12Count * B.ObjectSize; | |||
148 | uint64_t BDensityCmp = B.D12Count * A.ObjectSize; | |||
149 | if (ADensityCmp != BDensityCmp) | |||
150 | return ADensityCmp < BDensityCmp; | |||
151 | return A.DPairCount * B.ObjectSize < B.DPairCount * A.ObjectSize; | |||
152 | }; | |||
153 | std::stable_sort(SortingObjects.begin(), SortingObjects.end(), CmpD12); | |||
154 | ||||
155 | // Now modify the original list to represent the final order that | |||
156 | // we want. | |||
157 | unsigned Idx = 0; | |||
158 | for (auto &Obj : SortingObjects) { | |||
159 | // All invalid items are sorted at the end, so it's safe to stop. | |||
160 | if (!Obj.IsValid) | |||
161 | break; | |||
162 | ObjectsToAllocate[Idx++] = Obj.ObjectIndex; | |||
163 | } | |||
164 | } | |||
165 | ||||
166 | bool SystemZFrameLowering::hasReservedCallFrame( | |||
167 | const MachineFunction &MF) const { | |||
168 | // The ELF ABI requires us to allocate 160 bytes of stack space for the | |||
169 | // callee, with any outgoing stack arguments being placed above that. It | |||
170 | // seems better to make that area a permanent feature of the frame even if | |||
171 | // we're using a frame pointer. Similarly, 64-bit XPLINK requires 96 bytes | |||
172 | // of stack space for the register save area. | |||
173 | return true; | |||
174 | } | |||
175 | ||||
176 | bool SystemZELFFrameLowering::assignCalleeSavedSpillSlots( | |||
177 | MachineFunction &MF, const TargetRegisterInfo *TRI, | |||
178 | std::vector<CalleeSavedInfo> &CSI) const { | |||
179 | SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>(); | |||
180 | MachineFrameInfo &MFFrame = MF.getFrameInfo(); | |||
181 | bool IsVarArg = MF.getFunction().isVarArg(); | |||
182 | if (CSI.empty()) | |||
183 | return true; // Early exit if no callee saved registers are modified! | |||
184 | ||||
185 | unsigned LowGPR = 0; | |||
186 | unsigned HighGPR = SystemZ::R15D; | |||
187 | int StartSPOffset = SystemZMC::ELFCallFrameSize; | |||
188 | for (auto &CS : CSI) { | |||
189 | Register Reg = CS.getReg(); | |||
190 | int Offset = getRegSpillOffset(MF, Reg); | |||
191 | if (Offset) { | |||
192 | if (SystemZ::GR64BitRegClass.contains(Reg) && StartSPOffset > Offset) { | |||
193 | LowGPR = Reg; | |||
194 | StartSPOffset = Offset; | |||
195 | } | |||
196 | Offset -= SystemZMC::ELFCallFrameSize; | |||
197 | int FrameIdx = MFFrame.CreateFixedSpillStackObject(8, Offset); | |||
198 | CS.setFrameIdx(FrameIdx); | |||
199 | } else | |||
200 | CS.setFrameIdx(INT32_MAX(2147483647)); | |||
201 | } | |||
202 | ||||
203 | // Save the range of call-saved registers, for use by the | |||
204 | // prologue/epilogue inserters. | |||
205 | ZFI->setRestoreGPRRegs(LowGPR, HighGPR, StartSPOffset); | |||
206 | if (IsVarArg) { | |||
207 | // Also save the GPR varargs, if any. R6D is call-saved, so would | |||
208 | // already be included, but we also need to handle the call-clobbered | |||
209 | // argument registers. | |||
210 | Register FirstGPR = ZFI->getVarArgsFirstGPR(); | |||
211 | if (FirstGPR < SystemZ::ELFNumArgGPRs) { | |||
212 | unsigned Reg = SystemZ::ELFArgGPRs[FirstGPR]; | |||
213 | int Offset = getRegSpillOffset(MF, Reg); | |||
214 | if (StartSPOffset > Offset) { | |||
215 | LowGPR = Reg; StartSPOffset = Offset; | |||
216 | } | |||
217 | } | |||
218 | } | |||
219 | ZFI->setSpillGPRRegs(LowGPR, HighGPR, StartSPOffset); | |||
220 | ||||
221 | // Create fixed stack objects for the remaining registers. | |||
222 | int CurrOffset = -SystemZMC::ELFCallFrameSize; | |||
223 | if (usePackedStack(MF)) | |||
224 | CurrOffset += StartSPOffset; | |||
225 | ||||
226 | for (auto &CS : CSI) { | |||
227 | if (CS.getFrameIdx() != INT32_MAX(2147483647)) | |||
228 | continue; | |||
229 | Register Reg = CS.getReg(); | |||
230 | const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); | |||
231 | unsigned Size = TRI->getSpillSize(*RC); | |||
232 | CurrOffset -= Size; | |||
233 | assert(CurrOffset % 8 == 0 &&(static_cast <bool> (CurrOffset % 8 == 0 && "8-byte alignment required for for all register save slots" ) ? void (0) : __assert_fail ("CurrOffset % 8 == 0 && \"8-byte alignment required for for all register save slots\"" , "llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp", 234, __extension__ __PRETTY_FUNCTION__)) | |||
234 | "8-byte alignment required for for all register save slots")(static_cast <bool> (CurrOffset % 8 == 0 && "8-byte alignment required for for all register save slots" ) ? void (0) : __assert_fail ("CurrOffset % 8 == 0 && \"8-byte alignment required for for all register save slots\"" , "llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp", 234, __extension__ __PRETTY_FUNCTION__)); | |||
235 | int FrameIdx = MFFrame.CreateFixedSpillStackObject(Size, CurrOffset); | |||
236 | CS.setFrameIdx(FrameIdx); | |||
237 | } | |||
238 | ||||
239 | return true; | |||
240 | } | |||
241 | ||||
242 | void SystemZELFFrameLowering::determineCalleeSaves(MachineFunction &MF, | |||
243 | BitVector &SavedRegs, | |||
244 | RegScavenger *RS) const { | |||
245 | TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); | |||
246 | ||||
247 | MachineFrameInfo &MFFrame = MF.getFrameInfo(); | |||
248 | const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); | |||
249 | bool HasFP = hasFP(MF); | |||
250 | SystemZMachineFunctionInfo *MFI = MF.getInfo<SystemZMachineFunctionInfo>(); | |||
251 | bool IsVarArg = MF.getFunction().isVarArg(); | |||
252 | ||||
253 | // va_start stores incoming FPR varargs in the normal way, but delegates | |||
254 | // the saving of incoming GPR varargs to spillCalleeSavedRegisters(). | |||
255 | // Record these pending uses, which typically include the call-saved | |||
256 | // argument register R6D. | |||
257 | if (IsVarArg) | |||
258 | for (unsigned I = MFI->getVarArgsFirstGPR(); I < SystemZ::ELFNumArgGPRs; ++I) | |||
259 | SavedRegs.set(SystemZ::ELFArgGPRs[I]); | |||
260 | ||||
261 | // If there are any landing pads, entering them will modify r6/r7. | |||
262 | if (!MF.getLandingPads().empty()) { | |||
263 | SavedRegs.set(SystemZ::R6D); | |||
264 | SavedRegs.set(SystemZ::R7D); | |||
265 | } | |||
266 | ||||
267 | // If the function requires a frame pointer, record that the hard | |||
268 | // frame pointer will be clobbered. | |||
269 | if (HasFP) | |||
270 | SavedRegs.set(SystemZ::R11D); | |||
271 | ||||
272 | // If the function calls other functions, record that the return | |||
273 | // address register will be clobbered. | |||
274 | if (MFFrame.hasCalls()) | |||
275 | SavedRegs.set(SystemZ::R14D); | |||
276 | ||||
277 | // If we are saving GPRs other than the stack pointer, we might as well | |||
278 | // save and restore the stack pointer at the same time, via STMG and LMG. | |||
279 | // This allows the deallocation to be done by the LMG, rather than needing | |||
280 | // a separate %r15 addition. | |||
281 | const MCPhysReg *CSRegs = TRI->getCalleeSavedRegs(&MF); | |||
282 | for (unsigned I = 0; CSRegs[I]; ++I) { | |||
283 | unsigned Reg = CSRegs[I]; | |||
284 | if (SystemZ::GR64BitRegClass.contains(Reg) && SavedRegs.test(Reg)) { | |||
285 | SavedRegs.set(SystemZ::R15D); | |||
286 | break; | |||
287 | } | |||
288 | } | |||
289 | } | |||
290 | ||||
291 | SystemZELFFrameLowering::SystemZELFFrameLowering() | |||
292 | : SystemZFrameLowering(TargetFrameLowering::StackGrowsDown, Align(8), 0, | |||
293 | Align(8), /* StackRealignable */ false), | |||
294 | RegSpillOffsets(0) { | |||
295 | ||||
296 | // Due to the SystemZ ABI, the DWARF CFA (Canonical Frame Address) is not | |||
297 | // equal to the incoming stack pointer, but to incoming stack pointer plus | |||
298 | // 160. Instead of using a Local Area Offset, the Register save area will | |||
299 | // be occupied by fixed frame objects, and all offsets are actually | |||
300 | // relative to CFA. | |||
301 | ||||
302 | // Create a mapping from register number to save slot offset. | |||
303 | // These offsets are relative to the start of the register save area. | |||
304 | RegSpillOffsets.grow(SystemZ::NUM_TARGET_REGS); | |||
305 | for (unsigned I = 0, E = array_lengthof(ELFSpillOffsetTable); I != E; ++I) | |||
306 | RegSpillOffsets[ELFSpillOffsetTable[I].Reg] = ELFSpillOffsetTable[I].Offset; | |||
307 | } | |||
308 | ||||
309 | // Add GPR64 to the save instruction being built by MIB, which is in basic | |||
310 | // block MBB. IsImplicit says whether this is an explicit operand to the | |||
311 | // instruction, or an implicit one that comes between the explicit start | |||
312 | // and end registers. | |||
313 | static void addSavedGPR(MachineBasicBlock &MBB, MachineInstrBuilder &MIB, | |||
314 | unsigned GPR64, bool IsImplicit) { | |||
315 | const TargetRegisterInfo *RI = | |||
316 | MBB.getParent()->getSubtarget().getRegisterInfo(); | |||
317 | Register GPR32 = RI->getSubReg(GPR64, SystemZ::subreg_l32); | |||
318 | bool IsLive = MBB.isLiveIn(GPR64) || MBB.isLiveIn(GPR32); | |||
319 | if (!IsLive || !IsImplicit) { | |||
320 | MIB.addReg(GPR64, getImplRegState(IsImplicit) | getKillRegState(!IsLive)); | |||
321 | if (!IsLive) | |||
322 | MBB.addLiveIn(GPR64); | |||
323 | } | |||
324 | } | |||
325 | ||||
326 | bool SystemZELFFrameLowering::spillCalleeSavedRegisters( | |||
327 | MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, | |||
328 | ArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const { | |||
329 | if (CSI.empty()) | |||
330 | return false; | |||
331 | ||||
332 | MachineFunction &MF = *MBB.getParent(); | |||
333 | const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); | |||
334 | SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>(); | |||
335 | bool IsVarArg = MF.getFunction().isVarArg(); | |||
336 | DebugLoc DL; | |||
337 | ||||
338 | // Save GPRs | |||
339 | SystemZ::GPRRegs SpillGPRs = ZFI->getSpillGPRRegs(); | |||
340 | if (SpillGPRs.LowGPR) { | |||
341 | assert(SpillGPRs.LowGPR != SpillGPRs.HighGPR &&(static_cast <bool> (SpillGPRs.LowGPR != SpillGPRs.HighGPR && "Should be saving %r15 and something else") ? void (0) : __assert_fail ("SpillGPRs.LowGPR != SpillGPRs.HighGPR && \"Should be saving %r15 and something else\"" , "llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp", 342, __extension__ __PRETTY_FUNCTION__)) | |||
342 | "Should be saving %r15 and something else")(static_cast <bool> (SpillGPRs.LowGPR != SpillGPRs.HighGPR && "Should be saving %r15 and something else") ? void (0) : __assert_fail ("SpillGPRs.LowGPR != SpillGPRs.HighGPR && \"Should be saving %r15 and something else\"" , "llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp", 342, __extension__ __PRETTY_FUNCTION__)); | |||
343 | ||||
344 | // Build an STMG instruction. | |||
345 | MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(SystemZ::STMG)); | |||
346 | ||||
347 | // Add the explicit register operands. | |||
348 | addSavedGPR(MBB, MIB, SpillGPRs.LowGPR, false); | |||
349 | addSavedGPR(MBB, MIB, SpillGPRs.HighGPR, false); | |||
350 | ||||
351 | // Add the address. | |||
352 | MIB.addReg(SystemZ::R15D).addImm(SpillGPRs.GPROffset); | |||
353 | ||||
354 | // Make sure all call-saved GPRs are included as operands and are | |||
355 | // marked as live on entry. | |||
356 | for (const CalleeSavedInfo &I : CSI) { | |||
357 | Register Reg = I.getReg(); | |||
358 | if (SystemZ::GR64BitRegClass.contains(Reg)) | |||
359 | addSavedGPR(MBB, MIB, Reg, true); | |||
360 | } | |||
361 | ||||
362 | // ...likewise GPR varargs. | |||
363 | if (IsVarArg) | |||
364 | for (unsigned I = ZFI->getVarArgsFirstGPR(); I < SystemZ::ELFNumArgGPRs; ++I) | |||
365 | addSavedGPR(MBB, MIB, SystemZ::ELFArgGPRs[I], true); | |||
366 | } | |||
367 | ||||
368 | // Save FPRs/VRs in the normal TargetInstrInfo way. | |||
369 | for (const CalleeSavedInfo &I : CSI) { | |||
370 | Register Reg = I.getReg(); | |||
371 | if (SystemZ::FP64BitRegClass.contains(Reg)) { | |||
372 | MBB.addLiveIn(Reg); | |||
373 | TII->storeRegToStackSlot(MBB, MBBI, Reg, true, I.getFrameIdx(), | |||
374 | &SystemZ::FP64BitRegClass, TRI); | |||
375 | } | |||
376 | if (SystemZ::VR128BitRegClass.contains(Reg)) { | |||
377 | MBB.addLiveIn(Reg); | |||
378 | TII->storeRegToStackSlot(MBB, MBBI, Reg, true, I.getFrameIdx(), | |||
379 | &SystemZ::VR128BitRegClass, TRI); | |||
380 | } | |||
381 | } | |||
382 | ||||
383 | return true; | |||
384 | } | |||
385 | ||||
386 | bool SystemZELFFrameLowering::restoreCalleeSavedRegisters( | |||
387 | MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, | |||
388 | MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const { | |||
389 | if (CSI.empty()) | |||
390 | return false; | |||
391 | ||||
392 | MachineFunction &MF = *MBB.getParent(); | |||
393 | const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); | |||
394 | SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>(); | |||
395 | bool HasFP = hasFP(MF); | |||
396 | DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); | |||
397 | ||||
398 | // Restore FPRs/VRs in the normal TargetInstrInfo way. | |||
399 | for (const CalleeSavedInfo &I : CSI) { | |||
400 | Register Reg = I.getReg(); | |||
401 | if (SystemZ::FP64BitRegClass.contains(Reg)) | |||
402 | TII->loadRegFromStackSlot(MBB, MBBI, Reg, I.getFrameIdx(), | |||
403 | &SystemZ::FP64BitRegClass, TRI); | |||
404 | if (SystemZ::VR128BitRegClass.contains(Reg)) | |||
405 | TII->loadRegFromStackSlot(MBB, MBBI, Reg, I.getFrameIdx(), | |||
406 | &SystemZ::VR128BitRegClass, TRI); | |||
407 | } | |||
408 | ||||
409 | // Restore call-saved GPRs (but not call-clobbered varargs, which at | |||
410 | // this point might hold return values). | |||
411 | SystemZ::GPRRegs RestoreGPRs = ZFI->getRestoreGPRRegs(); | |||
412 | if (RestoreGPRs.LowGPR) { | |||
413 | // If we saved any of %r2-%r5 as varargs, we should also be saving | |||
414 | // and restoring %r6. If we're saving %r6 or above, we should be | |||
415 | // restoring it too. | |||
416 | assert(RestoreGPRs.LowGPR != RestoreGPRs.HighGPR &&(static_cast <bool> (RestoreGPRs.LowGPR != RestoreGPRs. HighGPR && "Should be loading %r15 and something else" ) ? void (0) : __assert_fail ("RestoreGPRs.LowGPR != RestoreGPRs.HighGPR && \"Should be loading %r15 and something else\"" , "llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp", 417, __extension__ __PRETTY_FUNCTION__)) | |||
417 | "Should be loading %r15 and something else")(static_cast <bool> (RestoreGPRs.LowGPR != RestoreGPRs. HighGPR && "Should be loading %r15 and something else" ) ? void (0) : __assert_fail ("RestoreGPRs.LowGPR != RestoreGPRs.HighGPR && \"Should be loading %r15 and something else\"" , "llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp", 417, __extension__ __PRETTY_FUNCTION__)); | |||
418 | ||||
419 | // Build an LMG instruction. | |||
420 | MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(SystemZ::LMG)); | |||
421 | ||||
422 | // Add the explicit register operands. | |||
423 | MIB.addReg(RestoreGPRs.LowGPR, RegState::Define); | |||
424 | MIB.addReg(RestoreGPRs.HighGPR, RegState::Define); | |||
425 | ||||
426 | // Add the address. | |||
427 | MIB.addReg(HasFP ? SystemZ::R11D : SystemZ::R15D); | |||
428 | MIB.addImm(RestoreGPRs.GPROffset); | |||
429 | ||||
430 | // Do a second scan adding regs as being defined by instruction | |||
431 | for (const CalleeSavedInfo &I : CSI) { | |||
432 | Register Reg = I.getReg(); | |||
433 | if (Reg != RestoreGPRs.LowGPR && Reg != RestoreGPRs.HighGPR && | |||
434 | SystemZ::GR64BitRegClass.contains(Reg)) | |||
435 | MIB.addReg(Reg, RegState::ImplicitDefine); | |||
436 | } | |||
437 | } | |||
438 | ||||
439 | return true; | |||
440 | } | |||
441 | ||||
442 | void SystemZELFFrameLowering::processFunctionBeforeFrameFinalized( | |||
443 | MachineFunction &MF, RegScavenger *RS) const { | |||
444 | MachineFrameInfo &MFFrame = MF.getFrameInfo(); | |||
445 | SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>(); | |||
446 | MachineRegisterInfo *MRI = &MF.getRegInfo(); | |||
447 | bool BackChain = MF.getFunction().hasFnAttribute("backchain"); | |||
448 | ||||
449 | if (!usePackedStack(MF) || BackChain) | |||
450 | // Create the incoming register save area. | |||
451 | getOrCreateFramePointerSaveIndex(MF); | |||
452 | ||||
453 | // Get the size of our stack frame to be allocated ... | |||
454 | uint64_t StackSize = (MFFrame.estimateStackSize(MF) + | |||
455 | SystemZMC::ELFCallFrameSize); | |||
456 | // ... and the maximum offset we may need to reach into the | |||
457 | // caller's frame to access the save area or stack arguments. | |||
458 | int64_t MaxArgOffset = 0; | |||
459 | for (int I = MFFrame.getObjectIndexBegin(); I != 0; ++I) | |||
460 | if (MFFrame.getObjectOffset(I) >= 0) { | |||
461 | int64_t ArgOffset = MFFrame.getObjectOffset(I) + | |||
462 | MFFrame.getObjectSize(I); | |||
463 | MaxArgOffset = std::max(MaxArgOffset, ArgOffset); | |||
464 | } | |||
465 | ||||
466 | uint64_t MaxReach = StackSize + MaxArgOffset; | |||
467 | if (!isUInt<12>(MaxReach)) { | |||
468 | // We may need register scavenging slots if some parts of the frame | |||
469 | // are outside the reach of an unsigned 12-bit displacement. | |||
470 | // Create 2 for the case where both addresses in an MVC are | |||
471 | // out of range. | |||
472 | RS->addScavengingFrameIndex(MFFrame.CreateStackObject(8, Align(8), false)); | |||
473 | RS->addScavengingFrameIndex(MFFrame.CreateStackObject(8, Align(8), false)); | |||
474 | } | |||
475 | ||||
476 | // If R6 is used as an argument register it is still callee saved. If it in | |||
477 | // this case is not clobbered (and restored) it should never be marked as | |||
478 | // killed. | |||
479 | if (MF.front().isLiveIn(SystemZ::R6D) && | |||
480 | ZFI->getRestoreGPRRegs().LowGPR != SystemZ::R6D) | |||
481 | for (auto &MO : MRI->use_nodbg_operands(SystemZ::R6D)) | |||
482 | MO.setIsKill(false); | |||
483 | } | |||
484 | ||||
485 | // Emit instructions before MBBI (in MBB) to add NumBytes to Reg. | |||
486 | static void emitIncrement(MachineBasicBlock &MBB, | |||
487 | MachineBasicBlock::iterator &MBBI, const DebugLoc &DL, | |||
488 | Register Reg, int64_t NumBytes, | |||
489 | const TargetInstrInfo *TII) { | |||
490 | while (NumBytes) { | |||
491 | unsigned Opcode; | |||
492 | int64_t ThisVal = NumBytes; | |||
493 | if (isInt<16>(NumBytes)) | |||
494 | Opcode = SystemZ::AGHI; | |||
495 | else { | |||
496 | Opcode = SystemZ::AGFI; | |||
497 | // Make sure we maintain 8-byte stack alignment. | |||
498 | int64_t MinVal = -uint64_t(1) << 31; | |||
499 | int64_t MaxVal = (int64_t(1) << 31) - 8; | |||
500 | if (ThisVal < MinVal) | |||
501 | ThisVal = MinVal; | |||
502 | else if (ThisVal > MaxVal) | |||
503 | ThisVal = MaxVal; | |||
504 | } | |||
505 | MachineInstr *MI = BuildMI(MBB, MBBI, DL, TII->get(Opcode), Reg) | |||
506 | .addReg(Reg).addImm(ThisVal); | |||
507 | // The CC implicit def is dead. | |||
508 | MI->getOperand(3).setIsDead(); | |||
509 | NumBytes -= ThisVal; | |||
510 | } | |||
511 | } | |||
512 | ||||
513 | // Add CFI for the new CFA offset. | |||
514 | static void buildCFAOffs(MachineBasicBlock &MBB, | |||
515 | MachineBasicBlock::iterator MBBI, | |||
516 | const DebugLoc &DL, int Offset, | |||
517 | const SystemZInstrInfo *ZII) { | |||
518 | unsigned CFIIndex = MBB.getParent()->addFrameInst( | |||
519 | MCCFIInstruction::cfiDefCfaOffset(nullptr, -Offset)); | |||
520 | BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::CFI_INSTRUCTION)) | |||
521 | .addCFIIndex(CFIIndex); | |||
522 | } | |||
523 | ||||
524 | // Add CFI for the new frame location. | |||
525 | static void buildDefCFAReg(MachineBasicBlock &MBB, | |||
526 | MachineBasicBlock::iterator MBBI, | |||
527 | const DebugLoc &DL, unsigned Reg, | |||
528 | const SystemZInstrInfo *ZII) { | |||
529 | MachineFunction &MF = *MBB.getParent(); | |||
530 | MachineModuleInfo &MMI = MF.getMMI(); | |||
531 | const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo(); | |||
532 | unsigned RegNum = MRI->getDwarfRegNum(Reg, true); | |||
533 | unsigned CFIIndex = MF.addFrameInst( | |||
534 | MCCFIInstruction::createDefCfaRegister(nullptr, RegNum)); | |||
535 | BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::CFI_INSTRUCTION)) | |||
536 | .addCFIIndex(CFIIndex); | |||
537 | } | |||
538 | ||||
539 | void SystemZELFFrameLowering::emitPrologue(MachineFunction &MF, | |||
540 | MachineBasicBlock &MBB) const { | |||
541 | assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported")(static_cast <bool> (&MF.front() == &MBB && "Shrink-wrapping not yet supported") ? void (0) : __assert_fail ("&MF.front() == &MBB && \"Shrink-wrapping not yet supported\"" , "llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp", 541, __extension__ __PRETTY_FUNCTION__)); | |||
542 | const SystemZSubtarget &STI = MF.getSubtarget<SystemZSubtarget>(); | |||
543 | const SystemZTargetLowering &TLI = *STI.getTargetLowering(); | |||
544 | MachineFrameInfo &MFFrame = MF.getFrameInfo(); | |||
545 | auto *ZII = static_cast<const SystemZInstrInfo *>(STI.getInstrInfo()); | |||
546 | SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>(); | |||
547 | MachineBasicBlock::iterator MBBI = MBB.begin(); | |||
548 | MachineModuleInfo &MMI = MF.getMMI(); | |||
549 | const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo(); | |||
550 | const std::vector<CalleeSavedInfo> &CSI = MFFrame.getCalleeSavedInfo(); | |||
551 | bool HasFP = hasFP(MF); | |||
552 | ||||
553 | // In GHC calling convention C stack space, including the ABI-defined | |||
554 | // 160-byte base area, is (de)allocated by GHC itself. This stack space may | |||
555 | // be used by LLVM as spill slots for the tail recursive GHC functions. Thus | |||
556 | // do not allocate stack space here, too. | |||
557 | if (MF.getFunction().getCallingConv() == CallingConv::GHC) { | |||
558 | if (MFFrame.getStackSize() > 2048 * sizeof(long)) { | |||
559 | report_fatal_error( | |||
560 | "Pre allocated stack space for GHC function is too small"); | |||
561 | } | |||
562 | if (HasFP) { | |||
563 | report_fatal_error( | |||
564 | "In GHC calling convention a frame pointer is not supported"); | |||
565 | } | |||
566 | MFFrame.setStackSize(MFFrame.getStackSize() + SystemZMC::ELFCallFrameSize); | |||
567 | return; | |||
568 | } | |||
569 | ||||
570 | // Debug location must be unknown since the first debug location is used | |||
571 | // to determine the end of the prologue. | |||
572 | DebugLoc DL; | |||
573 | ||||
574 | // The current offset of the stack pointer from the CFA. | |||
575 | int64_t SPOffsetFromCFA = -SystemZMC::ELFCFAOffsetFromInitialSP; | |||
576 | ||||
577 | if (ZFI->getSpillGPRRegs().LowGPR) { | |||
578 | // Skip over the GPR saves. | |||
579 | if (MBBI != MBB.end() && MBBI->getOpcode() == SystemZ::STMG) | |||
580 | ++MBBI; | |||
581 | else | |||
582 | llvm_unreachable("Couldn't skip over GPR saves")::llvm::llvm_unreachable_internal("Couldn't skip over GPR saves" , "llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp", 582); | |||
583 | ||||
584 | // Add CFI for the GPR saves. | |||
585 | for (auto &Save : CSI) { | |||
586 | Register Reg = Save.getReg(); | |||
587 | if (SystemZ::GR64BitRegClass.contains(Reg)) { | |||
588 | int FI = Save.getFrameIdx(); | |||
589 | int64_t Offset = MFFrame.getObjectOffset(FI); | |||
590 | unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( | |||
591 | nullptr, MRI->getDwarfRegNum(Reg, true), Offset)); | |||
592 | BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::CFI_INSTRUCTION)) | |||
593 | .addCFIIndex(CFIIndex); | |||
594 | } | |||
595 | } | |||
596 | } | |||
597 | ||||
598 | uint64_t StackSize = MFFrame.getStackSize(); | |||
599 | // We need to allocate the ABI-defined 160-byte base area whenever | |||
600 | // we allocate stack space for our own use and whenever we call another | |||
601 | // function. | |||
602 | bool HasStackObject = false; | |||
603 | for (unsigned i = 0, e = MFFrame.getObjectIndexEnd(); i != e; ++i) | |||
604 | if (!MFFrame.isDeadObjectIndex(i)) { | |||
605 | HasStackObject = true; | |||
606 | break; | |||
607 | } | |||
608 | if (HasStackObject || MFFrame.hasCalls()) | |||
609 | StackSize += SystemZMC::ELFCallFrameSize; | |||
610 | // Don't allocate the incoming reg save area. | |||
611 | StackSize = StackSize > SystemZMC::ELFCallFrameSize | |||
612 | ? StackSize - SystemZMC::ELFCallFrameSize | |||
613 | : 0; | |||
614 | MFFrame.setStackSize(StackSize); | |||
615 | ||||
616 | if (StackSize) { | |||
617 | // Allocate StackSize bytes. | |||
618 | int64_t Delta = -int64_t(StackSize); | |||
619 | const unsigned ProbeSize = TLI.getStackProbeSize(MF); | |||
620 | bool FreeProbe = (ZFI->getSpillGPRRegs().GPROffset && | |||
621 | (ZFI->getSpillGPRRegs().GPROffset + StackSize) < ProbeSize); | |||
622 | if (!FreeProbe && | |||
623 | MF.getSubtarget().getTargetLowering()->hasInlineStackProbe(MF)) { | |||
624 | // Stack probing may involve looping, but splitting the prologue block | |||
625 | // is not possible at this point since it would invalidate the | |||
626 | // SaveBlocks / RestoreBlocks sets of PEI in the single block function | |||
627 | // case. Build a pseudo to be handled later by inlineStackProbe(). | |||
628 | BuildMI(MBB, MBBI, DL, ZII->get(SystemZ::PROBED_STACKALLOC)) | |||
629 | .addImm(StackSize); | |||
630 | } | |||
631 | else { | |||
632 | bool StoreBackchain = MF.getFunction().hasFnAttribute("backchain"); | |||
633 | // If we need backchain, save current stack pointer. R1 is free at | |||
634 | // this point. | |||
635 | if (StoreBackchain) | |||
636 | BuildMI(MBB, MBBI, DL, ZII->get(SystemZ::LGR)) | |||
637 | .addReg(SystemZ::R1D, RegState::Define).addReg(SystemZ::R15D); | |||
638 | emitIncrement(MBB, MBBI, DL, SystemZ::R15D, Delta, ZII); | |||
639 | buildCFAOffs(MBB, MBBI, DL, SPOffsetFromCFA + Delta, ZII); | |||
640 | if (StoreBackchain) | |||
641 | BuildMI(MBB, MBBI, DL, ZII->get(SystemZ::STG)) | |||
642 | .addReg(SystemZ::R1D, RegState::Kill).addReg(SystemZ::R15D) | |||
643 | .addImm(getBackchainOffset(MF)).addReg(0); | |||
644 | } | |||
645 | SPOffsetFromCFA += Delta; | |||
646 | } | |||
647 | ||||
648 | if (HasFP) { | |||
649 | // Copy the base of the frame to R11. | |||
650 | BuildMI(MBB, MBBI, DL, ZII->get(SystemZ::LGR), SystemZ::R11D) | |||
651 | .addReg(SystemZ::R15D); | |||
652 | ||||
653 | // Add CFI for the new frame location. | |||
654 | buildDefCFAReg(MBB, MBBI, DL, SystemZ::R11D, ZII); | |||
655 | ||||
656 | // Mark the FramePtr as live at the beginning of every block except | |||
657 | // the entry block. (We'll have marked R11 as live on entry when | |||
658 | // saving the GPRs.) | |||
659 | for (MachineBasicBlock &MBBJ : llvm::drop_begin(MF)) | |||
660 | MBBJ.addLiveIn(SystemZ::R11D); | |||
661 | } | |||
662 | ||||
663 | // Skip over the FPR/VR saves. | |||
664 | SmallVector<unsigned, 8> CFIIndexes; | |||
665 | for (auto &Save : CSI) { | |||
666 | Register Reg = Save.getReg(); | |||
667 | if (SystemZ::FP64BitRegClass.contains(Reg)) { | |||
668 | if (MBBI != MBB.end() && | |||
669 | (MBBI->getOpcode() == SystemZ::STD || | |||
670 | MBBI->getOpcode() == SystemZ::STDY)) | |||
671 | ++MBBI; | |||
672 | else | |||
673 | llvm_unreachable("Couldn't skip over FPR save")::llvm::llvm_unreachable_internal("Couldn't skip over FPR save" , "llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp", 673); | |||
674 | } else if (SystemZ::VR128BitRegClass.contains(Reg)) { | |||
675 | if (MBBI != MBB.end() && | |||
676 | MBBI->getOpcode() == SystemZ::VST) | |||
677 | ++MBBI; | |||
678 | else | |||
679 | llvm_unreachable("Couldn't skip over VR save")::llvm::llvm_unreachable_internal("Couldn't skip over VR save" , "llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp", 679); | |||
680 | } else | |||
681 | continue; | |||
682 | ||||
683 | // Add CFI for the this save. | |||
684 | unsigned DwarfReg = MRI->getDwarfRegNum(Reg, true); | |||
685 | Register IgnoredFrameReg; | |||
686 | int64_t Offset = | |||
687 | getFrameIndexReference(MF, Save.getFrameIdx(), IgnoredFrameReg) | |||
688 | .getFixed(); | |||
689 | ||||
690 | unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( | |||
691 | nullptr, DwarfReg, SPOffsetFromCFA + Offset)); | |||
692 | CFIIndexes.push_back(CFIIndex); | |||
693 | } | |||
694 | // Complete the CFI for the FPR/VR saves, modelling them as taking effect | |||
695 | // after the last save. | |||
696 | for (auto CFIIndex : CFIIndexes) { | |||
697 | BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::CFI_INSTRUCTION)) | |||
698 | .addCFIIndex(CFIIndex); | |||
699 | } | |||
700 | } | |||
701 | ||||
702 | void SystemZELFFrameLowering::emitEpilogue(MachineFunction &MF, | |||
703 | MachineBasicBlock &MBB) const { | |||
704 | MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); | |||
705 | auto *ZII = | |||
706 | static_cast<const SystemZInstrInfo *>(MF.getSubtarget().getInstrInfo()); | |||
707 | SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>(); | |||
708 | MachineFrameInfo &MFFrame = MF.getFrameInfo(); | |||
709 | ||||
710 | // See SystemZELFFrameLowering::emitPrologue | |||
711 | if (MF.getFunction().getCallingConv() == CallingConv::GHC) | |||
712 | return; | |||
713 | ||||
714 | // Skip the return instruction. | |||
715 | assert(MBBI->isReturn() && "Can only insert epilogue into returning blocks")(static_cast <bool> (MBBI->isReturn() && "Can only insert epilogue into returning blocks" ) ? void (0) : __assert_fail ("MBBI->isReturn() && \"Can only insert epilogue into returning blocks\"" , "llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp", 715, __extension__ __PRETTY_FUNCTION__)); | |||
716 | ||||
717 | uint64_t StackSize = MFFrame.getStackSize(); | |||
718 | if (ZFI->getRestoreGPRRegs().LowGPR) { | |||
719 | --MBBI; | |||
720 | unsigned Opcode = MBBI->getOpcode(); | |||
721 | if (Opcode != SystemZ::LMG) | |||
722 | llvm_unreachable("Expected to see callee-save register restore code")::llvm::llvm_unreachable_internal("Expected to see callee-save register restore code" , "llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp", 722); | |||
723 | ||||
724 | unsigned AddrOpNo = 2; | |||
725 | DebugLoc DL = MBBI->getDebugLoc(); | |||
726 | uint64_t Offset = StackSize + MBBI->getOperand(AddrOpNo + 1).getImm(); | |||
727 | unsigned NewOpcode = ZII->getOpcodeForOffset(Opcode, Offset); | |||
728 | ||||
729 | // If the offset is too large, use the largest stack-aligned offset | |||
730 | // and add the rest to the base register (the stack or frame pointer). | |||
731 | if (!NewOpcode) { | |||
732 | uint64_t NumBytes = Offset - 0x7fff8; | |||
733 | emitIncrement(MBB, MBBI, DL, MBBI->getOperand(AddrOpNo).getReg(), | |||
734 | NumBytes, ZII); | |||
735 | Offset -= NumBytes; | |||
736 | NewOpcode = ZII->getOpcodeForOffset(Opcode, Offset); | |||
737 | assert(NewOpcode && "No restore instruction available")(static_cast <bool> (NewOpcode && "No restore instruction available" ) ? void (0) : __assert_fail ("NewOpcode && \"No restore instruction available\"" , "llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp", 737, __extension__ __PRETTY_FUNCTION__)); | |||
738 | } | |||
739 | ||||
740 | MBBI->setDesc(ZII->get(NewOpcode)); | |||
741 | MBBI->getOperand(AddrOpNo + 1).ChangeToImmediate(Offset); | |||
742 | } else if (StackSize) { | |||
743 | DebugLoc DL = MBBI->getDebugLoc(); | |||
744 | emitIncrement(MBB, MBBI, DL, SystemZ::R15D, StackSize, ZII); | |||
745 | } | |||
746 | } | |||
747 | ||||
748 | void SystemZELFFrameLowering::inlineStackProbe( | |||
749 | MachineFunction &MF, MachineBasicBlock &PrologMBB) const { | |||
750 | auto *ZII = | |||
751 | static_cast<const SystemZInstrInfo *>(MF.getSubtarget().getInstrInfo()); | |||
752 | const SystemZSubtarget &STI = MF.getSubtarget<SystemZSubtarget>(); | |||
753 | const SystemZTargetLowering &TLI = *STI.getTargetLowering(); | |||
754 | ||||
755 | MachineInstr *StackAllocMI = nullptr; | |||
756 | for (MachineInstr &MI : PrologMBB) | |||
757 | if (MI.getOpcode() == SystemZ::PROBED_STACKALLOC) { | |||
758 | StackAllocMI = &MI; | |||
759 | break; | |||
760 | } | |||
761 | if (StackAllocMI == nullptr) | |||
762 | return; | |||
763 | uint64_t StackSize = StackAllocMI->getOperand(0).getImm(); | |||
764 | const unsigned ProbeSize = TLI.getStackProbeSize(MF); | |||
765 | uint64_t NumFullBlocks = StackSize / ProbeSize; | |||
766 | uint64_t Residual = StackSize % ProbeSize; | |||
767 | int64_t SPOffsetFromCFA = -SystemZMC::ELFCFAOffsetFromInitialSP; | |||
768 | MachineBasicBlock *MBB = &PrologMBB; | |||
769 | MachineBasicBlock::iterator MBBI = StackAllocMI; | |||
770 | const DebugLoc DL = StackAllocMI->getDebugLoc(); | |||
771 | ||||
772 | // Allocate a block of Size bytes on the stack and probe it. | |||
773 | auto allocateAndProbe = [&](MachineBasicBlock &InsMBB, | |||
774 | MachineBasicBlock::iterator InsPt, unsigned Size, | |||
775 | bool EmitCFI) -> void { | |||
776 | emitIncrement(InsMBB, InsPt, DL, SystemZ::R15D, -int64_t(Size), ZII); | |||
777 | if (EmitCFI) { | |||
778 | SPOffsetFromCFA -= Size; | |||
779 | buildCFAOffs(InsMBB, InsPt, DL, SPOffsetFromCFA, ZII); | |||
780 | } | |||
781 | // Probe by means of a volatile compare. | |||
782 | MachineMemOperand *MMO = MF.getMachineMemOperand(MachinePointerInfo(), | |||
783 | MachineMemOperand::MOVolatile | MachineMemOperand::MOLoad, 8, Align(1)); | |||
784 | BuildMI(InsMBB, InsPt, DL, ZII->get(SystemZ::CG)) | |||
785 | .addReg(SystemZ::R0D, RegState::Undef) | |||
786 | .addReg(SystemZ::R15D).addImm(Size - 8).addReg(0) | |||
787 | .addMemOperand(MMO); | |||
788 | }; | |||
789 | ||||
790 | bool StoreBackchain = MF.getFunction().hasFnAttribute("backchain"); | |||
791 | if (StoreBackchain) | |||
792 | BuildMI(*MBB, MBBI, DL, ZII->get(SystemZ::LGR)) | |||
793 | .addReg(SystemZ::R1D, RegState::Define).addReg(SystemZ::R15D); | |||
794 | ||||
795 | MachineBasicBlock *DoneMBB = nullptr; | |||
796 | MachineBasicBlock *LoopMBB = nullptr; | |||
797 | if (NumFullBlocks < 3) { | |||
798 | // Emit unrolled probe statements. | |||
799 | for (unsigned int i = 0; i < NumFullBlocks; i++) | |||
800 | allocateAndProbe(*MBB, MBBI, ProbeSize, true/*EmitCFI*/); | |||
801 | } else { | |||
802 | // Emit a loop probing the pages. | |||
803 | uint64_t LoopAlloc = ProbeSize * NumFullBlocks; | |||
804 | SPOffsetFromCFA -= LoopAlloc; | |||
805 | ||||
806 | // Use R0D to hold the exit value. | |||
807 | BuildMI(*MBB, MBBI, DL, ZII->get(SystemZ::LGR), SystemZ::R0D) | |||
808 | .addReg(SystemZ::R15D); | |||
809 | buildDefCFAReg(*MBB, MBBI, DL, SystemZ::R0D, ZII); | |||
810 | emitIncrement(*MBB, MBBI, DL, SystemZ::R0D, -int64_t(LoopAlloc), ZII); | |||
811 | buildCFAOffs(*MBB, MBBI, DL, -int64_t(SystemZMC::ELFCallFrameSize + LoopAlloc), | |||
812 | ZII); | |||
813 | ||||
814 | DoneMBB = SystemZ::splitBlockBefore(MBBI, MBB); | |||
815 | LoopMBB = SystemZ::emitBlockAfter(MBB); | |||
816 | MBB->addSuccessor(LoopMBB); | |||
817 | LoopMBB->addSuccessor(LoopMBB); | |||
818 | LoopMBB->addSuccessor(DoneMBB); | |||
819 | ||||
820 | MBB = LoopMBB; | |||
821 | allocateAndProbe(*MBB, MBB->end(), ProbeSize, false/*EmitCFI*/); | |||
822 | BuildMI(*MBB, MBB->end(), DL, ZII->get(SystemZ::CLGR)) | |||
823 | .addReg(SystemZ::R15D).addReg(SystemZ::R0D); | |||
824 | BuildMI(*MBB, MBB->end(), DL, ZII->get(SystemZ::BRC)) | |||
825 | .addImm(SystemZ::CCMASK_ICMP).addImm(SystemZ::CCMASK_CMP_GT).addMBB(MBB); | |||
826 | ||||
827 | MBB = DoneMBB; | |||
828 | MBBI = DoneMBB->begin(); | |||
829 | buildDefCFAReg(*MBB, MBBI, DL, SystemZ::R15D, ZII); | |||
830 | } | |||
831 | ||||
832 | if (Residual) | |||
833 | allocateAndProbe(*MBB, MBBI, Residual, true/*EmitCFI*/); | |||
834 | ||||
835 | if (StoreBackchain) | |||
836 | BuildMI(*MBB, MBBI, DL, ZII->get(SystemZ::STG)) | |||
837 | .addReg(SystemZ::R1D, RegState::Kill).addReg(SystemZ::R15D) | |||
838 | .addImm(getBackchainOffset(MF)).addReg(0); | |||
839 | ||||
840 | StackAllocMI->eraseFromParent(); | |||
841 | if (DoneMBB != nullptr) { | |||
842 | // Compute the live-in lists for the new blocks. | |||
843 | recomputeLiveIns(*DoneMBB); | |||
844 | recomputeLiveIns(*LoopMBB); | |||
845 | } | |||
846 | } | |||
847 | ||||
848 | bool SystemZELFFrameLowering::hasFP(const MachineFunction &MF) const { | |||
849 | return (MF.getTarget().Options.DisableFramePointerElim(MF) || | |||
850 | MF.getFrameInfo().hasVarSizedObjects()); | |||
851 | } | |||
852 | ||||
853 | StackOffset SystemZELFFrameLowering::getFrameIndexReference( | |||
854 | const MachineFunction &MF, int FI, Register &FrameReg) const { | |||
855 | // Our incoming SP is actually SystemZMC::ELFCallFrameSize below the CFA, so | |||
856 | // add that difference here. | |||
857 | StackOffset Offset = | |||
858 | TargetFrameLowering::getFrameIndexReference(MF, FI, FrameReg); | |||
859 | return Offset + StackOffset::getFixed(SystemZMC::ELFCallFrameSize); | |||
860 | } | |||
861 | ||||
862 | unsigned SystemZELFFrameLowering::getRegSpillOffset(MachineFunction &MF, | |||
863 | Register Reg) const { | |||
864 | bool IsVarArg = MF.getFunction().isVarArg(); | |||
865 | bool BackChain = MF.getFunction().hasFnAttribute("backchain"); | |||
866 | bool SoftFloat = MF.getSubtarget<SystemZSubtarget>().hasSoftFloat(); | |||
867 | unsigned Offset = RegSpillOffsets[Reg]; | |||
868 | if (usePackedStack(MF) && !(IsVarArg && !SoftFloat)) { | |||
869 | if (SystemZ::GR64BitRegClass.contains(Reg)) | |||
870 | // Put all GPRs at the top of the Register save area with packed | |||
871 | // stack. Make room for the backchain if needed. | |||
872 | Offset += BackChain ? 24 : 32; | |||
873 | else | |||
874 | Offset = 0; | |||
875 | } | |||
876 | return Offset; | |||
877 | } | |||
878 | ||||
879 | int SystemZELFFrameLowering::getOrCreateFramePointerSaveIndex( | |||
880 | MachineFunction &MF) const { | |||
881 | SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>(); | |||
882 | int FI = ZFI->getFramePointerSaveIndex(); | |||
883 | if (!FI) { | |||
884 | MachineFrameInfo &MFFrame = MF.getFrameInfo(); | |||
885 | int Offset = getBackchainOffset(MF) - SystemZMC::ELFCallFrameSize; | |||
886 | FI = MFFrame.CreateFixedObject(8, Offset, false); | |||
887 | ZFI->setFramePointerSaveIndex(FI); | |||
888 | } | |||
889 | return FI; | |||
890 | } | |||
891 | ||||
892 | bool SystemZELFFrameLowering::usePackedStack(MachineFunction &MF) const { | |||
893 | bool HasPackedStackAttr = MF.getFunction().hasFnAttribute("packed-stack"); | |||
894 | bool BackChain = MF.getFunction().hasFnAttribute("backchain"); | |||
895 | bool SoftFloat = MF.getSubtarget<SystemZSubtarget>().hasSoftFloat(); | |||
896 | if (HasPackedStackAttr && BackChain && !SoftFloat) | |||
897 | report_fatal_error("packed-stack + backchain + hard-float is unsupported."); | |||
898 | bool CallConv = MF.getFunction().getCallingConv() != CallingConv::GHC; | |||
899 | return HasPackedStackAttr && CallConv; | |||
900 | } | |||
901 | ||||
902 | SystemZXPLINKFrameLowering::SystemZXPLINKFrameLowering() | |||
903 | : SystemZFrameLowering(TargetFrameLowering::StackGrowsDown, Align(32), 0, | |||
904 | Align(32), /* StackRealignable */ false), | |||
905 | RegSpillOffsets(-1) { | |||
906 | ||||
907 | // Create a mapping from register number to save slot offset. | |||
908 | // These offsets are relative to the start of the local are area. | |||
909 | RegSpillOffsets.grow(SystemZ::NUM_TARGET_REGS); | |||
910 | for (unsigned I = 0, E = array_lengthof(XPLINKSpillOffsetTable); I != E; ++I) | |||
911 | RegSpillOffsets[XPLINKSpillOffsetTable[I].Reg] = | |||
912 | XPLINKSpillOffsetTable[I].Offset; | |||
913 | } | |||
914 | ||||
915 | bool SystemZXPLINKFrameLowering::assignCalleeSavedSpillSlots( | |||
916 | MachineFunction &MF, const TargetRegisterInfo *TRI, | |||
917 | std::vector<CalleeSavedInfo> &CSI) const { | |||
918 | MachineFrameInfo &MFFrame = MF.getFrameInfo(); | |||
919 | SystemZMachineFunctionInfo *MFI = MF.getInfo<SystemZMachineFunctionInfo>(); | |||
920 | const SystemZSubtarget &Subtarget = MF.getSubtarget<SystemZSubtarget>(); | |||
921 | auto &Regs = Subtarget.getSpecialRegisters<SystemZXPLINK64Registers>(); | |||
922 | ||||
923 | // Scan the call-saved GPRs and find the bounds of the register spill area. | |||
924 | unsigned LowGPR = 0; | |||
925 | int LowOffset = INT32_MAX(2147483647); | |||
926 | unsigned HighGPR = LowGPR; | |||
927 | int HighOffset = -1; | |||
928 | ||||
929 | unsigned RegSP = Regs.getStackPointerRegister(); | |||
930 | auto &GRRegClass = SystemZ::GR64BitRegClass; | |||
| ||||
931 | const unsigned RegSize = 8; | |||
932 | ||||
933 | auto ProcessCSI = [&](std::vector<CalleeSavedInfo> &CSIList) { | |||
934 | for (auto &CS : CSIList) { | |||
935 | Register Reg = CS.getReg(); | |||
936 | int Offset = RegSpillOffsets[Reg]; | |||
937 | if (Offset
| |||
938 | if (GRRegClass.contains(Reg)) { | |||
| ||||
939 | if (LowOffset > Offset) { | |||
940 | LowOffset = Offset; | |||
941 | LowGPR = Reg; | |||
942 | } | |||
943 | ||||
944 | if (Offset > HighOffset) { | |||
945 | HighOffset = Offset; | |||
946 | HighGPR = Reg; | |||
947 | } | |||
948 | } | |||
949 | int FrameIdx = MFFrame.CreateFixedSpillStackObject(RegSize, Offset); | |||
950 | CS.setFrameIdx(FrameIdx); | |||
951 | } else | |||
952 | CS.setFrameIdx(INT32_MAX(2147483647)); | |||
953 | } | |||
954 | }; | |||
955 | ||||
956 | std::vector<CalleeSavedInfo> Spills; | |||
957 | ||||
958 | // For non-leaf functions: | |||
959 | // - the address of callee (entry point) register R6 must be saved | |||
960 | Spills.push_back(CalleeSavedInfo(Regs.getAddressOfCalleeRegister())); | |||
961 | ||||
962 | // If the function needs a frame pointer, or if the backchain pointer should | |||
963 | // be stored, then save the stack pointer register R4. | |||
964 | if (hasFP(MF) || MF.getFunction().hasFnAttribute("backchain")) | |||
965 | Spills.push_back(CalleeSavedInfo(RegSP)); | |||
966 | ||||
967 | // Save the range of call-saved registers, for use by the | |||
968 | // prologue/epilogue inserters. | |||
969 | ProcessCSI(CSI); | |||
970 | MFI->setRestoreGPRRegs(LowGPR, HighGPR, LowOffset); | |||
971 | ||||
972 | // Save the range of call-saved registers, for use by the epilogue inserter. | |||
973 | ProcessCSI(Spills); | |||
974 | MFI->setSpillGPRRegs(LowGPR, HighGPR, LowOffset); | |||
975 | ||||
976 | // Create spill slots for the remaining registers. | |||
977 | for (auto &CS : CSI) { | |||
978 | if (CS.getFrameIdx() != INT32_MAX(2147483647)) | |||
979 | continue; | |||
980 | Register Reg = CS.getReg(); | |||
981 | const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); | |||
982 | Align Alignment = TRI->getSpillAlign(*RC); | |||
983 | unsigned Size = TRI->getSpillSize(*RC); | |||
984 | Alignment = std::min(Alignment, getStackAlign()); | |||
985 | int FrameIdx = MFFrame.CreateStackObject(Size, Alignment, true); | |||
986 | CS.setFrameIdx(FrameIdx); | |||
987 | } | |||
988 | ||||
989 | return true; | |||
990 | } | |||
991 | ||||
992 | void SystemZXPLINKFrameLowering::determineCalleeSaves(MachineFunction &MF, | |||
993 | BitVector &SavedRegs, | |||
994 | RegScavenger *RS) const { | |||
995 | TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); | |||
996 | ||||
997 | bool HasFP = hasFP(MF); | |||
998 | const SystemZSubtarget &Subtarget = MF.getSubtarget<SystemZSubtarget>(); | |||
999 | auto &Regs = Subtarget.getSpecialRegisters<SystemZXPLINK64Registers>(); | |||
1000 | ||||
1001 | // If the function requires a frame pointer, record that the hard | |||
1002 | // frame pointer will be clobbered. | |||
1003 | if (HasFP) | |||
1004 | SavedRegs.set(Regs.getFramePointerRegister()); | |||
1005 | ||||
1006 | // If the function is not an XPLeaf function, we need to save the | |||
1007 | // return address register. We also always use that register for | |||
1008 | // the return instruction, so it needs to be restored in the | |||
1009 | // epilogue even though that register is considered to be volatile. | |||
1010 | // #TODO: Implement leaf detection. | |||
1011 | SavedRegs.set(Regs.getReturnFunctionAddressRegister()); | |||
1012 | } | |||
1013 | ||||
1014 | bool SystemZXPLINKFrameLowering::spillCalleeSavedRegisters( | |||
1015 | MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, | |||
1016 | ArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const { | |||
1017 | if (CSI.empty()) | |||
1018 | return true; | |||
1019 | ||||
1020 | MachineFunction &MF = *MBB.getParent(); | |||
1021 | SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>(); | |||
1022 | const SystemZSubtarget &Subtarget = MF.getSubtarget<SystemZSubtarget>(); | |||
1023 | const TargetInstrInfo *TII = Subtarget.getInstrInfo(); | |||
1024 | auto &Regs = Subtarget.getSpecialRegisters<SystemZXPLINK64Registers>(); | |||
1025 | SystemZ::GPRRegs SpillGPRs = ZFI->getSpillGPRRegs(); | |||
1026 | DebugLoc DL; | |||
1027 | ||||
1028 | // Save GPRs | |||
1029 | if (SpillGPRs.LowGPR) { | |||
1030 | assert(SpillGPRs.LowGPR != SpillGPRs.HighGPR &&(static_cast <bool> (SpillGPRs.LowGPR != SpillGPRs.HighGPR && "Should be saving multiple registers") ? void (0) : __assert_fail ("SpillGPRs.LowGPR != SpillGPRs.HighGPR && \"Should be saving multiple registers\"" , "llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp", 1031, __extension__ __PRETTY_FUNCTION__)) | |||
1031 | "Should be saving multiple registers")(static_cast <bool> (SpillGPRs.LowGPR != SpillGPRs.HighGPR && "Should be saving multiple registers") ? void (0) : __assert_fail ("SpillGPRs.LowGPR != SpillGPRs.HighGPR && \"Should be saving multiple registers\"" , "llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp", 1031, __extension__ __PRETTY_FUNCTION__)); | |||
1032 | ||||
1033 | // Build an STM/STMG instruction. | |||
1034 | MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(SystemZ::STMG)); | |||
1035 | ||||
1036 | // Add the explicit register operands. | |||
1037 | addSavedGPR(MBB, MIB, SpillGPRs.LowGPR, false); | |||
1038 | addSavedGPR(MBB, MIB, SpillGPRs.HighGPR, false); | |||
1039 | ||||
1040 | // Add the address r4 | |||
1041 | MIB.addReg(Regs.getStackPointerRegister()); | |||
1042 | ||||
1043 | // Add the partial offset | |||
1044 | // We cannot add the actual offset as, at the stack is not finalized | |||
1045 | MIB.addImm(SpillGPRs.GPROffset); | |||
1046 | ||||
1047 | // Make sure all call-saved GPRs are included as operands and are | |||
1048 | // marked as live on entry. | |||
1049 | auto &GRRegClass = SystemZ::GR64BitRegClass; | |||
1050 | for (const CalleeSavedInfo &I : CSI) { | |||
1051 | Register Reg = I.getReg(); | |||
1052 | if (GRRegClass.contains(Reg)) | |||
1053 | addSavedGPR(MBB, MIB, Reg, true); | |||
1054 | } | |||
1055 | } | |||
1056 | ||||
1057 | // Spill FPRs to the stack in the normal TargetInstrInfo way | |||
1058 | for (const CalleeSavedInfo &I : CSI) { | |||
1059 | Register Reg = I.getReg(); | |||
1060 | if (SystemZ::FP64BitRegClass.contains(Reg)) { | |||
1061 | MBB.addLiveIn(Reg); | |||
1062 | TII->storeRegToStackSlot(MBB, MBBI, Reg, true, I.getFrameIdx(), | |||
1063 | &SystemZ::FP64BitRegClass, TRI); | |||
1064 | } | |||
1065 | if (SystemZ::VR128BitRegClass.contains(Reg)) { | |||
1066 | MBB.addLiveIn(Reg); | |||
1067 | TII->storeRegToStackSlot(MBB, MBBI, Reg, true, I.getFrameIdx(), | |||
1068 | &SystemZ::VR128BitRegClass, TRI); | |||
1069 | } | |||
1070 | } | |||
1071 | ||||
1072 | return true; | |||
1073 | } | |||
1074 | ||||
1075 | bool SystemZXPLINKFrameLowering::restoreCalleeSavedRegisters( | |||
1076 | MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, | |||
1077 | MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const { | |||
1078 | ||||
1079 | if (CSI.empty()) | |||
1080 | return false; | |||
1081 | ||||
1082 | MachineFunction &MF = *MBB.getParent(); | |||
1083 | SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>(); | |||
1084 | const SystemZSubtarget &Subtarget = MF.getSubtarget<SystemZSubtarget>(); | |||
1085 | const TargetInstrInfo *TII = Subtarget.getInstrInfo(); | |||
1086 | auto &Regs = Subtarget.getSpecialRegisters<SystemZXPLINK64Registers>(); | |||
1087 | ||||
1088 | DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); | |||
1089 | ||||
1090 | // Restore FPRs in the normal TargetInstrInfo way. | |||
1091 | for (unsigned I = 0, E = CSI.size(); I != E; ++I) { | |||
1092 | Register Reg = CSI[I].getReg(); | |||
1093 | if (SystemZ::FP64BitRegClass.contains(Reg)) | |||
1094 | TII->loadRegFromStackSlot(MBB, MBBI, Reg, CSI[I].getFrameIdx(), | |||
1095 | &SystemZ::FP64BitRegClass, TRI); | |||
1096 | if (SystemZ::VR128BitRegClass.contains(Reg)) | |||
1097 | TII->loadRegFromStackSlot(MBB, MBBI, Reg, CSI[I].getFrameIdx(), | |||
1098 | &SystemZ::VR128BitRegClass, TRI); | |||
1099 | } | |||
1100 | ||||
1101 | // Restore call-saved GPRs (but not call-clobbered varargs, which at | |||
1102 | // this point might hold return values). | |||
1103 | SystemZ::GPRRegs RestoreGPRs = ZFI->getRestoreGPRRegs(); | |||
1104 | if (RestoreGPRs.LowGPR) { | |||
1105 | assert(isInt<20>(Regs.getStackPointerBias() + RestoreGPRs.GPROffset))(static_cast <bool> (isInt<20>(Regs.getStackPointerBias () + RestoreGPRs.GPROffset)) ? void (0) : __assert_fail ("isInt<20>(Regs.getStackPointerBias() + RestoreGPRs.GPROffset)" , "llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp", 1105, __extension__ __PRETTY_FUNCTION__)); | |||
1106 | if (RestoreGPRs.LowGPR == RestoreGPRs.HighGPR) | |||
1107 | // Build an LG/L instruction. | |||
1108 | BuildMI(MBB, MBBI, DL, TII->get(SystemZ::LG), RestoreGPRs.LowGPR) | |||
1109 | .addReg(Regs.getStackPointerRegister()) | |||
1110 | .addImm(Regs.getStackPointerBias() + RestoreGPRs.GPROffset) | |||
1111 | .addReg(0); | |||
1112 | else { | |||
1113 | // Build an LMG/LM instruction. | |||
1114 | MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(SystemZ::LMG)); | |||
1115 | ||||
1116 | // Add the explicit register operands. | |||
1117 | MIB.addReg(RestoreGPRs.LowGPR, RegState::Define); | |||
1118 | MIB.addReg(RestoreGPRs.HighGPR, RegState::Define); | |||
1119 | ||||
1120 | // Add the address. | |||
1121 | MIB.addReg(Regs.getStackPointerRegister()); | |||
1122 | MIB.addImm(Regs.getStackPointerBias() + RestoreGPRs.GPROffset); | |||
1123 | ||||
1124 | // Do a second scan adding regs as being defined by instruction | |||
1125 | for (unsigned I = 0, E = CSI.size(); I != E; ++I) { | |||
1126 | Register Reg = CSI[I].getReg(); | |||
1127 | if (Reg > RestoreGPRs.LowGPR && Reg < RestoreGPRs.HighGPR) | |||
1128 | MIB.addReg(Reg, RegState::ImplicitDefine); | |||
1129 | } | |||
1130 | } | |||
1131 | } | |||
1132 | ||||
1133 | return true; | |||
1134 | } | |||
1135 | ||||
1136 | void SystemZXPLINKFrameLowering::emitPrologue(MachineFunction &MF, | |||
1137 | MachineBasicBlock &MBB) const { | |||
1138 | assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported")(static_cast <bool> (&MF.front() == &MBB && "Shrink-wrapping not yet supported") ? void (0) : __assert_fail ("&MF.front() == &MBB && \"Shrink-wrapping not yet supported\"" , "llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp", 1138, __extension__ __PRETTY_FUNCTION__)); | |||
1139 | const SystemZSubtarget &Subtarget = MF.getSubtarget<SystemZSubtarget>(); | |||
1140 | SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>(); | |||
1141 | MachineBasicBlock::iterator MBBI = MBB.begin(); | |||
1142 | auto *ZII = static_cast<const SystemZInstrInfo *>(Subtarget.getInstrInfo()); | |||
1143 | auto &Regs = Subtarget.getSpecialRegisters<SystemZXPLINK64Registers>(); | |||
1144 | MachineFrameInfo &MFFrame = MF.getFrameInfo(); | |||
1145 | MachineInstr *StoreInstr = nullptr; | |||
1146 | bool HasFP = hasFP(MF); | |||
1147 | // Debug location must be unknown since the first debug location is used | |||
1148 | // to determine the end of the prologue. | |||
1149 | DebugLoc DL; | |||
1150 | uint64_t Offset = 0; | |||
1151 | ||||
1152 | // TODO: Support leaf functions; only add size of save+reserved area when | |||
1153 | // function is non-leaf. | |||
1154 | MFFrame.setStackSize(MFFrame.getStackSize() + Regs.getCallFrameSize()); | |||
1155 | uint64_t StackSize = MFFrame.getStackSize(); | |||
1156 | ||||
1157 | if (ZFI->getSpillGPRRegs().LowGPR) { | |||
1158 | // Skip over the GPR saves. | |||
1159 | if ((MBBI != MBB.end()) && ((MBBI->getOpcode() == SystemZ::STMG))) { | |||
1160 | const int Operand = 3; | |||
1161 | // Now we can set the offset for the operation, since now the Stack | |||
1162 | // has been finalized. | |||
1163 | Offset = Regs.getStackPointerBias() + MBBI->getOperand(Operand).getImm(); | |||
1164 | // Maximum displacement for STMG instruction. | |||
1165 | if (isInt<20>(Offset - StackSize)) | |||
1166 | Offset -= StackSize; | |||
1167 | else | |||
1168 | StoreInstr = &*MBBI; | |||
1169 | MBBI->getOperand(Operand).setImm(Offset); | |||
1170 | ++MBBI; | |||
1171 | } else | |||
1172 | llvm_unreachable("Couldn't skip over GPR saves")::llvm::llvm_unreachable_internal("Couldn't skip over GPR saves" , "llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp", 1172); | |||
1173 | } | |||
1174 | ||||
1175 | if (StackSize) { | |||
1176 | MachineBasicBlock::iterator InsertPt = StoreInstr ? StoreInstr : MBBI; | |||
1177 | // Allocate StackSize bytes. | |||
1178 | int64_t Delta = -int64_t(StackSize); | |||
1179 | ||||
1180 | // In case the STM(G) instruction also stores SP (R4), but the displacement | |||
1181 | // is too large, the SP register is manipulated first before storing, | |||
1182 | // resulting in the wrong value stored and retrieved later. In this case, we | |||
1183 | // need to temporarily save the value of SP, and store it later to memory. | |||
1184 | if (StoreInstr && HasFP) { | |||
1185 | // Insert LR r0,r4 before STMG instruction. | |||
1186 | BuildMI(MBB, InsertPt, DL, ZII->get(SystemZ::LGR)) | |||
1187 | .addReg(SystemZ::R0D, RegState::Define) | |||
1188 | .addReg(SystemZ::R4D); | |||
1189 | // Insert ST r0,xxx(,r4) after STMG instruction. | |||
1190 | BuildMI(MBB, MBBI, DL, ZII->get(SystemZ::STG)) | |||
1191 | .addReg(SystemZ::R0D, RegState::Kill) | |||
1192 | .addReg(SystemZ::R4D) | |||
1193 | .addImm(Offset) | |||
1194 | .addReg(0); | |||
1195 | } | |||
1196 | ||||
1197 | emitIncrement(MBB, InsertPt, DL, Regs.getStackPointerRegister(), Delta, | |||
1198 | ZII); | |||
1199 | ||||
1200 | // If the requested stack size is larger than the guard page, then we need | |||
1201 | // to check if we need to call the stack extender. This requires adding a | |||
1202 | // conditional branch, but splitting the prologue block is not possible at | |||
1203 | // this point since it would invalidate the SaveBlocks / RestoreBlocks sets | |||
1204 | // of PEI in the single block function case. Build a pseudo to be handled | |||
1205 | // later by inlineStackProbe(). | |||
1206 | const uint64_t GuardPageSize = 1024 * 1024; | |||
1207 | if (StackSize > GuardPageSize) { | |||
1208 | assert(StoreInstr && "Wrong insertion point")(static_cast <bool> (StoreInstr && "Wrong insertion point" ) ? void (0) : __assert_fail ("StoreInstr && \"Wrong insertion point\"" , "llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp", 1208, __extension__ __PRETTY_FUNCTION__)); | |||
1209 | BuildMI(MBB, InsertPt, DL, ZII->get(SystemZ::XPLINK_STACKALLOC)); | |||
1210 | } | |||
1211 | } | |||
1212 | ||||
1213 | if (HasFP) { | |||
1214 | // Copy the base of the frame to Frame Pointer Register. | |||
1215 | BuildMI(MBB, MBBI, DL, ZII->get(SystemZ::LGR), | |||
1216 | Regs.getFramePointerRegister()) | |||
1217 | .addReg(Regs.getStackPointerRegister()); | |||
1218 | ||||
1219 | // Mark the FramePtr as live at the beginning of every block except | |||
1220 | // the entry block. (We'll have marked R8 as live on entry when | |||
1221 | // saving the GPRs.) | |||
1222 | for (auto I = std::next(MF.begin()), E = MF.end(); I != E; ++I) | |||
1223 | I->addLiveIn(Regs.getFramePointerRegister()); | |||
1224 | } | |||
1225 | } | |||
1226 | ||||
1227 | void SystemZXPLINKFrameLowering::emitEpilogue(MachineFunction &MF, | |||
1228 | MachineBasicBlock &MBB) const { | |||
1229 | const SystemZSubtarget &Subtarget = MF.getSubtarget<SystemZSubtarget>(); | |||
1230 | MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); | |||
1231 | SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>(); | |||
1232 | MachineFrameInfo &MFFrame = MF.getFrameInfo(); | |||
1233 | auto *ZII = static_cast<const SystemZInstrInfo *>(Subtarget.getInstrInfo()); | |||
1234 | auto &Regs = Subtarget.getSpecialRegisters<SystemZXPLINK64Registers>(); | |||
1235 | ||||
1236 | // Skip the return instruction. | |||
1237 | assert(MBBI->isReturn() && "Can only insert epilogue into returning blocks")(static_cast <bool> (MBBI->isReturn() && "Can only insert epilogue into returning blocks" ) ? void (0) : __assert_fail ("MBBI->isReturn() && \"Can only insert epilogue into returning blocks\"" , "llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp", 1237, __extension__ __PRETTY_FUNCTION__)); | |||
1238 | ||||
1239 | uint64_t StackSize = MFFrame.getStackSize(); | |||
1240 | if (StackSize) { | |||
1241 | unsigned SPReg = Regs.getStackPointerRegister(); | |||
1242 | if (ZFI->getRestoreGPRRegs().LowGPR != SPReg) { | |||
1243 | DebugLoc DL = MBBI->getDebugLoc(); | |||
1244 | emitIncrement(MBB, MBBI, DL, SPReg, StackSize, ZII); | |||
1245 | } | |||
1246 | } | |||
1247 | } | |||
1248 | ||||
1249 | // Emit a compare of the stack pointer against the stack floor, and a call to | |||
1250 | // the LE stack extender if needed. | |||
1251 | void SystemZXPLINKFrameLowering::inlineStackProbe( | |||
1252 | MachineFunction &MF, MachineBasicBlock &PrologMBB) const { | |||
1253 | auto *ZII = | |||
1254 | static_cast<const SystemZInstrInfo *>(MF.getSubtarget().getInstrInfo()); | |||
1255 | ||||
1256 | MachineInstr *StackAllocMI = nullptr; | |||
1257 | for (MachineInstr &MI : PrologMBB) | |||
1258 | if (MI.getOpcode() == SystemZ::XPLINK_STACKALLOC) { | |||
1259 | StackAllocMI = &MI; | |||
1260 | break; | |||
1261 | } | |||
1262 | if (StackAllocMI == nullptr) | |||
1263 | return; | |||
1264 | ||||
1265 | MachineBasicBlock &MBB = PrologMBB; | |||
1266 | const DebugLoc DL = StackAllocMI->getDebugLoc(); | |||
1267 | ||||
1268 | // The 2nd half of block MBB after split. | |||
1269 | MachineBasicBlock *NextMBB; | |||
1270 | ||||
1271 | // Add new basic block for the call to the stack overflow function. | |||
1272 | MachineBasicBlock *StackExtMBB = | |||
1273 | MF.CreateMachineBasicBlock(MBB.getBasicBlock()); | |||
1274 | MF.push_back(StackExtMBB); | |||
1275 | ||||
1276 | // LG r3,72(,r3) | |||
1277 | BuildMI(StackExtMBB, DL, ZII->get(SystemZ::LG), SystemZ::R3D) | |||
1278 | .addReg(SystemZ::R3D) | |||
1279 | .addImm(72) | |||
1280 | .addReg(0); | |||
1281 | // BASR r3,r3 | |||
1282 | BuildMI(StackExtMBB, DL, ZII->get(SystemZ::CallBASR_STACKEXT)) | |||
1283 | .addReg(SystemZ::R3D); | |||
1284 | ||||
1285 | // LLGT r3,1208 | |||
1286 | BuildMI(MBB, StackAllocMI, DL, ZII->get(SystemZ::LLGT), SystemZ::R3D) | |||
1287 | .addReg(0) | |||
1288 | .addImm(1208) | |||
1289 | .addReg(0); | |||
1290 | // CG r4,64(,r3) | |||
1291 | BuildMI(MBB, StackAllocMI, DL, ZII->get(SystemZ::CG)) | |||
1292 | .addReg(SystemZ::R4D) | |||
1293 | .addReg(SystemZ::R3D) | |||
1294 | .addImm(64) | |||
1295 | .addReg(0); | |||
1296 | // JLL b'0100',F'37' | |||
1297 | BuildMI(MBB, StackAllocMI, DL, ZII->get(SystemZ::BRC)) | |||
1298 | .addImm(SystemZ::CCMASK_ICMP) | |||
1299 | .addImm(SystemZ::CCMASK_CMP_LT) | |||
1300 | .addMBB(StackExtMBB); | |||
1301 | ||||
1302 | NextMBB = SystemZ::splitBlockBefore(StackAllocMI, &MBB); | |||
1303 | MBB.addSuccessor(NextMBB); | |||
1304 | MBB.addSuccessor(StackExtMBB); | |||
1305 | ||||
1306 | // Add jump back from stack extension BB. | |||
1307 | BuildMI(StackExtMBB, DL, ZII->get(SystemZ::J)).addMBB(NextMBB); | |||
1308 | StackExtMBB->addSuccessor(NextMBB); | |||
1309 | ||||
1310 | StackAllocMI->eraseFromParent(); | |||
1311 | ||||
1312 | // Compute the live-in lists for the new blocks. | |||
1313 | recomputeLiveIns(*NextMBB); | |||
1314 | recomputeLiveIns(*StackExtMBB); | |||
1315 | } | |||
1316 | ||||
1317 | bool SystemZXPLINKFrameLowering::hasFP(const MachineFunction &MF) const { | |||
1318 | return (MF.getFrameInfo().hasVarSizedObjects()); | |||
1319 | } | |||
1320 | ||||
1321 | void SystemZXPLINKFrameLowering::processFunctionBeforeFrameFinalized( | |||
1322 | MachineFunction &MF, RegScavenger *RS) const { | |||
1323 | MachineFrameInfo &MFFrame = MF.getFrameInfo(); | |||
1324 | const SystemZSubtarget &Subtarget = MF.getSubtarget<SystemZSubtarget>(); | |||
1325 | auto &Regs = Subtarget.getSpecialRegisters<SystemZXPLINK64Registers>(); | |||
1326 | ||||
1327 | // Setup stack frame offset | |||
1328 | MFFrame.setOffsetAdjustment(Regs.getStackPointerBias()); | |||
1329 | } |