xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp (revision 5ffd83dbcc34f10e07f6d3e968ae6365869615f4)
1*5ffd83dbSDimitry Andric //===--- AArch64CallLowering.cpp - Call lowering --------------------------===//
2*5ffd83dbSDimitry Andric //
3*5ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*5ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*5ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*5ffd83dbSDimitry Andric //
7*5ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
8*5ffd83dbSDimitry Andric ///
9*5ffd83dbSDimitry Andric /// \file
10*5ffd83dbSDimitry Andric /// This file implements the lowering of LLVM calls to machine code calls for
11*5ffd83dbSDimitry Andric /// GlobalISel.
12*5ffd83dbSDimitry Andric ///
13*5ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
14*5ffd83dbSDimitry Andric 
15*5ffd83dbSDimitry Andric #include "AArch64CallLowering.h"
16*5ffd83dbSDimitry Andric #include "AArch64ISelLowering.h"
17*5ffd83dbSDimitry Andric #include "AArch64MachineFunctionInfo.h"
18*5ffd83dbSDimitry Andric #include "AArch64Subtarget.h"
19*5ffd83dbSDimitry Andric #include "llvm/ADT/ArrayRef.h"
20*5ffd83dbSDimitry Andric #include "llvm/ADT/SmallVector.h"
21*5ffd83dbSDimitry Andric #include "llvm/CodeGen/Analysis.h"
22*5ffd83dbSDimitry Andric #include "llvm/CodeGen/CallingConvLower.h"
23*5ffd83dbSDimitry Andric #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
24*5ffd83dbSDimitry Andric #include "llvm/CodeGen/GlobalISel/Utils.h"
25*5ffd83dbSDimitry Andric #include "llvm/CodeGen/LowLevelType.h"
26*5ffd83dbSDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
27*5ffd83dbSDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
28*5ffd83dbSDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
29*5ffd83dbSDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
30*5ffd83dbSDimitry Andric #include "llvm/CodeGen/MachineMemOperand.h"
31*5ffd83dbSDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
32*5ffd83dbSDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
33*5ffd83dbSDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
34*5ffd83dbSDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
35*5ffd83dbSDimitry Andric #include "llvm/CodeGen/ValueTypes.h"
36*5ffd83dbSDimitry Andric #include "llvm/IR/Argument.h"
37*5ffd83dbSDimitry Andric #include "llvm/IR/Attributes.h"
38*5ffd83dbSDimitry Andric #include "llvm/IR/Function.h"
39*5ffd83dbSDimitry Andric #include "llvm/IR/Type.h"
40*5ffd83dbSDimitry Andric #include "llvm/IR/Value.h"
41*5ffd83dbSDimitry Andric #include "llvm/Support/MachineValueType.h"
42*5ffd83dbSDimitry Andric #include <algorithm>
43*5ffd83dbSDimitry Andric #include <cassert>
44*5ffd83dbSDimitry Andric #include <cstdint>
45*5ffd83dbSDimitry Andric #include <iterator>
46*5ffd83dbSDimitry Andric 
47*5ffd83dbSDimitry Andric #define DEBUG_TYPE "aarch64-call-lowering"
48*5ffd83dbSDimitry Andric 
49*5ffd83dbSDimitry Andric using namespace llvm;
50*5ffd83dbSDimitry Andric 
51*5ffd83dbSDimitry Andric AArch64CallLowering::AArch64CallLowering(const AArch64TargetLowering &TLI)
52*5ffd83dbSDimitry Andric   : CallLowering(&TLI) {}
53*5ffd83dbSDimitry Andric 
54*5ffd83dbSDimitry Andric namespace {
55*5ffd83dbSDimitry Andric struct IncomingArgHandler : public CallLowering::ValueHandler {
56*5ffd83dbSDimitry Andric   IncomingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
57*5ffd83dbSDimitry Andric                      CCAssignFn *AssignFn)
58*5ffd83dbSDimitry Andric       : ValueHandler(MIRBuilder, MRI, AssignFn), StackUsed(0) {}
59*5ffd83dbSDimitry Andric 
60*5ffd83dbSDimitry Andric   Register getStackAddress(uint64_t Size, int64_t Offset,
61*5ffd83dbSDimitry Andric                            MachinePointerInfo &MPO) override {
62*5ffd83dbSDimitry Andric     auto &MFI = MIRBuilder.getMF().getFrameInfo();
63*5ffd83dbSDimitry Andric     int FI = MFI.CreateFixedObject(Size, Offset, true);
64*5ffd83dbSDimitry Andric     MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
65*5ffd83dbSDimitry Andric     auto AddrReg = MIRBuilder.buildFrameIndex(LLT::pointer(0, 64), FI);
66*5ffd83dbSDimitry Andric     StackUsed = std::max(StackUsed, Size + Offset);
67*5ffd83dbSDimitry Andric     return AddrReg.getReg(0);
68*5ffd83dbSDimitry Andric   }
69*5ffd83dbSDimitry Andric 
70*5ffd83dbSDimitry Andric   void assignValueToReg(Register ValVReg, Register PhysReg,
71*5ffd83dbSDimitry Andric                         CCValAssign &VA) override {
72*5ffd83dbSDimitry Andric     markPhysRegUsed(PhysReg);
73*5ffd83dbSDimitry Andric     switch (VA.getLocInfo()) {
74*5ffd83dbSDimitry Andric     default:
75*5ffd83dbSDimitry Andric       MIRBuilder.buildCopy(ValVReg, PhysReg);
76*5ffd83dbSDimitry Andric       break;
77*5ffd83dbSDimitry Andric     case CCValAssign::LocInfo::SExt:
78*5ffd83dbSDimitry Andric     case CCValAssign::LocInfo::ZExt:
79*5ffd83dbSDimitry Andric     case CCValAssign::LocInfo::AExt: {
80*5ffd83dbSDimitry Andric       auto Copy = MIRBuilder.buildCopy(LLT{VA.getLocVT()}, PhysReg);
81*5ffd83dbSDimitry Andric       MIRBuilder.buildTrunc(ValVReg, Copy);
82*5ffd83dbSDimitry Andric       break;
83*5ffd83dbSDimitry Andric     }
84*5ffd83dbSDimitry Andric     }
85*5ffd83dbSDimitry Andric   }
86*5ffd83dbSDimitry Andric 
87*5ffd83dbSDimitry Andric   void assignValueToAddress(Register ValVReg, Register Addr, uint64_t Size,
88*5ffd83dbSDimitry Andric                             MachinePointerInfo &MPO, CCValAssign &VA) override {
89*5ffd83dbSDimitry Andric     MachineFunction &MF = MIRBuilder.getMF();
90*5ffd83dbSDimitry Andric     auto MMO = MF.getMachineMemOperand(
91*5ffd83dbSDimitry Andric         MPO, MachineMemOperand::MOLoad | MachineMemOperand::MOInvariant, Size,
92*5ffd83dbSDimitry Andric         inferAlignFromPtrInfo(MF, MPO));
93*5ffd83dbSDimitry Andric     MIRBuilder.buildLoad(ValVReg, Addr, *MMO);
94*5ffd83dbSDimitry Andric   }
95*5ffd83dbSDimitry Andric 
96*5ffd83dbSDimitry Andric   /// How the physical register gets marked varies between formal
97*5ffd83dbSDimitry Andric   /// parameters (it's a basic-block live-in), and a call instruction
98*5ffd83dbSDimitry Andric   /// (it's an implicit-def of the BL).
99*5ffd83dbSDimitry Andric   virtual void markPhysRegUsed(unsigned PhysReg) = 0;
100*5ffd83dbSDimitry Andric 
101*5ffd83dbSDimitry Andric   bool isIncomingArgumentHandler() const override { return true; }
102*5ffd83dbSDimitry Andric 
103*5ffd83dbSDimitry Andric   uint64_t StackUsed;
104*5ffd83dbSDimitry Andric };
105*5ffd83dbSDimitry Andric 
106*5ffd83dbSDimitry Andric struct FormalArgHandler : public IncomingArgHandler {
107*5ffd83dbSDimitry Andric   FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
108*5ffd83dbSDimitry Andric                    CCAssignFn *AssignFn)
109*5ffd83dbSDimitry Andric     : IncomingArgHandler(MIRBuilder, MRI, AssignFn) {}
110*5ffd83dbSDimitry Andric 
111*5ffd83dbSDimitry Andric   void markPhysRegUsed(unsigned PhysReg) override {
112*5ffd83dbSDimitry Andric     MIRBuilder.getMRI()->addLiveIn(PhysReg);
113*5ffd83dbSDimitry Andric     MIRBuilder.getMBB().addLiveIn(PhysReg);
114*5ffd83dbSDimitry Andric   }
115*5ffd83dbSDimitry Andric };
116*5ffd83dbSDimitry Andric 
117*5ffd83dbSDimitry Andric struct CallReturnHandler : public IncomingArgHandler {
118*5ffd83dbSDimitry Andric   CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
119*5ffd83dbSDimitry Andric                     MachineInstrBuilder MIB, CCAssignFn *AssignFn)
120*5ffd83dbSDimitry Andric     : IncomingArgHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
121*5ffd83dbSDimitry Andric 
122*5ffd83dbSDimitry Andric   void markPhysRegUsed(unsigned PhysReg) override {
123*5ffd83dbSDimitry Andric     MIB.addDef(PhysReg, RegState::Implicit);
124*5ffd83dbSDimitry Andric   }
125*5ffd83dbSDimitry Andric 
126*5ffd83dbSDimitry Andric   MachineInstrBuilder MIB;
127*5ffd83dbSDimitry Andric };
128*5ffd83dbSDimitry Andric 
129*5ffd83dbSDimitry Andric struct OutgoingArgHandler : public CallLowering::ValueHandler {
130*5ffd83dbSDimitry Andric   OutgoingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
131*5ffd83dbSDimitry Andric                      MachineInstrBuilder MIB, CCAssignFn *AssignFn,
132*5ffd83dbSDimitry Andric                      CCAssignFn *AssignFnVarArg, bool IsTailCall = false,
133*5ffd83dbSDimitry Andric                      int FPDiff = 0)
134*5ffd83dbSDimitry Andric       : ValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB),
135*5ffd83dbSDimitry Andric         AssignFnVarArg(AssignFnVarArg), IsTailCall(IsTailCall), FPDiff(FPDiff),
136*5ffd83dbSDimitry Andric         StackSize(0), SPReg(0) {}
137*5ffd83dbSDimitry Andric 
138*5ffd83dbSDimitry Andric   bool isIncomingArgumentHandler() const override { return false; }
139*5ffd83dbSDimitry Andric 
140*5ffd83dbSDimitry Andric   Register getStackAddress(uint64_t Size, int64_t Offset,
141*5ffd83dbSDimitry Andric                            MachinePointerInfo &MPO) override {
142*5ffd83dbSDimitry Andric     MachineFunction &MF = MIRBuilder.getMF();
143*5ffd83dbSDimitry Andric     LLT p0 = LLT::pointer(0, 64);
144*5ffd83dbSDimitry Andric     LLT s64 = LLT::scalar(64);
145*5ffd83dbSDimitry Andric 
146*5ffd83dbSDimitry Andric     if (IsTailCall) {
147*5ffd83dbSDimitry Andric       Offset += FPDiff;
148*5ffd83dbSDimitry Andric       int FI = MF.getFrameInfo().CreateFixedObject(Size, Offset, true);
149*5ffd83dbSDimitry Andric       auto FIReg = MIRBuilder.buildFrameIndex(p0, FI);
150*5ffd83dbSDimitry Andric       MPO = MachinePointerInfo::getFixedStack(MF, FI);
151*5ffd83dbSDimitry Andric       return FIReg.getReg(0);
152*5ffd83dbSDimitry Andric     }
153*5ffd83dbSDimitry Andric 
154*5ffd83dbSDimitry Andric     if (!SPReg)
155*5ffd83dbSDimitry Andric       SPReg = MIRBuilder.buildCopy(p0, Register(AArch64::SP)).getReg(0);
156*5ffd83dbSDimitry Andric 
157*5ffd83dbSDimitry Andric     auto OffsetReg = MIRBuilder.buildConstant(s64, Offset);
158*5ffd83dbSDimitry Andric 
159*5ffd83dbSDimitry Andric     auto AddrReg = MIRBuilder.buildPtrAdd(p0, SPReg, OffsetReg);
160*5ffd83dbSDimitry Andric 
161*5ffd83dbSDimitry Andric     MPO = MachinePointerInfo::getStack(MF, Offset);
162*5ffd83dbSDimitry Andric     return AddrReg.getReg(0);
163*5ffd83dbSDimitry Andric   }
164*5ffd83dbSDimitry Andric 
165*5ffd83dbSDimitry Andric   void assignValueToReg(Register ValVReg, Register PhysReg,
166*5ffd83dbSDimitry Andric                         CCValAssign &VA) override {
167*5ffd83dbSDimitry Andric     MIB.addUse(PhysReg, RegState::Implicit);
168*5ffd83dbSDimitry Andric     Register ExtReg = extendRegister(ValVReg, VA);
169*5ffd83dbSDimitry Andric     MIRBuilder.buildCopy(PhysReg, ExtReg);
170*5ffd83dbSDimitry Andric   }
171*5ffd83dbSDimitry Andric 
172*5ffd83dbSDimitry Andric   void assignValueToAddress(Register ValVReg, Register Addr, uint64_t Size,
173*5ffd83dbSDimitry Andric                             MachinePointerInfo &MPO, CCValAssign &VA) override {
174*5ffd83dbSDimitry Andric     MachineFunction &MF = MIRBuilder.getMF();
175*5ffd83dbSDimitry Andric     auto MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOStore, Size,
176*5ffd83dbSDimitry Andric                                        inferAlignFromPtrInfo(MF, MPO));
177*5ffd83dbSDimitry Andric     MIRBuilder.buildStore(ValVReg, Addr, *MMO);
178*5ffd83dbSDimitry Andric   }
179*5ffd83dbSDimitry Andric 
180*5ffd83dbSDimitry Andric   void assignValueToAddress(const CallLowering::ArgInfo &Arg, Register Addr,
181*5ffd83dbSDimitry Andric                             uint64_t Size, MachinePointerInfo &MPO,
182*5ffd83dbSDimitry Andric                             CCValAssign &VA) override {
183*5ffd83dbSDimitry Andric     unsigned MaxSize = Size * 8;
184*5ffd83dbSDimitry Andric     // For varargs, we always want to extend them to 8 bytes, in which case
185*5ffd83dbSDimitry Andric     // we disable setting a max.
186*5ffd83dbSDimitry Andric     if (!Arg.IsFixed)
187*5ffd83dbSDimitry Andric       MaxSize = 0;
188*5ffd83dbSDimitry Andric 
189*5ffd83dbSDimitry Andric     Register ValVReg = VA.getLocInfo() != CCValAssign::LocInfo::FPExt
190*5ffd83dbSDimitry Andric                            ? extendRegister(Arg.Regs[0], VA, MaxSize)
191*5ffd83dbSDimitry Andric                            : Arg.Regs[0];
192*5ffd83dbSDimitry Andric 
193*5ffd83dbSDimitry Andric     // If we extended we might need to adjust the MMO's Size.
194*5ffd83dbSDimitry Andric     const LLT RegTy = MRI.getType(ValVReg);
195*5ffd83dbSDimitry Andric     if (RegTy.getSizeInBytes() > Size)
196*5ffd83dbSDimitry Andric       Size = RegTy.getSizeInBytes();
197*5ffd83dbSDimitry Andric 
198*5ffd83dbSDimitry Andric     assignValueToAddress(ValVReg, Addr, Size, MPO, VA);
199*5ffd83dbSDimitry Andric   }
200*5ffd83dbSDimitry Andric 
201*5ffd83dbSDimitry Andric   bool assignArg(unsigned ValNo, MVT ValVT, MVT LocVT,
202*5ffd83dbSDimitry Andric                  CCValAssign::LocInfo LocInfo,
203*5ffd83dbSDimitry Andric                  const CallLowering::ArgInfo &Info,
204*5ffd83dbSDimitry Andric                  ISD::ArgFlagsTy Flags,
205*5ffd83dbSDimitry Andric                  CCState &State) override {
206*5ffd83dbSDimitry Andric     bool Res;
207*5ffd83dbSDimitry Andric     if (Info.IsFixed)
208*5ffd83dbSDimitry Andric       Res = AssignFn(ValNo, ValVT, LocVT, LocInfo, Flags, State);
209*5ffd83dbSDimitry Andric     else
210*5ffd83dbSDimitry Andric       Res = AssignFnVarArg(ValNo, ValVT, LocVT, LocInfo, Flags, State);
211*5ffd83dbSDimitry Andric 
212*5ffd83dbSDimitry Andric     StackSize = State.getNextStackOffset();
213*5ffd83dbSDimitry Andric     return Res;
214*5ffd83dbSDimitry Andric   }
215*5ffd83dbSDimitry Andric 
216*5ffd83dbSDimitry Andric   MachineInstrBuilder MIB;
217*5ffd83dbSDimitry Andric   CCAssignFn *AssignFnVarArg;
218*5ffd83dbSDimitry Andric   bool IsTailCall;
219*5ffd83dbSDimitry Andric 
220*5ffd83dbSDimitry Andric   /// For tail calls, the byte offset of the call's argument area from the
221*5ffd83dbSDimitry Andric   /// callee's. Unused elsewhere.
222*5ffd83dbSDimitry Andric   int FPDiff;
223*5ffd83dbSDimitry Andric   uint64_t StackSize;
224*5ffd83dbSDimitry Andric 
225*5ffd83dbSDimitry Andric   // Cache the SP register vreg if we need it more than once in this call site.
226*5ffd83dbSDimitry Andric   Register SPReg;
227*5ffd83dbSDimitry Andric };
228*5ffd83dbSDimitry Andric } // namespace
229*5ffd83dbSDimitry Andric 
230*5ffd83dbSDimitry Andric static bool doesCalleeRestoreStack(CallingConv::ID CallConv, bool TailCallOpt) {
231*5ffd83dbSDimitry Andric   return CallConv == CallingConv::Fast && TailCallOpt;
232*5ffd83dbSDimitry Andric }
233*5ffd83dbSDimitry Andric 
234*5ffd83dbSDimitry Andric void AArch64CallLowering::splitToValueTypes(
235*5ffd83dbSDimitry Andric     const ArgInfo &OrigArg, SmallVectorImpl<ArgInfo> &SplitArgs,
236*5ffd83dbSDimitry Andric     const DataLayout &DL, MachineRegisterInfo &MRI, CallingConv::ID CallConv) const {
237*5ffd83dbSDimitry Andric   const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
238*5ffd83dbSDimitry Andric   LLVMContext &Ctx = OrigArg.Ty->getContext();
239*5ffd83dbSDimitry Andric 
240*5ffd83dbSDimitry Andric   SmallVector<EVT, 4> SplitVTs;
241*5ffd83dbSDimitry Andric   SmallVector<uint64_t, 4> Offsets;
242*5ffd83dbSDimitry Andric   ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs, &Offsets, 0);
243*5ffd83dbSDimitry Andric 
244*5ffd83dbSDimitry Andric   if (SplitVTs.size() == 0)
245*5ffd83dbSDimitry Andric     return;
246*5ffd83dbSDimitry Andric 
247*5ffd83dbSDimitry Andric   if (SplitVTs.size() == 1) {
248*5ffd83dbSDimitry Andric     // No splitting to do, but we want to replace the original type (e.g. [1 x
249*5ffd83dbSDimitry Andric     // double] -> double).
250*5ffd83dbSDimitry Andric     SplitArgs.emplace_back(OrigArg.Regs[0], SplitVTs[0].getTypeForEVT(Ctx),
251*5ffd83dbSDimitry Andric                            OrigArg.Flags[0], OrigArg.IsFixed);
252*5ffd83dbSDimitry Andric     return;
253*5ffd83dbSDimitry Andric   }
254*5ffd83dbSDimitry Andric 
255*5ffd83dbSDimitry Andric   // Create one ArgInfo for each virtual register in the original ArgInfo.
256*5ffd83dbSDimitry Andric   assert(OrigArg.Regs.size() == SplitVTs.size() && "Regs / types mismatch");
257*5ffd83dbSDimitry Andric 
258*5ffd83dbSDimitry Andric   bool NeedsRegBlock = TLI.functionArgumentNeedsConsecutiveRegisters(
259*5ffd83dbSDimitry Andric       OrigArg.Ty, CallConv, false);
260*5ffd83dbSDimitry Andric   for (unsigned i = 0, e = SplitVTs.size(); i < e; ++i) {
261*5ffd83dbSDimitry Andric     Type *SplitTy = SplitVTs[i].getTypeForEVT(Ctx);
262*5ffd83dbSDimitry Andric     SplitArgs.emplace_back(OrigArg.Regs[i], SplitTy, OrigArg.Flags[0],
263*5ffd83dbSDimitry Andric                            OrigArg.IsFixed);
264*5ffd83dbSDimitry Andric     if (NeedsRegBlock)
265*5ffd83dbSDimitry Andric       SplitArgs.back().Flags[0].setInConsecutiveRegs();
266*5ffd83dbSDimitry Andric   }
267*5ffd83dbSDimitry Andric 
268*5ffd83dbSDimitry Andric   SplitArgs.back().Flags[0].setInConsecutiveRegsLast();
269*5ffd83dbSDimitry Andric }
270*5ffd83dbSDimitry Andric 
271*5ffd83dbSDimitry Andric bool AArch64CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
272*5ffd83dbSDimitry Andric                                       const Value *Val,
273*5ffd83dbSDimitry Andric                                       ArrayRef<Register> VRegs,
274*5ffd83dbSDimitry Andric                                       Register SwiftErrorVReg) const {
275*5ffd83dbSDimitry Andric   auto MIB = MIRBuilder.buildInstrNoInsert(AArch64::RET_ReallyLR);
276*5ffd83dbSDimitry Andric   assert(((Val && !VRegs.empty()) || (!Val && VRegs.empty())) &&
277*5ffd83dbSDimitry Andric          "Return value without a vreg");
278*5ffd83dbSDimitry Andric 
279*5ffd83dbSDimitry Andric   bool Success = true;
280*5ffd83dbSDimitry Andric   if (!VRegs.empty()) {
281*5ffd83dbSDimitry Andric     MachineFunction &MF = MIRBuilder.getMF();
282*5ffd83dbSDimitry Andric     const Function &F = MF.getFunction();
283*5ffd83dbSDimitry Andric 
284*5ffd83dbSDimitry Andric     MachineRegisterInfo &MRI = MF.getRegInfo();
285*5ffd83dbSDimitry Andric     const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
286*5ffd83dbSDimitry Andric     CCAssignFn *AssignFn = TLI.CCAssignFnForReturn(F.getCallingConv());
287*5ffd83dbSDimitry Andric     auto &DL = F.getParent()->getDataLayout();
288*5ffd83dbSDimitry Andric     LLVMContext &Ctx = Val->getType()->getContext();
289*5ffd83dbSDimitry Andric 
290*5ffd83dbSDimitry Andric     SmallVector<EVT, 4> SplitEVTs;
291*5ffd83dbSDimitry Andric     ComputeValueVTs(TLI, DL, Val->getType(), SplitEVTs);
292*5ffd83dbSDimitry Andric     assert(VRegs.size() == SplitEVTs.size() &&
293*5ffd83dbSDimitry Andric            "For each split Type there should be exactly one VReg.");
294*5ffd83dbSDimitry Andric 
295*5ffd83dbSDimitry Andric     SmallVector<ArgInfo, 8> SplitArgs;
296*5ffd83dbSDimitry Andric     CallingConv::ID CC = F.getCallingConv();
297*5ffd83dbSDimitry Andric 
298*5ffd83dbSDimitry Andric     for (unsigned i = 0; i < SplitEVTs.size(); ++i) {
299*5ffd83dbSDimitry Andric       if (TLI.getNumRegistersForCallingConv(Ctx, CC, SplitEVTs[i]) > 1) {
300*5ffd83dbSDimitry Andric         LLVM_DEBUG(dbgs() << "Can't handle extended arg types which need split");
301*5ffd83dbSDimitry Andric         return false;
302*5ffd83dbSDimitry Andric       }
303*5ffd83dbSDimitry Andric 
304*5ffd83dbSDimitry Andric       Register CurVReg = VRegs[i];
305*5ffd83dbSDimitry Andric       ArgInfo CurArgInfo = ArgInfo{CurVReg, SplitEVTs[i].getTypeForEVT(Ctx)};
306*5ffd83dbSDimitry Andric       setArgFlags(CurArgInfo, AttributeList::ReturnIndex, DL, F);
307*5ffd83dbSDimitry Andric 
308*5ffd83dbSDimitry Andric       // i1 is a special case because SDAG i1 true is naturally zero extended
309*5ffd83dbSDimitry Andric       // when widened using ANYEXT. We need to do it explicitly here.
310*5ffd83dbSDimitry Andric       if (MRI.getType(CurVReg).getSizeInBits() == 1) {
311*5ffd83dbSDimitry Andric         CurVReg = MIRBuilder.buildZExt(LLT::scalar(8), CurVReg).getReg(0);
312*5ffd83dbSDimitry Andric       } else {
313*5ffd83dbSDimitry Andric         // Some types will need extending as specified by the CC.
314*5ffd83dbSDimitry Andric         MVT NewVT = TLI.getRegisterTypeForCallingConv(Ctx, CC, SplitEVTs[i]);
315*5ffd83dbSDimitry Andric         if (EVT(NewVT) != SplitEVTs[i]) {
316*5ffd83dbSDimitry Andric           unsigned ExtendOp = TargetOpcode::G_ANYEXT;
317*5ffd83dbSDimitry Andric           if (F.getAttributes().hasAttribute(AttributeList::ReturnIndex,
318*5ffd83dbSDimitry Andric                                              Attribute::SExt))
319*5ffd83dbSDimitry Andric             ExtendOp = TargetOpcode::G_SEXT;
320*5ffd83dbSDimitry Andric           else if (F.getAttributes().hasAttribute(AttributeList::ReturnIndex,
321*5ffd83dbSDimitry Andric                                                   Attribute::ZExt))
322*5ffd83dbSDimitry Andric             ExtendOp = TargetOpcode::G_ZEXT;
323*5ffd83dbSDimitry Andric 
324*5ffd83dbSDimitry Andric           LLT NewLLT(NewVT);
325*5ffd83dbSDimitry Andric           LLT OldLLT(MVT::getVT(CurArgInfo.Ty));
326*5ffd83dbSDimitry Andric           CurArgInfo.Ty = EVT(NewVT).getTypeForEVT(Ctx);
327*5ffd83dbSDimitry Andric           // Instead of an extend, we might have a vector type which needs
328*5ffd83dbSDimitry Andric           // padding with more elements, e.g. <2 x half> -> <4 x half>.
329*5ffd83dbSDimitry Andric           if (NewVT.isVector()) {
330*5ffd83dbSDimitry Andric             if (OldLLT.isVector()) {
331*5ffd83dbSDimitry Andric               if (NewLLT.getNumElements() > OldLLT.getNumElements()) {
332*5ffd83dbSDimitry Andric                 // We don't handle VA types which are not exactly twice the
333*5ffd83dbSDimitry Andric                 // size, but can easily be done in future.
334*5ffd83dbSDimitry Andric                 if (NewLLT.getNumElements() != OldLLT.getNumElements() * 2) {
335*5ffd83dbSDimitry Andric                   LLVM_DEBUG(dbgs() << "Outgoing vector ret has too many elts");
336*5ffd83dbSDimitry Andric                   return false;
337*5ffd83dbSDimitry Andric                 }
338*5ffd83dbSDimitry Andric                 auto Undef = MIRBuilder.buildUndef({OldLLT});
339*5ffd83dbSDimitry Andric                 CurVReg =
340*5ffd83dbSDimitry Andric                     MIRBuilder.buildMerge({NewLLT}, {CurVReg, Undef}).getReg(0);
341*5ffd83dbSDimitry Andric               } else {
342*5ffd83dbSDimitry Andric                 // Just do a vector extend.
343*5ffd83dbSDimitry Andric                 CurVReg = MIRBuilder.buildInstr(ExtendOp, {NewLLT}, {CurVReg})
344*5ffd83dbSDimitry Andric                               .getReg(0);
345*5ffd83dbSDimitry Andric               }
346*5ffd83dbSDimitry Andric             } else if (NewLLT.getNumElements() == 2) {
347*5ffd83dbSDimitry Andric               // We need to pad a <1 x S> type to <2 x S>. Since we don't have
348*5ffd83dbSDimitry Andric               // <1 x S> vector types in GISel we use a build_vector instead
349*5ffd83dbSDimitry Andric               // of a vector merge/concat.
350*5ffd83dbSDimitry Andric               auto Undef = MIRBuilder.buildUndef({OldLLT});
351*5ffd83dbSDimitry Andric               CurVReg =
352*5ffd83dbSDimitry Andric                   MIRBuilder
353*5ffd83dbSDimitry Andric                       .buildBuildVector({NewLLT}, {CurVReg, Undef.getReg(0)})
354*5ffd83dbSDimitry Andric                       .getReg(0);
355*5ffd83dbSDimitry Andric             } else {
356*5ffd83dbSDimitry Andric               LLVM_DEBUG(dbgs() << "Could not handle ret ty");
357*5ffd83dbSDimitry Andric               return false;
358*5ffd83dbSDimitry Andric             }
359*5ffd83dbSDimitry Andric           } else {
360*5ffd83dbSDimitry Andric             // A scalar extend.
361*5ffd83dbSDimitry Andric             CurVReg =
362*5ffd83dbSDimitry Andric                 MIRBuilder.buildInstr(ExtendOp, {NewLLT}, {CurVReg}).getReg(0);
363*5ffd83dbSDimitry Andric           }
364*5ffd83dbSDimitry Andric         }
365*5ffd83dbSDimitry Andric       }
366*5ffd83dbSDimitry Andric       if (CurVReg != CurArgInfo.Regs[0]) {
367*5ffd83dbSDimitry Andric         CurArgInfo.Regs[0] = CurVReg;
368*5ffd83dbSDimitry Andric         // Reset the arg flags after modifying CurVReg.
369*5ffd83dbSDimitry Andric         setArgFlags(CurArgInfo, AttributeList::ReturnIndex, DL, F);
370*5ffd83dbSDimitry Andric       }
371*5ffd83dbSDimitry Andric      splitToValueTypes(CurArgInfo, SplitArgs, DL, MRI, CC);
372*5ffd83dbSDimitry Andric     }
373*5ffd83dbSDimitry Andric 
374*5ffd83dbSDimitry Andric     OutgoingArgHandler Handler(MIRBuilder, MRI, MIB, AssignFn, AssignFn);
375*5ffd83dbSDimitry Andric     Success = handleAssignments(MIRBuilder, SplitArgs, Handler);
376*5ffd83dbSDimitry Andric   }
377*5ffd83dbSDimitry Andric 
378*5ffd83dbSDimitry Andric   if (SwiftErrorVReg) {
379*5ffd83dbSDimitry Andric     MIB.addUse(AArch64::X21, RegState::Implicit);
380*5ffd83dbSDimitry Andric     MIRBuilder.buildCopy(AArch64::X21, SwiftErrorVReg);
381*5ffd83dbSDimitry Andric   }
382*5ffd83dbSDimitry Andric 
383*5ffd83dbSDimitry Andric   MIRBuilder.insertInstr(MIB);
384*5ffd83dbSDimitry Andric   return Success;
385*5ffd83dbSDimitry Andric }
386*5ffd83dbSDimitry Andric 
387*5ffd83dbSDimitry Andric /// Helper function to compute forwarded registers for musttail calls. Computes
388*5ffd83dbSDimitry Andric /// the forwarded registers, sets MBB liveness, and emits COPY instructions that
389*5ffd83dbSDimitry Andric /// can be used to save + restore registers later.
390*5ffd83dbSDimitry Andric static void handleMustTailForwardedRegisters(MachineIRBuilder &MIRBuilder,
391*5ffd83dbSDimitry Andric                                              CCAssignFn *AssignFn) {
392*5ffd83dbSDimitry Andric   MachineBasicBlock &MBB = MIRBuilder.getMBB();
393*5ffd83dbSDimitry Andric   MachineFunction &MF = MIRBuilder.getMF();
394*5ffd83dbSDimitry Andric   MachineFrameInfo &MFI = MF.getFrameInfo();
395*5ffd83dbSDimitry Andric 
396*5ffd83dbSDimitry Andric   if (!MFI.hasMustTailInVarArgFunc())
397*5ffd83dbSDimitry Andric     return;
398*5ffd83dbSDimitry Andric 
399*5ffd83dbSDimitry Andric   AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>();
400*5ffd83dbSDimitry Andric   const Function &F = MF.getFunction();
401*5ffd83dbSDimitry Andric   assert(F.isVarArg() && "Expected F to be vararg?");
402*5ffd83dbSDimitry Andric 
403*5ffd83dbSDimitry Andric   // Compute the set of forwarded registers. The rest are scratch.
404*5ffd83dbSDimitry Andric   SmallVector<CCValAssign, 16> ArgLocs;
405*5ffd83dbSDimitry Andric   CCState CCInfo(F.getCallingConv(), /*IsVarArg=*/true, MF, ArgLocs,
406*5ffd83dbSDimitry Andric                  F.getContext());
407*5ffd83dbSDimitry Andric   SmallVector<MVT, 2> RegParmTypes;
408*5ffd83dbSDimitry Andric   RegParmTypes.push_back(MVT::i64);
409*5ffd83dbSDimitry Andric   RegParmTypes.push_back(MVT::f128);
410*5ffd83dbSDimitry Andric 
411*5ffd83dbSDimitry Andric   // Later on, we can use this vector to restore the registers if necessary.
412*5ffd83dbSDimitry Andric   SmallVectorImpl<ForwardedRegister> &Forwards =
413*5ffd83dbSDimitry Andric       FuncInfo->getForwardedMustTailRegParms();
414*5ffd83dbSDimitry Andric   CCInfo.analyzeMustTailForwardedRegisters(Forwards, RegParmTypes, AssignFn);
415*5ffd83dbSDimitry Andric 
416*5ffd83dbSDimitry Andric   // Conservatively forward X8, since it might be used for an aggregate
417*5ffd83dbSDimitry Andric   // return.
418*5ffd83dbSDimitry Andric   if (!CCInfo.isAllocated(AArch64::X8)) {
419*5ffd83dbSDimitry Andric     unsigned X8VReg = MF.addLiveIn(AArch64::X8, &AArch64::GPR64RegClass);
420*5ffd83dbSDimitry Andric     Forwards.push_back(ForwardedRegister(X8VReg, AArch64::X8, MVT::i64));
421*5ffd83dbSDimitry Andric   }
422*5ffd83dbSDimitry Andric 
423*5ffd83dbSDimitry Andric   // Add the forwards to the MachineBasicBlock and MachineFunction.
424*5ffd83dbSDimitry Andric   for (const auto &F : Forwards) {
425*5ffd83dbSDimitry Andric     MBB.addLiveIn(F.PReg);
426*5ffd83dbSDimitry Andric     MIRBuilder.buildCopy(Register(F.VReg), Register(F.PReg));
427*5ffd83dbSDimitry Andric   }
428*5ffd83dbSDimitry Andric }
429*5ffd83dbSDimitry Andric 
430*5ffd83dbSDimitry Andric bool AArch64CallLowering::fallBackToDAGISel(const Function &F) const {
431*5ffd83dbSDimitry Andric   if (isa<ScalableVectorType>(F.getReturnType()))
432*5ffd83dbSDimitry Andric     return true;
433*5ffd83dbSDimitry Andric   return llvm::any_of(F.args(), [](const Argument &A) {
434*5ffd83dbSDimitry Andric     return isa<ScalableVectorType>(A.getType());
435*5ffd83dbSDimitry Andric   });
436*5ffd83dbSDimitry Andric }
437*5ffd83dbSDimitry Andric 
438*5ffd83dbSDimitry Andric bool AArch64CallLowering::lowerFormalArguments(
439*5ffd83dbSDimitry Andric     MachineIRBuilder &MIRBuilder, const Function &F,
440*5ffd83dbSDimitry Andric     ArrayRef<ArrayRef<Register>> VRegs) const {
441*5ffd83dbSDimitry Andric   MachineFunction &MF = MIRBuilder.getMF();
442*5ffd83dbSDimitry Andric   MachineBasicBlock &MBB = MIRBuilder.getMBB();
443*5ffd83dbSDimitry Andric   MachineRegisterInfo &MRI = MF.getRegInfo();
444*5ffd83dbSDimitry Andric   auto &DL = F.getParent()->getDataLayout();
445*5ffd83dbSDimitry Andric 
446*5ffd83dbSDimitry Andric   SmallVector<ArgInfo, 8> SplitArgs;
447*5ffd83dbSDimitry Andric   unsigned i = 0;
448*5ffd83dbSDimitry Andric   for (auto &Arg : F.args()) {
449*5ffd83dbSDimitry Andric     if (DL.getTypeStoreSize(Arg.getType()).isZero())
450*5ffd83dbSDimitry Andric       continue;
451*5ffd83dbSDimitry Andric 
452*5ffd83dbSDimitry Andric     ArgInfo OrigArg{VRegs[i], Arg.getType()};
453*5ffd83dbSDimitry Andric     setArgFlags(OrigArg, i + AttributeList::FirstArgIndex, DL, F);
454*5ffd83dbSDimitry Andric 
455*5ffd83dbSDimitry Andric     splitToValueTypes(OrigArg, SplitArgs, DL, MRI, F.getCallingConv());
456*5ffd83dbSDimitry Andric     ++i;
457*5ffd83dbSDimitry Andric   }
458*5ffd83dbSDimitry Andric 
459*5ffd83dbSDimitry Andric   if (!MBB.empty())
460*5ffd83dbSDimitry Andric     MIRBuilder.setInstr(*MBB.begin());
461*5ffd83dbSDimitry Andric 
462*5ffd83dbSDimitry Andric   const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
463*5ffd83dbSDimitry Andric   CCAssignFn *AssignFn =
464*5ffd83dbSDimitry Andric       TLI.CCAssignFnForCall(F.getCallingConv(), /*IsVarArg=*/false);
465*5ffd83dbSDimitry Andric 
466*5ffd83dbSDimitry Andric   FormalArgHandler Handler(MIRBuilder, MRI, AssignFn);
467*5ffd83dbSDimitry Andric   if (!handleAssignments(MIRBuilder, SplitArgs, Handler))
468*5ffd83dbSDimitry Andric     return false;
469*5ffd83dbSDimitry Andric 
470*5ffd83dbSDimitry Andric   AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>();
471*5ffd83dbSDimitry Andric   uint64_t StackOffset = Handler.StackUsed;
472*5ffd83dbSDimitry Andric   if (F.isVarArg()) {
473*5ffd83dbSDimitry Andric     auto &Subtarget = MF.getSubtarget<AArch64Subtarget>();
474*5ffd83dbSDimitry Andric     if (!Subtarget.isTargetDarwin()) {
475*5ffd83dbSDimitry Andric         // FIXME: we need to reimplement saveVarArgsRegisters from
476*5ffd83dbSDimitry Andric       // AArch64ISelLowering.
477*5ffd83dbSDimitry Andric       return false;
478*5ffd83dbSDimitry Andric     }
479*5ffd83dbSDimitry Andric 
480*5ffd83dbSDimitry Andric     // We currently pass all varargs at 8-byte alignment, or 4 in ILP32.
481*5ffd83dbSDimitry Andric     StackOffset = alignTo(Handler.StackUsed, Subtarget.isTargetILP32() ? 4 : 8);
482*5ffd83dbSDimitry Andric 
483*5ffd83dbSDimitry Andric     auto &MFI = MIRBuilder.getMF().getFrameInfo();
484*5ffd83dbSDimitry Andric     FuncInfo->setVarArgsStackIndex(MFI.CreateFixedObject(4, StackOffset, true));
485*5ffd83dbSDimitry Andric   }
486*5ffd83dbSDimitry Andric 
487*5ffd83dbSDimitry Andric   if (doesCalleeRestoreStack(F.getCallingConv(),
488*5ffd83dbSDimitry Andric                              MF.getTarget().Options.GuaranteedTailCallOpt)) {
489*5ffd83dbSDimitry Andric     // We have a non-standard ABI, so why not make full use of the stack that
490*5ffd83dbSDimitry Andric     // we're going to pop? It must be aligned to 16 B in any case.
491*5ffd83dbSDimitry Andric     StackOffset = alignTo(StackOffset, 16);
492*5ffd83dbSDimitry Andric 
493*5ffd83dbSDimitry Andric     // If we're expected to restore the stack (e.g. fastcc), then we'll be
494*5ffd83dbSDimitry Andric     // adding a multiple of 16.
495*5ffd83dbSDimitry Andric     FuncInfo->setArgumentStackToRestore(StackOffset);
496*5ffd83dbSDimitry Andric 
497*5ffd83dbSDimitry Andric     // Our own callers will guarantee that the space is free by giving an
498*5ffd83dbSDimitry Andric     // aligned value to CALLSEQ_START.
499*5ffd83dbSDimitry Andric   }
500*5ffd83dbSDimitry Andric 
501*5ffd83dbSDimitry Andric   // When we tail call, we need to check if the callee's arguments
502*5ffd83dbSDimitry Andric   // will fit on the caller's stack. So, whenever we lower formal arguments,
503*5ffd83dbSDimitry Andric   // we should keep track of this information, since we might lower a tail call
504*5ffd83dbSDimitry Andric   // in this function later.
505*5ffd83dbSDimitry Andric   FuncInfo->setBytesInStackArgArea(StackOffset);
506*5ffd83dbSDimitry Andric 
507*5ffd83dbSDimitry Andric   auto &Subtarget = MF.getSubtarget<AArch64Subtarget>();
508*5ffd83dbSDimitry Andric   if (Subtarget.hasCustomCallingConv())
509*5ffd83dbSDimitry Andric     Subtarget.getRegisterInfo()->UpdateCustomCalleeSavedRegs(MF);
510*5ffd83dbSDimitry Andric 
511*5ffd83dbSDimitry Andric   handleMustTailForwardedRegisters(MIRBuilder, AssignFn);
512*5ffd83dbSDimitry Andric 
513*5ffd83dbSDimitry Andric   // Move back to the end of the basic block.
514*5ffd83dbSDimitry Andric   MIRBuilder.setMBB(MBB);
515*5ffd83dbSDimitry Andric 
516*5ffd83dbSDimitry Andric   return true;
517*5ffd83dbSDimitry Andric }
518*5ffd83dbSDimitry Andric 
519*5ffd83dbSDimitry Andric /// Return true if the calling convention is one that we can guarantee TCO for.
520*5ffd83dbSDimitry Andric static bool canGuaranteeTCO(CallingConv::ID CC) {
521*5ffd83dbSDimitry Andric   return CC == CallingConv::Fast;
522*5ffd83dbSDimitry Andric }
523*5ffd83dbSDimitry Andric 
524*5ffd83dbSDimitry Andric /// Return true if we might ever do TCO for calls with this calling convention.
525*5ffd83dbSDimitry Andric static bool mayTailCallThisCC(CallingConv::ID CC) {
526*5ffd83dbSDimitry Andric   switch (CC) {
527*5ffd83dbSDimitry Andric   case CallingConv::C:
528*5ffd83dbSDimitry Andric   case CallingConv::PreserveMost:
529*5ffd83dbSDimitry Andric   case CallingConv::Swift:
530*5ffd83dbSDimitry Andric     return true;
531*5ffd83dbSDimitry Andric   default:
532*5ffd83dbSDimitry Andric     return canGuaranteeTCO(CC);
533*5ffd83dbSDimitry Andric   }
534*5ffd83dbSDimitry Andric }
535*5ffd83dbSDimitry Andric 
536*5ffd83dbSDimitry Andric /// Returns a pair containing the fixed CCAssignFn and the vararg CCAssignFn for
537*5ffd83dbSDimitry Andric /// CC.
538*5ffd83dbSDimitry Andric static std::pair<CCAssignFn *, CCAssignFn *>
539*5ffd83dbSDimitry Andric getAssignFnsForCC(CallingConv::ID CC, const AArch64TargetLowering &TLI) {
540*5ffd83dbSDimitry Andric   return {TLI.CCAssignFnForCall(CC, false), TLI.CCAssignFnForCall(CC, true)};
541*5ffd83dbSDimitry Andric }
542*5ffd83dbSDimitry Andric 
543*5ffd83dbSDimitry Andric bool AArch64CallLowering::doCallerAndCalleePassArgsTheSameWay(
544*5ffd83dbSDimitry Andric     CallLoweringInfo &Info, MachineFunction &MF,
545*5ffd83dbSDimitry Andric     SmallVectorImpl<ArgInfo> &InArgs) const {
546*5ffd83dbSDimitry Andric   const Function &CallerF = MF.getFunction();
547*5ffd83dbSDimitry Andric   CallingConv::ID CalleeCC = Info.CallConv;
548*5ffd83dbSDimitry Andric   CallingConv::ID CallerCC = CallerF.getCallingConv();
549*5ffd83dbSDimitry Andric 
550*5ffd83dbSDimitry Andric   // If the calling conventions match, then everything must be the same.
551*5ffd83dbSDimitry Andric   if (CalleeCC == CallerCC)
552*5ffd83dbSDimitry Andric     return true;
553*5ffd83dbSDimitry Andric 
554*5ffd83dbSDimitry Andric   // Check if the caller and callee will handle arguments in the same way.
555*5ffd83dbSDimitry Andric   const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
556*5ffd83dbSDimitry Andric   CCAssignFn *CalleeAssignFnFixed;
557*5ffd83dbSDimitry Andric   CCAssignFn *CalleeAssignFnVarArg;
558*5ffd83dbSDimitry Andric   std::tie(CalleeAssignFnFixed, CalleeAssignFnVarArg) =
559*5ffd83dbSDimitry Andric       getAssignFnsForCC(CalleeCC, TLI);
560*5ffd83dbSDimitry Andric 
561*5ffd83dbSDimitry Andric   CCAssignFn *CallerAssignFnFixed;
562*5ffd83dbSDimitry Andric   CCAssignFn *CallerAssignFnVarArg;
563*5ffd83dbSDimitry Andric   std::tie(CallerAssignFnFixed, CallerAssignFnVarArg) =
564*5ffd83dbSDimitry Andric       getAssignFnsForCC(CallerCC, TLI);
565*5ffd83dbSDimitry Andric 
566*5ffd83dbSDimitry Andric   if (!resultsCompatible(Info, MF, InArgs, *CalleeAssignFnFixed,
567*5ffd83dbSDimitry Andric                          *CalleeAssignFnVarArg, *CallerAssignFnFixed,
568*5ffd83dbSDimitry Andric                          *CallerAssignFnVarArg))
569*5ffd83dbSDimitry Andric     return false;
570*5ffd83dbSDimitry Andric 
571*5ffd83dbSDimitry Andric   // Make sure that the caller and callee preserve all of the same registers.
572*5ffd83dbSDimitry Andric   auto TRI = MF.getSubtarget<AArch64Subtarget>().getRegisterInfo();
573*5ffd83dbSDimitry Andric   const uint32_t *CallerPreserved = TRI->getCallPreservedMask(MF, CallerCC);
574*5ffd83dbSDimitry Andric   const uint32_t *CalleePreserved = TRI->getCallPreservedMask(MF, CalleeCC);
575*5ffd83dbSDimitry Andric   if (MF.getSubtarget<AArch64Subtarget>().hasCustomCallingConv()) {
576*5ffd83dbSDimitry Andric     TRI->UpdateCustomCallPreservedMask(MF, &CallerPreserved);
577*5ffd83dbSDimitry Andric     TRI->UpdateCustomCallPreservedMask(MF, &CalleePreserved);
578*5ffd83dbSDimitry Andric   }
579*5ffd83dbSDimitry Andric 
580*5ffd83dbSDimitry Andric   return TRI->regmaskSubsetEqual(CallerPreserved, CalleePreserved);
581*5ffd83dbSDimitry Andric }
582*5ffd83dbSDimitry Andric 
583*5ffd83dbSDimitry Andric bool AArch64CallLowering::areCalleeOutgoingArgsTailCallable(
584*5ffd83dbSDimitry Andric     CallLoweringInfo &Info, MachineFunction &MF,
585*5ffd83dbSDimitry Andric     SmallVectorImpl<ArgInfo> &OutArgs) const {
586*5ffd83dbSDimitry Andric   // If there are no outgoing arguments, then we are done.
587*5ffd83dbSDimitry Andric   if (OutArgs.empty())
588*5ffd83dbSDimitry Andric     return true;
589*5ffd83dbSDimitry Andric 
590*5ffd83dbSDimitry Andric   const Function &CallerF = MF.getFunction();
591*5ffd83dbSDimitry Andric   CallingConv::ID CalleeCC = Info.CallConv;
592*5ffd83dbSDimitry Andric   CallingConv::ID CallerCC = CallerF.getCallingConv();
593*5ffd83dbSDimitry Andric   const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
594*5ffd83dbSDimitry Andric 
595*5ffd83dbSDimitry Andric   CCAssignFn *AssignFnFixed;
596*5ffd83dbSDimitry Andric   CCAssignFn *AssignFnVarArg;
597*5ffd83dbSDimitry Andric   std::tie(AssignFnFixed, AssignFnVarArg) = getAssignFnsForCC(CalleeCC, TLI);
598*5ffd83dbSDimitry Andric 
599*5ffd83dbSDimitry Andric   // We have outgoing arguments. Make sure that we can tail call with them.
600*5ffd83dbSDimitry Andric   SmallVector<CCValAssign, 16> OutLocs;
601*5ffd83dbSDimitry Andric   CCState OutInfo(CalleeCC, false, MF, OutLocs, CallerF.getContext());
602*5ffd83dbSDimitry Andric 
603*5ffd83dbSDimitry Andric   if (!analyzeArgInfo(OutInfo, OutArgs, *AssignFnFixed, *AssignFnVarArg)) {
604*5ffd83dbSDimitry Andric     LLVM_DEBUG(dbgs() << "... Could not analyze call operands.\n");
605*5ffd83dbSDimitry Andric     return false;
606*5ffd83dbSDimitry Andric   }
607*5ffd83dbSDimitry Andric 
608*5ffd83dbSDimitry Andric   // Make sure that they can fit on the caller's stack.
609*5ffd83dbSDimitry Andric   const AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>();
610*5ffd83dbSDimitry Andric   if (OutInfo.getNextStackOffset() > FuncInfo->getBytesInStackArgArea()) {
611*5ffd83dbSDimitry Andric     LLVM_DEBUG(dbgs() << "... Cannot fit call operands on caller's stack.\n");
612*5ffd83dbSDimitry Andric     return false;
613*5ffd83dbSDimitry Andric   }
614*5ffd83dbSDimitry Andric 
615*5ffd83dbSDimitry Andric   // Verify that the parameters in callee-saved registers match.
616*5ffd83dbSDimitry Andric   // TODO: Port this over to CallLowering as general code once swiftself is
617*5ffd83dbSDimitry Andric   // supported.
618*5ffd83dbSDimitry Andric   auto TRI = MF.getSubtarget<AArch64Subtarget>().getRegisterInfo();
619*5ffd83dbSDimitry Andric   const uint32_t *CallerPreservedMask = TRI->getCallPreservedMask(MF, CallerCC);
620*5ffd83dbSDimitry Andric   MachineRegisterInfo &MRI = MF.getRegInfo();
621*5ffd83dbSDimitry Andric 
622*5ffd83dbSDimitry Andric   for (unsigned i = 0; i < OutLocs.size(); ++i) {
623*5ffd83dbSDimitry Andric     auto &ArgLoc = OutLocs[i];
624*5ffd83dbSDimitry Andric     // If it's not a register, it's fine.
625*5ffd83dbSDimitry Andric     if (!ArgLoc.isRegLoc()) {
626*5ffd83dbSDimitry Andric       if (Info.IsVarArg) {
627*5ffd83dbSDimitry Andric         // Be conservative and disallow variadic memory operands to match SDAG's
628*5ffd83dbSDimitry Andric         // behaviour.
629*5ffd83dbSDimitry Andric         // FIXME: If the caller's calling convention is C, then we can
630*5ffd83dbSDimitry Andric         // potentially use its argument area. However, for cases like fastcc,
631*5ffd83dbSDimitry Andric         // we can't do anything.
632*5ffd83dbSDimitry Andric         LLVM_DEBUG(
633*5ffd83dbSDimitry Andric             dbgs()
634*5ffd83dbSDimitry Andric             << "... Cannot tail call vararg function with stack arguments\n");
635*5ffd83dbSDimitry Andric         return false;
636*5ffd83dbSDimitry Andric       }
637*5ffd83dbSDimitry Andric       continue;
638*5ffd83dbSDimitry Andric     }
639*5ffd83dbSDimitry Andric 
640*5ffd83dbSDimitry Andric     Register Reg = ArgLoc.getLocReg();
641*5ffd83dbSDimitry Andric 
642*5ffd83dbSDimitry Andric     // Only look at callee-saved registers.
643*5ffd83dbSDimitry Andric     if (MachineOperand::clobbersPhysReg(CallerPreservedMask, Reg))
644*5ffd83dbSDimitry Andric       continue;
645*5ffd83dbSDimitry Andric 
646*5ffd83dbSDimitry Andric     LLVM_DEBUG(
647*5ffd83dbSDimitry Andric         dbgs()
648*5ffd83dbSDimitry Andric         << "... Call has an argument passed in a callee-saved register.\n");
649*5ffd83dbSDimitry Andric 
650*5ffd83dbSDimitry Andric     // Check if it was copied from.
651*5ffd83dbSDimitry Andric     ArgInfo &OutInfo = OutArgs[i];
652*5ffd83dbSDimitry Andric 
653*5ffd83dbSDimitry Andric     if (OutInfo.Regs.size() > 1) {
654*5ffd83dbSDimitry Andric       LLVM_DEBUG(
655*5ffd83dbSDimitry Andric           dbgs() << "... Cannot handle arguments in multiple registers.\n");
656*5ffd83dbSDimitry Andric       return false;
657*5ffd83dbSDimitry Andric     }
658*5ffd83dbSDimitry Andric 
659*5ffd83dbSDimitry Andric     // Check if we copy the register, walking through copies from virtual
660*5ffd83dbSDimitry Andric     // registers. Note that getDefIgnoringCopies does not ignore copies from
661*5ffd83dbSDimitry Andric     // physical registers.
662*5ffd83dbSDimitry Andric     MachineInstr *RegDef = getDefIgnoringCopies(OutInfo.Regs[0], MRI);
663*5ffd83dbSDimitry Andric     if (!RegDef || RegDef->getOpcode() != TargetOpcode::COPY) {
664*5ffd83dbSDimitry Andric       LLVM_DEBUG(
665*5ffd83dbSDimitry Andric           dbgs()
666*5ffd83dbSDimitry Andric           << "... Parameter was not copied into a VReg, cannot tail call.\n");
667*5ffd83dbSDimitry Andric       return false;
668*5ffd83dbSDimitry Andric     }
669*5ffd83dbSDimitry Andric 
670*5ffd83dbSDimitry Andric     // Got a copy. Verify that it's the same as the register we want.
671*5ffd83dbSDimitry Andric     Register CopyRHS = RegDef->getOperand(1).getReg();
672*5ffd83dbSDimitry Andric     if (CopyRHS != Reg) {
673*5ffd83dbSDimitry Andric       LLVM_DEBUG(dbgs() << "... Callee-saved register was not copied into "
674*5ffd83dbSDimitry Andric                            "VReg, cannot tail call.\n");
675*5ffd83dbSDimitry Andric       return false;
676*5ffd83dbSDimitry Andric     }
677*5ffd83dbSDimitry Andric   }
678*5ffd83dbSDimitry Andric 
679*5ffd83dbSDimitry Andric   return true;
680*5ffd83dbSDimitry Andric }
681*5ffd83dbSDimitry Andric 
682*5ffd83dbSDimitry Andric bool AArch64CallLowering::isEligibleForTailCallOptimization(
683*5ffd83dbSDimitry Andric     MachineIRBuilder &MIRBuilder, CallLoweringInfo &Info,
684*5ffd83dbSDimitry Andric     SmallVectorImpl<ArgInfo> &InArgs,
685*5ffd83dbSDimitry Andric     SmallVectorImpl<ArgInfo> &OutArgs) const {
686*5ffd83dbSDimitry Andric 
687*5ffd83dbSDimitry Andric   // Must pass all target-independent checks in order to tail call optimize.
688*5ffd83dbSDimitry Andric   if (!Info.IsTailCall)
689*5ffd83dbSDimitry Andric     return false;
690*5ffd83dbSDimitry Andric 
691*5ffd83dbSDimitry Andric   CallingConv::ID CalleeCC = Info.CallConv;
692*5ffd83dbSDimitry Andric   MachineFunction &MF = MIRBuilder.getMF();
693*5ffd83dbSDimitry Andric   const Function &CallerF = MF.getFunction();
694*5ffd83dbSDimitry Andric 
695*5ffd83dbSDimitry Andric   LLVM_DEBUG(dbgs() << "Attempting to lower call as tail call\n");
696*5ffd83dbSDimitry Andric 
697*5ffd83dbSDimitry Andric   if (Info.SwiftErrorVReg) {
698*5ffd83dbSDimitry Andric     // TODO: We should handle this.
699*5ffd83dbSDimitry Andric     // Note that this is also handled by the check for no outgoing arguments.
700*5ffd83dbSDimitry Andric     // Proactively disabling this though, because the swifterror handling in
701*5ffd83dbSDimitry Andric     // lowerCall inserts a COPY *after* the location of the call.
702*5ffd83dbSDimitry Andric     LLVM_DEBUG(dbgs() << "... Cannot handle tail calls with swifterror yet.\n");
703*5ffd83dbSDimitry Andric     return false;
704*5ffd83dbSDimitry Andric   }
705*5ffd83dbSDimitry Andric 
706*5ffd83dbSDimitry Andric   if (!mayTailCallThisCC(CalleeCC)) {
707*5ffd83dbSDimitry Andric     LLVM_DEBUG(dbgs() << "... Calling convention cannot be tail called.\n");
708*5ffd83dbSDimitry Andric     return false;
709*5ffd83dbSDimitry Andric   }
710*5ffd83dbSDimitry Andric 
711*5ffd83dbSDimitry Andric   // Byval parameters hand the function a pointer directly into the stack area
712*5ffd83dbSDimitry Andric   // we want to reuse during a tail call. Working around this *is* possible (see
713*5ffd83dbSDimitry Andric   // X86).
714*5ffd83dbSDimitry Andric   //
715*5ffd83dbSDimitry Andric   // FIXME: In AArch64ISelLowering, this isn't worked around. Can/should we try
716*5ffd83dbSDimitry Andric   // it?
717*5ffd83dbSDimitry Andric   //
718*5ffd83dbSDimitry Andric   // On Windows, "inreg" attributes signify non-aggregate indirect returns.
719*5ffd83dbSDimitry Andric   // In this case, it is necessary to save/restore X0 in the callee. Tail
720*5ffd83dbSDimitry Andric   // call opt interferes with this. So we disable tail call opt when the
721*5ffd83dbSDimitry Andric   // caller has an argument with "inreg" attribute.
722*5ffd83dbSDimitry Andric   //
723*5ffd83dbSDimitry Andric   // FIXME: Check whether the callee also has an "inreg" argument.
724*5ffd83dbSDimitry Andric   //
725*5ffd83dbSDimitry Andric   // When the caller has a swifterror argument, we don't want to tail call
726*5ffd83dbSDimitry Andric   // because would have to move into the swifterror register before the
727*5ffd83dbSDimitry Andric   // tail call.
728*5ffd83dbSDimitry Andric   if (any_of(CallerF.args(), [](const Argument &A) {
729*5ffd83dbSDimitry Andric         return A.hasByValAttr() || A.hasInRegAttr() || A.hasSwiftErrorAttr();
730*5ffd83dbSDimitry Andric       })) {
731*5ffd83dbSDimitry Andric     LLVM_DEBUG(dbgs() << "... Cannot tail call from callers with byval, "
732*5ffd83dbSDimitry Andric                          "inreg, or swifterror arguments\n");
733*5ffd83dbSDimitry Andric     return false;
734*5ffd83dbSDimitry Andric   }
735*5ffd83dbSDimitry Andric 
736*5ffd83dbSDimitry Andric   // Externally-defined functions with weak linkage should not be
737*5ffd83dbSDimitry Andric   // tail-called on AArch64 when the OS does not support dynamic
738*5ffd83dbSDimitry Andric   // pre-emption of symbols, as the AAELF spec requires normal calls
739*5ffd83dbSDimitry Andric   // to undefined weak functions to be replaced with a NOP or jump to the
740*5ffd83dbSDimitry Andric   // next instruction. The behaviour of branch instructions in this
741*5ffd83dbSDimitry Andric   // situation (as used for tail calls) is implementation-defined, so we
742*5ffd83dbSDimitry Andric   // cannot rely on the linker replacing the tail call with a return.
743*5ffd83dbSDimitry Andric   if (Info.Callee.isGlobal()) {
744*5ffd83dbSDimitry Andric     const GlobalValue *GV = Info.Callee.getGlobal();
745*5ffd83dbSDimitry Andric     const Triple &TT = MF.getTarget().getTargetTriple();
746*5ffd83dbSDimitry Andric     if (GV->hasExternalWeakLinkage() &&
747*5ffd83dbSDimitry Andric         (!TT.isOSWindows() || TT.isOSBinFormatELF() ||
748*5ffd83dbSDimitry Andric          TT.isOSBinFormatMachO())) {
749*5ffd83dbSDimitry Andric       LLVM_DEBUG(dbgs() << "... Cannot tail call externally-defined function "
750*5ffd83dbSDimitry Andric                            "with weak linkage for this OS.\n");
751*5ffd83dbSDimitry Andric       return false;
752*5ffd83dbSDimitry Andric     }
753*5ffd83dbSDimitry Andric   }
754*5ffd83dbSDimitry Andric 
755*5ffd83dbSDimitry Andric   // If we have -tailcallopt, then we're done.
756*5ffd83dbSDimitry Andric   if (MF.getTarget().Options.GuaranteedTailCallOpt)
757*5ffd83dbSDimitry Andric     return canGuaranteeTCO(CalleeCC) && CalleeCC == CallerF.getCallingConv();
758*5ffd83dbSDimitry Andric 
759*5ffd83dbSDimitry Andric   // We don't have -tailcallopt, so we're allowed to change the ABI (sibcall).
760*5ffd83dbSDimitry Andric   // Try to find cases where we can do that.
761*5ffd83dbSDimitry Andric 
762*5ffd83dbSDimitry Andric   // I want anyone implementing a new calling convention to think long and hard
763*5ffd83dbSDimitry Andric   // about this assert.
764*5ffd83dbSDimitry Andric   assert((!Info.IsVarArg || CalleeCC == CallingConv::C) &&
765*5ffd83dbSDimitry Andric          "Unexpected variadic calling convention");
766*5ffd83dbSDimitry Andric 
767*5ffd83dbSDimitry Andric   // Verify that the incoming and outgoing arguments from the callee are
768*5ffd83dbSDimitry Andric   // safe to tail call.
769*5ffd83dbSDimitry Andric   if (!doCallerAndCalleePassArgsTheSameWay(Info, MF, InArgs)) {
770*5ffd83dbSDimitry Andric     LLVM_DEBUG(
771*5ffd83dbSDimitry Andric         dbgs()
772*5ffd83dbSDimitry Andric         << "... Caller and callee have incompatible calling conventions.\n");
773*5ffd83dbSDimitry Andric     return false;
774*5ffd83dbSDimitry Andric   }
775*5ffd83dbSDimitry Andric 
776*5ffd83dbSDimitry Andric   if (!areCalleeOutgoingArgsTailCallable(Info, MF, OutArgs))
777*5ffd83dbSDimitry Andric     return false;
778*5ffd83dbSDimitry Andric 
779*5ffd83dbSDimitry Andric   LLVM_DEBUG(
780*5ffd83dbSDimitry Andric       dbgs() << "... Call is eligible for tail call optimization.\n");
781*5ffd83dbSDimitry Andric   return true;
782*5ffd83dbSDimitry Andric }
783*5ffd83dbSDimitry Andric 
784*5ffd83dbSDimitry Andric static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect,
785*5ffd83dbSDimitry Andric                               bool IsTailCall) {
786*5ffd83dbSDimitry Andric   if (!IsTailCall)
787*5ffd83dbSDimitry Andric     return IsIndirect ? getBLRCallOpcode(CallerF) : (unsigned)AArch64::BL;
788*5ffd83dbSDimitry Andric 
789*5ffd83dbSDimitry Andric   if (!IsIndirect)
790*5ffd83dbSDimitry Andric     return AArch64::TCRETURNdi;
791*5ffd83dbSDimitry Andric 
792*5ffd83dbSDimitry Andric   // When BTI is enabled, we need to use TCRETURNriBTI to make sure that we use
793*5ffd83dbSDimitry Andric   // x16 or x17.
794*5ffd83dbSDimitry Andric   if (CallerF.getFunction().hasFnAttribute("branch-target-enforcement"))
795*5ffd83dbSDimitry Andric     return AArch64::TCRETURNriBTI;
796*5ffd83dbSDimitry Andric 
797*5ffd83dbSDimitry Andric   return AArch64::TCRETURNri;
798*5ffd83dbSDimitry Andric }
799*5ffd83dbSDimitry Andric 
800*5ffd83dbSDimitry Andric bool AArch64CallLowering::lowerTailCall(
801*5ffd83dbSDimitry Andric     MachineIRBuilder &MIRBuilder, CallLoweringInfo &Info,
802*5ffd83dbSDimitry Andric     SmallVectorImpl<ArgInfo> &OutArgs) const {
803*5ffd83dbSDimitry Andric   MachineFunction &MF = MIRBuilder.getMF();
804*5ffd83dbSDimitry Andric   const Function &F = MF.getFunction();
805*5ffd83dbSDimitry Andric   MachineRegisterInfo &MRI = MF.getRegInfo();
806*5ffd83dbSDimitry Andric   const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
807*5ffd83dbSDimitry Andric   AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>();
808*5ffd83dbSDimitry Andric 
809*5ffd83dbSDimitry Andric   // True when we're tail calling, but without -tailcallopt.
810*5ffd83dbSDimitry Andric   bool IsSibCall = !MF.getTarget().Options.GuaranteedTailCallOpt;
811*5ffd83dbSDimitry Andric 
812*5ffd83dbSDimitry Andric   // TODO: Right now, regbankselect doesn't know how to handle the rtcGPR64
813*5ffd83dbSDimitry Andric   // register class. Until we can do that, we should fall back here.
814*5ffd83dbSDimitry Andric   if (F.hasFnAttribute("branch-target-enforcement")) {
815*5ffd83dbSDimitry Andric     LLVM_DEBUG(
816*5ffd83dbSDimitry Andric         dbgs() << "Cannot lower indirect tail calls with BTI enabled yet.\n");
817*5ffd83dbSDimitry Andric     return false;
818*5ffd83dbSDimitry Andric   }
819*5ffd83dbSDimitry Andric 
820*5ffd83dbSDimitry Andric   // Find out which ABI gets to decide where things go.
821*5ffd83dbSDimitry Andric   CallingConv::ID CalleeCC = Info.CallConv;
822*5ffd83dbSDimitry Andric   CCAssignFn *AssignFnFixed;
823*5ffd83dbSDimitry Andric   CCAssignFn *AssignFnVarArg;
824*5ffd83dbSDimitry Andric   std::tie(AssignFnFixed, AssignFnVarArg) = getAssignFnsForCC(CalleeCC, TLI);
825*5ffd83dbSDimitry Andric 
826*5ffd83dbSDimitry Andric   MachineInstrBuilder CallSeqStart;
827*5ffd83dbSDimitry Andric   if (!IsSibCall)
828*5ffd83dbSDimitry Andric     CallSeqStart = MIRBuilder.buildInstr(AArch64::ADJCALLSTACKDOWN);
829*5ffd83dbSDimitry Andric 
830*5ffd83dbSDimitry Andric   unsigned Opc = getCallOpcode(MF, Info.Callee.isReg(), true);
831*5ffd83dbSDimitry Andric   auto MIB = MIRBuilder.buildInstrNoInsert(Opc);
832*5ffd83dbSDimitry Andric   MIB.add(Info.Callee);
833*5ffd83dbSDimitry Andric 
834*5ffd83dbSDimitry Andric   // Byte offset for the tail call. When we are sibcalling, this will always
835*5ffd83dbSDimitry Andric   // be 0.
836*5ffd83dbSDimitry Andric   MIB.addImm(0);
837*5ffd83dbSDimitry Andric 
838*5ffd83dbSDimitry Andric   // Tell the call which registers are clobbered.
839*5ffd83dbSDimitry Andric   auto TRI = MF.getSubtarget<AArch64Subtarget>().getRegisterInfo();
840*5ffd83dbSDimitry Andric   const uint32_t *Mask = TRI->getCallPreservedMask(MF, CalleeCC);
841*5ffd83dbSDimitry Andric   if (MF.getSubtarget<AArch64Subtarget>().hasCustomCallingConv())
842*5ffd83dbSDimitry Andric     TRI->UpdateCustomCallPreservedMask(MF, &Mask);
843*5ffd83dbSDimitry Andric   MIB.addRegMask(Mask);
844*5ffd83dbSDimitry Andric 
845*5ffd83dbSDimitry Andric   if (TRI->isAnyArgRegReserved(MF))
846*5ffd83dbSDimitry Andric     TRI->emitReservedArgRegCallError(MF);
847*5ffd83dbSDimitry Andric 
848*5ffd83dbSDimitry Andric   // FPDiff is the byte offset of the call's argument area from the callee's.
849*5ffd83dbSDimitry Andric   // Stores to callee stack arguments will be placed in FixedStackSlots offset
850*5ffd83dbSDimitry Andric   // by this amount for a tail call. In a sibling call it must be 0 because the
851*5ffd83dbSDimitry Andric   // caller will deallocate the entire stack and the callee still expects its
852*5ffd83dbSDimitry Andric   // arguments to begin at SP+0.
853*5ffd83dbSDimitry Andric   int FPDiff = 0;
854*5ffd83dbSDimitry Andric 
855*5ffd83dbSDimitry Andric   // This will be 0 for sibcalls, potentially nonzero for tail calls produced
856*5ffd83dbSDimitry Andric   // by -tailcallopt. For sibcalls, the memory operands for the call are
857*5ffd83dbSDimitry Andric   // already available in the caller's incoming argument space.
858*5ffd83dbSDimitry Andric   unsigned NumBytes = 0;
859*5ffd83dbSDimitry Andric   if (!IsSibCall) {
860*5ffd83dbSDimitry Andric     // We aren't sibcalling, so we need to compute FPDiff. We need to do this
861*5ffd83dbSDimitry Andric     // before handling assignments, because FPDiff must be known for memory
862*5ffd83dbSDimitry Andric     // arguments.
863*5ffd83dbSDimitry Andric     unsigned NumReusableBytes = FuncInfo->getBytesInStackArgArea();
864*5ffd83dbSDimitry Andric     SmallVector<CCValAssign, 16> OutLocs;
865*5ffd83dbSDimitry Andric     CCState OutInfo(CalleeCC, false, MF, OutLocs, F.getContext());
866*5ffd83dbSDimitry Andric     analyzeArgInfo(OutInfo, OutArgs, *AssignFnFixed, *AssignFnVarArg);
867*5ffd83dbSDimitry Andric 
868*5ffd83dbSDimitry Andric     // The callee will pop the argument stack as a tail call. Thus, we must
869*5ffd83dbSDimitry Andric     // keep it 16-byte aligned.
870*5ffd83dbSDimitry Andric     NumBytes = alignTo(OutInfo.getNextStackOffset(), 16);
871*5ffd83dbSDimitry Andric 
872*5ffd83dbSDimitry Andric     // FPDiff will be negative if this tail call requires more space than we
873*5ffd83dbSDimitry Andric     // would automatically have in our incoming argument space. Positive if we
874*5ffd83dbSDimitry Andric     // actually shrink the stack.
875*5ffd83dbSDimitry Andric     FPDiff = NumReusableBytes - NumBytes;
876*5ffd83dbSDimitry Andric 
877*5ffd83dbSDimitry Andric     // The stack pointer must be 16-byte aligned at all times it's used for a
878*5ffd83dbSDimitry Andric     // memory operation, which in practice means at *all* times and in
879*5ffd83dbSDimitry Andric     // particular across call boundaries. Therefore our own arguments started at
880*5ffd83dbSDimitry Andric     // a 16-byte aligned SP and the delta applied for the tail call should
881*5ffd83dbSDimitry Andric     // satisfy the same constraint.
882*5ffd83dbSDimitry Andric     assert(FPDiff % 16 == 0 && "unaligned stack on tail call");
883*5ffd83dbSDimitry Andric   }
884*5ffd83dbSDimitry Andric 
885*5ffd83dbSDimitry Andric   const auto &Forwards = FuncInfo->getForwardedMustTailRegParms();
886*5ffd83dbSDimitry Andric 
887*5ffd83dbSDimitry Andric   // Do the actual argument marshalling.
888*5ffd83dbSDimitry Andric   OutgoingArgHandler Handler(MIRBuilder, MRI, MIB, AssignFnFixed,
889*5ffd83dbSDimitry Andric                              AssignFnVarArg, true, FPDiff);
890*5ffd83dbSDimitry Andric   if (!handleAssignments(MIRBuilder, OutArgs, Handler))
891*5ffd83dbSDimitry Andric     return false;
892*5ffd83dbSDimitry Andric 
893*5ffd83dbSDimitry Andric   if (Info.IsVarArg && Info.IsMustTailCall) {
894*5ffd83dbSDimitry Andric     // Now we know what's being passed to the function. Add uses to the call for
895*5ffd83dbSDimitry Andric     // the forwarded registers that we *aren't* passing as parameters. This will
896*5ffd83dbSDimitry Andric     // preserve the copies we build earlier.
897*5ffd83dbSDimitry Andric     for (const auto &F : Forwards) {
898*5ffd83dbSDimitry Andric       Register ForwardedReg = F.PReg;
899*5ffd83dbSDimitry Andric       // If the register is already passed, or aliases a register which is
900*5ffd83dbSDimitry Andric       // already being passed, then skip it.
901*5ffd83dbSDimitry Andric       if (any_of(MIB->uses(), [&ForwardedReg, &TRI](const MachineOperand &Use) {
902*5ffd83dbSDimitry Andric             if (!Use.isReg())
903*5ffd83dbSDimitry Andric               return false;
904*5ffd83dbSDimitry Andric             return TRI->regsOverlap(Use.getReg(), ForwardedReg);
905*5ffd83dbSDimitry Andric           }))
906*5ffd83dbSDimitry Andric         continue;
907*5ffd83dbSDimitry Andric 
908*5ffd83dbSDimitry Andric       // We aren't passing it already, so we should add it to the call.
909*5ffd83dbSDimitry Andric       MIRBuilder.buildCopy(ForwardedReg, Register(F.VReg));
910*5ffd83dbSDimitry Andric       MIB.addReg(ForwardedReg, RegState::Implicit);
911*5ffd83dbSDimitry Andric     }
912*5ffd83dbSDimitry Andric   }
913*5ffd83dbSDimitry Andric 
914*5ffd83dbSDimitry Andric   // If we have -tailcallopt, we need to adjust the stack. We'll do the call
915*5ffd83dbSDimitry Andric   // sequence start and end here.
916*5ffd83dbSDimitry Andric   if (!IsSibCall) {
917*5ffd83dbSDimitry Andric     MIB->getOperand(1).setImm(FPDiff);
918*5ffd83dbSDimitry Andric     CallSeqStart.addImm(NumBytes).addImm(0);
919*5ffd83dbSDimitry Andric     // End the call sequence *before* emitting the call. Normally, we would
920*5ffd83dbSDimitry Andric     // tidy the frame up after the call. However, here, we've laid out the
921*5ffd83dbSDimitry Andric     // parameters so that when SP is reset, they will be in the correct
922*5ffd83dbSDimitry Andric     // location.
923*5ffd83dbSDimitry Andric     MIRBuilder.buildInstr(AArch64::ADJCALLSTACKUP).addImm(NumBytes).addImm(0);
924*5ffd83dbSDimitry Andric   }
925*5ffd83dbSDimitry Andric 
926*5ffd83dbSDimitry Andric   // Now we can add the actual call instruction to the correct basic block.
927*5ffd83dbSDimitry Andric   MIRBuilder.insertInstr(MIB);
928*5ffd83dbSDimitry Andric 
929*5ffd83dbSDimitry Andric   // If Callee is a reg, since it is used by a target specific instruction,
930*5ffd83dbSDimitry Andric   // it must have a register class matching the constraint of that instruction.
931*5ffd83dbSDimitry Andric   if (Info.Callee.isReg())
932*5ffd83dbSDimitry Andric     MIB->getOperand(0).setReg(constrainOperandRegClass(
933*5ffd83dbSDimitry Andric         MF, *TRI, MRI, *MF.getSubtarget().getInstrInfo(),
934*5ffd83dbSDimitry Andric         *MF.getSubtarget().getRegBankInfo(), *MIB, MIB->getDesc(), Info.Callee,
935*5ffd83dbSDimitry Andric         0));
936*5ffd83dbSDimitry Andric 
937*5ffd83dbSDimitry Andric   MF.getFrameInfo().setHasTailCall();
938*5ffd83dbSDimitry Andric   Info.LoweredTailCall = true;
939*5ffd83dbSDimitry Andric   return true;
940*5ffd83dbSDimitry Andric }
941*5ffd83dbSDimitry Andric 
942*5ffd83dbSDimitry Andric bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
943*5ffd83dbSDimitry Andric                                     CallLoweringInfo &Info) const {
944*5ffd83dbSDimitry Andric   MachineFunction &MF = MIRBuilder.getMF();
945*5ffd83dbSDimitry Andric   const Function &F = MF.getFunction();
946*5ffd83dbSDimitry Andric   MachineRegisterInfo &MRI = MF.getRegInfo();
947*5ffd83dbSDimitry Andric   auto &DL = F.getParent()->getDataLayout();
948*5ffd83dbSDimitry Andric   const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
949*5ffd83dbSDimitry Andric 
950*5ffd83dbSDimitry Andric   SmallVector<ArgInfo, 8> OutArgs;
951*5ffd83dbSDimitry Andric   for (auto &OrigArg : Info.OrigArgs) {
952*5ffd83dbSDimitry Andric     splitToValueTypes(OrigArg, OutArgs, DL, MRI, Info.CallConv);
953*5ffd83dbSDimitry Andric     // AAPCS requires that we zero-extend i1 to 8 bits by the caller.
954*5ffd83dbSDimitry Andric     if (OrigArg.Ty->isIntegerTy(1))
955*5ffd83dbSDimitry Andric       OutArgs.back().Flags[0].setZExt();
956*5ffd83dbSDimitry Andric   }
957*5ffd83dbSDimitry Andric 
958*5ffd83dbSDimitry Andric   SmallVector<ArgInfo, 8> InArgs;
959*5ffd83dbSDimitry Andric   if (!Info.OrigRet.Ty->isVoidTy())
960*5ffd83dbSDimitry Andric     splitToValueTypes(Info.OrigRet, InArgs, DL, MRI, F.getCallingConv());
961*5ffd83dbSDimitry Andric 
962*5ffd83dbSDimitry Andric   // If we can lower as a tail call, do that instead.
963*5ffd83dbSDimitry Andric   bool CanTailCallOpt =
964*5ffd83dbSDimitry Andric       isEligibleForTailCallOptimization(MIRBuilder, Info, InArgs, OutArgs);
965*5ffd83dbSDimitry Andric 
966*5ffd83dbSDimitry Andric   // We must emit a tail call if we have musttail.
967*5ffd83dbSDimitry Andric   if (Info.IsMustTailCall && !CanTailCallOpt) {
968*5ffd83dbSDimitry Andric     // There are types of incoming/outgoing arguments we can't handle yet, so
969*5ffd83dbSDimitry Andric     // it doesn't make sense to actually die here like in ISelLowering. Instead,
970*5ffd83dbSDimitry Andric     // fall back to SelectionDAG and let it try to handle this.
971*5ffd83dbSDimitry Andric     LLVM_DEBUG(dbgs() << "Failed to lower musttail call as tail call\n");
972*5ffd83dbSDimitry Andric     return false;
973*5ffd83dbSDimitry Andric   }
974*5ffd83dbSDimitry Andric 
975*5ffd83dbSDimitry Andric   if (CanTailCallOpt)
976*5ffd83dbSDimitry Andric     return lowerTailCall(MIRBuilder, Info, OutArgs);
977*5ffd83dbSDimitry Andric 
978*5ffd83dbSDimitry Andric   // Find out which ABI gets to decide where things go.
979*5ffd83dbSDimitry Andric   CCAssignFn *AssignFnFixed;
980*5ffd83dbSDimitry Andric   CCAssignFn *AssignFnVarArg;
981*5ffd83dbSDimitry Andric   std::tie(AssignFnFixed, AssignFnVarArg) =
982*5ffd83dbSDimitry Andric       getAssignFnsForCC(Info.CallConv, TLI);
983*5ffd83dbSDimitry Andric 
984*5ffd83dbSDimitry Andric   MachineInstrBuilder CallSeqStart;
985*5ffd83dbSDimitry Andric   CallSeqStart = MIRBuilder.buildInstr(AArch64::ADJCALLSTACKDOWN);
986*5ffd83dbSDimitry Andric 
987*5ffd83dbSDimitry Andric   // Create a temporarily-floating call instruction so we can add the implicit
988*5ffd83dbSDimitry Andric   // uses of arg registers.
989*5ffd83dbSDimitry Andric   unsigned Opc = getCallOpcode(MF, Info.Callee.isReg(), false);
990*5ffd83dbSDimitry Andric 
991*5ffd83dbSDimitry Andric   auto MIB = MIRBuilder.buildInstrNoInsert(Opc);
992*5ffd83dbSDimitry Andric   MIB.add(Info.Callee);
993*5ffd83dbSDimitry Andric 
994*5ffd83dbSDimitry Andric   // Tell the call which registers are clobbered.
995*5ffd83dbSDimitry Andric   auto TRI = MF.getSubtarget<AArch64Subtarget>().getRegisterInfo();
996*5ffd83dbSDimitry Andric   const uint32_t *Mask = TRI->getCallPreservedMask(MF, Info.CallConv);
997*5ffd83dbSDimitry Andric   if (MF.getSubtarget<AArch64Subtarget>().hasCustomCallingConv())
998*5ffd83dbSDimitry Andric     TRI->UpdateCustomCallPreservedMask(MF, &Mask);
999*5ffd83dbSDimitry Andric   MIB.addRegMask(Mask);
1000*5ffd83dbSDimitry Andric 
1001*5ffd83dbSDimitry Andric   if (TRI->isAnyArgRegReserved(MF))
1002*5ffd83dbSDimitry Andric     TRI->emitReservedArgRegCallError(MF);
1003*5ffd83dbSDimitry Andric 
1004*5ffd83dbSDimitry Andric   // Do the actual argument marshalling.
1005*5ffd83dbSDimitry Andric   OutgoingArgHandler Handler(MIRBuilder, MRI, MIB, AssignFnFixed,
1006*5ffd83dbSDimitry Andric                              AssignFnVarArg, false);
1007*5ffd83dbSDimitry Andric   if (!handleAssignments(MIRBuilder, OutArgs, Handler))
1008*5ffd83dbSDimitry Andric     return false;
1009*5ffd83dbSDimitry Andric 
1010*5ffd83dbSDimitry Andric   // Now we can add the actual call instruction to the correct basic block.
1011*5ffd83dbSDimitry Andric   MIRBuilder.insertInstr(MIB);
1012*5ffd83dbSDimitry Andric 
1013*5ffd83dbSDimitry Andric   // If Callee is a reg, since it is used by a target specific
1014*5ffd83dbSDimitry Andric   // instruction, it must have a register class matching the
1015*5ffd83dbSDimitry Andric   // constraint of that instruction.
1016*5ffd83dbSDimitry Andric   if (Info.Callee.isReg())
1017*5ffd83dbSDimitry Andric     MIB->getOperand(0).setReg(constrainOperandRegClass(
1018*5ffd83dbSDimitry Andric         MF, *TRI, MRI, *MF.getSubtarget().getInstrInfo(),
1019*5ffd83dbSDimitry Andric         *MF.getSubtarget().getRegBankInfo(), *MIB, MIB->getDesc(), Info.Callee,
1020*5ffd83dbSDimitry Andric         0));
1021*5ffd83dbSDimitry Andric 
1022*5ffd83dbSDimitry Andric   // Finally we can copy the returned value back into its virtual-register. In
1023*5ffd83dbSDimitry Andric   // symmetry with the arguments, the physical register must be an
1024*5ffd83dbSDimitry Andric   // implicit-define of the call instruction.
1025*5ffd83dbSDimitry Andric   if (!Info.OrigRet.Ty->isVoidTy()) {
1026*5ffd83dbSDimitry Andric     CCAssignFn *RetAssignFn = TLI.CCAssignFnForReturn(Info.CallConv);
1027*5ffd83dbSDimitry Andric     CallReturnHandler Handler(MIRBuilder, MRI, MIB, RetAssignFn);
1028*5ffd83dbSDimitry Andric     if (!handleAssignments(MIRBuilder, InArgs, Handler))
1029*5ffd83dbSDimitry Andric       return false;
1030*5ffd83dbSDimitry Andric   }
1031*5ffd83dbSDimitry Andric 
1032*5ffd83dbSDimitry Andric   if (Info.SwiftErrorVReg) {
1033*5ffd83dbSDimitry Andric     MIB.addDef(AArch64::X21, RegState::Implicit);
1034*5ffd83dbSDimitry Andric     MIRBuilder.buildCopy(Info.SwiftErrorVReg, Register(AArch64::X21));
1035*5ffd83dbSDimitry Andric   }
1036*5ffd83dbSDimitry Andric 
1037*5ffd83dbSDimitry Andric   uint64_t CalleePopBytes =
1038*5ffd83dbSDimitry Andric       doesCalleeRestoreStack(Info.CallConv,
1039*5ffd83dbSDimitry Andric                              MF.getTarget().Options.GuaranteedTailCallOpt)
1040*5ffd83dbSDimitry Andric           ? alignTo(Handler.StackSize, 16)
1041*5ffd83dbSDimitry Andric           : 0;
1042*5ffd83dbSDimitry Andric 
1043*5ffd83dbSDimitry Andric   CallSeqStart.addImm(Handler.StackSize).addImm(0);
1044*5ffd83dbSDimitry Andric   MIRBuilder.buildInstr(AArch64::ADJCALLSTACKUP)
1045*5ffd83dbSDimitry Andric       .addImm(Handler.StackSize)
1046*5ffd83dbSDimitry Andric       .addImm(CalleePopBytes);
1047*5ffd83dbSDimitry Andric 
1048*5ffd83dbSDimitry Andric   return true;
1049*5ffd83dbSDimitry Andric }
1050