File: | build/source/llvm/include/llvm/Analysis/ObjCARCUtil.h |
Warning: | line 44, column 12 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===--- AArch64CallLowering.cpp - Call lowering --------------------------===// | ||||
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 | /// \file | ||||
10 | /// This file implements the lowering of LLVM calls to machine code calls for | ||||
11 | /// GlobalISel. | ||||
12 | /// | ||||
13 | //===----------------------------------------------------------------------===// | ||||
14 | |||||
15 | #include "AArch64CallLowering.h" | ||||
16 | #include "AArch64ISelLowering.h" | ||||
17 | #include "AArch64MachineFunctionInfo.h" | ||||
18 | #include "AArch64Subtarget.h" | ||||
19 | #include "llvm/ADT/ArrayRef.h" | ||||
20 | #include "llvm/ADT/SmallVector.h" | ||||
21 | #include "llvm/Analysis/ObjCARCUtil.h" | ||||
22 | #include "llvm/CodeGen/Analysis.h" | ||||
23 | #include "llvm/CodeGen/CallingConvLower.h" | ||||
24 | #include "llvm/CodeGen/FunctionLoweringInfo.h" | ||||
25 | #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" | ||||
26 | #include "llvm/CodeGen/GlobalISel/Utils.h" | ||||
27 | #include "llvm/CodeGen/LowLevelType.h" | ||||
28 | #include "llvm/CodeGen/MachineBasicBlock.h" | ||||
29 | #include "llvm/CodeGen/MachineFrameInfo.h" | ||||
30 | #include "llvm/CodeGen/MachineFunction.h" | ||||
31 | #include "llvm/CodeGen/MachineInstrBuilder.h" | ||||
32 | #include "llvm/CodeGen/MachineMemOperand.h" | ||||
33 | #include "llvm/CodeGen/MachineOperand.h" | ||||
34 | #include "llvm/CodeGen/MachineRegisterInfo.h" | ||||
35 | #include "llvm/CodeGen/TargetRegisterInfo.h" | ||||
36 | #include "llvm/CodeGen/TargetSubtargetInfo.h" | ||||
37 | #include "llvm/CodeGen/ValueTypes.h" | ||||
38 | #include "llvm/IR/Argument.h" | ||||
39 | #include "llvm/IR/Attributes.h" | ||||
40 | #include "llvm/IR/Function.h" | ||||
41 | #include "llvm/IR/Type.h" | ||||
42 | #include "llvm/IR/Value.h" | ||||
43 | #include "llvm/Support/MachineValueType.h" | ||||
44 | #include <algorithm> | ||||
45 | #include <cassert> | ||||
46 | #include <cstdint> | ||||
47 | #include <iterator> | ||||
48 | |||||
49 | #define DEBUG_TYPE"aarch64-call-lowering" "aarch64-call-lowering" | ||||
50 | |||||
51 | using namespace llvm; | ||||
52 | |||||
53 | AArch64CallLowering::AArch64CallLowering(const AArch64TargetLowering &TLI) | ||||
54 | : CallLowering(&TLI) {} | ||||
55 | |||||
56 | static void applyStackPassedSmallTypeDAGHack(EVT OrigVT, MVT &ValVT, | ||||
57 | MVT &LocVT) { | ||||
58 | // If ValVT is i1/i8/i16, we should set LocVT to i8/i8/i16. This is a legacy | ||||
59 | // hack because the DAG calls the assignment function with pre-legalized | ||||
60 | // register typed values, not the raw type. | ||||
61 | // | ||||
62 | // This hack is not applied to return values which are not passed on the | ||||
63 | // stack. | ||||
64 | if (OrigVT == MVT::i1 || OrigVT == MVT::i8) | ||||
65 | ValVT = LocVT = MVT::i8; | ||||
66 | else if (OrigVT == MVT::i16) | ||||
67 | ValVT = LocVT = MVT::i16; | ||||
68 | } | ||||
69 | |||||
70 | // Account for i1/i8/i16 stack passed value hack | ||||
71 | static LLT getStackValueStoreTypeHack(const CCValAssign &VA) { | ||||
72 | const MVT ValVT = VA.getValVT(); | ||||
73 | return (ValVT == MVT::i8 || ValVT == MVT::i16) ? LLT(ValVT) | ||||
74 | : LLT(VA.getLocVT()); | ||||
75 | } | ||||
76 | |||||
77 | namespace { | ||||
78 | |||||
79 | struct AArch64IncomingValueAssigner | ||||
80 | : public CallLowering::IncomingValueAssigner { | ||||
81 | AArch64IncomingValueAssigner(CCAssignFn *AssignFn_, | ||||
82 | CCAssignFn *AssignFnVarArg_) | ||||
83 | : IncomingValueAssigner(AssignFn_, AssignFnVarArg_) {} | ||||
84 | |||||
85 | bool assignArg(unsigned ValNo, EVT OrigVT, MVT ValVT, MVT LocVT, | ||||
86 | CCValAssign::LocInfo LocInfo, | ||||
87 | const CallLowering::ArgInfo &Info, ISD::ArgFlagsTy Flags, | ||||
88 | CCState &State) override { | ||||
89 | applyStackPassedSmallTypeDAGHack(OrigVT, ValVT, LocVT); | ||||
90 | return IncomingValueAssigner::assignArg(ValNo, OrigVT, ValVT, LocVT, | ||||
91 | LocInfo, Info, Flags, State); | ||||
92 | } | ||||
93 | }; | ||||
94 | |||||
95 | struct AArch64OutgoingValueAssigner | ||||
96 | : public CallLowering::OutgoingValueAssigner { | ||||
97 | const AArch64Subtarget &Subtarget; | ||||
98 | |||||
99 | /// Track if this is used for a return instead of function argument | ||||
100 | /// passing. We apply a hack to i1/i8/i16 stack passed values, but do not use | ||||
101 | /// stack passed returns for them and cannot apply the type adjustment. | ||||
102 | bool IsReturn; | ||||
103 | |||||
104 | AArch64OutgoingValueAssigner(CCAssignFn *AssignFn_, | ||||
105 | CCAssignFn *AssignFnVarArg_, | ||||
106 | const AArch64Subtarget &Subtarget_, | ||||
107 | bool IsReturn) | ||||
108 | : OutgoingValueAssigner(AssignFn_, AssignFnVarArg_), | ||||
109 | Subtarget(Subtarget_), IsReturn(IsReturn) {} | ||||
110 | |||||
111 | bool assignArg(unsigned ValNo, EVT OrigVT, MVT ValVT, MVT LocVT, | ||||
112 | CCValAssign::LocInfo LocInfo, | ||||
113 | const CallLowering::ArgInfo &Info, ISD::ArgFlagsTy Flags, | ||||
114 | CCState &State) override { | ||||
115 | bool IsCalleeWin = Subtarget.isCallingConvWin64(State.getCallingConv()); | ||||
116 | bool UseVarArgsCCForFixed = IsCalleeWin && State.isVarArg(); | ||||
117 | |||||
118 | if (!State.isVarArg() && !UseVarArgsCCForFixed && !IsReturn) | ||||
119 | applyStackPassedSmallTypeDAGHack(OrigVT, ValVT, LocVT); | ||||
120 | |||||
121 | bool Res; | ||||
122 | if (Info.IsFixed && !UseVarArgsCCForFixed) | ||||
123 | Res = AssignFn(ValNo, ValVT, LocVT, LocInfo, Flags, State); | ||||
124 | else | ||||
125 | Res = AssignFnVarArg(ValNo, ValVT, LocVT, LocInfo, Flags, State); | ||||
126 | |||||
127 | StackOffset = State.getNextStackOffset(); | ||||
128 | return Res; | ||||
129 | } | ||||
130 | }; | ||||
131 | |||||
132 | struct IncomingArgHandler : public CallLowering::IncomingValueHandler { | ||||
133 | IncomingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI) | ||||
134 | : IncomingValueHandler(MIRBuilder, MRI) {} | ||||
135 | |||||
136 | Register getStackAddress(uint64_t Size, int64_t Offset, | ||||
137 | MachinePointerInfo &MPO, | ||||
138 | ISD::ArgFlagsTy Flags) override { | ||||
139 | auto &MFI = MIRBuilder.getMF().getFrameInfo(); | ||||
140 | |||||
141 | // Byval is assumed to be writable memory, but other stack passed arguments | ||||
142 | // are not. | ||||
143 | const bool IsImmutable = !Flags.isByVal(); | ||||
144 | |||||
145 | int FI = MFI.CreateFixedObject(Size, Offset, IsImmutable); | ||||
146 | MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI); | ||||
147 | auto AddrReg = MIRBuilder.buildFrameIndex(LLT::pointer(0, 64), FI); | ||||
148 | return AddrReg.getReg(0); | ||||
149 | } | ||||
150 | |||||
151 | LLT getStackValueStoreType(const DataLayout &DL, const CCValAssign &VA, | ||||
152 | ISD::ArgFlagsTy Flags) const override { | ||||
153 | // For pointers, we just need to fixup the integer types reported in the | ||||
154 | // CCValAssign. | ||||
155 | if (Flags.isPointer()) | ||||
156 | return CallLowering::ValueHandler::getStackValueStoreType(DL, VA, Flags); | ||||
157 | return getStackValueStoreTypeHack(VA); | ||||
158 | } | ||||
159 | |||||
160 | void assignValueToReg(Register ValVReg, Register PhysReg, | ||||
161 | CCValAssign VA) override { | ||||
162 | markPhysRegUsed(PhysReg); | ||||
163 | IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA); | ||||
164 | } | ||||
165 | |||||
166 | void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy, | ||||
167 | MachinePointerInfo &MPO, CCValAssign &VA) override { | ||||
168 | MachineFunction &MF = MIRBuilder.getMF(); | ||||
169 | |||||
170 | LLT ValTy(VA.getValVT()); | ||||
171 | LLT LocTy(VA.getLocVT()); | ||||
172 | |||||
173 | // Fixup the types for the DAG compatibility hack. | ||||
174 | if (VA.getValVT() == MVT::i8 || VA.getValVT() == MVT::i16) | ||||
175 | std::swap(ValTy, LocTy); | ||||
176 | else { | ||||
177 | // The calling code knows if this is a pointer or not, we're only touching | ||||
178 | // the LocTy for the i8/i16 hack. | ||||
179 | assert(LocTy.getSizeInBits() == MemTy.getSizeInBits())(static_cast <bool> (LocTy.getSizeInBits() == MemTy.getSizeInBits ()) ? void (0) : __assert_fail ("LocTy.getSizeInBits() == MemTy.getSizeInBits()" , "llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp", 179 , __extension__ __PRETTY_FUNCTION__)); | ||||
180 | LocTy = MemTy; | ||||
181 | } | ||||
182 | |||||
183 | auto MMO = MF.getMachineMemOperand( | ||||
184 | MPO, MachineMemOperand::MOLoad | MachineMemOperand::MOInvariant, LocTy, | ||||
185 | inferAlignFromPtrInfo(MF, MPO)); | ||||
186 | |||||
187 | switch (VA.getLocInfo()) { | ||||
188 | case CCValAssign::LocInfo::ZExt: | ||||
189 | MIRBuilder.buildLoadInstr(TargetOpcode::G_ZEXTLOAD, ValVReg, Addr, *MMO); | ||||
190 | return; | ||||
191 | case CCValAssign::LocInfo::SExt: | ||||
192 | MIRBuilder.buildLoadInstr(TargetOpcode::G_SEXTLOAD, ValVReg, Addr, *MMO); | ||||
193 | return; | ||||
194 | default: | ||||
195 | MIRBuilder.buildLoad(ValVReg, Addr, *MMO); | ||||
196 | return; | ||||
197 | } | ||||
198 | } | ||||
199 | |||||
200 | /// How the physical register gets marked varies between formal | ||||
201 | /// parameters (it's a basic-block live-in), and a call instruction | ||||
202 | /// (it's an implicit-def of the BL). | ||||
203 | virtual void markPhysRegUsed(MCRegister PhysReg) = 0; | ||||
204 | }; | ||||
205 | |||||
206 | struct FormalArgHandler : public IncomingArgHandler { | ||||
207 | FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI) | ||||
208 | : IncomingArgHandler(MIRBuilder, MRI) {} | ||||
209 | |||||
210 | void markPhysRegUsed(MCRegister PhysReg) override { | ||||
211 | MIRBuilder.getMRI()->addLiveIn(PhysReg); | ||||
212 | MIRBuilder.getMBB().addLiveIn(PhysReg); | ||||
213 | } | ||||
214 | }; | ||||
215 | |||||
216 | struct CallReturnHandler : public IncomingArgHandler { | ||||
217 | CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, | ||||
218 | MachineInstrBuilder MIB) | ||||
219 | : IncomingArgHandler(MIRBuilder, MRI), MIB(MIB) {} | ||||
220 | |||||
221 | void markPhysRegUsed(MCRegister PhysReg) override { | ||||
222 | MIB.addDef(PhysReg, RegState::Implicit); | ||||
223 | } | ||||
224 | |||||
225 | MachineInstrBuilder MIB; | ||||
226 | }; | ||||
227 | |||||
228 | /// A special return arg handler for "returned" attribute arg calls. | ||||
229 | struct ReturnedArgCallReturnHandler : public CallReturnHandler { | ||||
230 | ReturnedArgCallReturnHandler(MachineIRBuilder &MIRBuilder, | ||||
231 | MachineRegisterInfo &MRI, | ||||
232 | MachineInstrBuilder MIB) | ||||
233 | : CallReturnHandler(MIRBuilder, MRI, MIB) {} | ||||
234 | |||||
235 | void markPhysRegUsed(MCRegister PhysReg) override {} | ||||
236 | }; | ||||
237 | |||||
238 | struct OutgoingArgHandler : public CallLowering::OutgoingValueHandler { | ||||
239 | OutgoingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, | ||||
240 | MachineInstrBuilder MIB, bool IsTailCall = false, | ||||
241 | int FPDiff = 0) | ||||
242 | : OutgoingValueHandler(MIRBuilder, MRI), MIB(MIB), IsTailCall(IsTailCall), | ||||
243 | FPDiff(FPDiff), | ||||
244 | Subtarget(MIRBuilder.getMF().getSubtarget<AArch64Subtarget>()) {} | ||||
245 | |||||
246 | Register getStackAddress(uint64_t Size, int64_t Offset, | ||||
247 | MachinePointerInfo &MPO, | ||||
248 | ISD::ArgFlagsTy Flags) override { | ||||
249 | MachineFunction &MF = MIRBuilder.getMF(); | ||||
250 | LLT p0 = LLT::pointer(0, 64); | ||||
251 | LLT s64 = LLT::scalar(64); | ||||
252 | |||||
253 | if (IsTailCall) { | ||||
254 | assert(!Flags.isByVal() && "byval unhandled with tail calls")(static_cast <bool> (!Flags.isByVal() && "byval unhandled with tail calls" ) ? void (0) : __assert_fail ("!Flags.isByVal() && \"byval unhandled with tail calls\"" , "llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp", 254 , __extension__ __PRETTY_FUNCTION__)); | ||||
255 | |||||
256 | Offset += FPDiff; | ||||
257 | int FI = MF.getFrameInfo().CreateFixedObject(Size, Offset, true); | ||||
258 | auto FIReg = MIRBuilder.buildFrameIndex(p0, FI); | ||||
259 | MPO = MachinePointerInfo::getFixedStack(MF, FI); | ||||
260 | return FIReg.getReg(0); | ||||
261 | } | ||||
262 | |||||
263 | if (!SPReg) | ||||
264 | SPReg = MIRBuilder.buildCopy(p0, Register(AArch64::SP)).getReg(0); | ||||
265 | |||||
266 | auto OffsetReg = MIRBuilder.buildConstant(s64, Offset); | ||||
267 | |||||
268 | auto AddrReg = MIRBuilder.buildPtrAdd(p0, SPReg, OffsetReg); | ||||
269 | |||||
270 | MPO = MachinePointerInfo::getStack(MF, Offset); | ||||
271 | return AddrReg.getReg(0); | ||||
272 | } | ||||
273 | |||||
274 | /// We need to fixup the reported store size for certain value types because | ||||
275 | /// we invert the interpretation of ValVT and LocVT in certain cases. This is | ||||
276 | /// for compatability with the DAG call lowering implementation, which we're | ||||
277 | /// currently building on top of. | ||||
278 | LLT getStackValueStoreType(const DataLayout &DL, const CCValAssign &VA, | ||||
279 | ISD::ArgFlagsTy Flags) const override { | ||||
280 | if (Flags.isPointer()) | ||||
281 | return CallLowering::ValueHandler::getStackValueStoreType(DL, VA, Flags); | ||||
282 | return getStackValueStoreTypeHack(VA); | ||||
283 | } | ||||
284 | |||||
285 | void assignValueToReg(Register ValVReg, Register PhysReg, | ||||
286 | CCValAssign VA) override { | ||||
287 | MIB.addUse(PhysReg, RegState::Implicit); | ||||
288 | Register ExtReg = extendRegister(ValVReg, VA); | ||||
289 | MIRBuilder.buildCopy(PhysReg, ExtReg); | ||||
290 | } | ||||
291 | |||||
292 | void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy, | ||||
293 | MachinePointerInfo &MPO, CCValAssign &VA) override { | ||||
294 | MachineFunction &MF = MIRBuilder.getMF(); | ||||
295 | auto MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOStore, MemTy, | ||||
296 | inferAlignFromPtrInfo(MF, MPO)); | ||||
297 | MIRBuilder.buildStore(ValVReg, Addr, *MMO); | ||||
298 | } | ||||
299 | |||||
300 | void assignValueToAddress(const CallLowering::ArgInfo &Arg, unsigned RegIndex, | ||||
301 | Register Addr, LLT MemTy, MachinePointerInfo &MPO, | ||||
302 | CCValAssign &VA) override { | ||||
303 | unsigned MaxSize = MemTy.getSizeInBytes() * 8; | ||||
304 | // For varargs, we always want to extend them to 8 bytes, in which case | ||||
305 | // we disable setting a max. | ||||
306 | if (!Arg.IsFixed) | ||||
307 | MaxSize = 0; | ||||
308 | |||||
309 | Register ValVReg = Arg.Regs[RegIndex]; | ||||
310 | if (VA.getLocInfo() != CCValAssign::LocInfo::FPExt) { | ||||
311 | MVT LocVT = VA.getLocVT(); | ||||
312 | MVT ValVT = VA.getValVT(); | ||||
313 | |||||
314 | if (VA.getValVT() == MVT::i8 || VA.getValVT() == MVT::i16) { | ||||
315 | std::swap(ValVT, LocVT); | ||||
316 | MemTy = LLT(VA.getValVT()); | ||||
317 | } | ||||
318 | |||||
319 | ValVReg = extendRegister(ValVReg, VA, MaxSize); | ||||
320 | } else { | ||||
321 | // The store does not cover the full allocated stack slot. | ||||
322 | MemTy = LLT(VA.getValVT()); | ||||
323 | } | ||||
324 | |||||
325 | assignValueToAddress(ValVReg, Addr, MemTy, MPO, VA); | ||||
326 | } | ||||
327 | |||||
328 | MachineInstrBuilder MIB; | ||||
329 | |||||
330 | bool IsTailCall; | ||||
331 | |||||
332 | /// For tail calls, the byte offset of the call's argument area from the | ||||
333 | /// callee's. Unused elsewhere. | ||||
334 | int FPDiff; | ||||
335 | |||||
336 | // Cache the SP register vreg if we need it more than once in this call site. | ||||
337 | Register SPReg; | ||||
338 | |||||
339 | const AArch64Subtarget &Subtarget; | ||||
340 | }; | ||||
341 | } // namespace | ||||
342 | |||||
343 | static bool doesCalleeRestoreStack(CallingConv::ID CallConv, bool TailCallOpt) { | ||||
344 | return (CallConv == CallingConv::Fast && TailCallOpt) || | ||||
345 | CallConv == CallingConv::Tail || CallConv == CallingConv::SwiftTail; | ||||
346 | } | ||||
347 | |||||
348 | bool AArch64CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, | ||||
349 | const Value *Val, | ||||
350 | ArrayRef<Register> VRegs, | ||||
351 | FunctionLoweringInfo &FLI, | ||||
352 | Register SwiftErrorVReg) const { | ||||
353 | auto MIB = MIRBuilder.buildInstrNoInsert(AArch64::RET_ReallyLR); | ||||
354 | assert(((Val && !VRegs.empty()) || (!Val && VRegs.empty())) &&(static_cast <bool> (((Val && !VRegs.empty()) || (!Val && VRegs.empty())) && "Return value without a vreg" ) ? void (0) : __assert_fail ("((Val && !VRegs.empty()) || (!Val && VRegs.empty())) && \"Return value without a vreg\"" , "llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp", 355 , __extension__ __PRETTY_FUNCTION__)) | ||||
355 | "Return value without a vreg")(static_cast <bool> (((Val && !VRegs.empty()) || (!Val && VRegs.empty())) && "Return value without a vreg" ) ? void (0) : __assert_fail ("((Val && !VRegs.empty()) || (!Val && VRegs.empty())) && \"Return value without a vreg\"" , "llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp", 355 , __extension__ __PRETTY_FUNCTION__)); | ||||
356 | |||||
357 | bool Success = true; | ||||
358 | if (!FLI.CanLowerReturn) { | ||||
359 | insertSRetStores(MIRBuilder, Val->getType(), VRegs, FLI.DemoteRegister); | ||||
360 | } else if (!VRegs.empty()) { | ||||
361 | MachineFunction &MF = MIRBuilder.getMF(); | ||||
362 | const Function &F = MF.getFunction(); | ||||
363 | const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>(); | ||||
364 | |||||
365 | MachineRegisterInfo &MRI = MF.getRegInfo(); | ||||
366 | const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>(); | ||||
367 | CCAssignFn *AssignFn = TLI.CCAssignFnForReturn(F.getCallingConv()); | ||||
368 | auto &DL = F.getParent()->getDataLayout(); | ||||
369 | LLVMContext &Ctx = Val->getType()->getContext(); | ||||
370 | |||||
371 | SmallVector<EVT, 4> SplitEVTs; | ||||
372 | ComputeValueVTs(TLI, DL, Val->getType(), SplitEVTs); | ||||
373 | assert(VRegs.size() == SplitEVTs.size() &&(static_cast <bool> (VRegs.size() == SplitEVTs.size() && "For each split Type there should be exactly one VReg.") ? void (0) : __assert_fail ("VRegs.size() == SplitEVTs.size() && \"For each split Type there should be exactly one VReg.\"" , "llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp", 374 , __extension__ __PRETTY_FUNCTION__)) | ||||
374 | "For each split Type there should be exactly one VReg.")(static_cast <bool> (VRegs.size() == SplitEVTs.size() && "For each split Type there should be exactly one VReg.") ? void (0) : __assert_fail ("VRegs.size() == SplitEVTs.size() && \"For each split Type there should be exactly one VReg.\"" , "llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp", 374 , __extension__ __PRETTY_FUNCTION__)); | ||||
375 | |||||
376 | SmallVector<ArgInfo, 8> SplitArgs; | ||||
377 | CallingConv::ID CC = F.getCallingConv(); | ||||
378 | |||||
379 | for (unsigned i = 0; i < SplitEVTs.size(); ++i) { | ||||
380 | Register CurVReg = VRegs[i]; | ||||
381 | ArgInfo CurArgInfo = ArgInfo{CurVReg, SplitEVTs[i].getTypeForEVT(Ctx), 0}; | ||||
382 | setArgFlags(CurArgInfo, AttributeList::ReturnIndex, DL, F); | ||||
383 | |||||
384 | // i1 is a special case because SDAG i1 true is naturally zero extended | ||||
385 | // when widened using ANYEXT. We need to do it explicitly here. | ||||
386 | auto &Flags = CurArgInfo.Flags[0]; | ||||
387 | if (MRI.getType(CurVReg).getSizeInBits() == 1 && !Flags.isSExt() && | ||||
388 | !Flags.isZExt()) { | ||||
389 | CurVReg = MIRBuilder.buildZExt(LLT::scalar(8), CurVReg).getReg(0); | ||||
390 | } else if (TLI.getNumRegistersForCallingConv(Ctx, CC, SplitEVTs[i]) == | ||||
391 | 1) { | ||||
392 | // Some types will need extending as specified by the CC. | ||||
393 | MVT NewVT = TLI.getRegisterTypeForCallingConv(Ctx, CC, SplitEVTs[i]); | ||||
394 | if (EVT(NewVT) != SplitEVTs[i]) { | ||||
395 | unsigned ExtendOp = TargetOpcode::G_ANYEXT; | ||||
396 | if (F.getAttributes().hasRetAttr(Attribute::SExt)) | ||||
397 | ExtendOp = TargetOpcode::G_SEXT; | ||||
398 | else if (F.getAttributes().hasRetAttr(Attribute::ZExt)) | ||||
399 | ExtendOp = TargetOpcode::G_ZEXT; | ||||
400 | |||||
401 | LLT NewLLT(NewVT); | ||||
402 | LLT OldLLT(MVT::getVT(CurArgInfo.Ty)); | ||||
403 | CurArgInfo.Ty = EVT(NewVT).getTypeForEVT(Ctx); | ||||
404 | // Instead of an extend, we might have a vector type which needs | ||||
405 | // padding with more elements, e.g. <2 x half> -> <4 x half>. | ||||
406 | if (NewVT.isVector()) { | ||||
407 | if (OldLLT.isVector()) { | ||||
408 | if (NewLLT.getNumElements() > OldLLT.getNumElements()) { | ||||
409 | // We don't handle VA types which are not exactly twice the | ||||
410 | // size, but can easily be done in future. | ||||
411 | if (NewLLT.getNumElements() != OldLLT.getNumElements() * 2) { | ||||
412 | LLVM_DEBUG(dbgs() << "Outgoing vector ret has too many elts")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("aarch64-call-lowering")) { dbgs() << "Outgoing vector ret has too many elts" ; } } while (false); | ||||
413 | return false; | ||||
414 | } | ||||
415 | auto Undef = MIRBuilder.buildUndef({OldLLT}); | ||||
416 | CurVReg = | ||||
417 | MIRBuilder.buildMerge({NewLLT}, {CurVReg, Undef}).getReg(0); | ||||
418 | } else { | ||||
419 | // Just do a vector extend. | ||||
420 | CurVReg = MIRBuilder.buildInstr(ExtendOp, {NewLLT}, {CurVReg}) | ||||
421 | .getReg(0); | ||||
422 | } | ||||
423 | } else if (NewLLT.getNumElements() == 2) { | ||||
424 | // We need to pad a <1 x S> type to <2 x S>. Since we don't have | ||||
425 | // <1 x S> vector types in GISel we use a build_vector instead | ||||
426 | // of a vector merge/concat. | ||||
427 | auto Undef = MIRBuilder.buildUndef({OldLLT}); | ||||
428 | CurVReg = | ||||
429 | MIRBuilder | ||||
430 | .buildBuildVector({NewLLT}, {CurVReg, Undef.getReg(0)}) | ||||
431 | .getReg(0); | ||||
432 | } else { | ||||
433 | LLVM_DEBUG(dbgs() << "Could not handle ret ty\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("aarch64-call-lowering")) { dbgs() << "Could not handle ret ty\n" ; } } while (false); | ||||
434 | return false; | ||||
435 | } | ||||
436 | } else { | ||||
437 | // If the split EVT was a <1 x T> vector, and NewVT is T, then we | ||||
438 | // don't have to do anything since we don't distinguish between the | ||||
439 | // two. | ||||
440 | if (NewLLT != MRI.getType(CurVReg)) { | ||||
441 | // A scalar extend. | ||||
442 | CurVReg = MIRBuilder.buildInstr(ExtendOp, {NewLLT}, {CurVReg}) | ||||
443 | .getReg(0); | ||||
444 | } | ||||
445 | } | ||||
446 | } | ||||
447 | } | ||||
448 | if (CurVReg != CurArgInfo.Regs[0]) { | ||||
449 | CurArgInfo.Regs[0] = CurVReg; | ||||
450 | // Reset the arg flags after modifying CurVReg. | ||||
451 | setArgFlags(CurArgInfo, AttributeList::ReturnIndex, DL, F); | ||||
452 | } | ||||
453 | splitToValueTypes(CurArgInfo, SplitArgs, DL, CC); | ||||
454 | } | ||||
455 | |||||
456 | AArch64OutgoingValueAssigner Assigner(AssignFn, AssignFn, Subtarget, | ||||
457 | /*IsReturn*/ true); | ||||
458 | OutgoingArgHandler Handler(MIRBuilder, MRI, MIB); | ||||
459 | Success = determineAndHandleAssignments(Handler, Assigner, SplitArgs, | ||||
460 | MIRBuilder, CC, F.isVarArg()); | ||||
461 | } | ||||
462 | |||||
463 | if (SwiftErrorVReg) { | ||||
464 | MIB.addUse(AArch64::X21, RegState::Implicit); | ||||
465 | MIRBuilder.buildCopy(AArch64::X21, SwiftErrorVReg); | ||||
466 | } | ||||
467 | |||||
468 | MIRBuilder.insertInstr(MIB); | ||||
469 | return Success; | ||||
470 | } | ||||
471 | |||||
472 | bool AArch64CallLowering::canLowerReturn(MachineFunction &MF, | ||||
473 | CallingConv::ID CallConv, | ||||
474 | SmallVectorImpl<BaseArgInfo> &Outs, | ||||
475 | bool IsVarArg) const { | ||||
476 | SmallVector<CCValAssign, 16> ArgLocs; | ||||
477 | const auto &TLI = *getTLI<AArch64TargetLowering>(); | ||||
478 | CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, | ||||
479 | MF.getFunction().getContext()); | ||||
480 | |||||
481 | return checkReturn(CCInfo, Outs, TLI.CCAssignFnForReturn(CallConv)); | ||||
482 | } | ||||
483 | |||||
484 | /// Helper function to compute forwarded registers for musttail calls. Computes | ||||
485 | /// the forwarded registers, sets MBB liveness, and emits COPY instructions that | ||||
486 | /// can be used to save + restore registers later. | ||||
487 | static void handleMustTailForwardedRegisters(MachineIRBuilder &MIRBuilder, | ||||
488 | CCAssignFn *AssignFn) { | ||||
489 | MachineBasicBlock &MBB = MIRBuilder.getMBB(); | ||||
490 | MachineFunction &MF = MIRBuilder.getMF(); | ||||
491 | MachineFrameInfo &MFI = MF.getFrameInfo(); | ||||
492 | |||||
493 | if (!MFI.hasMustTailInVarArgFunc()) | ||||
494 | return; | ||||
495 | |||||
496 | AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>(); | ||||
497 | const Function &F = MF.getFunction(); | ||||
498 | assert(F.isVarArg() && "Expected F to be vararg?")(static_cast <bool> (F.isVarArg() && "Expected F to be vararg?" ) ? void (0) : __assert_fail ("F.isVarArg() && \"Expected F to be vararg?\"" , "llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp", 498 , __extension__ __PRETTY_FUNCTION__)); | ||||
499 | |||||
500 | // Compute the set of forwarded registers. The rest are scratch. | ||||
501 | SmallVector<CCValAssign, 16> ArgLocs; | ||||
502 | CCState CCInfo(F.getCallingConv(), /*IsVarArg=*/true, MF, ArgLocs, | ||||
503 | F.getContext()); | ||||
504 | SmallVector<MVT, 2> RegParmTypes; | ||||
505 | RegParmTypes.push_back(MVT::i64); | ||||
506 | RegParmTypes.push_back(MVT::f128); | ||||
507 | |||||
508 | // Later on, we can use this vector to restore the registers if necessary. | ||||
509 | SmallVectorImpl<ForwardedRegister> &Forwards = | ||||
510 | FuncInfo->getForwardedMustTailRegParms(); | ||||
511 | CCInfo.analyzeMustTailForwardedRegisters(Forwards, RegParmTypes, AssignFn); | ||||
512 | |||||
513 | // Conservatively forward X8, since it might be used for an aggregate | ||||
514 | // return. | ||||
515 | if (!CCInfo.isAllocated(AArch64::X8)) { | ||||
516 | Register X8VReg = MF.addLiveIn(AArch64::X8, &AArch64::GPR64RegClass); | ||||
517 | Forwards.push_back(ForwardedRegister(X8VReg, AArch64::X8, MVT::i64)); | ||||
518 | } | ||||
519 | |||||
520 | // Add the forwards to the MachineBasicBlock and MachineFunction. | ||||
521 | for (const auto &F : Forwards) { | ||||
522 | MBB.addLiveIn(F.PReg); | ||||
523 | MIRBuilder.buildCopy(Register(F.VReg), Register(F.PReg)); | ||||
524 | } | ||||
525 | } | ||||
526 | |||||
527 | bool AArch64CallLowering::fallBackToDAGISel(const MachineFunction &MF) const { | ||||
528 | auto &F = MF.getFunction(); | ||||
529 | if (isa<ScalableVectorType>(F.getReturnType())) | ||||
530 | return true; | ||||
531 | if (llvm::any_of(F.args(), [](const Argument &A) { | ||||
532 | return isa<ScalableVectorType>(A.getType()); | ||||
533 | })) | ||||
534 | return true; | ||||
535 | const auto &ST = MF.getSubtarget<AArch64Subtarget>(); | ||||
536 | if (!ST.hasNEON() || !ST.hasFPARMv8()) { | ||||
537 | LLVM_DEBUG(dbgs() << "Falling back to SDAG because we don't support no-NEON\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("aarch64-call-lowering")) { dbgs() << "Falling back to SDAG because we don't support no-NEON\n" ; } } while (false); | ||||
538 | return true; | ||||
539 | } | ||||
540 | |||||
541 | SMEAttrs Attrs(F); | ||||
542 | if (Attrs.hasNewZAInterface() || | ||||
543 | (!Attrs.hasStreamingInterface() && Attrs.hasStreamingBody())) | ||||
544 | return true; | ||||
545 | |||||
546 | return false; | ||||
547 | } | ||||
548 | |||||
549 | bool AArch64CallLowering::lowerFormalArguments( | ||||
550 | MachineIRBuilder &MIRBuilder, const Function &F, | ||||
551 | ArrayRef<ArrayRef<Register>> VRegs, FunctionLoweringInfo &FLI) const { | ||||
552 | MachineFunction &MF = MIRBuilder.getMF(); | ||||
553 | MachineBasicBlock &MBB = MIRBuilder.getMBB(); | ||||
554 | MachineRegisterInfo &MRI = MF.getRegInfo(); | ||||
555 | auto &DL = F.getParent()->getDataLayout(); | ||||
556 | |||||
557 | SmallVector<ArgInfo, 8> SplitArgs; | ||||
558 | SmallVector<std::pair<Register, Register>> BoolArgs; | ||||
559 | |||||
560 | // Insert the hidden sret parameter if the return value won't fit in the | ||||
561 | // return registers. | ||||
562 | if (!FLI.CanLowerReturn) | ||||
563 | insertSRetIncomingArgument(F, SplitArgs, FLI.DemoteRegister, MRI, DL); | ||||
564 | |||||
565 | unsigned i = 0; | ||||
566 | for (auto &Arg : F.args()) { | ||||
567 | if (DL.getTypeStoreSize(Arg.getType()).isZero()) | ||||
568 | continue; | ||||
569 | |||||
570 | ArgInfo OrigArg{VRegs[i], Arg, i}; | ||||
571 | setArgFlags(OrigArg, i + AttributeList::FirstArgIndex, DL, F); | ||||
572 | |||||
573 | // i1 arguments are zero-extended to i8 by the caller. Emit a | ||||
574 | // hint to reflect this. | ||||
575 | if (OrigArg.Ty->isIntegerTy(1)) { | ||||
576 | assert(OrigArg.Regs.size() == 1 &&(static_cast <bool> (OrigArg.Regs.size() == 1 && MRI.getType(OrigArg.Regs[0]).getSizeInBits() == 1 && "Unexpected registers used for i1 arg") ? void (0) : __assert_fail ("OrigArg.Regs.size() == 1 && MRI.getType(OrigArg.Regs[0]).getSizeInBits() == 1 && \"Unexpected registers used for i1 arg\"" , "llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp", 578 , __extension__ __PRETTY_FUNCTION__)) | ||||
577 | MRI.getType(OrigArg.Regs[0]).getSizeInBits() == 1 &&(static_cast <bool> (OrigArg.Regs.size() == 1 && MRI.getType(OrigArg.Regs[0]).getSizeInBits() == 1 && "Unexpected registers used for i1 arg") ? void (0) : __assert_fail ("OrigArg.Regs.size() == 1 && MRI.getType(OrigArg.Regs[0]).getSizeInBits() == 1 && \"Unexpected registers used for i1 arg\"" , "llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp", 578 , __extension__ __PRETTY_FUNCTION__)) | ||||
578 | "Unexpected registers used for i1 arg")(static_cast <bool> (OrigArg.Regs.size() == 1 && MRI.getType(OrigArg.Regs[0]).getSizeInBits() == 1 && "Unexpected registers used for i1 arg") ? void (0) : __assert_fail ("OrigArg.Regs.size() == 1 && MRI.getType(OrigArg.Regs[0]).getSizeInBits() == 1 && \"Unexpected registers used for i1 arg\"" , "llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp", 578 , __extension__ __PRETTY_FUNCTION__)); | ||||
579 | |||||
580 | auto &Flags = OrigArg.Flags[0]; | ||||
581 | if (!Flags.isZExt() && !Flags.isSExt()) { | ||||
582 | // Lower i1 argument as i8, and insert AssertZExt + Trunc later. | ||||
583 | Register OrigReg = OrigArg.Regs[0]; | ||||
584 | Register WideReg = MRI.createGenericVirtualRegister(LLT::scalar(8)); | ||||
585 | OrigArg.Regs[0] = WideReg; | ||||
586 | BoolArgs.push_back({OrigReg, WideReg}); | ||||
587 | } | ||||
588 | } | ||||
589 | |||||
590 | if (Arg.hasAttribute(Attribute::SwiftAsync)) | ||||
591 | MF.getInfo<AArch64FunctionInfo>()->setHasSwiftAsyncContext(true); | ||||
592 | |||||
593 | splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv()); | ||||
594 | ++i; | ||||
595 | } | ||||
596 | |||||
597 | if (!MBB.empty()) | ||||
598 | MIRBuilder.setInstr(*MBB.begin()); | ||||
599 | |||||
600 | const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>(); | ||||
601 | CCAssignFn *AssignFn = | ||||
602 | TLI.CCAssignFnForCall(F.getCallingConv(), /*IsVarArg=*/false); | ||||
603 | |||||
604 | AArch64IncomingValueAssigner Assigner(AssignFn, AssignFn); | ||||
605 | FormalArgHandler Handler(MIRBuilder, MRI); | ||||
606 | if (!determineAndHandleAssignments(Handler, Assigner, SplitArgs, MIRBuilder, | ||||
607 | F.getCallingConv(), F.isVarArg())) | ||||
608 | return false; | ||||
609 | |||||
610 | if (!BoolArgs.empty()) { | ||||
611 | for (auto &KV : BoolArgs) { | ||||
612 | Register OrigReg = KV.first; | ||||
613 | Register WideReg = KV.second; | ||||
614 | LLT WideTy = MRI.getType(WideReg); | ||||
615 | assert(MRI.getType(OrigReg).getScalarSizeInBits() == 1 &&(static_cast <bool> (MRI.getType(OrigReg).getScalarSizeInBits () == 1 && "Unexpected bit size of a bool arg") ? void (0) : __assert_fail ("MRI.getType(OrigReg).getScalarSizeInBits() == 1 && \"Unexpected bit size of a bool arg\"" , "llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp", 616 , __extension__ __PRETTY_FUNCTION__)) | ||||
616 | "Unexpected bit size of a bool arg")(static_cast <bool> (MRI.getType(OrigReg).getScalarSizeInBits () == 1 && "Unexpected bit size of a bool arg") ? void (0) : __assert_fail ("MRI.getType(OrigReg).getScalarSizeInBits() == 1 && \"Unexpected bit size of a bool arg\"" , "llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp", 616 , __extension__ __PRETTY_FUNCTION__)); | ||||
617 | MIRBuilder.buildTrunc( | ||||
618 | OrigReg, MIRBuilder.buildAssertZExt(WideTy, WideReg, 1).getReg(0)); | ||||
619 | } | ||||
620 | } | ||||
621 | |||||
622 | AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>(); | ||||
623 | uint64_t StackOffset = Assigner.StackOffset; | ||||
624 | if (F.isVarArg()) { | ||||
625 | auto &Subtarget = MF.getSubtarget<AArch64Subtarget>(); | ||||
626 | if (!Subtarget.isTargetDarwin()) { | ||||
627 | // FIXME: we need to reimplement saveVarArgsRegisters from | ||||
628 | // AArch64ISelLowering. | ||||
629 | return false; | ||||
630 | } | ||||
631 | |||||
632 | // We currently pass all varargs at 8-byte alignment, or 4 in ILP32. | ||||
633 | StackOffset = | ||||
634 | alignTo(Assigner.StackOffset, Subtarget.isTargetILP32() ? 4 : 8); | ||||
635 | |||||
636 | auto &MFI = MIRBuilder.getMF().getFrameInfo(); | ||||
637 | FuncInfo->setVarArgsStackIndex(MFI.CreateFixedObject(4, StackOffset, true)); | ||||
638 | } | ||||
639 | |||||
640 | if (doesCalleeRestoreStack(F.getCallingConv(), | ||||
641 | MF.getTarget().Options.GuaranteedTailCallOpt)) { | ||||
642 | // We have a non-standard ABI, so why not make full use of the stack that | ||||
643 | // we're going to pop? It must be aligned to 16 B in any case. | ||||
644 | StackOffset = alignTo(StackOffset, 16); | ||||
645 | |||||
646 | // If we're expected to restore the stack (e.g. fastcc), then we'll be | ||||
647 | // adding a multiple of 16. | ||||
648 | FuncInfo->setArgumentStackToRestore(StackOffset); | ||||
649 | |||||
650 | // Our own callers will guarantee that the space is free by giving an | ||||
651 | // aligned value to CALLSEQ_START. | ||||
652 | } | ||||
653 | |||||
654 | // When we tail call, we need to check if the callee's arguments | ||||
655 | // will fit on the caller's stack. So, whenever we lower formal arguments, | ||||
656 | // we should keep track of this information, since we might lower a tail call | ||||
657 | // in this function later. | ||||
658 | FuncInfo->setBytesInStackArgArea(StackOffset); | ||||
659 | |||||
660 | auto &Subtarget = MF.getSubtarget<AArch64Subtarget>(); | ||||
661 | if (Subtarget.hasCustomCallingConv()) | ||||
662 | Subtarget.getRegisterInfo()->UpdateCustomCalleeSavedRegs(MF); | ||||
663 | |||||
664 | handleMustTailForwardedRegisters(MIRBuilder, AssignFn); | ||||
665 | |||||
666 | // Move back to the end of the basic block. | ||||
667 | MIRBuilder.setMBB(MBB); | ||||
668 | |||||
669 | return true; | ||||
670 | } | ||||
671 | |||||
672 | /// Return true if the calling convention is one that we can guarantee TCO for. | ||||
673 | static bool canGuaranteeTCO(CallingConv::ID CC, bool GuaranteeTailCalls) { | ||||
674 | return (CC == CallingConv::Fast && GuaranteeTailCalls) || | ||||
675 | CC == CallingConv::Tail || CC == CallingConv::SwiftTail; | ||||
676 | } | ||||
677 | |||||
678 | /// Return true if we might ever do TCO for calls with this calling convention. | ||||
679 | static bool mayTailCallThisCC(CallingConv::ID CC) { | ||||
680 | switch (CC) { | ||||
681 | case CallingConv::C: | ||||
682 | case CallingConv::PreserveMost: | ||||
683 | case CallingConv::Swift: | ||||
684 | case CallingConv::SwiftTail: | ||||
685 | case CallingConv::Tail: | ||||
686 | case CallingConv::Fast: | ||||
687 | return true; | ||||
688 | default: | ||||
689 | return false; | ||||
690 | } | ||||
691 | } | ||||
692 | |||||
693 | /// Returns a pair containing the fixed CCAssignFn and the vararg CCAssignFn for | ||||
694 | /// CC. | ||||
695 | static std::pair<CCAssignFn *, CCAssignFn *> | ||||
696 | getAssignFnsForCC(CallingConv::ID CC, const AArch64TargetLowering &TLI) { | ||||
697 | return {TLI.CCAssignFnForCall(CC, false), TLI.CCAssignFnForCall(CC, true)}; | ||||
698 | } | ||||
699 | |||||
700 | bool AArch64CallLowering::doCallerAndCalleePassArgsTheSameWay( | ||||
701 | CallLoweringInfo &Info, MachineFunction &MF, | ||||
702 | SmallVectorImpl<ArgInfo> &InArgs) const { | ||||
703 | const Function &CallerF = MF.getFunction(); | ||||
704 | CallingConv::ID CalleeCC = Info.CallConv; | ||||
705 | CallingConv::ID CallerCC = CallerF.getCallingConv(); | ||||
706 | |||||
707 | // If the calling conventions match, then everything must be the same. | ||||
708 | if (CalleeCC == CallerCC) | ||||
709 | return true; | ||||
710 | |||||
711 | // Check if the caller and callee will handle arguments in the same way. | ||||
712 | const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>(); | ||||
713 | CCAssignFn *CalleeAssignFnFixed; | ||||
714 | CCAssignFn *CalleeAssignFnVarArg; | ||||
715 | std::tie(CalleeAssignFnFixed, CalleeAssignFnVarArg) = | ||||
716 | getAssignFnsForCC(CalleeCC, TLI); | ||||
717 | |||||
718 | CCAssignFn *CallerAssignFnFixed; | ||||
719 | CCAssignFn *CallerAssignFnVarArg; | ||||
720 | std::tie(CallerAssignFnFixed, CallerAssignFnVarArg) = | ||||
721 | getAssignFnsForCC(CallerCC, TLI); | ||||
722 | |||||
723 | AArch64IncomingValueAssigner CalleeAssigner(CalleeAssignFnFixed, | ||||
724 | CalleeAssignFnVarArg); | ||||
725 | AArch64IncomingValueAssigner CallerAssigner(CallerAssignFnFixed, | ||||
726 | CallerAssignFnVarArg); | ||||
727 | |||||
728 | if (!resultsCompatible(Info, MF, InArgs, CalleeAssigner, CallerAssigner)) | ||||
729 | return false; | ||||
730 | |||||
731 | // Make sure that the caller and callee preserve all of the same registers. | ||||
732 | auto TRI = MF.getSubtarget<AArch64Subtarget>().getRegisterInfo(); | ||||
733 | const uint32_t *CallerPreserved = TRI->getCallPreservedMask(MF, CallerCC); | ||||
734 | const uint32_t *CalleePreserved = TRI->getCallPreservedMask(MF, CalleeCC); | ||||
735 | if (MF.getSubtarget<AArch64Subtarget>().hasCustomCallingConv()) { | ||||
736 | TRI->UpdateCustomCallPreservedMask(MF, &CallerPreserved); | ||||
737 | TRI->UpdateCustomCallPreservedMask(MF, &CalleePreserved); | ||||
738 | } | ||||
739 | |||||
740 | return TRI->regmaskSubsetEqual(CallerPreserved, CalleePreserved); | ||||
741 | } | ||||
742 | |||||
743 | bool AArch64CallLowering::areCalleeOutgoingArgsTailCallable( | ||||
744 | CallLoweringInfo &Info, MachineFunction &MF, | ||||
745 | SmallVectorImpl<ArgInfo> &OutArgs) const { | ||||
746 | // If there are no outgoing arguments, then we are done. | ||||
747 | if (OutArgs.empty()) | ||||
748 | return true; | ||||
749 | |||||
750 | const Function &CallerF = MF.getFunction(); | ||||
751 | LLVMContext &Ctx = CallerF.getContext(); | ||||
752 | CallingConv::ID CalleeCC = Info.CallConv; | ||||
753 | CallingConv::ID CallerCC = CallerF.getCallingConv(); | ||||
754 | const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>(); | ||||
755 | const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>(); | ||||
756 | |||||
757 | CCAssignFn *AssignFnFixed; | ||||
758 | CCAssignFn *AssignFnVarArg; | ||||
759 | std::tie(AssignFnFixed, AssignFnVarArg) = getAssignFnsForCC(CalleeCC, TLI); | ||||
760 | |||||
761 | // We have outgoing arguments. Make sure that we can tail call with them. | ||||
762 | SmallVector<CCValAssign, 16> OutLocs; | ||||
763 | CCState OutInfo(CalleeCC, false, MF, OutLocs, Ctx); | ||||
764 | |||||
765 | AArch64OutgoingValueAssigner CalleeAssigner(AssignFnFixed, AssignFnVarArg, | ||||
766 | Subtarget, /*IsReturn*/ false); | ||||
767 | if (!determineAssignments(CalleeAssigner, OutArgs, OutInfo)) { | ||||
768 | LLVM_DEBUG(dbgs() << "... Could not analyze call operands.\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("aarch64-call-lowering")) { dbgs() << "... Could not analyze call operands.\n" ; } } while (false); | ||||
769 | return false; | ||||
770 | } | ||||
771 | |||||
772 | // Make sure that they can fit on the caller's stack. | ||||
773 | const AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>(); | ||||
774 | if (OutInfo.getNextStackOffset() > FuncInfo->getBytesInStackArgArea()) { | ||||
775 | LLVM_DEBUG(dbgs() << "... Cannot fit call operands on caller's stack.\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("aarch64-call-lowering")) { dbgs() << "... Cannot fit call operands on caller's stack.\n" ; } } while (false); | ||||
776 | return false; | ||||
777 | } | ||||
778 | |||||
779 | // Verify that the parameters in callee-saved registers match. | ||||
780 | // TODO: Port this over to CallLowering as general code once swiftself is | ||||
781 | // supported. | ||||
782 | auto TRI = MF.getSubtarget<AArch64Subtarget>().getRegisterInfo(); | ||||
783 | const uint32_t *CallerPreservedMask = TRI->getCallPreservedMask(MF, CallerCC); | ||||
784 | MachineRegisterInfo &MRI = MF.getRegInfo(); | ||||
785 | |||||
786 | if (Info.IsVarArg) { | ||||
787 | // Be conservative and disallow variadic memory operands to match SDAG's | ||||
788 | // behaviour. | ||||
789 | // FIXME: If the caller's calling convention is C, then we can | ||||
790 | // potentially use its argument area. However, for cases like fastcc, | ||||
791 | // we can't do anything. | ||||
792 | for (unsigned i = 0; i < OutLocs.size(); ++i) { | ||||
793 | auto &ArgLoc = OutLocs[i]; | ||||
794 | if (ArgLoc.isRegLoc()) | ||||
795 | continue; | ||||
796 | |||||
797 | LLVM_DEBUG(do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("aarch64-call-lowering")) { dbgs() << "... Cannot tail call vararg function with stack arguments\n" ; } } while (false) | ||||
798 | dbgs()do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("aarch64-call-lowering")) { dbgs() << "... Cannot tail call vararg function with stack arguments\n" ; } } while (false) | ||||
799 | << "... Cannot tail call vararg function with stack arguments\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("aarch64-call-lowering")) { dbgs() << "... Cannot tail call vararg function with stack arguments\n" ; } } while (false); | ||||
800 | return false; | ||||
801 | } | ||||
802 | } | ||||
803 | |||||
804 | return parametersInCSRMatch(MRI, CallerPreservedMask, OutLocs, OutArgs); | ||||
805 | } | ||||
806 | |||||
807 | bool AArch64CallLowering::isEligibleForTailCallOptimization( | ||||
808 | MachineIRBuilder &MIRBuilder, CallLoweringInfo &Info, | ||||
809 | SmallVectorImpl<ArgInfo> &InArgs, | ||||
810 | SmallVectorImpl<ArgInfo> &OutArgs) const { | ||||
811 | |||||
812 | // Must pass all target-independent checks in order to tail call optimize. | ||||
813 | if (!Info.IsTailCall) | ||||
814 | return false; | ||||
815 | |||||
816 | CallingConv::ID CalleeCC = Info.CallConv; | ||||
817 | MachineFunction &MF = MIRBuilder.getMF(); | ||||
818 | const Function &CallerF = MF.getFunction(); | ||||
819 | |||||
820 | LLVM_DEBUG(dbgs() << "Attempting to lower call as tail call\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("aarch64-call-lowering")) { dbgs() << "Attempting to lower call as tail call\n" ; } } while (false); | ||||
821 | |||||
822 | if (Info.SwiftErrorVReg) { | ||||
823 | // TODO: We should handle this. | ||||
824 | // Note that this is also handled by the check for no outgoing arguments. | ||||
825 | // Proactively disabling this though, because the swifterror handling in | ||||
826 | // lowerCall inserts a COPY *after* the location of the call. | ||||
827 | LLVM_DEBUG(dbgs() << "... Cannot handle tail calls with swifterror yet.\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("aarch64-call-lowering")) { dbgs() << "... Cannot handle tail calls with swifterror yet.\n" ; } } while (false); | ||||
828 | return false; | ||||
829 | } | ||||
830 | |||||
831 | if (!mayTailCallThisCC(CalleeCC)) { | ||||
832 | LLVM_DEBUG(dbgs() << "... Calling convention cannot be tail called.\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("aarch64-call-lowering")) { dbgs() << "... Calling convention cannot be tail called.\n" ; } } while (false); | ||||
833 | return false; | ||||
834 | } | ||||
835 | |||||
836 | // Byval parameters hand the function a pointer directly into the stack area | ||||
837 | // we want to reuse during a tail call. Working around this *is* possible (see | ||||
838 | // X86). | ||||
839 | // | ||||
840 | // FIXME: In AArch64ISelLowering, this isn't worked around. Can/should we try | ||||
841 | // it? | ||||
842 | // | ||||
843 | // On Windows, "inreg" attributes signify non-aggregate indirect returns. | ||||
844 | // In this case, it is necessary to save/restore X0 in the callee. Tail | ||||
845 | // call opt interferes with this. So we disable tail call opt when the | ||||
846 | // caller has an argument with "inreg" attribute. | ||||
847 | // | ||||
848 | // FIXME: Check whether the callee also has an "inreg" argument. | ||||
849 | // | ||||
850 | // When the caller has a swifterror argument, we don't want to tail call | ||||
851 | // because would have to move into the swifterror register before the | ||||
852 | // tail call. | ||||
853 | if (any_of(CallerF.args(), [](const Argument &A) { | ||||
854 | return A.hasByValAttr() || A.hasInRegAttr() || A.hasSwiftErrorAttr(); | ||||
855 | })) { | ||||
856 | LLVM_DEBUG(dbgs() << "... Cannot tail call from callers with byval, "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("aarch64-call-lowering")) { dbgs() << "... Cannot tail call from callers with byval, " "inreg, or swifterror arguments\n"; } } while (false) | ||||
857 | "inreg, or swifterror arguments\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("aarch64-call-lowering")) { dbgs() << "... Cannot tail call from callers with byval, " "inreg, or swifterror arguments\n"; } } while (false); | ||||
858 | return false; | ||||
859 | } | ||||
860 | |||||
861 | // Externally-defined functions with weak linkage should not be | ||||
862 | // tail-called on AArch64 when the OS does not support dynamic | ||||
863 | // pre-emption of symbols, as the AAELF spec requires normal calls | ||||
864 | // to undefined weak functions to be replaced with a NOP or jump to the | ||||
865 | // next instruction. The behaviour of branch instructions in this | ||||
866 | // situation (as used for tail calls) is implementation-defined, so we | ||||
867 | // cannot rely on the linker replacing the tail call with a return. | ||||
868 | if (Info.Callee.isGlobal()) { | ||||
869 | const GlobalValue *GV = Info.Callee.getGlobal(); | ||||
870 | const Triple &TT = MF.getTarget().getTargetTriple(); | ||||
871 | if (GV->hasExternalWeakLinkage() && | ||||
872 | (!TT.isOSWindows() || TT.isOSBinFormatELF() || | ||||
873 | TT.isOSBinFormatMachO())) { | ||||
874 | LLVM_DEBUG(dbgs() << "... Cannot tail call externally-defined function "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("aarch64-call-lowering")) { dbgs() << "... Cannot tail call externally-defined function " "with weak linkage for this OS.\n"; } } while (false) | ||||
875 | "with weak linkage for this OS.\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("aarch64-call-lowering")) { dbgs() << "... Cannot tail call externally-defined function " "with weak linkage for this OS.\n"; } } while (false); | ||||
876 | return false; | ||||
877 | } | ||||
878 | } | ||||
879 | |||||
880 | // If we have -tailcallopt, then we're done. | ||||
881 | if (canGuaranteeTCO(CalleeCC, MF.getTarget().Options.GuaranteedTailCallOpt)) | ||||
882 | return CalleeCC == CallerF.getCallingConv(); | ||||
883 | |||||
884 | // We don't have -tailcallopt, so we're allowed to change the ABI (sibcall). | ||||
885 | // Try to find cases where we can do that. | ||||
886 | |||||
887 | // I want anyone implementing a new calling convention to think long and hard | ||||
888 | // about this assert. | ||||
889 | assert((!Info.IsVarArg || CalleeCC == CallingConv::C) &&(static_cast <bool> ((!Info.IsVarArg || CalleeCC == CallingConv ::C) && "Unexpected variadic calling convention") ? void (0) : __assert_fail ("(!Info.IsVarArg || CalleeCC == CallingConv::C) && \"Unexpected variadic calling convention\"" , "llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp", 890 , __extension__ __PRETTY_FUNCTION__)) | ||||
890 | "Unexpected variadic calling convention")(static_cast <bool> ((!Info.IsVarArg || CalleeCC == CallingConv ::C) && "Unexpected variadic calling convention") ? void (0) : __assert_fail ("(!Info.IsVarArg || CalleeCC == CallingConv::C) && \"Unexpected variadic calling convention\"" , "llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp", 890 , __extension__ __PRETTY_FUNCTION__)); | ||||
891 | |||||
892 | // Verify that the incoming and outgoing arguments from the callee are | ||||
893 | // safe to tail call. | ||||
894 | if (!doCallerAndCalleePassArgsTheSameWay(Info, MF, InArgs)) { | ||||
895 | LLVM_DEBUG(do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("aarch64-call-lowering")) { dbgs() << "... Caller and callee have incompatible calling conventions.\n" ; } } while (false) | ||||
896 | dbgs()do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("aarch64-call-lowering")) { dbgs() << "... Caller and callee have incompatible calling conventions.\n" ; } } while (false) | ||||
897 | << "... Caller and callee have incompatible calling conventions.\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("aarch64-call-lowering")) { dbgs() << "... Caller and callee have incompatible calling conventions.\n" ; } } while (false); | ||||
898 | return false; | ||||
899 | } | ||||
900 | |||||
901 | if (!areCalleeOutgoingArgsTailCallable(Info, MF, OutArgs)) | ||||
902 | return false; | ||||
903 | |||||
904 | LLVM_DEBUG(do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("aarch64-call-lowering")) { dbgs() << "... Call is eligible for tail call optimization.\n" ; } } while (false) | ||||
905 | dbgs() << "... Call is eligible for tail call optimization.\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("aarch64-call-lowering")) { dbgs() << "... Call is eligible for tail call optimization.\n" ; } } while (false); | ||||
906 | return true; | ||||
907 | } | ||||
908 | |||||
909 | static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect, | ||||
910 | bool IsTailCall) { | ||||
911 | if (!IsTailCall) | ||||
912 | return IsIndirect ? getBLRCallOpcode(CallerF) : (unsigned)AArch64::BL; | ||||
913 | |||||
914 | if (!IsIndirect) | ||||
915 | return AArch64::TCRETURNdi; | ||||
916 | |||||
917 | // When BTI is enabled, we need to use TCRETURNriBTI to make sure that we use | ||||
918 | // x16 or x17. | ||||
919 | if (CallerF.getInfo<AArch64FunctionInfo>()->branchTargetEnforcement()) | ||||
920 | return AArch64::TCRETURNriBTI; | ||||
921 | |||||
922 | return AArch64::TCRETURNri; | ||||
923 | } | ||||
924 | |||||
925 | static const uint32_t * | ||||
926 | getMaskForArgs(SmallVectorImpl<AArch64CallLowering::ArgInfo> &OutArgs, | ||||
927 | AArch64CallLowering::CallLoweringInfo &Info, | ||||
928 | const AArch64RegisterInfo &TRI, MachineFunction &MF) { | ||||
929 | const uint32_t *Mask; | ||||
930 | if (!OutArgs.empty() && OutArgs[0].Flags[0].isReturned()) { | ||||
931 | // For 'this' returns, use the X0-preserving mask if applicable | ||||
932 | Mask = TRI.getThisReturnPreservedMask(MF, Info.CallConv); | ||||
933 | if (!Mask) { | ||||
934 | OutArgs[0].Flags[0].setReturned(false); | ||||
935 | Mask = TRI.getCallPreservedMask(MF, Info.CallConv); | ||||
936 | } | ||||
937 | } else { | ||||
938 | Mask = TRI.getCallPreservedMask(MF, Info.CallConv); | ||||
939 | } | ||||
940 | return Mask; | ||||
941 | } | ||||
942 | |||||
943 | bool AArch64CallLowering::lowerTailCall( | ||||
944 | MachineIRBuilder &MIRBuilder, CallLoweringInfo &Info, | ||||
945 | SmallVectorImpl<ArgInfo> &OutArgs) const { | ||||
946 | MachineFunction &MF = MIRBuilder.getMF(); | ||||
947 | const Function &F = MF.getFunction(); | ||||
948 | MachineRegisterInfo &MRI = MF.getRegInfo(); | ||||
949 | const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>(); | ||||
950 | AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>(); | ||||
951 | |||||
952 | // True when we're tail calling, but without -tailcallopt. | ||||
953 | bool IsSibCall = !MF.getTarget().Options.GuaranteedTailCallOpt && | ||||
954 | Info.CallConv != CallingConv::Tail && | ||||
955 | Info.CallConv != CallingConv::SwiftTail; | ||||
956 | |||||
957 | // TODO: Right now, regbankselect doesn't know how to handle the rtcGPR64 | ||||
958 | // register class. Until we can do that, we should fall back here. | ||||
959 | if (MF.getInfo<AArch64FunctionInfo>()->branchTargetEnforcement()) { | ||||
960 | LLVM_DEBUG(do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("aarch64-call-lowering")) { dbgs() << "Cannot lower indirect tail calls with BTI enabled yet.\n" ; } } while (false) | ||||
961 | dbgs() << "Cannot lower indirect tail calls with BTI enabled yet.\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("aarch64-call-lowering")) { dbgs() << "Cannot lower indirect tail calls with BTI enabled yet.\n" ; } } while (false); | ||||
962 | return false; | ||||
963 | } | ||||
964 | |||||
965 | // Find out which ABI gets to decide where things go. | ||||
966 | CallingConv::ID CalleeCC = Info.CallConv; | ||||
967 | CCAssignFn *AssignFnFixed; | ||||
968 | CCAssignFn *AssignFnVarArg; | ||||
969 | std::tie(AssignFnFixed, AssignFnVarArg) = getAssignFnsForCC(CalleeCC, TLI); | ||||
970 | |||||
971 | MachineInstrBuilder CallSeqStart; | ||||
972 | if (!IsSibCall) | ||||
973 | CallSeqStart = MIRBuilder.buildInstr(AArch64::ADJCALLSTACKDOWN); | ||||
974 | |||||
975 | unsigned Opc = getCallOpcode(MF, Info.Callee.isReg(), true); | ||||
976 | auto MIB = MIRBuilder.buildInstrNoInsert(Opc); | ||||
977 | MIB.add(Info.Callee); | ||||
978 | |||||
979 | // Byte offset for the tail call. When we are sibcalling, this will always | ||||
980 | // be 0. | ||||
981 | MIB.addImm(0); | ||||
982 | |||||
983 | // Tell the call which registers are clobbered. | ||||
984 | const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>(); | ||||
985 | auto TRI = Subtarget.getRegisterInfo(); | ||||
986 | const uint32_t *Mask = TRI->getCallPreservedMask(MF, CalleeCC); | ||||
987 | if (Subtarget.hasCustomCallingConv()) | ||||
988 | TRI->UpdateCustomCallPreservedMask(MF, &Mask); | ||||
989 | MIB.addRegMask(Mask); | ||||
990 | |||||
991 | if (Info.CFIType) | ||||
992 | MIB->setCFIType(MF, Info.CFIType->getZExtValue()); | ||||
993 | |||||
994 | if (TRI->isAnyArgRegReserved(MF)) | ||||
995 | TRI->emitReservedArgRegCallError(MF); | ||||
996 | |||||
997 | // FPDiff is the byte offset of the call's argument area from the callee's. | ||||
998 | // Stores to callee stack arguments will be placed in FixedStackSlots offset | ||||
999 | // by this amount for a tail call. In a sibling call it must be 0 because the | ||||
1000 | // caller will deallocate the entire stack and the callee still expects its | ||||
1001 | // arguments to begin at SP+0. | ||||
1002 | int FPDiff = 0; | ||||
1003 | |||||
1004 | // This will be 0 for sibcalls, potentially nonzero for tail calls produced | ||||
1005 | // by -tailcallopt. For sibcalls, the memory operands for the call are | ||||
1006 | // already available in the caller's incoming argument space. | ||||
1007 | unsigned NumBytes = 0; | ||||
1008 | if (!IsSibCall) { | ||||
1009 | // We aren't sibcalling, so we need to compute FPDiff. We need to do this | ||||
1010 | // before handling assignments, because FPDiff must be known for memory | ||||
1011 | // arguments. | ||||
1012 | unsigned NumReusableBytes = FuncInfo->getBytesInStackArgArea(); | ||||
1013 | SmallVector<CCValAssign, 16> OutLocs; | ||||
1014 | CCState OutInfo(CalleeCC, false, MF, OutLocs, F.getContext()); | ||||
1015 | |||||
1016 | AArch64OutgoingValueAssigner CalleeAssigner(AssignFnFixed, AssignFnVarArg, | ||||
1017 | Subtarget, /*IsReturn*/ false); | ||||
1018 | if (!determineAssignments(CalleeAssigner, OutArgs, OutInfo)) | ||||
1019 | return false; | ||||
1020 | |||||
1021 | // The callee will pop the argument stack as a tail call. Thus, we must | ||||
1022 | // keep it 16-byte aligned. | ||||
1023 | NumBytes = alignTo(OutInfo.getNextStackOffset(), 16); | ||||
1024 | |||||
1025 | // FPDiff will be negative if this tail call requires more space than we | ||||
1026 | // would automatically have in our incoming argument space. Positive if we | ||||
1027 | // actually shrink the stack. | ||||
1028 | FPDiff = NumReusableBytes - NumBytes; | ||||
1029 | |||||
1030 | // Update the required reserved area if this is the tail call requiring the | ||||
1031 | // most argument stack space. | ||||
1032 | if (FPDiff < 0 && FuncInfo->getTailCallReservedStack() < (unsigned)-FPDiff) | ||||
1033 | FuncInfo->setTailCallReservedStack(-FPDiff); | ||||
1034 | |||||
1035 | // The stack pointer must be 16-byte aligned at all times it's used for a | ||||
1036 | // memory operation, which in practice means at *all* times and in | ||||
1037 | // particular across call boundaries. Therefore our own arguments started at | ||||
1038 | // a 16-byte aligned SP and the delta applied for the tail call should | ||||
1039 | // satisfy the same constraint. | ||||
1040 | assert(FPDiff % 16 == 0 && "unaligned stack on tail call")(static_cast <bool> (FPDiff % 16 == 0 && "unaligned stack on tail call" ) ? void (0) : __assert_fail ("FPDiff % 16 == 0 && \"unaligned stack on tail call\"" , "llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp", 1040 , __extension__ __PRETTY_FUNCTION__)); | ||||
1041 | } | ||||
1042 | |||||
1043 | const auto &Forwards = FuncInfo->getForwardedMustTailRegParms(); | ||||
1044 | |||||
1045 | AArch64OutgoingValueAssigner Assigner(AssignFnFixed, AssignFnVarArg, | ||||
1046 | Subtarget, /*IsReturn*/ false); | ||||
1047 | |||||
1048 | // Do the actual argument marshalling. | ||||
1049 | OutgoingArgHandler Handler(MIRBuilder, MRI, MIB, | ||||
1050 | /*IsTailCall*/ true, FPDiff); | ||||
1051 | if (!determineAndHandleAssignments(Handler, Assigner, OutArgs, MIRBuilder, | ||||
1052 | CalleeCC, Info.IsVarArg)) | ||||
1053 | return false; | ||||
1054 | |||||
1055 | Mask = getMaskForArgs(OutArgs, Info, *TRI, MF); | ||||
1056 | |||||
1057 | if (Info.IsVarArg && Info.IsMustTailCall) { | ||||
1058 | // Now we know what's being passed to the function. Add uses to the call for | ||||
1059 | // the forwarded registers that we *aren't* passing as parameters. This will | ||||
1060 | // preserve the copies we build earlier. | ||||
1061 | for (const auto &F : Forwards) { | ||||
1062 | Register ForwardedReg = F.PReg; | ||||
1063 | // If the register is already passed, or aliases a register which is | ||||
1064 | // already being passed, then skip it. | ||||
1065 | if (any_of(MIB->uses(), [&ForwardedReg, &TRI](const MachineOperand &Use) { | ||||
1066 | if (!Use.isReg()) | ||||
1067 | return false; | ||||
1068 | return TRI->regsOverlap(Use.getReg(), ForwardedReg); | ||||
1069 | })) | ||||
1070 | continue; | ||||
1071 | |||||
1072 | // We aren't passing it already, so we should add it to the call. | ||||
1073 | MIRBuilder.buildCopy(ForwardedReg, Register(F.VReg)); | ||||
1074 | MIB.addReg(ForwardedReg, RegState::Implicit); | ||||
1075 | } | ||||
1076 | } | ||||
1077 | |||||
1078 | // If we have -tailcallopt, we need to adjust the stack. We'll do the call | ||||
1079 | // sequence start and end here. | ||||
1080 | if (!IsSibCall) { | ||||
1081 | MIB->getOperand(1).setImm(FPDiff); | ||||
1082 | CallSeqStart.addImm(0).addImm(0); | ||||
1083 | // End the call sequence *before* emitting the call. Normally, we would | ||||
1084 | // tidy the frame up after the call. However, here, we've laid out the | ||||
1085 | // parameters so that when SP is reset, they will be in the correct | ||||
1086 | // location. | ||||
1087 | MIRBuilder.buildInstr(AArch64::ADJCALLSTACKUP).addImm(0).addImm(0); | ||||
1088 | } | ||||
1089 | |||||
1090 | // Now we can add the actual call instruction to the correct basic block. | ||||
1091 | MIRBuilder.insertInstr(MIB); | ||||
1092 | |||||
1093 | // If Callee is a reg, since it is used by a target specific instruction, | ||||
1094 | // it must have a register class matching the constraint of that instruction. | ||||
1095 | if (MIB->getOperand(0).isReg()) | ||||
1096 | constrainOperandRegClass(MF, *TRI, MRI, *MF.getSubtarget().getInstrInfo(), | ||||
1097 | *MF.getSubtarget().getRegBankInfo(), *MIB, | ||||
1098 | MIB->getDesc(), MIB->getOperand(0), 0); | ||||
1099 | |||||
1100 | MF.getFrameInfo().setHasTailCall(); | ||||
1101 | Info.LoweredTailCall = true; | ||||
1102 | return true; | ||||
1103 | } | ||||
1104 | |||||
1105 | bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, | ||||
1106 | CallLoweringInfo &Info) const { | ||||
1107 | MachineFunction &MF = MIRBuilder.getMF(); | ||||
1108 | const Function &F = MF.getFunction(); | ||||
1109 | MachineRegisterInfo &MRI = MF.getRegInfo(); | ||||
1110 | auto &DL = F.getParent()->getDataLayout(); | ||||
1111 | const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>(); | ||||
1112 | const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>(); | ||||
1113 | |||||
1114 | // Arm64EC has extra requirements for varargs calls; bail out for now. | ||||
1115 | if (Info.IsVarArg && Subtarget.isWindowsArm64EC()) | ||||
| |||||
1116 | return false; | ||||
1117 | |||||
1118 | SmallVector<ArgInfo, 8> OutArgs; | ||||
1119 | for (auto &OrigArg : Info.OrigArgs) { | ||||
1120 | splitToValueTypes(OrigArg, OutArgs, DL, Info.CallConv); | ||||
1121 | // AAPCS requires that we zero-extend i1 to 8 bits by the caller. | ||||
1122 | auto &Flags = OrigArg.Flags[0]; | ||||
1123 | if (OrigArg.Ty->isIntegerTy(1) && !Flags.isSExt() && !Flags.isZExt()) { | ||||
1124 | ArgInfo &OutArg = OutArgs.back(); | ||||
1125 | assert(OutArg.Regs.size() == 1 &&(static_cast <bool> (OutArg.Regs.size() == 1 && MRI.getType(OutArg.Regs[0]).getSizeInBits() == 1 && "Unexpected registers used for i1 arg" ) ? void (0) : __assert_fail ("OutArg.Regs.size() == 1 && MRI.getType(OutArg.Regs[0]).getSizeInBits() == 1 && \"Unexpected registers used for i1 arg\"" , "llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp", 1127 , __extension__ __PRETTY_FUNCTION__)) | ||||
1126 | MRI.getType(OutArg.Regs[0]).getSizeInBits() == 1 &&(static_cast <bool> (OutArg.Regs.size() == 1 && MRI.getType(OutArg.Regs[0]).getSizeInBits() == 1 && "Unexpected registers used for i1 arg" ) ? void (0) : __assert_fail ("OutArg.Regs.size() == 1 && MRI.getType(OutArg.Regs[0]).getSizeInBits() == 1 && \"Unexpected registers used for i1 arg\"" , "llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp", 1127 , __extension__ __PRETTY_FUNCTION__)) | ||||
1127 | "Unexpected registers used for i1 arg")(static_cast <bool> (OutArg.Regs.size() == 1 && MRI.getType(OutArg.Regs[0]).getSizeInBits() == 1 && "Unexpected registers used for i1 arg" ) ? void (0) : __assert_fail ("OutArg.Regs.size() == 1 && MRI.getType(OutArg.Regs[0]).getSizeInBits() == 1 && \"Unexpected registers used for i1 arg\"" , "llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp", 1127 , __extension__ __PRETTY_FUNCTION__)); | ||||
1128 | |||||
1129 | // We cannot use a ZExt ArgInfo flag here, because it will | ||||
1130 | // zero-extend the argument to i32 instead of just i8. | ||||
1131 | OutArg.Regs[0] = | ||||
1132 | MIRBuilder.buildZExt(LLT::scalar(8), OutArg.Regs[0]).getReg(0); | ||||
1133 | LLVMContext &Ctx = MF.getFunction().getContext(); | ||||
1134 | OutArg.Ty = Type::getInt8Ty(Ctx); | ||||
1135 | } | ||||
1136 | } | ||||
1137 | |||||
1138 | SmallVector<ArgInfo, 8> InArgs; | ||||
1139 | if (!Info.OrigRet.Ty->isVoidTy()) | ||||
1140 | splitToValueTypes(Info.OrigRet, InArgs, DL, Info.CallConv); | ||||
1141 | |||||
1142 | // If we can lower as a tail call, do that instead. | ||||
1143 | bool CanTailCallOpt = | ||||
1144 | isEligibleForTailCallOptimization(MIRBuilder, Info, InArgs, OutArgs); | ||||
1145 | |||||
1146 | // We must emit a tail call if we have musttail. | ||||
1147 | if (Info.IsMustTailCall && !CanTailCallOpt) { | ||||
1148 | // There are types of incoming/outgoing arguments we can't handle yet, so | ||||
1149 | // it doesn't make sense to actually die here like in ISelLowering. Instead, | ||||
1150 | // fall back to SelectionDAG and let it try to handle this. | ||||
1151 | LLVM_DEBUG(dbgs() << "Failed to lower musttail call as tail call\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("aarch64-call-lowering")) { dbgs() << "Failed to lower musttail call as tail call\n" ; } } while (false); | ||||
1152 | return false; | ||||
1153 | } | ||||
1154 | |||||
1155 | Info.IsTailCall = CanTailCallOpt; | ||||
1156 | if (CanTailCallOpt
| ||||
1157 | return lowerTailCall(MIRBuilder, Info, OutArgs); | ||||
1158 | |||||
1159 | // Find out which ABI gets to decide where things go. | ||||
1160 | CCAssignFn *AssignFnFixed; | ||||
1161 | CCAssignFn *AssignFnVarArg; | ||||
1162 | std::tie(AssignFnFixed, AssignFnVarArg) = | ||||
1163 | getAssignFnsForCC(Info.CallConv, TLI); | ||||
1164 | |||||
1165 | MachineInstrBuilder CallSeqStart; | ||||
1166 | CallSeqStart = MIRBuilder.buildInstr(AArch64::ADJCALLSTACKDOWN); | ||||
1167 | |||||
1168 | // Create a temporarily-floating call instruction so we can add the implicit | ||||
1169 | // uses of arg registers. | ||||
1170 | |||||
1171 | unsigned Opc = 0; | ||||
1172 | // Calls with operand bundle "clang.arc.attachedcall" are special. They should | ||||
1173 | // be expanded to the call, directly followed by a special marker sequence and | ||||
1174 | // a call to an ObjC library function. | ||||
1175 | if (Info.CB && objcarc::hasAttachedCallOpBundle(Info.CB)) | ||||
1176 | Opc = AArch64::BLR_RVMARKER; | ||||
1177 | // A call to a returns twice function like setjmp must be followed by a bti | ||||
1178 | // instruction. | ||||
1179 | else if (Info.CB
| ||||
1180 | Info.CB->getAttributes().hasFnAttr(Attribute::ReturnsTwice) && | ||||
1181 | !Subtarget.noBTIAtReturnTwice() && | ||||
1182 | MF.getInfo<AArch64FunctionInfo>()->branchTargetEnforcement()) | ||||
1183 | Opc = AArch64::BLR_BTI; | ||||
1184 | else | ||||
1185 | Opc = getCallOpcode(MF, Info.Callee.isReg(), false); | ||||
1186 | |||||
1187 | auto MIB = MIRBuilder.buildInstrNoInsert(Opc); | ||||
1188 | unsigned CalleeOpNo = 0; | ||||
1189 | |||||
1190 | if (Opc == AArch64::BLR_RVMARKER) { | ||||
1191 | // Add a target global address for the retainRV/claimRV runtime function | ||||
1192 | // just before the call target. | ||||
1193 | Function *ARCFn = *objcarc::getAttachedARCFunction(Info.CB); | ||||
1194 | MIB.addGlobalAddress(ARCFn); | ||||
1195 | ++CalleeOpNo; | ||||
1196 | } else if (Info.CFIType) { | ||||
1197 | MIB->setCFIType(MF, Info.CFIType->getZExtValue()); | ||||
1198 | } | ||||
1199 | |||||
1200 | MIB.add(Info.Callee); | ||||
1201 | |||||
1202 | // Tell the call which registers are clobbered. | ||||
1203 | const uint32_t *Mask; | ||||
1204 | const auto *TRI = Subtarget.getRegisterInfo(); | ||||
1205 | |||||
1206 | AArch64OutgoingValueAssigner Assigner(AssignFnFixed, AssignFnVarArg, | ||||
1207 | Subtarget, /*IsReturn*/ false); | ||||
1208 | // Do the actual argument marshalling. | ||||
1209 | OutgoingArgHandler Handler(MIRBuilder, MRI, MIB, /*IsReturn*/ false); | ||||
1210 | if (!determineAndHandleAssignments(Handler, Assigner, OutArgs, MIRBuilder, | ||||
1211 | Info.CallConv, Info.IsVarArg)) | ||||
1212 | return false; | ||||
1213 | |||||
1214 | Mask = getMaskForArgs(OutArgs, Info, *TRI, MF); | ||||
1215 | |||||
1216 | if (MF.getSubtarget<AArch64Subtarget>().hasCustomCallingConv()) | ||||
1217 | TRI->UpdateCustomCallPreservedMask(MF, &Mask); | ||||
1218 | MIB.addRegMask(Mask); | ||||
1219 | |||||
1220 | if (TRI->isAnyArgRegReserved(MF)) | ||||
1221 | TRI->emitReservedArgRegCallError(MF); | ||||
1222 | |||||
1223 | // Now we can add the actual call instruction to the correct basic block. | ||||
1224 | MIRBuilder.insertInstr(MIB); | ||||
1225 | |||||
1226 | // If Callee is a reg, since it is used by a target specific | ||||
1227 | // instruction, it must have a register class matching the | ||||
1228 | // constraint of that instruction. | ||||
1229 | if (MIB->getOperand(CalleeOpNo).isReg()) | ||||
1230 | constrainOperandRegClass(MF, *TRI, MRI, *Subtarget.getInstrInfo(), | ||||
1231 | *Subtarget.getRegBankInfo(), *MIB, MIB->getDesc(), | ||||
1232 | MIB->getOperand(CalleeOpNo), CalleeOpNo); | ||||
1233 | |||||
1234 | // Finally we can copy the returned value back into its virtual-register. In | ||||
1235 | // symmetry with the arguments, the physical register must be an | ||||
1236 | // implicit-define of the call instruction. | ||||
1237 | if (Info.CanLowerReturn && !Info.OrigRet.Ty->isVoidTy()) { | ||||
1238 | CCAssignFn *RetAssignFn = TLI.CCAssignFnForReturn(Info.CallConv); | ||||
1239 | CallReturnHandler Handler(MIRBuilder, MRI, MIB); | ||||
1240 | bool UsingReturnedArg = | ||||
1241 | !OutArgs.empty() && OutArgs[0].Flags[0].isReturned(); | ||||
1242 | |||||
1243 | AArch64OutgoingValueAssigner Assigner(RetAssignFn, RetAssignFn, Subtarget, | ||||
1244 | /*IsReturn*/ false); | ||||
1245 | ReturnedArgCallReturnHandler ReturnedArgHandler(MIRBuilder, MRI, MIB); | ||||
1246 | if (!determineAndHandleAssignments( | ||||
1247 | UsingReturnedArg ? ReturnedArgHandler : Handler, Assigner, InArgs, | ||||
1248 | MIRBuilder, Info.CallConv, Info.IsVarArg, | ||||
1249 | UsingReturnedArg ? makeArrayRef(OutArgs[0].Regs) : std::nullopt)) | ||||
1250 | return false; | ||||
1251 | } | ||||
1252 | |||||
1253 | if (Info.SwiftErrorVReg) { | ||||
1254 | MIB.addDef(AArch64::X21, RegState::Implicit); | ||||
1255 | MIRBuilder.buildCopy(Info.SwiftErrorVReg, Register(AArch64::X21)); | ||||
1256 | } | ||||
1257 | |||||
1258 | uint64_t CalleePopBytes = | ||||
1259 | doesCalleeRestoreStack(Info.CallConv, | ||||
1260 | MF.getTarget().Options.GuaranteedTailCallOpt) | ||||
1261 | ? alignTo(Assigner.StackOffset, 16) | ||||
1262 | : 0; | ||||
1263 | |||||
1264 | CallSeqStart.addImm(Assigner.StackOffset).addImm(0); | ||||
1265 | MIRBuilder.buildInstr(AArch64::ADJCALLSTACKUP) | ||||
1266 | .addImm(Assigner.StackOffset) | ||||
1267 | .addImm(CalleePopBytes); | ||||
1268 | |||||
1269 | if (!Info.CanLowerReturn) { | ||||
1270 | insertSRetLoads(MIRBuilder, Info.OrigRet.Ty, Info.OrigRet.Regs, | ||||
1271 | Info.DemoteRegister, Info.DemoteStackIndex); | ||||
1272 | } | ||||
1273 | return true; | ||||
1274 | } | ||||
1275 | |||||
1276 | bool AArch64CallLowering::isTypeIsValidForThisReturn(EVT Ty) const { | ||||
1277 | return Ty.getSizeInBits() == 64; | ||||
1278 | } |
1 | //===- ObjCARCUtil.h - ObjC ARC Utility Functions ---------------*- C++ -*-===// | |||
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 | /// \file | |||
9 | /// This file defines ARC utility functions which are used by various parts of | |||
10 | /// the compiler. | |||
11 | /// | |||
12 | //===----------------------------------------------------------------------===// | |||
13 | ||||
14 | #ifndef LLVM_ANALYSIS_OBJCARCUTIL_H | |||
15 | #define LLVM_ANALYSIS_OBJCARCUTIL_H | |||
16 | ||||
17 | #include "llvm/Analysis/ObjCARCInstKind.h" | |||
18 | #include "llvm/IR/Function.h" | |||
19 | #include "llvm/IR/InstrTypes.h" | |||
20 | #include "llvm/IR/LLVMContext.h" | |||
21 | ||||
22 | namespace llvm { | |||
23 | namespace objcarc { | |||
24 | ||||
25 | inline const char *getRVMarkerModuleFlagStr() { | |||
26 | return "clang.arc.retainAutoreleasedReturnValueMarker"; | |||
27 | } | |||
28 | ||||
29 | inline bool hasAttachedCallOpBundle(const CallBase *CB) { | |||
30 | // Ignore the bundle if the return type is void. Global optimization passes | |||
31 | // can turn the called function's return type to void. That should happen only | |||
32 | // if the call doesn't return and the call to @llvm.objc.clang.arc.noop.use | |||
33 | // no longer consumes the function return or is deleted. In that case, it's | |||
34 | // not necessary to emit the marker instruction or calls to the ARC runtime | |||
35 | // functions. | |||
36 | return !CB->getFunctionType()->getReturnType()->isVoidTy() && | |||
37 | CB->getOperandBundle(LLVMContext::OB_clang_arc_attachedcall) | |||
38 | .has_value(); | |||
39 | } | |||
40 | ||||
41 | /// This function returns operand bundle clang_arc_attachedcall's argument, | |||
42 | /// which is the address of the ARC runtime function. | |||
43 | inline Optional<Function *> getAttachedARCFunction(const CallBase *CB) { | |||
44 | auto B = CB->getOperandBundle(LLVMContext::OB_clang_arc_attachedcall); | |||
| ||||
45 | if (!B) | |||
46 | return std::nullopt; | |||
47 | ||||
48 | return cast<Function>(B->Inputs[0]); | |||
49 | } | |||
50 | ||||
51 | /// Check whether the function is retainRV/unsafeClaimRV. | |||
52 | inline bool isRetainOrClaimRV(ARCInstKind Kind) { | |||
53 | return Kind == ARCInstKind::RetainRV || Kind == ARCInstKind::UnsafeClaimRV; | |||
54 | } | |||
55 | ||||
56 | /// This function returns the ARCInstKind of the function attached to operand | |||
57 | /// bundle clang_arc_attachedcall. It returns std::nullopt if the call doesn't | |||
58 | /// have the operand bundle or the operand is null. Otherwise it returns either | |||
59 | /// RetainRV or UnsafeClaimRV. | |||
60 | inline ARCInstKind getAttachedARCFunctionKind(const CallBase *CB) { | |||
61 | Optional<Function *> Fn = getAttachedARCFunction(CB); | |||
62 | if (!Fn) | |||
63 | return ARCInstKind::None; | |||
64 | auto FnClass = GetFunctionClass(*Fn); | |||
65 | assert(isRetainOrClaimRV(FnClass) && "unexpected ARC runtime function")(static_cast <bool> (isRetainOrClaimRV(FnClass) && "unexpected ARC runtime function") ? void (0) : __assert_fail ("isRetainOrClaimRV(FnClass) && \"unexpected ARC runtime function\"" , "llvm/include/llvm/Analysis/ObjCARCUtil.h", 65, __extension__ __PRETTY_FUNCTION__)); | |||
66 | return FnClass; | |||
67 | } | |||
68 | ||||
69 | } // end namespace objcarc | |||
70 | } // end namespace llvm | |||
71 | ||||
72 | #endif |