LLVM 23.0.0git
AArch64CallLowering.cpp
Go to the documentation of this file.
1//===--- AArch64CallLowering.cpp - Call lowering --------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This file implements the lowering of LLVM calls to machine code calls for
11/// GlobalISel.
12///
13//===----------------------------------------------------------------------===//
14
15#include "AArch64CallLowering.h"
17#include "AArch64ISelLowering.h"
19#include "AArch64RegisterInfo.h"
21#include "AArch64Subtarget.h"
23#include "llvm/ADT/ArrayRef.h"
45#include "llvm/IR/Argument.h"
46#include "llvm/IR/Attributes.h"
47#include "llvm/IR/Function.h"
48#include "llvm/IR/Type.h"
49#include "llvm/IR/Value.h"
50#include <algorithm>
51#include <cassert>
52#include <cstdint>
53
54#define DEBUG_TYPE "aarch64-call-lowering"
55
56using namespace llvm;
57using namespace AArch64GISelUtils;
58
60
63
64static void applyStackPassedSmallTypeDAGHack(EVT OrigVT, MVT &ValVT,
65 MVT &LocVT) {
66 // If ValVT is i1/i8/i16, we should set LocVT to i8/i8/i16. This is a legacy
67 // hack because the DAG calls the assignment function with pre-legalized
68 // register typed values, not the raw type.
69 //
70 // This hack is not applied to return values which are not passed on the
71 // stack.
72 if (OrigVT == MVT::i1 || OrigVT == MVT::i8)
73 ValVT = LocVT = MVT::i8;
74 else if (OrigVT == MVT::i16)
75 ValVT = LocVT = MVT::i16;
76}
77
78// Account for i1/i8/i16 stack passed value hack
80 const MVT ValVT = VA.getValVT();
81 return (ValVT == MVT::i8 || ValVT == MVT::i16) ? LLT(ValVT)
82 : LLT(VA.getLocVT());
83}
84
85namespace {
86
87struct AArch64IncomingValueAssigner
89 AArch64IncomingValueAssigner(CCAssignFn *AssignFn_,
90 CCAssignFn *AssignFnVarArg_)
91 : IncomingValueAssigner(AssignFn_, AssignFnVarArg_) {}
92
93 bool assignArg(unsigned ValNo, EVT OrigVT, MVT ValVT, MVT LocVT,
95 const CallLowering::ArgInfo &Info, ISD::ArgFlagsTy Flags,
96 CCState &State) override {
97 applyStackPassedSmallTypeDAGHack(OrigVT, ValVT, LocVT);
98 return IncomingValueAssigner::assignArg(ValNo, OrigVT, ValVT, LocVT,
99 LocInfo, Info, Flags, State);
100 }
101};
102
103struct AArch64OutgoingValueAssigner
105 const AArch64Subtarget &Subtarget;
106
107 /// Track if this is used for a return instead of function argument
108 /// passing. We apply a hack to i1/i8/i16 stack passed values, but do not use
109 /// stack passed returns for them and cannot apply the type adjustment.
110 bool IsReturn;
111
112 AArch64OutgoingValueAssigner(CCAssignFn *AssignFn_,
113 CCAssignFn *AssignFnVarArg_,
114 const AArch64Subtarget &Subtarget_,
115 bool IsReturn)
116 : OutgoingValueAssigner(AssignFn_, AssignFnVarArg_),
117 Subtarget(Subtarget_), IsReturn(IsReturn) {}
118
119 bool assignArg(unsigned ValNo, EVT OrigVT, MVT ValVT, MVT LocVT,
120 CCValAssign::LocInfo LocInfo,
121 const CallLowering::ArgInfo &Info, ISD::ArgFlagsTy Flags,
122 CCState &State) override {
123 const Function &F = State.getMachineFunction().getFunction();
124 bool IsCalleeWin =
125 Subtarget.isCallingConvWin64(State.getCallingConv(), F.isVarArg());
126 bool UseVarArgsCCForFixed = IsCalleeWin && State.isVarArg();
127
128 bool Res;
129 if (!Flags.isVarArg() && !UseVarArgsCCForFixed) {
130 if (!IsReturn)
131 applyStackPassedSmallTypeDAGHack(OrigVT, ValVT, LocVT);
132 Res = AssignFn(ValNo, ValVT, LocVT, LocInfo, Flags, Info.Ty, State);
133 } else
134 Res = AssignFnVarArg(ValNo, ValVT, LocVT, LocInfo, Flags, Info.Ty, State);
135
136 StackSize = State.getStackSize();
137 return Res;
138 }
139};
140
141struct IncomingArgHandler : public CallLowering::IncomingValueHandler {
142 IncomingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
143 : IncomingValueHandler(MIRBuilder, MRI) {}
144
145 Register getStackAddress(uint64_t Size, int64_t Offset,
146 MachinePointerInfo &MPO,
147 ISD::ArgFlagsTy Flags) override {
148 auto &MFI = MIRBuilder.getMF().getFrameInfo();
149
150 // Byval is assumed to be writable memory, but other stack passed arguments
151 // are not.
152 const bool IsImmutable = !Flags.isByVal();
153
154 int FI = MFI.CreateFixedObject(Size, Offset, IsImmutable);
155 MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
156 auto AddrReg = MIRBuilder.buildFrameIndex(LLT::pointer(0, 64), FI);
157 return AddrReg.getReg(0);
158 }
159
160 LLT getStackValueStoreType(const DataLayout &DL, const CCValAssign &VA,
161 ISD::ArgFlagsTy Flags) const override {
162 // For pointers, we just need to fixup the integer types reported in the
163 // CCValAssign.
164 if (Flags.isPointer())
167 }
168
169 void assignValueToReg(Register ValVReg, Register PhysReg,
170 const CCValAssign &VA) override {
171 markRegUsed(PhysReg);
172 IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA);
173 }
174
175 void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy,
176 const MachinePointerInfo &MPO,
177 const CCValAssign &VA) override {
178 MachineFunction &MF = MIRBuilder.getMF();
179
180 LLT ValTy(VA.getValVT());
181 LLT LocTy(VA.getLocVT());
182
183 // Fixup the types for the DAG compatibility hack.
184 if (VA.getValVT() == MVT::i8 || VA.getValVT() == MVT::i16)
185 std::swap(ValTy, LocTy);
186 else {
187 // The calling code knows if this is a pointer or not, we're only touching
188 // the LocTy for the i8/i16 hack.
189 assert(LocTy.getSizeInBits() == MemTy.getSizeInBits());
190 LocTy = MemTy;
191 }
192
193 auto MMO = MF.getMachineMemOperand(
195 inferAlignFromPtrInfo(MF, MPO));
196
197 switch (VA.getLocInfo()) {
198 case CCValAssign::LocInfo::ZExt:
199 MIRBuilder.buildLoadInstr(TargetOpcode::G_ZEXTLOAD, ValVReg, Addr, *MMO);
200 return;
201 case CCValAssign::LocInfo::SExt:
202 MIRBuilder.buildLoadInstr(TargetOpcode::G_SEXTLOAD, ValVReg, Addr, *MMO);
203 return;
204 default:
205 MIRBuilder.buildLoad(ValVReg, Addr, *MMO);
206 return;
207 }
208 }
209
210 /// How the physical register gets marked varies between formal
211 /// parameters (it's a basic-block live-in), and a call instruction
212 /// (it's an implicit-def of the BL).
213 virtual void markRegUsed(Register Reg) = 0;
214};
215
216struct FormalArgHandler : public IncomingArgHandler {
217 FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
218 : IncomingArgHandler(MIRBuilder, MRI) {}
219
220 void markRegUsed(Register Reg) override {
221 MIRBuilder.getMRI()->addLiveIn(Reg.asMCReg());
222 MIRBuilder.getMBB().addLiveIn(Reg.asMCReg());
223 }
224};
225
226struct CallReturnHandler : public IncomingArgHandler {
227 CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
228 MachineInstrBuilder MIB)
229 : IncomingArgHandler(MIRBuilder, MRI), MIB(MIB) {}
230
231 void markRegUsed(Register Reg) override {
232 MIB.addDef(Reg, RegState::Implicit);
233 }
234
235 MachineInstrBuilder MIB;
236};
237
238/// A special return arg handler for "returned" attribute arg calls.
239struct ReturnedArgCallReturnHandler : public CallReturnHandler {
240 ReturnedArgCallReturnHandler(MachineIRBuilder &MIRBuilder,
241 MachineRegisterInfo &MRI,
242 MachineInstrBuilder MIB)
243 : CallReturnHandler(MIRBuilder, MRI, MIB) {}
244
245 void markRegUsed(Register Reg) override {}
246};
247
248struct OutgoingArgHandler : public CallLowering::OutgoingValueHandler {
249 OutgoingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
250 MachineInstrBuilder MIB, bool IsTailCall = false,
251 int FPDiff = 0)
252 : OutgoingValueHandler(MIRBuilder, MRI), MIB(MIB), IsTailCall(IsTailCall),
253 FPDiff(FPDiff),
254 Subtarget(MIRBuilder.getMF().getSubtarget<AArch64Subtarget>()) {}
255
256 Register getStackAddress(uint64_t Size, int64_t Offset,
257 MachinePointerInfo &MPO,
258 ISD::ArgFlagsTy Flags) override {
259 MachineFunction &MF = MIRBuilder.getMF();
260 LLT p0 = LLT::pointer(0, 64);
261 LLT s64 = LLT::scalar(64);
262
263 if (IsTailCall) {
264 assert(!Flags.isByVal() && "byval unhandled with tail calls");
265
266 Offset += FPDiff;
267 int FI = MF.getFrameInfo().CreateFixedObject(Size, Offset, true);
268 auto FIReg = MIRBuilder.buildFrameIndex(p0, FI);
270 return FIReg.getReg(0);
271 }
272
273 if (!SPReg)
274 SPReg = MIRBuilder.buildCopy(p0, Register(AArch64::SP)).getReg(0);
275
276 auto OffsetReg = MIRBuilder.buildConstant(s64, Offset);
277
278 auto AddrReg = MIRBuilder.buildPtrAdd(p0, SPReg, OffsetReg);
279
281 return AddrReg.getReg(0);
282 }
283
284 /// We need to fixup the reported store size for certain value types because
285 /// we invert the interpretation of ValVT and LocVT in certain cases. This is
286 /// for compatibility with the DAG call lowering implementation, which we're
287 /// currently building on top of.
288 LLT getStackValueStoreType(const DataLayout &DL, const CCValAssign &VA,
289 ISD::ArgFlagsTy Flags) const override {
290 if (Flags.isPointer())
293 }
294
295 void assignValueToReg(Register ValVReg, Register PhysReg,
296 const CCValAssign &VA) override {
297 MIB.addUse(PhysReg, RegState::Implicit);
298 Register ExtReg = extendRegister(ValVReg, VA);
299 MIRBuilder.buildCopy(PhysReg, ExtReg);
300 }
301
302 /// Check whether a stack argument requires lowering in a tail call.
303 static bool shouldLowerTailCallStackArg(const MachineFunction &MF,
304 const CCValAssign &VA,
305 Register ValVReg,
306 Register StoreAddr) {
307 const MachineRegisterInfo &MRI = MF.getRegInfo();
308 // Print the defining instruction for the value.
309 auto *DefMI = MRI.getVRegDef(ValVReg);
310 assert(DefMI && "No defining instruction");
311 for (;;) {
312 // Look through nodes that don't alter the bits of the incoming value.
313 unsigned Op = DefMI->getOpcode();
314 if (Op == TargetOpcode::G_ZEXT || Op == TargetOpcode::G_ANYEXT ||
315 Op == TargetOpcode::G_BITCAST || isAssertMI(*DefMI)) {
316 DefMI = MRI.getVRegDef(DefMI->getOperand(1).getReg());
317 continue;
318 }
319 break;
320 }
321
322 auto *Load = dyn_cast<GLoad>(DefMI);
323 if (!Load)
324 return true;
325 Register LoadReg = Load->getPointerReg();
326 auto *LoadAddrDef = MRI.getVRegDef(LoadReg);
327 if (LoadAddrDef->getOpcode() != TargetOpcode::G_FRAME_INDEX)
328 return true;
329 const MachineFrameInfo &MFI = MF.getFrameInfo();
330 int LoadFI = LoadAddrDef->getOperand(1).getIndex();
331
332 auto *StoreAddrDef = MRI.getVRegDef(StoreAddr);
333 if (StoreAddrDef->getOpcode() != TargetOpcode::G_FRAME_INDEX)
334 return true;
335 int StoreFI = StoreAddrDef->getOperand(1).getIndex();
336
337 if (!MFI.isImmutableObjectIndex(LoadFI))
338 return true;
339 if (MFI.getObjectOffset(LoadFI) != MFI.getObjectOffset(StoreFI))
340 return true;
341 if (Load->getMemSize() != MFI.getObjectSize(StoreFI))
342 return true;
343
344 return false;
345 }
346
347 void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy,
348 const MachinePointerInfo &MPO,
349 const CCValAssign &VA) override {
350 MachineFunction &MF = MIRBuilder.getMF();
351 if (!FPDiff && !shouldLowerTailCallStackArg(MF, VA, ValVReg, Addr))
352 return;
353 auto MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOStore, MemTy,
354 inferAlignFromPtrInfo(MF, MPO));
355 MIRBuilder.buildStore(ValVReg, Addr, *MMO);
356 }
357
358 void assignValueToAddress(const CallLowering::ArgInfo &Arg, unsigned RegIndex,
359 Register Addr, LLT MemTy,
360 const MachinePointerInfo &MPO,
361 const CCValAssign &VA) override {
362 unsigned MaxSize = MemTy.getSizeInBytes() * 8;
363 // For varargs, we always want to extend them to 8 bytes, in which case
364 // we disable setting a max.
365 if (Arg.Flags[0].isVarArg())
366 MaxSize = 0;
367
368 Register ValVReg = Arg.Regs[RegIndex];
369 if (VA.getLocInfo() != CCValAssign::LocInfo::FPExt) {
370 MVT LocVT = VA.getLocVT();
371 MVT ValVT = VA.getValVT();
372
373 if (VA.getValVT() == MVT::i8 || VA.getValVT() == MVT::i16) {
374 std::swap(ValVT, LocVT);
375 MemTy = LLT(VA.getValVT());
376 }
377
378 ValVReg = extendRegister(ValVReg, VA, MaxSize);
379 } else {
380 // The store does not cover the full allocated stack slot.
381 MemTy = LLT(VA.getValVT());
382 }
383
384 assignValueToAddress(ValVReg, Addr, MemTy, MPO, VA);
385 }
386
387 MachineInstrBuilder MIB;
388
389 bool IsTailCall;
390
391 /// For tail calls, the byte offset of the call's argument area from the
392 /// callee's. Unused elsewhere.
393 int FPDiff;
394
395 // Cache the SP register vreg if we need it more than once in this call site.
397
398 const AArch64Subtarget &Subtarget;
399};
400} // namespace
401
402static bool doesCalleeRestoreStack(CallingConv::ID CallConv, bool TailCallOpt) {
403 return (CallConv == CallingConv::Fast && TailCallOpt) ||
404 CallConv == CallingConv::Tail || CallConv == CallingConv::SwiftTail;
405}
406
408 const Value *Val,
409 ArrayRef<Register> VRegs,
411 Register SwiftErrorVReg) const {
412 auto MIB = MIRBuilder.buildInstrNoInsert(AArch64::RET_ReallyLR);
413 assert(((Val && !VRegs.empty()) || (!Val && VRegs.empty())) &&
414 "Return value without a vreg");
415
416 bool Success = true;
417 if (!FLI.CanLowerReturn) {
418 insertSRetStores(MIRBuilder, Val->getType(), VRegs, FLI.DemoteRegister);
419 } else if (!VRegs.empty()) {
420 MachineFunction &MF = MIRBuilder.getMF();
421 const Function &F = MF.getFunction();
422 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
423
426 CCAssignFn *AssignFn = TLI.CCAssignFnForReturn(F.getCallingConv());
427 auto &DL = F.getDataLayout();
428 LLVMContext &Ctx = Val->getType()->getContext();
429
430 SmallVector<EVT, 4> SplitEVTs;
431 ComputeValueVTs(TLI, DL, Val->getType(), SplitEVTs);
432 assert(VRegs.size() == SplitEVTs.size() &&
433 "For each split Type there should be exactly one VReg.");
434
435 SmallVector<ArgInfo, 8> SplitArgs;
436 CallingConv::ID CC = F.getCallingConv();
437
438 for (unsigned i = 0; i < SplitEVTs.size(); ++i) {
439 Register CurVReg = VRegs[i];
440 ArgInfo CurArgInfo = ArgInfo{CurVReg, SplitEVTs[i].getTypeForEVT(Ctx), 0};
441 setArgFlags(CurArgInfo, AttributeList::ReturnIndex, DL, F);
442
443 // i1 is a special case because SDAG i1 true is naturally zero extended
444 // when widened using ANYEXT. We need to do it explicitly here.
445 auto &Flags = CurArgInfo.Flags[0];
446 if (MRI.getType(CurVReg).getSizeInBits() == TypeSize::getFixed(1) &&
447 !Flags.isSExt() && !Flags.isZExt()) {
448 CurVReg = MIRBuilder.buildZExt(LLT::scalar(8), CurVReg).getReg(0);
449 } else if (TLI.getNumRegistersForCallingConv(Ctx, CC, SplitEVTs[i]) ==
450 1) {
451 // Some types will need extending as specified by the CC.
452 MVT NewVT = TLI.getRegisterTypeForCallingConv(Ctx, CC, SplitEVTs[i]);
453 if (EVT(NewVT) != SplitEVTs[i]) {
454 unsigned ExtendOp = TargetOpcode::G_ANYEXT;
455 if (F.getAttributes().hasRetAttr(Attribute::SExt))
456 ExtendOp = TargetOpcode::G_SEXT;
457 else if (F.getAttributes().hasRetAttr(Attribute::ZExt))
458 ExtendOp = TargetOpcode::G_ZEXT;
459
460 LLT NewLLT(NewVT);
461 LLT OldLLT = getLLTForType(*CurArgInfo.Ty, DL);
462 CurArgInfo.Ty = EVT(NewVT).getTypeForEVT(Ctx);
463 // Instead of an extend, we might have a vector type which needs
464 // padding with more elements, e.g. <2 x half> -> <4 x half>.
465 if (NewVT.isVector()) {
466 if (OldLLT.isVector()) {
467 if (NewLLT.getNumElements() > OldLLT.getNumElements()) {
468 CurVReg =
469 MIRBuilder.buildPadVectorWithUndefElements(NewLLT, CurVReg)
470 .getReg(0);
471 } else {
472 // Just do a vector extend.
473 CurVReg = MIRBuilder.buildInstr(ExtendOp, {NewLLT}, {CurVReg})
474 .getReg(0);
475 }
476 } else if (NewLLT.getNumElements() >= 2 &&
477 NewLLT.getNumElements() <= 8) {
478 // We need to pad a <1 x S> type to <2/4/8 x S>. Since we don't
479 // have <1 x S> vector types in GISel we use a build_vector
480 // instead of a vector merge/concat.
481 CurVReg =
482 MIRBuilder.buildPadVectorWithUndefElements(NewLLT, CurVReg)
483 .getReg(0);
484 } else {
485 LLVM_DEBUG(dbgs() << "Could not handle ret ty\n");
486 return false;
487 }
488 } else {
489 // If the split EVT was a <1 x T> vector, and NewVT is T, then we
490 // don't have to do anything since we don't distinguish between the
491 // two.
492 if (NewLLT != MRI.getType(CurVReg)) {
493 // A scalar extend.
494 CurVReg = MIRBuilder.buildInstr(ExtendOp, {NewLLT}, {CurVReg})
495 .getReg(0);
496 }
497 }
498 }
499 }
500 if (CurVReg != CurArgInfo.Regs[0]) {
501 CurArgInfo.Regs[0] = CurVReg;
502 // Reset the arg flags after modifying CurVReg.
503 setArgFlags(CurArgInfo, AttributeList::ReturnIndex, DL, F);
504 }
505 splitToValueTypes(CurArgInfo, SplitArgs, DL, CC);
506 }
507
508 AArch64OutgoingValueAssigner Assigner(AssignFn, AssignFn, Subtarget,
509 /*IsReturn*/ true);
510 OutgoingArgHandler Handler(MIRBuilder, MRI, MIB);
511 Success = determineAndHandleAssignments(Handler, Assigner, SplitArgs,
512 MIRBuilder, CC, F.isVarArg());
513 }
514
515 if (SwiftErrorVReg) {
516 MIB.addUse(AArch64::X21, RegState::Implicit);
517 MIRBuilder.buildCopy(AArch64::X21, SwiftErrorVReg);
518 }
519
520 MIRBuilder.insertInstr(MIB);
521 return Success;
522}
523
525 CallingConv::ID CallConv,
527 bool IsVarArg) const {
529 const auto &TLI = *getTLI<AArch64TargetLowering>();
530 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs,
531 MF.getFunction().getContext());
532
533 return checkReturn(CCInfo, Outs, TLI.CCAssignFnForReturn(CallConv));
534}
535
536/// Helper function to compute forwarded registers for musttail calls. Computes
537/// the forwarded registers, sets MBB liveness, and emits COPY instructions that
538/// can be used to save + restore registers later.
540 CCAssignFn *AssignFn) {
541 MachineBasicBlock &MBB = MIRBuilder.getMBB();
542 MachineFunction &MF = MIRBuilder.getMF();
543 MachineFrameInfo &MFI = MF.getFrameInfo();
544
545 if (!MFI.hasMustTailInVarArgFunc())
546 return;
547
549 const Function &F = MF.getFunction();
550 assert(F.isVarArg() && "Expected F to be vararg?");
551
552 // Compute the set of forwarded registers. The rest are scratch.
554 CCState CCInfo(F.getCallingConv(), /*IsVarArg=*/true, MF, ArgLocs,
555 F.getContext());
556 SmallVector<MVT, 2> RegParmTypes;
557 RegParmTypes.push_back(MVT::i64);
558 RegParmTypes.push_back(MVT::f128);
559
560 // Later on, we can use this vector to restore the registers if necessary.
563 CCInfo.analyzeMustTailForwardedRegisters(Forwards, RegParmTypes, AssignFn);
564
565 // Conservatively forward X8, since it might be used for an aggregate
566 // return.
567 if (!CCInfo.isAllocated(AArch64::X8)) {
568 Register X8VReg = MF.addLiveIn(AArch64::X8, &AArch64::GPR64RegClass);
569 Forwards.push_back(ForwardedRegister(X8VReg, AArch64::X8, MVT::i64));
570 }
571
572 // Add the forwards to the MachineBasicBlock and MachineFunction.
573 for (const auto &F : Forwards) {
574 MBB.addLiveIn(F.PReg);
575 MIRBuilder.buildCopy(Register(F.VReg), Register(F.PReg));
576 }
577}
578
580 auto &F = MF.getFunction();
581 const auto &TM = static_cast<const AArch64TargetMachine &>(MF.getTarget());
582
583 const bool GlobalISelFlag =
585
586 auto OptLevel = MF.getTarget().getOptLevel();
587 auto EnableGlobalISelAtO = TM.getEnableGlobalISelAtO();
588
589 // GlobalISel is currently only enabled when the opt level is less than or
590 // equal to EnableGlobalISelAt or it was explicitly enabled via the CLI. If we
591 // encounter this check, we know GlobalISel was enabled. If not by these two,
592 // it must have been used as part of the SDAG pipeline to use GlobalISel for
593 // optnone.
594 if (static_cast<unsigned>(OptLevel) > EnableGlobalISelAtO && !GlobalISelFlag)
595 return !F.hasOptNone();
596
597 if (!EnableSVEGISel && (F.getReturnType()->isScalableTy() ||
598 llvm::any_of(F.args(), [](const Argument &A) {
599 return A.getType()->isScalableTy();
600 })))
601 return true;
602 const auto &ST = MF.getSubtarget<AArch64Subtarget>();
603 if (!ST.hasNEON() || !ST.hasFPARMv8()) {
604 LLVM_DEBUG(dbgs() << "Falling back to SDAG because we don't support no-NEON\n");
605 return true;
606 }
607
608 SMEAttrs Attrs = MF.getInfo<AArch64FunctionInfo>()->getSMEFnAttrs();
609 if (Attrs.hasZAState() || Attrs.hasZT0State() ||
610 Attrs.hasStreamingInterfaceOrBody() ||
611 Attrs.hasStreamingCompatibleInterface())
612 return true;
613
614 return false;
615}
616
617void AArch64CallLowering::saveVarArgRegisters(
619 CCState &CCInfo) const {
622
623 MachineFunction &MF = MIRBuilder.getMF();
625 MachineFrameInfo &MFI = MF.getFrameInfo();
627 auto &Subtarget = MF.getSubtarget<AArch64Subtarget>();
628 bool IsWin64CC = Subtarget.isCallingConvWin64(CCInfo.getCallingConv(),
629 MF.getFunction().isVarArg());
630 const LLT p0 = LLT::pointer(0, 64);
631 const LLT s64 = LLT::scalar(64);
632
633 unsigned FirstVariadicGPR = CCInfo.getFirstUnallocated(GPRArgRegs);
634 unsigned NumVariadicGPRArgRegs = GPRArgRegs.size() - FirstVariadicGPR + 1;
635
636 unsigned GPRSaveSize = 8 * (GPRArgRegs.size() - FirstVariadicGPR);
637 int GPRIdx = 0;
638 if (GPRSaveSize != 0) {
639 if (IsWin64CC) {
640 GPRIdx = MFI.CreateFixedObject(GPRSaveSize,
641 -static_cast<int>(GPRSaveSize), false);
642 if (GPRSaveSize & 15)
643 // The extra size here, if triggered, will always be 8.
644 MFI.CreateFixedObject(16 - (GPRSaveSize & 15),
645 -static_cast<int>(alignTo(GPRSaveSize, 16)),
646 false);
647 } else
648 GPRIdx = MFI.CreateStackObject(GPRSaveSize, Align(8), false);
649
650 auto FIN = MIRBuilder.buildFrameIndex(p0, GPRIdx);
651 auto Offset =
652 MIRBuilder.buildConstant(MRI.createGenericVirtualRegister(s64), 8);
653
654 for (unsigned i = FirstVariadicGPR; i < GPRArgRegs.size(); ++i) {
655 Register Val = MRI.createGenericVirtualRegister(s64);
656 Handler.assignValueToReg(
657 Val, GPRArgRegs[i],
659 GPRArgRegs[i], MVT::i64, CCValAssign::Full));
660 auto MPO = IsWin64CC ? MachinePointerInfo::getFixedStack(
661 MF, GPRIdx, (i - FirstVariadicGPR) * 8)
662 : MachinePointerInfo::getStack(MF, i * 8);
663 MIRBuilder.buildStore(Val, FIN, MPO, inferAlignFromPtrInfo(MF, MPO));
664
665 FIN = MIRBuilder.buildPtrAdd(MRI.createGenericVirtualRegister(p0),
666 FIN.getReg(0), Offset);
667 }
668 }
669 FuncInfo->setVarArgsGPRIndex(GPRIdx);
670 FuncInfo->setVarArgsGPRSize(GPRSaveSize);
671
672 if (Subtarget.hasFPARMv8() && !IsWin64CC) {
673 unsigned FirstVariadicFPR = CCInfo.getFirstUnallocated(FPRArgRegs);
674
675 unsigned FPRSaveSize = 16 * (FPRArgRegs.size() - FirstVariadicFPR);
676 int FPRIdx = 0;
677 if (FPRSaveSize != 0) {
678 FPRIdx = MFI.CreateStackObject(FPRSaveSize, Align(16), false);
679
680 auto FIN = MIRBuilder.buildFrameIndex(p0, FPRIdx);
681 auto Offset =
682 MIRBuilder.buildConstant(MRI.createGenericVirtualRegister(s64), 16);
683
684 for (unsigned i = FirstVariadicFPR; i < FPRArgRegs.size(); ++i) {
685 Register Val = MRI.createGenericVirtualRegister(LLT::scalar(128));
686 Handler.assignValueToReg(
687 Val, FPRArgRegs[i],
689 i + MF.getFunction().getNumOperands() + NumVariadicGPRArgRegs,
690 MVT::f128, FPRArgRegs[i], MVT::f128, CCValAssign::Full));
691
692 auto MPO = MachinePointerInfo::getStack(MF, i * 16);
693 MIRBuilder.buildStore(Val, FIN, MPO, inferAlignFromPtrInfo(MF, MPO));
694
695 FIN = MIRBuilder.buildPtrAdd(MRI.createGenericVirtualRegister(p0),
696 FIN.getReg(0), Offset);
697 }
698 }
699 FuncInfo->setVarArgsFPRIndex(FPRIdx);
700 FuncInfo->setVarArgsFPRSize(FPRSaveSize);
701 }
702}
703
705 MachineIRBuilder &MIRBuilder, const Function &F,
707 MachineFunction &MF = MIRBuilder.getMF();
708 MachineBasicBlock &MBB = MIRBuilder.getMBB();
710 auto &DL = F.getDataLayout();
711 auto &Subtarget = MF.getSubtarget<AArch64Subtarget>();
712
713 // Arm64EC has extra requirements for varargs calls which are only implemented
714 // in SelectionDAG; bail out for now.
715 if (F.isVarArg() && Subtarget.isWindowsArm64EC())
716 return false;
717
718 // Arm64EC thunks have a special calling convention which is only implemented
719 // in SelectionDAG; bail out for now.
720 if (F.getCallingConv() == CallingConv::ARM64EC_Thunk_Native ||
721 F.getCallingConv() == CallingConv::ARM64EC_Thunk_X64)
722 return false;
723
724 bool IsWin64 =
725 Subtarget.isCallingConvWin64(F.getCallingConv(), F.isVarArg()) &&
726 !Subtarget.isWindowsArm64EC();
727
728 SmallVector<ArgInfo, 8> SplitArgs;
730
731 // Insert the hidden sret parameter if the return value won't fit in the
732 // return registers.
733 if (!FLI.CanLowerReturn)
735
736 unsigned i = 0;
737 for (auto &Arg : F.args()) {
738 if (DL.getTypeStoreSize(Arg.getType()).isZero())
739 continue;
740
741 ArgInfo OrigArg{VRegs[i], Arg, i};
742 setArgFlags(OrigArg, i + AttributeList::FirstArgIndex, DL, F);
743
744 // i1 arguments are zero-extended to i8 by the caller. Emit a
745 // hint to reflect this.
746 if (OrigArg.Ty->isIntegerTy(1)) {
747 assert(OrigArg.Regs.size() == 1 &&
748 MRI.getType(OrigArg.Regs[0]).getSizeInBits() == 1 &&
749 "Unexpected registers used for i1 arg");
750
751 auto &Flags = OrigArg.Flags[0];
752 if (!Flags.isZExt() && !Flags.isSExt()) {
753 // Lower i1 argument as i8, and insert AssertZExt + Trunc later.
754 Register OrigReg = OrigArg.Regs[0];
755 Register WideReg = MRI.createGenericVirtualRegister(LLT::scalar(8));
756 OrigArg.Regs[0] = WideReg;
757 BoolArgs.push_back({OrigReg, WideReg});
758 }
759 }
760
761 if (Arg.hasAttribute(Attribute::SwiftAsync))
762 MF.getInfo<AArch64FunctionInfo>()->setHasSwiftAsyncContext(true);
763
764 splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv());
765 ++i;
766 }
767
768 if (!MBB.empty())
769 MIRBuilder.setInstr(*MBB.begin());
770
772 CCAssignFn *AssignFn = TLI.CCAssignFnForCall(F.getCallingConv(), IsWin64 && F.isVarArg());
773
774 AArch64IncomingValueAssigner Assigner(AssignFn, AssignFn);
775 FormalArgHandler Handler(MIRBuilder, MRI);
777 CCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, F.getContext());
778 if (!determineAssignments(Assigner, SplitArgs, CCInfo) ||
779 !handleAssignments(Handler, SplitArgs, CCInfo, ArgLocs, MIRBuilder))
780 return false;
781
782 if (!BoolArgs.empty()) {
783 for (auto &KV : BoolArgs) {
784 Register OrigReg = KV.first;
785 Register WideReg = KV.second;
786 LLT WideTy = MRI.getType(WideReg);
787 assert(MRI.getType(OrigReg).getScalarSizeInBits() == 1 &&
788 "Unexpected bit size of a bool arg");
789 MIRBuilder.buildTrunc(
790 OrigReg, MIRBuilder.buildAssertZExt(WideTy, WideReg, 1).getReg(0));
791 }
792 }
793
795 uint64_t StackSize = Assigner.StackSize;
796 if (F.isVarArg()) {
797 if ((!Subtarget.isTargetDarwin() && !Subtarget.isWindowsArm64EC()) || IsWin64) {
798 // The AAPCS variadic function ABI is identical to the non-variadic
799 // one. As a result there may be more arguments in registers and we should
800 // save them for future reference.
801 // Win64 variadic functions also pass arguments in registers, but all
802 // float arguments are passed in integer registers.
803 saveVarArgRegisters(MIRBuilder, Handler, CCInfo);
804 } else if (Subtarget.isWindowsArm64EC()) {
805 return false;
806 }
807
808 // We currently pass all varargs at 8-byte alignment, or 4 in ILP32.
809 StackSize = alignTo(Assigner.StackSize, Subtarget.isTargetILP32() ? 4 : 8);
810
811 auto &MFI = MIRBuilder.getMF().getFrameInfo();
812 FuncInfo->setVarArgsStackIndex(MFI.CreateFixedObject(4, StackSize, true));
813 }
814
815 if (doesCalleeRestoreStack(F.getCallingConv(),
817 // We have a non-standard ABI, so why not make full use of the stack that
818 // we're going to pop? It must be aligned to 16 B in any case.
819 StackSize = alignTo(StackSize, 16);
820
821 // If we're expected to restore the stack (e.g. fastcc), then we'll be
822 // adding a multiple of 16.
823 FuncInfo->setArgumentStackToRestore(StackSize);
824
825 // Our own callers will guarantee that the space is free by giving an
826 // aligned value to CALLSEQ_START.
827 }
828
829 // When we tail call, we need to check if the callee's arguments
830 // will fit on the caller's stack. So, whenever we lower formal arguments,
831 // we should keep track of this information, since we might lower a tail call
832 // in this function later.
833 FuncInfo->setBytesInStackArgArea(StackSize);
834
835 if (Subtarget.hasCustomCallingConv())
836 Subtarget.getRegisterInfo()->UpdateCustomCalleeSavedRegs(MF);
837
838 handleMustTailForwardedRegisters(MIRBuilder, AssignFn);
839
840 // Move back to the end of the basic block.
841 MIRBuilder.setMBB(MBB);
842
843 return true;
844}
845
846/// Return true if the calling convention is one that we can guarantee TCO for.
847static bool canGuaranteeTCO(CallingConv::ID CC, bool GuaranteeTailCalls) {
848 return (CC == CallingConv::Fast && GuaranteeTailCalls) ||
850}
851
852/// Return true if we might ever do TCO for calls with this calling convention.
854 switch (CC) {
855 case CallingConv::C:
863 return true;
864 default:
865 return false;
866 }
867}
868
869/// Returns a pair containing the fixed CCAssignFn and the vararg CCAssignFn for
870/// CC.
871static std::pair<CCAssignFn *, CCAssignFn *>
873 return {TLI.CCAssignFnForCall(CC, false), TLI.CCAssignFnForCall(CC, true)};
874}
875
876bool AArch64CallLowering::doCallerAndCalleePassArgsTheSameWay(
877 CallLoweringInfo &Info, MachineFunction &MF,
878 SmallVectorImpl<ArgInfo> &InArgs) const {
879 const Function &CallerF = MF.getFunction();
880 CallingConv::ID CalleeCC = Info.CallConv;
881 CallingConv::ID CallerCC = CallerF.getCallingConv();
882
883 // If the calling conventions match, then everything must be the same.
884 if (CalleeCC == CallerCC)
885 return true;
886
887 // Check if the caller and callee will handle arguments in the same way.
888 const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
889 CCAssignFn *CalleeAssignFnFixed;
890 CCAssignFn *CalleeAssignFnVarArg;
891 std::tie(CalleeAssignFnFixed, CalleeAssignFnVarArg) =
892 getAssignFnsForCC(CalleeCC, TLI);
893
894 CCAssignFn *CallerAssignFnFixed;
895 CCAssignFn *CallerAssignFnVarArg;
896 std::tie(CallerAssignFnFixed, CallerAssignFnVarArg) =
897 getAssignFnsForCC(CallerCC, TLI);
898
899 AArch64IncomingValueAssigner CalleeAssigner(CalleeAssignFnFixed,
900 CalleeAssignFnVarArg);
901 AArch64IncomingValueAssigner CallerAssigner(CallerAssignFnFixed,
902 CallerAssignFnVarArg);
903
904 if (!resultsCompatible(Info, MF, InArgs, CalleeAssigner, CallerAssigner))
905 return false;
906
907 // Make sure that the caller and callee preserve all of the same registers.
908 auto TRI = MF.getSubtarget<AArch64Subtarget>().getRegisterInfo();
909 const uint32_t *CallerPreserved = TRI->getCallPreservedMask(MF, CallerCC);
910 const uint32_t *CalleePreserved = TRI->getCallPreservedMask(MF, CalleeCC);
911 if (MF.getSubtarget<AArch64Subtarget>().hasCustomCallingConv()) {
912 TRI->UpdateCustomCallPreservedMask(MF, &CallerPreserved);
913 TRI->UpdateCustomCallPreservedMask(MF, &CalleePreserved);
914 }
915
916 return TRI->regmaskSubsetEqual(CallerPreserved, CalleePreserved);
917}
918
919bool AArch64CallLowering::areCalleeOutgoingArgsTailCallable(
920 CallLoweringInfo &Info, MachineFunction &MF,
921 SmallVectorImpl<ArgInfo> &OrigOutArgs) const {
922 // If there are no outgoing arguments, then we are done.
923 if (OrigOutArgs.empty())
924 return true;
925
926 const Function &CallerF = MF.getFunction();
927 LLVMContext &Ctx = CallerF.getContext();
928 CallingConv::ID CalleeCC = Info.CallConv;
929 CallingConv::ID CallerCC = CallerF.getCallingConv();
930 const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
931 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
932
933 CCAssignFn *AssignFnFixed;
934 CCAssignFn *AssignFnVarArg;
935 std::tie(AssignFnFixed, AssignFnVarArg) = getAssignFnsForCC(CalleeCC, TLI);
936
937 // We have outgoing arguments. Make sure that we can tail call with them.
939 CCState OutInfo(CalleeCC, false, MF, OutLocs, Ctx);
940
941 AArch64OutgoingValueAssigner CalleeAssigner(AssignFnFixed, AssignFnVarArg,
942 Subtarget, /*IsReturn*/ false);
943 // determineAssignments() may modify argument flags, so make a copy.
945 append_range(OutArgs, OrigOutArgs);
946 if (!determineAssignments(CalleeAssigner, OutArgs, OutInfo)) {
947 LLVM_DEBUG(dbgs() << "... Could not analyze call operands.\n");
948 return false;
949 }
950
951 // Make sure that they can fit on the caller's stack.
952 const AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>();
953 if (OutInfo.getStackSize() > FuncInfo->getBytesInStackArgArea()) {
954 LLVM_DEBUG(dbgs() << "... Cannot fit call operands on caller's stack.\n");
955 return false;
956 }
957
958 // Verify that the parameters in callee-saved registers match.
959 // TODO: Port this over to CallLowering as general code once swiftself is
960 // supported.
961 auto TRI = MF.getSubtarget<AArch64Subtarget>().getRegisterInfo();
962 const uint32_t *CallerPreservedMask = TRI->getCallPreservedMask(MF, CallerCC);
963 MachineRegisterInfo &MRI = MF.getRegInfo();
964
965 if (Info.IsVarArg) {
966 // Be conservative and disallow variadic memory operands to match SDAG's
967 // behaviour.
968 // FIXME: If the caller's calling convention is C, then we can
969 // potentially use its argument area. However, for cases like fastcc,
970 // we can't do anything.
971 for (unsigned i = 0; i < OutLocs.size(); ++i) {
972 auto &ArgLoc = OutLocs[i];
973 if (ArgLoc.isRegLoc())
974 continue;
975
977 dbgs()
978 << "... Cannot tail call vararg function with stack arguments\n");
979 return false;
980 }
981 }
982
983 return parametersInCSRMatch(MRI, CallerPreservedMask, OutLocs, OutArgs);
984}
985
987 MachineIRBuilder &MIRBuilder, CallLoweringInfo &Info,
989 SmallVectorImpl<ArgInfo> &OutArgs) const {
990
991 // Must pass all target-independent checks in order to tail call optimize.
992 if (!Info.IsTailCall)
993 return false;
994
995 CallingConv::ID CalleeCC = Info.CallConv;
996 MachineFunction &MF = MIRBuilder.getMF();
997 const Function &CallerF = MF.getFunction();
998
999 LLVM_DEBUG(dbgs() << "Attempting to lower call as tail call\n");
1000
1001 if (Info.SwiftErrorVReg) {
1002 // TODO: We should handle this.
1003 // Note that this is also handled by the check for no outgoing arguments.
1004 // Proactively disabling this though, because the swifterror handling in
1005 // lowerCall inserts a COPY *after* the location of the call.
1006 LLVM_DEBUG(dbgs() << "... Cannot handle tail calls with swifterror yet.\n");
1007 return false;
1008 }
1009
1010 if (!mayTailCallThisCC(CalleeCC)) {
1011 LLVM_DEBUG(dbgs() << "... Calling convention cannot be tail called.\n");
1012 return false;
1013 }
1014
1015 // Byval parameters hand the function a pointer directly into the stack area
1016 // we want to reuse during a tail call. Working around this *is* possible (see
1017 // X86).
1018 //
1019 // FIXME: In AArch64ISelLowering, this isn't worked around. Can/should we try
1020 // it?
1021 //
1022 // On Windows, "inreg" attributes signify non-aggregate indirect returns.
1023 // In this case, it is necessary to save/restore X0 in the callee. Tail
1024 // call opt interferes with this. So we disable tail call opt when the
1025 // caller has an argument with "inreg" attribute.
1026 //
1027 // FIXME: Check whether the callee also has an "inreg" argument.
1028 //
1029 // When the caller has a swifterror argument, we don't want to tail call
1030 // because would have to move into the swifterror register before the
1031 // tail call.
1032 if (any_of(CallerF.args(), [](const Argument &A) {
1033 return A.hasByValAttr() || A.hasInRegAttr() || A.hasSwiftErrorAttr();
1034 })) {
1035 LLVM_DEBUG(dbgs() << "... Cannot tail call from callers with byval, "
1036 "inreg, or swifterror arguments\n");
1037 return false;
1038 }
1039
1040 // Externally-defined functions with weak linkage should not be
1041 // tail-called on AArch64 when the OS does not support dynamic
1042 // pre-emption of symbols, as the AAELF spec requires normal calls
1043 // to undefined weak functions to be replaced with a NOP or jump to the
1044 // next instruction. The behaviour of branch instructions in this
1045 // situation (as used for tail calls) is implementation-defined, so we
1046 // cannot rely on the linker replacing the tail call with a return.
1047 if (Info.Callee.isGlobal()) {
1048 const GlobalValue *GV = Info.Callee.getGlobal();
1049 const Triple &TT = MF.getTarget().getTargetTriple();
1050 if (GV->hasExternalWeakLinkage() &&
1051 (!TT.isOSWindows() || TT.isOSBinFormatELF() ||
1052 TT.isOSBinFormatMachO())) {
1053 LLVM_DEBUG(dbgs() << "... Cannot tail call externally-defined function "
1054 "with weak linkage for this OS.\n");
1055 return false;
1056 }
1057 }
1058
1059 // If we have -tailcallopt, then we're done.
1061 return CalleeCC == CallerF.getCallingConv();
1062
1063 // We don't have -tailcallopt, so we're allowed to change the ABI (sibcall).
1064 // Try to find cases where we can do that.
1065
1066 // I want anyone implementing a new calling convention to think long and hard
1067 // about this assert.
1068 assert((!Info.IsVarArg || CalleeCC == CallingConv::C) &&
1069 "Unexpected variadic calling convention");
1070
1071 // Verify that the incoming and outgoing arguments from the callee are
1072 // safe to tail call.
1073 if (!doCallerAndCalleePassArgsTheSameWay(Info, MF, InArgs)) {
1074 LLVM_DEBUG(
1075 dbgs()
1076 << "... Caller and callee have incompatible calling conventions.\n");
1077 return false;
1078 }
1079
1080 if (!areCalleeOutgoingArgsTailCallable(Info, MF, OutArgs))
1081 return false;
1082
1083 LLVM_DEBUG(
1084 dbgs() << "... Call is eligible for tail call optimization.\n");
1085 return true;
1086}
1087
1088static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect,
1089 bool IsTailCall,
1090 std::optional<CallLowering::PtrAuthInfo> &PAI,
1092 const AArch64FunctionInfo *FuncInfo = CallerF.getInfo<AArch64FunctionInfo>();
1093
1094 if (!IsTailCall) {
1095 if (!PAI)
1096 return IsIndirect ? getBLRCallOpcode(CallerF) : (unsigned)AArch64::BL;
1097
1098 assert(IsIndirect && "Direct call should not be authenticated");
1099 assert((PAI->Key == AArch64PACKey::IA || PAI->Key == AArch64PACKey::IB) &&
1100 "Invalid auth call key");
1101 return AArch64::BLRA;
1102 }
1103
1104 if (!IsIndirect)
1105 return AArch64::TCRETURNdi;
1106
1107 // When BTI or PAuthLR are enabled, there are restrictions on using x16 and
1108 // x17 to hold the function pointer.
1109 if (FuncInfo->branchTargetEnforcement()) {
1110 if (FuncInfo->branchProtectionPAuthLR()) {
1111 assert(!PAI && "ptrauth tail-calls not yet supported with PAuthLR");
1112 return AArch64::TCRETURNrix17;
1113 }
1114 if (PAI)
1115 return AArch64::AUTH_TCRETURN_BTI;
1116 return AArch64::TCRETURNrix16x17;
1117 }
1118
1119 if (FuncInfo->branchProtectionPAuthLR()) {
1120 assert(!PAI && "ptrauth tail-calls not yet supported with PAuthLR");
1121 return AArch64::TCRETURNrinotx16;
1122 }
1123
1124 if (PAI)
1125 return AArch64::AUTH_TCRETURN;
1126 return AArch64::TCRETURNri;
1127}
1128
1129static const uint32_t *
1133 const uint32_t *Mask;
1134 if (!OutArgs.empty() && OutArgs[0].Flags[0].isReturned()) {
1135 // For 'this' returns, use the X0-preserving mask if applicable
1136 Mask = TRI.getThisReturnPreservedMask(MF, Info.CallConv);
1137 if (!Mask) {
1138 OutArgs[0].Flags[0].setReturned(false);
1139 Mask = TRI.getCallPreservedMask(MF, Info.CallConv);
1140 }
1141 } else {
1142 Mask = TRI.getCallPreservedMask(MF, Info.CallConv);
1143 }
1144 return Mask;
1145}
1146
1147bool AArch64CallLowering::lowerTailCall(
1148 MachineIRBuilder &MIRBuilder, CallLoweringInfo &Info,
1149 SmallVectorImpl<ArgInfo> &OutArgs) const {
1150 MachineFunction &MF = MIRBuilder.getMF();
1151 const Function &F = MF.getFunction();
1152 MachineRegisterInfo &MRI = MF.getRegInfo();
1153 const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
1154 AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>();
1155
1156 // True when we're tail calling, but without -tailcallopt.
1157 bool IsSibCall = !MF.getTarget().Options.GuaranteedTailCallOpt &&
1158 Info.CallConv != CallingConv::Tail &&
1159 Info.CallConv != CallingConv::SwiftTail;
1160
1161 // Find out which ABI gets to decide where things go.
1162 CallingConv::ID CalleeCC = Info.CallConv;
1163 CCAssignFn *AssignFnFixed;
1164 CCAssignFn *AssignFnVarArg;
1165 std::tie(AssignFnFixed, AssignFnVarArg) = getAssignFnsForCC(CalleeCC, TLI);
1166
1167 MachineInstrBuilder CallSeqStart;
1168 if (!IsSibCall)
1169 CallSeqStart = MIRBuilder.buildInstr(AArch64::ADJCALLSTACKDOWN);
1170
1171 unsigned Opc = getCallOpcode(MF, Info.Callee.isReg(), true, Info.PAI, MRI);
1172 auto MIB = MIRBuilder.buildInstrNoInsert(Opc);
1173 MIB.add(Info.Callee);
1174
1175 // Tell the call which registers are clobbered.
1176 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
1177 auto TRI = Subtarget.getRegisterInfo();
1178
1179 // Byte offset for the tail call. When we are sibcalling, this will always
1180 // be 0.
1181 MIB.addImm(0);
1182
1183 // Authenticated tail calls always take key/discriminator arguments.
1184 if (Opc == AArch64::AUTH_TCRETURN || Opc == AArch64::AUTH_TCRETURN_BTI) {
1185 assert((Info.PAI->Key == AArch64PACKey::IA ||
1186 Info.PAI->Key == AArch64PACKey::IB) &&
1187 "Invalid auth call key");
1188 MIB.addImm(Info.PAI->Key);
1189
1190 Register AddrDisc = 0;
1191 uint16_t IntDisc = 0;
1192 std::tie(IntDisc, AddrDisc) =
1193 extractPtrauthBlendDiscriminators(Info.PAI->Discriminator, MRI);
1194
1195 MIB.addImm(IntDisc);
1196 MIB.addUse(AddrDisc);
1197 if (AddrDisc != AArch64::NoRegister) {
1198 MIB->getOperand(4).setReg(constrainOperandRegClass(
1199 MF, *TRI, MRI, *MF.getSubtarget().getInstrInfo(),
1200 *MF.getSubtarget().getRegBankInfo(), *MIB, MIB->getDesc(),
1201 MIB->getOperand(4), 4));
1202 }
1203 }
1204
1205 // Tell the call which registers are clobbered.
1206 const uint32_t *Mask = TRI->getCallPreservedMask(MF, CalleeCC);
1207 if (Subtarget.hasCustomCallingConv())
1208 TRI->UpdateCustomCallPreservedMask(MF, &Mask);
1209 MIB.addRegMask(Mask);
1210
1211 if (Info.CFIType)
1212 MIB->setCFIType(MF, Info.CFIType->getZExtValue());
1213
1214 if (TRI->isAnyArgRegReserved(MF))
1215 TRI->emitReservedArgRegCallError(MF);
1216
1217 // FPDiff is the byte offset of the call's argument area from the callee's.
1218 // Stores to callee stack arguments will be placed in FixedStackSlots offset
1219 // by this amount for a tail call. In a sibling call it must be 0 because the
1220 // caller will deallocate the entire stack and the callee still expects its
1221 // arguments to begin at SP+0.
1222 int FPDiff = 0;
1223
1224 // This will be 0 for sibcalls, potentially nonzero for tail calls produced
1225 // by -tailcallopt. For sibcalls, the memory operands for the call are
1226 // already available in the caller's incoming argument space.
1227 unsigned NumBytes = 0;
1228 if (!IsSibCall) {
1229 // We aren't sibcalling, so we need to compute FPDiff. We need to do this
1230 // before handling assignments, because FPDiff must be known for memory
1231 // arguments.
1232 unsigned NumReusableBytes = FuncInfo->getBytesInStackArgArea();
1234 CCState OutInfo(CalleeCC, false, MF, OutLocs, F.getContext());
1235
1236 AArch64OutgoingValueAssigner CalleeAssigner(AssignFnFixed, AssignFnVarArg,
1237 Subtarget, /*IsReturn*/ false);
1238 if (!determineAssignments(CalleeAssigner, OutArgs, OutInfo))
1239 return false;
1240
1241 // The callee will pop the argument stack as a tail call. Thus, we must
1242 // keep it 16-byte aligned.
1243 NumBytes = alignTo(OutInfo.getStackSize(), 16);
1244
1245 // FPDiff will be negative if this tail call requires more space than we
1246 // would automatically have in our incoming argument space. Positive if we
1247 // actually shrink the stack.
1248 FPDiff = NumReusableBytes - NumBytes;
1249
1250 // Update the required reserved area if this is the tail call requiring the
1251 // most argument stack space.
1252 if (FPDiff < 0 && FuncInfo->getTailCallReservedStack() < (unsigned)-FPDiff)
1253 FuncInfo->setTailCallReservedStack(-FPDiff);
1254
1255 // The stack pointer must be 16-byte aligned at all times it's used for a
1256 // memory operation, which in practice means at *all* times and in
1257 // particular across call boundaries. Therefore our own arguments started at
1258 // a 16-byte aligned SP and the delta applied for the tail call should
1259 // satisfy the same constraint.
1260 assert(FPDiff % 16 == 0 && "unaligned stack on tail call");
1261 }
1262
1263 const auto &Forwards = FuncInfo->getForwardedMustTailRegParms();
1264
1265 AArch64OutgoingValueAssigner Assigner(AssignFnFixed, AssignFnVarArg,
1266 Subtarget, /*IsReturn*/ false);
1267
1268 // Do the actual argument marshalling.
1269 OutgoingArgHandler Handler(MIRBuilder, MRI, MIB,
1270 /*IsTailCall*/ true, FPDiff);
1271 if (!determineAndHandleAssignments(Handler, Assigner, OutArgs, MIRBuilder,
1272 CalleeCC, Info.IsVarArg))
1273 return false;
1274
1275 Mask = getMaskForArgs(OutArgs, Info, *TRI, MF);
1276
1277 if (Info.IsVarArg && Info.IsMustTailCall) {
1278 // Now we know what's being passed to the function. Add uses to the call for
1279 // the forwarded registers that we *aren't* passing as parameters. This will
1280 // preserve the copies we build earlier.
1281 for (const auto &F : Forwards) {
1282 Register ForwardedReg = F.PReg;
1283 // If the register is already passed, or aliases a register which is
1284 // already being passed, then skip it.
1285 if (any_of(MIB->uses(), [&ForwardedReg, &TRI](const MachineOperand &Use) {
1286 if (!Use.isReg())
1287 return false;
1288 return TRI->regsOverlap(Use.getReg(), ForwardedReg);
1289 }))
1290 continue;
1291
1292 // We aren't passing it already, so we should add it to the call.
1293 MIRBuilder.buildCopy(ForwardedReg, Register(F.VReg));
1294 MIB.addReg(ForwardedReg, RegState::Implicit);
1295 }
1296 }
1297
1298 // If we have -tailcallopt, we need to adjust the stack. We'll do the call
1299 // sequence start and end here.
1300 if (!IsSibCall) {
1301 MIB->getOperand(1).setImm(FPDiff);
1302 CallSeqStart.addImm(0).addImm(0);
1303 // End the call sequence *before* emitting the call. Normally, we would
1304 // tidy the frame up after the call. However, here, we've laid out the
1305 // parameters so that when SP is reset, they will be in the correct
1306 // location.
1307 MIRBuilder.buildInstr(AArch64::ADJCALLSTACKUP).addImm(0).addImm(0);
1308 }
1309
1310 // Now we can add the actual call instruction to the correct basic block.
1311 MIRBuilder.insertInstr(MIB);
1312
1313 // If Callee is a reg, since it is used by a target specific instruction,
1314 // it must have a register class matching the constraint of that instruction.
1315 if (MIB->getOperand(0).isReg())
1317 *MF.getSubtarget().getRegBankInfo(), *MIB,
1318 MIB->getDesc(), MIB->getOperand(0), 0);
1319
1321 Info.LoweredTailCall = true;
1322 return true;
1323}
1324
1326 CallLoweringInfo &Info) const {
1327 MachineFunction &MF = MIRBuilder.getMF();
1328 const Function &F = MF.getFunction();
1330 auto &DL = F.getDataLayout();
1332 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
1333
1334 // Arm64EC has extra requirements for varargs calls; bail out for now.
1335 //
1336 // Arm64EC has special mangling rules for calls; bail out on all calls for
1337 // now.
1338 if (Subtarget.isWindowsArm64EC())
1339 return false;
1340
1341 // Arm64EC thunks have a special calling convention which is only implemented
1342 // in SelectionDAG; bail out for now.
1343 if (Info.CallConv == CallingConv::ARM64EC_Thunk_Native ||
1344 Info.CallConv == CallingConv::ARM64EC_Thunk_X64)
1345 return false;
1346
1348 for (auto &OrigArg : Info.OrigArgs) {
1349 splitToValueTypes(OrigArg, OutArgs, DL, Info.CallConv);
1350 // AAPCS requires that we zero-extend i1 to 8 bits by the caller.
1351 auto &Flags = OrigArg.Flags[0];
1352 if (OrigArg.Ty->isIntegerTy(1) && !Flags.isSExt() && !Flags.isZExt()) {
1353 ArgInfo &OutArg = OutArgs.back();
1354 assert(OutArg.Regs.size() == 1 &&
1355 MRI.getType(OutArg.Regs[0]).getSizeInBits() == 1 &&
1356 "Unexpected registers used for i1 arg");
1357
1358 // We cannot use a ZExt ArgInfo flag here, because it will
1359 // zero-extend the argument to i32 instead of just i8.
1360 OutArg.Regs[0] =
1361 MIRBuilder.buildZExt(LLT::scalar(8), OutArg.Regs[0]).getReg(0);
1362 LLVMContext &Ctx = MF.getFunction().getContext();
1363 OutArg.Ty = Type::getInt8Ty(Ctx);
1364 }
1365 }
1366
1368 if (!Info.OrigRet.Ty->isVoidTy())
1369 splitToValueTypes(Info.OrigRet, InArgs, DL, Info.CallConv);
1370
1371 // If we can lower as a tail call, do that instead.
1372 bool CanTailCallOpt =
1373 isEligibleForTailCallOptimization(MIRBuilder, Info, InArgs, OutArgs);
1374
1375 // We must emit a tail call if we have musttail.
1376 if (Info.IsMustTailCall && !CanTailCallOpt) {
1377 // There are types of incoming/outgoing arguments we can't handle yet, so
1378 // it doesn't make sense to actually die here like in ISelLowering. Instead,
1379 // fall back to SelectionDAG and let it try to handle this.
1380 LLVM_DEBUG(dbgs() << "Failed to lower musttail call as tail call\n");
1381 return false;
1382 }
1383
1384 Info.IsTailCall = CanTailCallOpt;
1385 if (CanTailCallOpt)
1386 return lowerTailCall(MIRBuilder, Info, OutArgs);
1387
1388 // Find out which ABI gets to decide where things go.
1389 CCAssignFn *AssignFnFixed;
1390 CCAssignFn *AssignFnVarArg;
1391 std::tie(AssignFnFixed, AssignFnVarArg) =
1392 getAssignFnsForCC(Info.CallConv, TLI);
1393
1394 MachineInstrBuilder CallSeqStart;
1395 CallSeqStart = MIRBuilder.buildInstr(AArch64::ADJCALLSTACKDOWN);
1396
1397 // Create a temporarily-floating call instruction so we can add the implicit
1398 // uses of arg registers.
1399
1400 unsigned Opc = 0;
1401 // Calls with operand bundle "clang.arc.attachedcall" are special. They should
1402 // be expanded to the call, directly followed by a special marker sequence and
1403 // a call to an ObjC library function.
1404 if (Info.CB && objcarc::hasAttachedCallOpBundle(Info.CB))
1405 Opc = Info.PAI ? AArch64::BLRA_RVMARKER : AArch64::BLR_RVMARKER;
1406 // A call to a returns twice function like setjmp must be followed by a bti
1407 // instruction.
1408 else if (Info.CB && Info.CB->hasFnAttr(Attribute::ReturnsTwice) &&
1409 !Subtarget.noBTIAtReturnTwice() &&
1411 Opc = AArch64::BLR_BTI;
1412 else {
1413 // For an intrinsic call (e.g. memset), use GOT if "RtLibUseGOT" (-fno-plt)
1414 // is set.
1415 if (Info.Callee.isSymbol() && F.getParent()->getRtLibUseGOT()) {
1416 auto MIB = MIRBuilder.buildInstr(TargetOpcode::G_GLOBAL_VALUE);
1417 DstOp(getLLTForType(*F.getType(), DL)).addDefToMIB(MRI, MIB);
1418 MIB.addExternalSymbol(Info.Callee.getSymbolName(), AArch64II::MO_GOT);
1419 Info.Callee = MachineOperand::CreateReg(MIB.getReg(0), false);
1420 }
1421 Opc = getCallOpcode(MF, Info.Callee.isReg(), false, Info.PAI, MRI);
1422 }
1423
1424 auto MIB = MIRBuilder.buildInstrNoInsert(Opc);
1425 unsigned CalleeOpNo = 0;
1426
1427 if (Opc == AArch64::BLR_RVMARKER || Opc == AArch64::BLRA_RVMARKER) {
1428 // Add a target global address for the retainRV/claimRV runtime function
1429 // just before the call target.
1430 Function *ARCFn = *objcarc::getAttachedARCFunction(Info.CB);
1431 MIB.addGlobalAddress(ARCFn);
1432 ++CalleeOpNo;
1433
1434 // We may or may not need to emit both the marker and the retain/claim call.
1435 // Tell the pseudo expansion using an additional boolean op.
1436 MIB.addImm(objcarc::attachedCallOpBundleNeedsMarker(Info.CB));
1437 ++CalleeOpNo;
1438 } else if (Info.CFIType) {
1439 MIB->setCFIType(MF, Info.CFIType->getZExtValue());
1440 }
1441 MIB->setDeactivationSymbol(MF, Info.DeactivationSymbol);
1442
1443 MIB.add(Info.Callee);
1444
1445 // Tell the call which registers are clobbered.
1446 const uint32_t *Mask;
1447 const auto *TRI = Subtarget.getRegisterInfo();
1448
1449 AArch64OutgoingValueAssigner Assigner(AssignFnFixed, AssignFnVarArg,
1450 Subtarget, /*IsReturn*/ false);
1451 // Do the actual argument marshalling.
1452 OutgoingArgHandler Handler(MIRBuilder, MRI, MIB, /*IsReturn*/ false);
1453 if (!determineAndHandleAssignments(Handler, Assigner, OutArgs, MIRBuilder,
1454 Info.CallConv, Info.IsVarArg))
1455 return false;
1456
1457 Mask = getMaskForArgs(OutArgs, Info, *TRI, MF);
1458
1459 if (Opc == AArch64::BLRA || Opc == AArch64::BLRA_RVMARKER) {
1460 assert((Info.PAI->Key == AArch64PACKey::IA ||
1461 Info.PAI->Key == AArch64PACKey::IB) &&
1462 "Invalid auth call key");
1463 MIB.addImm(Info.PAI->Key);
1464
1465 Register AddrDisc = 0;
1466 uint16_t IntDisc = 0;
1467 std::tie(IntDisc, AddrDisc) =
1468 extractPtrauthBlendDiscriminators(Info.PAI->Discriminator, MRI);
1469
1470 MIB.addImm(IntDisc);
1471 MIB.addUse(AddrDisc);
1472 if (AddrDisc != AArch64::NoRegister) {
1474 *MF.getSubtarget().getRegBankInfo(), *MIB,
1475 MIB->getDesc(), MIB->getOperand(CalleeOpNo + 3),
1476 CalleeOpNo + 3);
1477 }
1478 }
1479
1480 // Tell the call which registers are clobbered.
1482 TRI->UpdateCustomCallPreservedMask(MF, &Mask);
1483 MIB.addRegMask(Mask);
1484
1485 if (TRI->isAnyArgRegReserved(MF))
1486 TRI->emitReservedArgRegCallError(MF);
1487
1488 // Now we can add the actual call instruction to the correct basic block.
1489 MIRBuilder.insertInstr(MIB);
1490
1491 uint64_t CalleePopBytes =
1492 doesCalleeRestoreStack(Info.CallConv,
1494 ? alignTo(Assigner.StackSize, 16)
1495 : 0;
1496
1497 CallSeqStart.addImm(Assigner.StackSize).addImm(0);
1498 MIRBuilder.buildInstr(AArch64::ADJCALLSTACKUP)
1499 .addImm(Assigner.StackSize)
1500 .addImm(CalleePopBytes);
1501
1502 // If Callee is a reg, since it is used by a target specific
1503 // instruction, it must have a register class matching the
1504 // constraint of that instruction.
1505 if (MIB->getOperand(CalleeOpNo).isReg())
1506 constrainOperandRegClass(MF, *TRI, MRI, *Subtarget.getInstrInfo(),
1507 *Subtarget.getRegBankInfo(), *MIB, MIB->getDesc(),
1508 MIB->getOperand(CalleeOpNo), CalleeOpNo);
1509
1510 // Finally we can copy the returned value back into its virtual-register. In
1511 // symmetry with the arguments, the physical register must be an
1512 // implicit-define of the call instruction.
1513 if (Info.CanLowerReturn && !Info.OrigRet.Ty->isVoidTy()) {
1514 CCAssignFn *RetAssignFn = TLI.CCAssignFnForReturn(Info.CallConv);
1515 CallReturnHandler Handler(MIRBuilder, MRI, MIB);
1516 bool UsingReturnedArg =
1517 !OutArgs.empty() && OutArgs[0].Flags[0].isReturned();
1518
1519 AArch64OutgoingValueAssigner Assigner(RetAssignFn, RetAssignFn, Subtarget,
1520 /*IsReturn*/ false);
1521 ReturnedArgCallReturnHandler ReturnedArgHandler(MIRBuilder, MRI, MIB);
1523 UsingReturnedArg ? ReturnedArgHandler : Handler, Assigner, InArgs,
1524 MIRBuilder, Info.CallConv, Info.IsVarArg,
1525 UsingReturnedArg ? ArrayRef(OutArgs[0].Regs)
1526 : ArrayRef<Register>()))
1527 return false;
1528 }
1529
1530 if (Info.SwiftErrorVReg) {
1531 MIB.addDef(AArch64::X21, RegState::Implicit);
1532 MIRBuilder.buildCopy(Info.SwiftErrorVReg, Register(AArch64::X21));
1533 }
1534
1535 if (!Info.CanLowerReturn) {
1536 insertSRetLoads(MIRBuilder, Info.OrigRet.Ty, Info.OrigRet.Regs,
1537 Info.DemoteRegister, Info.DemoteStackIndex);
1538 }
1539 return true;
1540}
1541
1543 return Ty.getSizeInBits() == 64;
1544}
unsigned const MachineRegisterInfo * MRI
static void handleMustTailForwardedRegisters(MachineIRBuilder &MIRBuilder, CCAssignFn *AssignFn)
Helper function to compute forwarded registers for musttail calls.
static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect, bool IsTailCall, std::optional< CallLowering::PtrAuthInfo > &PAI, MachineRegisterInfo &MRI)
static LLT getStackValueStoreTypeHack(const CCValAssign &VA)
static const uint32_t * getMaskForArgs(SmallVectorImpl< AArch64CallLowering::ArgInfo > &OutArgs, AArch64CallLowering::CallLoweringInfo &Info, const AArch64RegisterInfo &TRI, MachineFunction &MF)
static void applyStackPassedSmallTypeDAGHack(EVT OrigVT, MVT &ValVT, MVT &LocVT)
static std::pair< CCAssignFn *, CCAssignFn * > getAssignFnsForCC(CallingConv::ID CC, const AArch64TargetLowering &TLI)
Returns a pair containing the fixed CCAssignFn and the vararg CCAssignFn for CC.
static bool doesCalleeRestoreStack(CallingConv::ID CallConv, bool TailCallOpt)
This file describes how to lower LLVM calls to machine code calls.
MachineInstrBuilder MachineInstrBuilder & DefMI
static std::tuple< SDValue, SDValue > extractPtrauthBlendDiscriminators(SDValue Disc, SelectionDAG *DAG)
static bool shouldLowerTailCallStackArg(const MachineFunction &MF, const CCValAssign &VA, SDValue Arg, ISD::ArgFlagsTy Flags, int CallOffset)
Check whether a stack argument requires lowering in a tail call.
static const MCPhysReg GPRArgRegs[]
static const MCPhysReg FPRArgRegs[]
cl::opt< bool > EnableSVEGISel("aarch64-enable-gisel-sve", cl::Hidden, cl::desc("Enable / disable SVE scalable vectors in Global ISel"), cl::init(false))
static bool canGuaranteeTCO(CallingConv::ID CC, bool GuaranteeTailCalls)
Return true if the calling convention is one that we can guarantee TCO for.
static bool mayTailCallThisCC(CallingConv::ID CC)
Return true if we might ever do TCO for calls with this calling convention.
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static cl::opt< int > EnableGlobalISelAtO("aarch64-enable-global-isel-at-O", cl::Hidden, cl::desc("Enable GlobalISel at or below an opt level (-1 to disable)"), cl::init(0))
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the simple types necessary to represent the attributes associated with functions a...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
Implement a low-level type suitable for MachineInstr level instruction selection.
#define F(x, y, z)
Definition MD5.cpp:54
This file declares the MachineIRBuilder class.
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
This file defines ARC utility functions which are used by various parts of the compiler.
static constexpr MCPhysReg SPReg
This file defines the SmallVector class.
#define LLVM_DEBUG(...)
Definition Debug.h:114
bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val, ArrayRef< Register > VRegs, FunctionLoweringInfo &FLI, Register SwiftErrorVReg) const override
This hook must be implemented to lower outgoing return values, described by Val, into the specified v...
bool canLowerReturn(MachineFunction &MF, CallingConv::ID CallConv, SmallVectorImpl< BaseArgInfo > &Outs, bool IsVarArg) const override
This hook must be implemented to check whether the return values described by Outs can fit into the r...
bool fallBackToDAGISel(const MachineFunction &MF) const override
bool isTypeIsValidForThisReturn(EVT Ty) const override
For targets which support the "returned" parameter attribute, returns true if the given type is a val...
bool isEligibleForTailCallOptimization(MachineIRBuilder &MIRBuilder, CallLoweringInfo &Info, SmallVectorImpl< ArgInfo > &InArgs, SmallVectorImpl< ArgInfo > &OutArgs) const
Returns true if the call can be lowered as a tail call.
AArch64CallLowering(const AArch64TargetLowering &TLI)
bool lowerCall(MachineIRBuilder &MIRBuilder, CallLoweringInfo &Info) const override
This hook must be implemented to lower the given call instruction, including argument and return valu...
bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F, ArrayRef< ArrayRef< Register > > VRegs, FunctionLoweringInfo &FLI) const override
This hook must be implemented to lower the incoming (formal) arguments, described by VRegs,...
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
void setTailCallReservedStack(unsigned bytes)
SmallVectorImpl< ForwardedRegister > & getForwardedMustTailRegParms()
void setBytesInStackArgArea(unsigned bytes)
void setArgumentStackToRestore(unsigned bytes)
const AArch64RegisterInfo * getRegisterInfo() const override
const AArch64InstrInfo * getInstrInfo() const override
bool isCallingConvWin64(CallingConv::ID CC, bool IsVarArg) const
const RegisterBankInfo * getRegBankInfo() const override
bool hasCustomCallingConv() const
CCAssignFn * CCAssignFnForCall(CallingConv::ID CC, bool IsVarArg) const
Selects the correct CCAssignFn for a given CallingConvention value.
This class represents an incoming formal argument to a Function.
Definition Argument.h:32
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
size - Get the array size.
Definition ArrayRef.h:142
bool empty() const
empty - Check if the array is empty.
Definition ArrayRef.h:137
CCState - This class holds information needed while lowering arguments and return values.
MachineFunction & getMachineFunction() const
unsigned getFirstUnallocated(ArrayRef< MCPhysReg > Regs) const
getFirstUnallocated - Return the index of the first unallocated register in the set,...
LLVM_ABI void analyzeMustTailForwardedRegisters(SmallVectorImpl< ForwardedRegister > &Forwards, ArrayRef< MVT > RegParmTypes, CCAssignFn Fn)
Compute the set of registers that need to be preserved and forwarded to any musttail calls.
CallingConv::ID getCallingConv() const
uint64_t getStackSize() const
Returns the size of the currently allocated portion of the stack.
bool isVarArg() const
bool isAllocated(MCRegister Reg) const
isAllocated - Return true if the specified register (or an alias) is allocated.
CCValAssign - Represent assignment of one arg/retval to a location.
LocInfo getLocInfo() const
static CCValAssign getReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP, bool IsCustom=false)
void insertSRetLoads(MachineIRBuilder &MIRBuilder, Type *RetTy, ArrayRef< Register > VRegs, Register DemoteReg, int FI) const
Load the returned value from the stack into virtual registers in VRegs.
bool handleAssignments(ValueHandler &Handler, SmallVectorImpl< ArgInfo > &Args, CCState &CCState, SmallVectorImpl< CCValAssign > &ArgLocs, MachineIRBuilder &MIRBuilder, ArrayRef< Register > ThisReturnRegs={}) const
Use Handler to insert code to handle the argument/return values represented by Args.
bool resultsCompatible(CallLoweringInfo &Info, MachineFunction &MF, SmallVectorImpl< ArgInfo > &InArgs, ValueAssigner &CalleeAssigner, ValueAssigner &CallerAssigner) const
void splitToValueTypes(const ArgInfo &OrigArgInfo, SmallVectorImpl< ArgInfo > &SplitArgs, const DataLayout &DL, CallingConv::ID CallConv, SmallVectorImpl< uint64_t > *Offsets=nullptr) const
Break OrigArgInfo into one or more pieces the calling convention can process, returned in SplitArgs.
void insertSRetIncomingArgument(const Function &F, SmallVectorImpl< ArgInfo > &SplitArgs, Register &DemoteReg, MachineRegisterInfo &MRI, const DataLayout &DL) const
Insert the hidden sret ArgInfo to the beginning of SplitArgs.
bool determineAndHandleAssignments(ValueHandler &Handler, ValueAssigner &Assigner, SmallVectorImpl< ArgInfo > &Args, MachineIRBuilder &MIRBuilder, CallingConv::ID CallConv, bool IsVarArg, ArrayRef< Register > ThisReturnRegs={}) const
Invoke ValueAssigner::assignArg on each of the given Args and then use Handler to move them to the as...
void insertSRetStores(MachineIRBuilder &MIRBuilder, Type *RetTy, ArrayRef< Register > VRegs, Register DemoteReg) const
Store the return value given by VRegs into stack starting at the offset specified in DemoteReg.
bool parametersInCSRMatch(const MachineRegisterInfo &MRI, const uint32_t *CallerPreservedMask, const SmallVectorImpl< CCValAssign > &ArgLocs, const SmallVectorImpl< ArgInfo > &OutVals) const
Check whether parameters to a call that are passed in callee saved registers are the same as from the...
bool determineAssignments(ValueAssigner &Assigner, SmallVectorImpl< ArgInfo > &Args, CCState &CCInfo) const
Analyze the argument list in Args, using Assigner to populate CCInfo.
bool checkReturn(CCState &CCInfo, SmallVectorImpl< BaseArgInfo > &Outs, CCAssignFn *Fn) const
CallLowering(const TargetLowering *TLI)
const TargetLowering * getTLI() const
Getter for generic TargetLowering class.
void setArgFlags(ArgInfo &Arg, unsigned OpIdx, const DataLayout &DL, const FuncInfoTy &FuncInfo) const
void addDefToMIB(MachineRegisterInfo &MRI, MachineInstrBuilder &MIB) const
FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
Register DemoteRegister
DemoteRegister - if CanLowerReturn is false, DemoteRegister is a vreg allocated to hold a pointer to ...
bool CanLowerReturn
CanLowerReturn - true iff the function's return value can be lowered to registers.
iterator_range< arg_iterator > args()
Definition Function.h:896
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition Function.h:270
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition Function.cpp:358
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition Function.h:227
bool hasExternalWeakLinkage() const
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
constexpr uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
constexpr bool isVector() const
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
constexpr TypeSize getSizeInBytes() const
Returns the total size of the type in bytes, i.e.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
Machine Value Type.
bool isVector() const
Return true if this is a vector value type.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
LLVM_ABI int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
bool isImmutableObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to an immutable object.
void setHasTailCall(bool V=true)
bool hasMustTailInVarArgFunc() const
Returns true if the function is variadic and contains a musttail call.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Helper class to build MachineInstr.
MachineInstrBuilder insertInstr(MachineInstrBuilder MIB)
Insert an existing instruction at the insertion point.
MachineInstrBuilder buildZExt(const DstOp &Res, const SrcOp &Op, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_ZEXT Op.
void setInstr(MachineInstr &MI)
Set the insertion point to before MI.
MachineInstrBuilder buildAssertZExt(const DstOp &Res, const SrcOp &Op, unsigned Size)
Build and insert Res = G_ASSERT_ZEXT Op, Size.
MachineInstrBuilder buildPtrAdd(const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_PTR_ADD Op0, Op1.
MachineInstrBuilder buildStore(const SrcOp &Val, const SrcOp &Addr, MachineMemOperand &MMO)
Build and insert G_STORE Val, Addr, MMO.
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
MachineInstrBuilder buildPadVectorWithUndefElements(const DstOp &Res, const SrcOp &Op0)
Build and insert a, b, ..., x = G_UNMERGE_VALUES Op0 Res = G_BUILD_VECTOR a, b, .....
MachineInstrBuilder buildFrameIndex(const DstOp &Res, int Idx)
Build and insert Res = G_FRAME_INDEX Idx.
MachineFunction & getMF()
Getter for the function we currently build.
MachineInstrBuilder buildTrunc(const DstOp &Res, const SrcOp &Op, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_TRUNC Op.
const MachineBasicBlock & getMBB() const
Getter for the basic block we currently build.
void setMBB(MachineBasicBlock &MBB)
Set the insertion point to the end of MBB.
MachineInstrBuilder buildInstrNoInsert(unsigned Opcode)
Build but don't insert <empty> = Opcode <empty>.
MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op)
Build and insert Res = COPY Op.
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
Register getReg(unsigned Idx) const
Get the register for the operand index.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI void setDeactivationSymbol(MachineFunction &MF, Value *DS)
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
Register getReg() const
getReg - Returns the register number.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Wrapper class representing virtual and physical registers.
Definition Register.h:20
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
Definition Register.h:107
SMEAttrs is a utility class to parse the SME ACLE attributes on functions.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
const Triple & getTargetTriple() const
TargetOptions Options
unsigned GuaranteedTailCallOpt
GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is specified on the commandline.
virtual const RegisterBankInfo * getRegBankInfo() const
If the information for the register banks is available, return it.
virtual const TargetInstrInfo * getInstrInfo() const
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:47
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition TypeSize.h:343
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:294
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition Type.h:128
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:240
unsigned getNumOperands() const
Definition User.h:229
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:256
@ MO_GOT
MO_GOT - This flag indicates that a symbol operand represents the address of the GOT entry for the sy...
ArrayRef< MCPhysReg > getFPRArgRegs()
ArrayRef< MCPhysReg > getGPRArgRegs()
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ ARM64EC_Thunk_Native
Calling convention used in the ARM64EC ABI to implement calls between ARM64 code and thunks.
@ Swift
Calling convention for Swift.
Definition CallingConv.h:69
@ PreserveMost
Used for runtime calls that preserves most registers.
Definition CallingConv.h:63
@ PreserveAll
Used for runtime calls that preserves (almost) all registers.
Definition CallingConv.h:66
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition CallingConv.h:41
@ PreserveNone
Used for runtime calls that preserves none general registers.
Definition CallingConv.h:90
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
Definition CallingConv.h:76
@ SwiftTail
This follows the Swift calling convention in how arguments are passed but guarantees tail calls will ...
Definition CallingConv.h:87
@ ARM64EC_Thunk_X64
Calling convention used in the ARM64EC ABI to implement calls between x64 code and thunks.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
std::optional< Function * > getAttachedARCFunction(const CallBase *CB)
This function returns operand bundle clang_arc_attachedcall's argument, which is the address of the A...
Definition ObjCARCUtil.h:43
bool attachedCallOpBundleNeedsMarker(const CallBase *CB)
This function determines whether the clang_arc_attachedcall should be emitted with or without the mar...
Definition ObjCARCUtil.h:58
bool hasAttachedCallOpBundle(const CallBase *CB)
Definition ObjCARCUtil.h:29
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
@ Offset
Definition DWP.cpp:532
LLVM_ABI Register constrainOperandRegClass(const MachineFunction &MF, const TargetRegisterInfo &TRI, MachineRegisterInfo &MRI, const TargetInstrInfo &TII, const RegisterBankInfo &RBI, MachineInstr &InsertPt, const TargetRegisterClass &RegClass, MachineOperand &RegMO)
Constrain the Register operand OpIdx, so that it is now constrained to the TargetRegisterClass passed...
Definition Utils.cpp:56
@ Implicit
Not emitted register (e.g. carry, or temporary result).
void ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL, Type *Ty, SmallVectorImpl< EVT > &ValueVTs, SmallVectorImpl< EVT > *MemVTs=nullptr, SmallVectorImpl< TypeSize > *Offsets=nullptr, TypeSize StartingOffset=TypeSize::getZero())
ComputeValueVTs - Given an LLVM IR type, compute a sequence of EVTs that represent all the individual...
Definition Analysis.cpp:119
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2198
unsigned getBLRCallOpcode(const MachineFunction &MF)
Return opcode to be used for indirect calls.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1744
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
@ Success
The lock was released successfully.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
DWARFExpression::Operation Op
LLVM_ABI bool isAssertMI(const MachineInstr &MI)
Returns true if the instruction MI is one of the assert instructions.
Definition Utils.cpp:2049
LLVM_ABI LLT getLLTForType(Type &Ty, const DataLayout &DL)
Construct a low-level type based on an LLVM type.
LLVM_ABI CGPassBuilderOption getCGPassBuilderOption()
LLVM_ABI Align inferAlignFromPtrInfo(MachineFunction &MF, const MachinePointerInfo &MPO)
Definition Utils.cpp:905
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:872
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
std::optional< bool > EnableGlobalISelOption
SmallVector< Register, 4 > Regs
SmallVector< ISD::ArgFlagsTy, 4 > Flags
Base class for ValueHandlers used for arguments coming into the current function, or for return value...
void assignValueToReg(Register ValVReg, Register PhysReg, const CCValAssign &VA) override
Provides a default implementation for argument handling.
Base class for ValueHandlers used for arguments passed to a function call, or for return values.
virtual LLT getStackValueStoreType(const DataLayout &DL, const CCValAssign &VA, ISD::ArgFlagsTy Flags) const
Return the in-memory size to write for the argument at VA.
Extended Value Type.
Definition ValueTypes.h:35
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
Describes a register that needs to be forwarded from the prologue to a musttail call.
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.