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