Bug Summary

File:llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
Warning:line 855, column 13
Called C++ object pointer is uninitialized

Annotated Source Code

Press '?' to see keyboard shortcuts

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