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,
171 ISD::ArgFlagsTy Flags = {}) override {
172 markRegUsed(PhysReg);
173 IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA);
174 }
175
176 void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy,
177 const MachinePointerInfo &MPO,
178 const CCValAssign &VA) override {
179 MachineFunction &MF = MIRBuilder.getMF();
180
181 LLT ValTy(VA.getValVT());
182 LLT LocTy(VA.getLocVT());
183
184 // Fixup the types for the DAG compatibility hack.
185 if (VA.getValVT() == MVT::i8 || VA.getValVT() == MVT::i16)
186 std::swap(ValTy, LocTy);
187 else {
188 // The calling code knows if this is a pointer or not, we're only touching
189 // the LocTy for the i8/i16 hack.
190 assert(LocTy.getSizeInBits() == MemTy.getSizeInBits());
191 LocTy = MemTy;
192 }
193
194 auto MMO = MF.getMachineMemOperand(
196 inferAlignFromPtrInfo(MF, MPO));
197
198 switch (VA.getLocInfo()) {
199 case CCValAssign::LocInfo::ZExt:
200 MIRBuilder.buildLoadInstr(TargetOpcode::G_ZEXTLOAD, ValVReg, Addr, *MMO);
201 return;
202 case CCValAssign::LocInfo::SExt:
203 MIRBuilder.buildLoadInstr(TargetOpcode::G_SEXTLOAD, ValVReg, Addr, *MMO);
204 return;
205 default:
206 MIRBuilder.buildLoad(ValVReg, Addr, *MMO);
207 return;
208 }
209 }
210
211 /// How the physical register gets marked varies between formal
212 /// parameters (it's a basic-block live-in), and a call instruction
213 /// (it's an implicit-def of the BL).
214 virtual void markRegUsed(Register Reg) = 0;
215};
216
217struct FormalArgHandler : public IncomingArgHandler {
218 FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
219 : IncomingArgHandler(MIRBuilder, MRI) {}
220
221 void markRegUsed(Register Reg) override {
222 MIRBuilder.getMRI()->addLiveIn(Reg.asMCReg());
223 MIRBuilder.getMBB().addLiveIn(Reg.asMCReg());
224 }
225};
226
227struct CallReturnHandler : public IncomingArgHandler {
228 CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
229 MachineInstrBuilder MIB)
230 : IncomingArgHandler(MIRBuilder, MRI), MIB(MIB) {}
231
232 void markRegUsed(Register Reg) override {
233 MIB.addDef(Reg, RegState::Implicit);
234 }
235
236 MachineInstrBuilder MIB;
237};
238
239/// A special return arg handler for "returned" attribute arg calls.
240struct ReturnedArgCallReturnHandler : public CallReturnHandler {
241 ReturnedArgCallReturnHandler(MachineIRBuilder &MIRBuilder,
242 MachineRegisterInfo &MRI,
243 MachineInstrBuilder MIB)
244 : CallReturnHandler(MIRBuilder, MRI, MIB) {}
245
246 void markRegUsed(Register Reg) override {}
247};
248
249struct OutgoingArgHandler : public CallLowering::OutgoingValueHandler {
250 OutgoingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
251 MachineInstrBuilder MIB, bool IsTailCall = false,
252 int FPDiff = 0)
253 : OutgoingValueHandler(MIRBuilder, MRI), MIB(MIB), IsTailCall(IsTailCall),
254 FPDiff(FPDiff),
255 Subtarget(MIRBuilder.getMF().getSubtarget<AArch64Subtarget>()) {}
256
257 Register getStackAddress(uint64_t Size, int64_t Offset,
258 MachinePointerInfo &MPO,
259 ISD::ArgFlagsTy Flags) override {
260 MachineFunction &MF = MIRBuilder.getMF();
261 LLT p0 = LLT::pointer(0, 64);
262 LLT s64 = LLT::integer(64);
263
264 if (IsTailCall) {
265 assert(!Flags.isByVal() && "byval unhandled with tail calls");
266
267 Offset += FPDiff;
268 int FI = MF.getFrameInfo().CreateFixedObject(Size, Offset, true);
269 auto FIReg = MIRBuilder.buildFrameIndex(p0, FI);
271 return FIReg.getReg(0);
272 }
273
274 if (!SPReg)
275 SPReg = MIRBuilder.buildCopy(p0, Register(AArch64::SP)).getReg(0);
276
277 auto OffsetReg = MIRBuilder.buildConstant(s64, Offset);
278
279 auto AddrReg = MIRBuilder.buildPtrAdd(p0, SPReg, OffsetReg);
280
282 return AddrReg.getReg(0);
283 }
284
285 /// We need to fixup the reported store size for certain value types because
286 /// we invert the interpretation of ValVT and LocVT in certain cases. This is
287 /// for compatibility with the DAG call lowering implementation, which we're
288 /// currently building on top of.
289 LLT getStackValueStoreType(const DataLayout &DL, const CCValAssign &VA,
290 ISD::ArgFlagsTy Flags) const override {
291 if (Flags.isPointer())
294 }
295
296 void assignValueToReg(Register ValVReg, Register PhysReg,
297 const CCValAssign &VA, ISD::ArgFlagsTy Flags) override {
298 MIB.addUse(PhysReg, RegState::Implicit);
299 Register ExtReg = extendRegister(ValVReg, VA);
300 MIRBuilder.buildCopy(PhysReg, ExtReg);
301 }
302
303 /// Check whether a stack argument requires lowering in a tail call.
304 static bool shouldLowerTailCallStackArg(const MachineFunction &MF,
305 const CCValAssign &VA,
306 Register ValVReg,
307 Register StoreAddr) {
308 const MachineRegisterInfo &MRI = MF.getRegInfo();
309 // Print the defining instruction for the value.
310 auto *DefMI = MRI.getVRegDef(ValVReg);
311 assert(DefMI && "No defining instruction");
312 for (;;) {
313 // Look through nodes that don't alter the bits of the incoming value.
314 unsigned Op = DefMI->getOpcode();
315 if (Op == TargetOpcode::G_ZEXT || Op == TargetOpcode::G_ANYEXT ||
316 Op == TargetOpcode::G_BITCAST || isAssertMI(*DefMI)) {
318 continue;
319 }
320 break;
321 }
322
323 auto *Load = dyn_cast<GLoad>(DefMI);
324 if (!Load)
325 return true;
326 Register LoadReg = Load->getPointerReg();
327 auto *LoadAddrDef = MRI.getVRegDef(LoadReg);
328 if (LoadAddrDef->getOpcode() != TargetOpcode::G_FRAME_INDEX)
329 return true;
330 const MachineFrameInfo &MFI = MF.getFrameInfo();
331 int LoadFI = LoadAddrDef->getOperand(1).getIndex();
332
333 auto *StoreAddrDef = MRI.getVRegDef(StoreAddr);
334 if (StoreAddrDef->getOpcode() != TargetOpcode::G_FRAME_INDEX)
335 return true;
336 int StoreFI = StoreAddrDef->getOperand(1).getIndex();
337
338 if (!MFI.isImmutableObjectIndex(LoadFI))
339 return true;
340 if (MFI.getObjectOffset(LoadFI) != MFI.getObjectOffset(StoreFI))
341 return true;
342 if (Load->getMemSize() != MFI.getObjectSize(StoreFI))
343 return true;
344
345 return false;
346 }
347
348 void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy,
349 const MachinePointerInfo &MPO,
350 const CCValAssign &VA) override {
351 MachineFunction &MF = MIRBuilder.getMF();
352 if (!FPDiff && !shouldLowerTailCallStackArg(MF, VA, ValVReg, Addr))
353 return;
354 auto MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOStore, MemTy,
355 inferAlignFromPtrInfo(MF, MPO));
356 MIRBuilder.buildStore(ValVReg, Addr, *MMO);
357 }
358
359 void assignValueToAddress(const CallLowering::ArgInfo &Arg, unsigned RegIndex,
360 Register Addr, LLT MemTy,
361 const MachinePointerInfo &MPO,
362 const CCValAssign &VA) override {
363 unsigned MaxSize = MemTy.getSizeInBytes() * 8;
364 // For varargs, we always want to extend them to 8 bytes, in which case
365 // we disable setting a max.
366 if (Arg.Flags[0].isVarArg())
367 MaxSize = 0;
368
369 Register ValVReg = Arg.Regs[RegIndex];
370 if (VA.getLocInfo() != CCValAssign::LocInfo::FPExt) {
371 MVT LocVT = VA.getLocVT();
372 MVT ValVT = VA.getValVT();
373
374 if (VA.getValVT() == MVT::i8 || VA.getValVT() == MVT::i16) {
375 std::swap(ValVT, LocVT);
376 MemTy = LLT(VA.getValVT());
377 }
378
379 ValVReg = extendRegister(ValVReg, VA, MaxSize);
380 } else {
381 // The store does not cover the full allocated stack slot.
382 MemTy = LLT(VA.getValVT());
383 }
384
385 assignValueToAddress(ValVReg, Addr, MemTy, MPO, VA);
386 }
387
388 MachineInstrBuilder MIB;
389
390 bool IsTailCall;
391
392 /// For tail calls, the byte offset of the call's argument area from the
393 /// callee's. Unused elsewhere.
394 int FPDiff;
395
396 // Cache the SP register vreg if we need it more than once in this call site.
398
399 const AArch64Subtarget &Subtarget;
400};
401} // namespace
402
403static bool doesCalleeRestoreStack(CallingConv::ID CallConv, bool TailCallOpt) {
404 return (CallConv == CallingConv::Fast && TailCallOpt) ||
405 CallConv == CallingConv::Tail || CallConv == CallingConv::SwiftTail;
406}
407
409 const Value *Val,
410 ArrayRef<Register> VRegs,
412 Register SwiftErrorVReg) const {
413 auto MIB = MIRBuilder.buildInstrNoInsert(AArch64::RET_ReallyLR);
414 assert(((Val && !VRegs.empty()) || (!Val && VRegs.empty())) &&
415 "Return value without a vreg");
416
417 bool Success = true;
418 if (!FLI.CanLowerReturn) {
419 insertSRetStores(MIRBuilder, Val->getType(), VRegs, FLI.DemoteRegister);
420 } else if (!VRegs.empty()) {
421 MachineFunction &MF = MIRBuilder.getMF();
422 const Function &F = MF.getFunction();
423 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
424
427 CCAssignFn *AssignFn = TLI.CCAssignFnForReturn(F.getCallingConv());
428 auto &DL = F.getDataLayout();
429 LLVMContext &Ctx = Val->getType()->getContext();
430
431 SmallVector<EVT, 4> SplitEVTs;
432 ComputeValueVTs(TLI, DL, Val->getType(), SplitEVTs);
433 assert(VRegs.size() == SplitEVTs.size() &&
434 "For each split Type there should be exactly one VReg.");
435
436 SmallVector<ArgInfo, 8> SplitArgs;
437 CallingConv::ID CC = F.getCallingConv();
438
439 for (unsigned i = 0; i < SplitEVTs.size(); ++i) {
440 Register CurVReg = VRegs[i];
441 ArgInfo CurArgInfo = ArgInfo{CurVReg, SplitEVTs[i].getTypeForEVT(Ctx), 0};
442 setArgFlags(CurArgInfo, AttributeList::ReturnIndex, DL, F);
443
444 // i1 is a special case because SDAG i1 true is naturally zero extended
445 // when widened using ANYEXT. We need to do it explicitly here.
446 auto &Flags = CurArgInfo.Flags[0];
447 if (MRI.getType(CurVReg).getSizeInBits() == TypeSize::getFixed(1) &&
448 !Flags.isSExt() && !Flags.isZExt()) {
449 CurVReg = MIRBuilder.buildZExt(LLT::integer(8), CurVReg).getReg(0);
450 } else if (TLI.getNumRegistersForCallingConv(Ctx, CC, SplitEVTs[i]) ==
451 1) {
452 // Some types will need extending as specified by the CC.
453 MVT NewVT = TLI.getRegisterTypeForCallingConv(Ctx, CC, SplitEVTs[i]);
454 if (EVT(NewVT) != SplitEVTs[i]) {
455 unsigned ExtendOp = TargetOpcode::G_ANYEXT;
456 if (F.getAttributes().hasRetAttr(Attribute::SExt))
457 ExtendOp = TargetOpcode::G_SEXT;
458 else if (F.getAttributes().hasRetAttr(Attribute::ZExt))
459 ExtendOp = TargetOpcode::G_ZEXT;
460
461 LLT NewLLT(NewVT);
462 LLT OldLLT = getLLTForType(*CurArgInfo.Ty, DL);
463 CurArgInfo.Ty = EVT(NewVT).getTypeForEVT(Ctx);
464 // Instead of an extend, we might have a vector type which needs
465 // padding with more elements, e.g. <2 x half> -> <4 x half>.
466 if (NewVT.isVector()) {
467 if (OldLLT.isVector()) {
468 if (NewLLT.getNumElements() > OldLLT.getNumElements()) {
469 CurVReg =
470 MIRBuilder.buildPadVectorWithUndefElements(NewLLT, CurVReg)
471 .getReg(0);
472 } else {
473 // Just do a vector extend.
474 CurVReg = MIRBuilder.buildInstr(ExtendOp, {NewLLT}, {CurVReg})
475 .getReg(0);
476 }
477 } else if (NewLLT.getNumElements() >= 2 &&
478 NewLLT.getNumElements() <= 8) {
479 // We need to pad a <1 x S> type to <2/4/8 x S>. Since we don't
480 // have <1 x S> vector types in GISel we use a build_vector
481 // instead of a vector merge/concat.
482 CurVReg =
483 MIRBuilder.buildPadVectorWithUndefElements(NewLLT, CurVReg)
484 .getReg(0);
485 } else {
486 LLVM_DEBUG(dbgs() << "Could not handle ret ty\n");
487 return false;
488 }
489 } else {
490 // If the split EVT was a <1 x T> vector, and NewVT is T, then we
491 // don't have to do anything since we don't distinguish between the
492 // two.
493 if (NewLLT.getScalarSizeInBits() !=
494 MRI.getType(CurVReg).getScalarSizeInBits()) {
495 // A scalar extend.
496 CurVReg = MIRBuilder.buildInstr(ExtendOp, {NewLLT}, {CurVReg})
497 .getReg(0);
498 }
499 }
500 }
501 }
502 if (CurVReg != CurArgInfo.Regs[0]) {
503 CurArgInfo.Regs[0] = CurVReg;
504 // Reset the arg flags after modifying CurVReg.
505 setArgFlags(CurArgInfo, AttributeList::ReturnIndex, DL, F);
506 }
507 splitToValueTypes(CurArgInfo, SplitArgs, DL, CC);
508 }
509
510 AArch64OutgoingValueAssigner Assigner(AssignFn, AssignFn, Subtarget,
511 /*IsReturn*/ true);
512 OutgoingArgHandler Handler(MIRBuilder, MRI, MIB);
513 Success = determineAndHandleAssignments(Handler, Assigner, SplitArgs,
514 MIRBuilder, CC, F.isVarArg());
515 }
516
517 if (SwiftErrorVReg) {
518 MIB.addUse(AArch64::X21, RegState::Implicit);
519 MIRBuilder.buildCopy(AArch64::X21, SwiftErrorVReg);
520 }
521
522 MIRBuilder.insertInstr(MIB);
523 return Success;
524}
525
527 CallingConv::ID CallConv,
529 bool IsVarArg) const {
531 const auto &TLI = *getTLI<AArch64TargetLowering>();
532 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs,
533 MF.getFunction().getContext());
534
535 return checkReturn(CCInfo, Outs, TLI.CCAssignFnForReturn(CallConv));
536}
537
538/// Helper function to compute forwarded registers for musttail calls. Computes
539/// the forwarded registers, sets MBB liveness, and emits COPY instructions that
540/// can be used to save + restore registers later.
542 CCAssignFn *AssignFn) {
543 MachineBasicBlock &MBB = MIRBuilder.getMBB();
544 MachineFunction &MF = MIRBuilder.getMF();
545 MachineFrameInfo &MFI = MF.getFrameInfo();
546
547 if (!MFI.hasMustTailInVarArgFunc())
548 return;
549
551 const Function &F = MF.getFunction();
552 assert(F.isVarArg() && "Expected F to be vararg?");
553
554 // Compute the set of forwarded registers. The rest are scratch.
556 CCState CCInfo(F.getCallingConv(), /*IsVarArg=*/true, MF, ArgLocs,
557 F.getContext());
558 SmallVector<MVT, 2> RegParmTypes;
559 RegParmTypes.push_back(MVT::i64);
560 RegParmTypes.push_back(MVT::f128);
561
562 // Later on, we can use this vector to restore the registers if necessary.
565 CCInfo.analyzeMustTailForwardedRegisters(Forwards, RegParmTypes, AssignFn);
566
567 // Conservatively forward X8, since it might be used for an aggregate
568 // return.
569 if (!CCInfo.isAllocated(AArch64::X8)) {
570 Register X8VReg = MF.addLiveIn(AArch64::X8, &AArch64::GPR64RegClass);
571 Forwards.push_back(ForwardedRegister(X8VReg, AArch64::X8, MVT::i64));
572 }
573
574 // Add the forwards to the MachineBasicBlock and MachineFunction.
575 for (const auto &F : Forwards) {
576 MBB.addLiveIn(F.PReg);
577 MIRBuilder.buildCopy(Register(F.VReg), Register(F.PReg));
578 }
579}
580
582 auto &F = MF.getFunction();
583 const auto &TM = static_cast<const AArch64TargetMachine &>(MF.getTarget());
584
585 const bool GlobalISelFlag =
587
588 auto OptLevel = MF.getTarget().getOptLevel();
589 auto EnableGlobalISelAtO = TM.getEnableGlobalISelAtO();
590
591 // GlobalISel is currently only enabled when the opt level is less than or
592 // equal to EnableGlobalISelAt or it was explicitly enabled via the CLI. If we
593 // encounter this check, we know GlobalISel was enabled. If not by these two,
594 // it must have been used as part of the SDAG pipeline to use GlobalISel for
595 // optnone.
596 if (static_cast<unsigned>(OptLevel) > EnableGlobalISelAtO && !GlobalISelFlag)
597 return !F.hasOptNone();
598
599 if (!EnableSVEGISel && (F.getReturnType()->isScalableTy() ||
600 llvm::any_of(F.args(), [](const Argument &A) {
601 return A.getType()->isScalableTy();
602 })))
603 return true;
604 const auto &ST = MF.getSubtarget<AArch64Subtarget>();
605 if (!ST.hasNEON() || !ST.hasFPARMv8()) {
606 LLVM_DEBUG(dbgs() << "Falling back to SDAG because we don't support no-NEON\n");
607 return true;
608 }
609
610 SMEAttrs Attrs = MF.getInfo<AArch64FunctionInfo>()->getSMEFnAttrs();
611 if (Attrs.hasZAState() || Attrs.hasZT0State() ||
612 Attrs.hasStreamingInterfaceOrBody() ||
613 Attrs.hasStreamingCompatibleInterface())
614 return true;
615
616 return false;
617}
618
619void AArch64CallLowering::saveVarArgRegisters(
621 CCState &CCInfo) const {
624
625 MachineFunction &MF = MIRBuilder.getMF();
627 MachineFrameInfo &MFI = MF.getFrameInfo();
629 auto &Subtarget = MF.getSubtarget<AArch64Subtarget>();
630 bool IsWin64CC = Subtarget.isCallingConvWin64(CCInfo.getCallingConv(),
631 MF.getFunction().isVarArg());
632 const LLT p0 = LLT::pointer(0, 64);
633 const LLT s64 = LLT::integer(64);
634
635 unsigned FirstVariadicGPR = CCInfo.getFirstUnallocated(GPRArgRegs);
636 unsigned NumVariadicGPRArgRegs = GPRArgRegs.size() - FirstVariadicGPR + 1;
637
638 unsigned GPRSaveSize = 8 * (GPRArgRegs.size() - FirstVariadicGPR);
639 int GPRIdx = 0;
640 if (GPRSaveSize != 0) {
641 if (IsWin64CC) {
642 GPRIdx = MFI.CreateFixedObject(GPRSaveSize,
643 -static_cast<int>(GPRSaveSize), false);
644 if (GPRSaveSize & 15)
645 // The extra size here, if triggered, will always be 8.
646 MFI.CreateFixedObject(16 - (GPRSaveSize & 15),
647 -static_cast<int>(alignTo(GPRSaveSize, 16)),
648 false);
649 } else
650 GPRIdx = MFI.CreateStackObject(GPRSaveSize, Align(8), false);
651
652 auto FIN = MIRBuilder.buildFrameIndex(p0, GPRIdx);
653 auto Offset =
654 MIRBuilder.buildConstant(MRI.createGenericVirtualRegister(s64), 8);
655
656 for (unsigned i = FirstVariadicGPR; i < GPRArgRegs.size(); ++i) {
658 Handler.assignValueToReg(
659 Val, GPRArgRegs[i],
661 GPRArgRegs[i], MVT::i64, CCValAssign::Full));
662 auto MPO = IsWin64CC ? MachinePointerInfo::getFixedStack(
663 MF, GPRIdx, (i - FirstVariadicGPR) * 8)
664 : MachinePointerInfo::getStack(MF, i * 8);
665 MIRBuilder.buildStore(Val, FIN, MPO, inferAlignFromPtrInfo(MF, MPO));
666
667 FIN = MIRBuilder.buildPtrAdd(MRI.createGenericVirtualRegister(p0),
668 FIN.getReg(0), Offset);
669 }
670 }
671 FuncInfo->setVarArgsGPRIndex(GPRIdx);
672 FuncInfo->setVarArgsGPRSize(GPRSaveSize);
673
674 if (Subtarget.hasFPARMv8() && !IsWin64CC) {
675 unsigned FirstVariadicFPR = CCInfo.getFirstUnallocated(FPRArgRegs);
676
677 unsigned FPRSaveSize = 16 * (FPRArgRegs.size() - FirstVariadicFPR);
678 int FPRIdx = 0;
679 if (FPRSaveSize != 0) {
680 FPRIdx = MFI.CreateStackObject(FPRSaveSize, Align(16), false);
681
682 auto FIN = MIRBuilder.buildFrameIndex(p0, FPRIdx);
683 auto Offset =
684 MIRBuilder.buildConstant(MRI.createGenericVirtualRegister(s64), 16);
685
686 for (unsigned i = FirstVariadicFPR; i < FPRArgRegs.size(); ++i) {
688 Handler.assignValueToReg(
689 Val, FPRArgRegs[i],
691 i + MF.getFunction().getNumOperands() + NumVariadicGPRArgRegs,
692 MVT::f128, FPRArgRegs[i], MVT::f128, CCValAssign::Full));
693
694 auto MPO = MachinePointerInfo::getStack(MF, i * 16);
695 MIRBuilder.buildStore(Val, FIN, MPO, inferAlignFromPtrInfo(MF, MPO));
696
697 FIN = MIRBuilder.buildPtrAdd(MRI.createGenericVirtualRegister(p0),
698 FIN.getReg(0), Offset);
699 }
700 }
701 FuncInfo->setVarArgsFPRIndex(FPRIdx);
702 FuncInfo->setVarArgsFPRSize(FPRSaveSize);
703 }
704}
705
707 MachineIRBuilder &MIRBuilder, const Function &F,
709 MachineFunction &MF = MIRBuilder.getMF();
710 MachineBasicBlock &MBB = MIRBuilder.getMBB();
712 auto &DL = F.getDataLayout();
713 auto &Subtarget = MF.getSubtarget<AArch64Subtarget>();
714
715 // Arm64EC has extra requirements for varargs calls which are only implemented
716 // in SelectionDAG; bail out for now.
717 if (F.isVarArg() && Subtarget.isWindowsArm64EC())
718 return false;
719
720 // Arm64EC thunks have a special calling convention which is only implemented
721 // in SelectionDAG; bail out for now.
722 if (F.getCallingConv() == CallingConv::ARM64EC_Thunk_Native ||
723 F.getCallingConv() == CallingConv::ARM64EC_Thunk_X64)
724 return false;
725
726 bool IsWin64 =
727 Subtarget.isCallingConvWin64(F.getCallingConv(), F.isVarArg()) &&
728 !Subtarget.isWindowsArm64EC();
729
730 SmallVector<ArgInfo, 8> SplitArgs;
732
733 // Insert the hidden sret parameter if the return value won't fit in the
734 // return registers.
735 if (!FLI.CanLowerReturn)
736 insertSRetIncomingArgument(F, SplitArgs, FLI.DemoteRegister, MRI, DL);
737
738 unsigned i = 0;
739 for (auto &Arg : F.args()) {
740 if (DL.getTypeStoreSize(Arg.getType()).isZero())
741 continue;
742
743 ArgInfo OrigArg{VRegs[i], Arg, i};
744 setArgFlags(OrigArg, i + AttributeList::FirstArgIndex, DL, F);
745
746 // i1 arguments are zero-extended to i8 by the caller. Emit a
747 // hint to reflect this.
748 if (OrigArg.Ty->isIntegerTy(1)) {
749 assert(OrigArg.Regs.size() == 1 &&
750 MRI.getType(OrigArg.Regs[0]).getSizeInBits() == 1 &&
751 "Unexpected registers used for i1 arg");
752
753 auto &Flags = OrigArg.Flags[0];
754 if (!Flags.isZExt() && !Flags.isSExt()) {
755 // Lower i1 argument as i8, and insert AssertZExt + Trunc later.
756 Register OrigReg = OrigArg.Regs[0];
758 OrigArg.Regs[0] = WideReg;
759 BoolArgs.push_back({OrigReg, WideReg});
760 }
761 }
762
763 if (Arg.hasAttribute(Attribute::SwiftAsync))
764 MF.getInfo<AArch64FunctionInfo>()->setHasSwiftAsyncContext(true);
765
766 splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv());
767 ++i;
768 }
769
770 if (!MBB.empty())
771 MIRBuilder.setInstr(*MBB.begin());
772
774 CCAssignFn *AssignFn = TLI.CCAssignFnForCall(F.getCallingConv(), IsWin64 && F.isVarArg());
775
776 AArch64IncomingValueAssigner Assigner(AssignFn, AssignFn);
777 FormalArgHandler Handler(MIRBuilder, MRI);
779 CCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, F.getContext());
780 if (!determineAssignments(Assigner, SplitArgs, CCInfo) ||
781 !handleAssignments(Handler, SplitArgs, CCInfo, ArgLocs, MIRBuilder))
782 return false;
783
784 if (!BoolArgs.empty()) {
785 for (auto &KV : BoolArgs) {
786 Register OrigReg = KV.first;
787 Register WideReg = KV.second;
788 LLT WideTy = MRI.getType(WideReg);
789 assert(MRI.getType(OrigReg).getScalarSizeInBits() == 1 &&
790 "Unexpected bit size of a bool arg");
791 MIRBuilder.buildTrunc(
792 OrigReg, MIRBuilder.buildAssertZExt(WideTy, WideReg, 1).getReg(0));
793 }
794 }
795
797 uint64_t StackSize = Assigner.StackSize;
798 if (F.isVarArg()) {
799 if ((!Subtarget.isTargetDarwin() && !Subtarget.isWindowsArm64EC()) || IsWin64) {
800 // The AAPCS variadic function ABI is identical to the non-variadic
801 // one. As a result there may be more arguments in registers and we should
802 // save them for future reference.
803 // Win64 variadic functions also pass arguments in registers, but all
804 // float arguments are passed in integer registers.
805 saveVarArgRegisters(MIRBuilder, Handler, CCInfo);
806 } else if (Subtarget.isWindowsArm64EC()) {
807 return false;
808 }
809
810 // We currently pass all varargs at 8-byte alignment, or 4 in ILP32.
811 StackSize = alignTo(Assigner.StackSize, Subtarget.isTargetILP32() ? 4 : 8);
812
813 auto &MFI = MIRBuilder.getMF().getFrameInfo();
814 FuncInfo->setVarArgsStackIndex(MFI.CreateFixedObject(4, StackSize, true));
815 }
816
817 if (doesCalleeRestoreStack(F.getCallingConv(),
819 // We have a non-standard ABI, so why not make full use of the stack that
820 // we're going to pop? It must be aligned to 16 B in any case.
821 StackSize = alignTo(StackSize, 16);
822
823 // If we're expected to restore the stack (e.g. fastcc), then we'll be
824 // adding a multiple of 16.
825 FuncInfo->setArgumentStackToRestore(StackSize);
826
827 // Our own callers will guarantee that the space is free by giving an
828 // aligned value to CALLSEQ_START.
829 }
830
831 // When we tail call, we need to check if the callee's arguments
832 // will fit on the caller's stack. So, whenever we lower formal arguments,
833 // we should keep track of this information, since we might lower a tail call
834 // in this function later.
835 FuncInfo->setBytesInStackArgArea(StackSize);
836
837 if (Subtarget.hasCustomCallingConv())
838 Subtarget.getRegisterInfo()->UpdateCustomCalleeSavedRegs(MF);
839
840 handleMustTailForwardedRegisters(MIRBuilder, AssignFn);
841
842 // Move back to the end of the basic block.
843 MIRBuilder.setMBB(MBB);
844
845 return true;
846}
847
848/// Return true if the calling convention is one that we can guarantee TCO for.
849static bool canGuaranteeTCO(CallingConv::ID CC, bool GuaranteeTailCalls) {
850 return (CC == CallingConv::Fast && GuaranteeTailCalls) ||
852}
853
854/// Return true if we might ever do TCO for calls with this calling convention.
856 switch (CC) {
857 case CallingConv::C:
865 return true;
866 default:
867 return false;
868 }
869}
870
871/// Returns a pair containing the fixed CCAssignFn and the vararg CCAssignFn for
872/// CC.
873static std::pair<CCAssignFn *, CCAssignFn *>
875 return {TLI.CCAssignFnForCall(CC, false), TLI.CCAssignFnForCall(CC, true)};
876}
877
878bool AArch64CallLowering::doCallerAndCalleePassArgsTheSameWay(
879 CallLoweringInfo &Info, MachineFunction &MF,
880 SmallVectorImpl<ArgInfo> &InArgs) const {
881 const Function &CallerF = MF.getFunction();
882 CallingConv::ID CalleeCC = Info.CallConv;
883 CallingConv::ID CallerCC = CallerF.getCallingConv();
884
885 // If the calling conventions match, then everything must be the same.
886 if (CalleeCC == CallerCC)
887 return true;
888
889 // Check if the caller and callee will handle arguments in the same way.
890 const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
891 CCAssignFn *CalleeAssignFnFixed;
892 CCAssignFn *CalleeAssignFnVarArg;
893 std::tie(CalleeAssignFnFixed, CalleeAssignFnVarArg) =
894 getAssignFnsForCC(CalleeCC, TLI);
895
896 CCAssignFn *CallerAssignFnFixed;
897 CCAssignFn *CallerAssignFnVarArg;
898 std::tie(CallerAssignFnFixed, CallerAssignFnVarArg) =
899 getAssignFnsForCC(CallerCC, TLI);
900
901 AArch64IncomingValueAssigner CalleeAssigner(CalleeAssignFnFixed,
902 CalleeAssignFnVarArg);
903 AArch64IncomingValueAssigner CallerAssigner(CallerAssignFnFixed,
904 CallerAssignFnVarArg);
905
906 if (!resultsCompatible(Info, MF, InArgs, CalleeAssigner, CallerAssigner))
907 return false;
908
909 // Make sure that the caller and callee preserve all of the same registers.
910 auto TRI = MF.getSubtarget<AArch64Subtarget>().getRegisterInfo();
911 const uint32_t *CallerPreserved = TRI->getCallPreservedMask(MF, CallerCC);
912 const uint32_t *CalleePreserved = TRI->getCallPreservedMask(MF, CalleeCC);
913 if (MF.getSubtarget<AArch64Subtarget>().hasCustomCallingConv()) {
914 TRI->UpdateCustomCallPreservedMask(MF, &CallerPreserved);
915 TRI->UpdateCustomCallPreservedMask(MF, &CalleePreserved);
916 }
917
918 return TRI->regmaskSubsetEqual(CallerPreserved, CalleePreserved);
919}
920
921bool AArch64CallLowering::areCalleeOutgoingArgsTailCallable(
922 CallLoweringInfo &Info, MachineFunction &MF,
923 SmallVectorImpl<ArgInfo> &OrigOutArgs) const {
924 // If there are no outgoing arguments, then we are done.
925 if (OrigOutArgs.empty())
926 return true;
927
928 const Function &CallerF = MF.getFunction();
929 LLVMContext &Ctx = CallerF.getContext();
930 CallingConv::ID CalleeCC = Info.CallConv;
931 CallingConv::ID CallerCC = CallerF.getCallingConv();
932 const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
933 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
934
935 CCAssignFn *AssignFnFixed;
936 CCAssignFn *AssignFnVarArg;
937 std::tie(AssignFnFixed, AssignFnVarArg) = getAssignFnsForCC(CalleeCC, TLI);
938
939 // We have outgoing arguments. Make sure that we can tail call with them.
941 CCState OutInfo(CalleeCC, false, MF, OutLocs, Ctx);
942
943 AArch64OutgoingValueAssigner CalleeAssigner(AssignFnFixed, AssignFnVarArg,
944 Subtarget, /*IsReturn*/ false);
945 // determineAssignments() may modify argument flags, so make a copy.
947 append_range(OutArgs, OrigOutArgs);
948 if (!determineAssignments(CalleeAssigner, OutArgs, OutInfo)) {
949 LLVM_DEBUG(dbgs() << "... Could not analyze call operands.\n");
950 return false;
951 }
952
953 // Make sure that they can fit on the caller's stack.
954 const AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>();
955 if (OutInfo.getStackSize() > FuncInfo->getBytesInStackArgArea()) {
956 LLVM_DEBUG(dbgs() << "... Cannot fit call operands on caller's stack.\n");
957 return false;
958 }
959
960 // Verify that the parameters in callee-saved registers match.
961 // TODO: Port this over to CallLowering as general code once swiftself is
962 // supported.
963 auto TRI = MF.getSubtarget<AArch64Subtarget>().getRegisterInfo();
964 const uint32_t *CallerPreservedMask = TRI->getCallPreservedMask(MF, CallerCC);
965 MachineRegisterInfo &MRI = MF.getRegInfo();
966
967 if (Info.IsVarArg) {
968 // Be conservative and disallow variadic memory operands to match SDAG's
969 // behaviour.
970 // FIXME: If the caller's calling convention is C, then we can
971 // potentially use its argument area. However, for cases like fastcc,
972 // we can't do anything.
973 for (unsigned i = 0; i < OutLocs.size(); ++i) {
974 auto &ArgLoc = OutLocs[i];
975 if (ArgLoc.isRegLoc())
976 continue;
977
979 dbgs()
980 << "... Cannot tail call vararg function with stack arguments\n");
981 return false;
982 }
983 }
984
985 return parametersInCSRMatch(MRI, CallerPreservedMask, OutLocs, OutArgs);
986}
987
989 MachineIRBuilder &MIRBuilder, CallLoweringInfo &Info,
991 SmallVectorImpl<ArgInfo> &OutArgs) const {
992
993 // Must pass all target-independent checks in order to tail call optimize.
994 if (!Info.IsTailCall)
995 return false;
996
997 CallingConv::ID CalleeCC = Info.CallConv;
998 MachineFunction &MF = MIRBuilder.getMF();
999 const Function &CallerF = MF.getFunction();
1000
1001 LLVM_DEBUG(dbgs() << "Attempting to lower call as tail call\n");
1002
1003 if (Info.SwiftErrorVReg) {
1004 // TODO: We should handle this.
1005 // Note that this is also handled by the check for no outgoing arguments.
1006 // Proactively disabling this though, because the swifterror handling in
1007 // lowerCall inserts a COPY *after* the location of the call.
1008 LLVM_DEBUG(dbgs() << "... Cannot handle tail calls with swifterror yet.\n");
1009 return false;
1010 }
1011
1012 if (!mayTailCallThisCC(CalleeCC)) {
1013 LLVM_DEBUG(dbgs() << "... Calling convention cannot be tail called.\n");
1014 return false;
1015 }
1016
1017 // Byval parameters hand the function a pointer directly into the stack area
1018 // we want to reuse during a tail call. Working around this *is* possible (see
1019 // X86).
1020 //
1021 // FIXME: In AArch64ISelLowering, this isn't worked around. Can/should we try
1022 // it?
1023 //
1024 // On Windows, "inreg" attributes signify non-aggregate indirect returns.
1025 // In this case, it is necessary to save/restore X0 in the callee. Tail
1026 // call opt interferes with this. So we disable tail call opt when the
1027 // caller has an argument with "inreg" attribute.
1028 //
1029 // FIXME: Check whether the callee also has an "inreg" argument.
1030 //
1031 // When the caller has a swifterror argument, we don't want to tail call
1032 // because would have to move into the swifterror register before the
1033 // tail call.
1034 if (any_of(CallerF.args(), [](const Argument &A) {
1035 return A.hasByValAttr() || A.hasInRegAttr() || A.hasSwiftErrorAttr();
1036 })) {
1037 LLVM_DEBUG(dbgs() << "... Cannot tail call from callers with byval, "
1038 "inreg, or swifterror arguments\n");
1039 return false;
1040 }
1041
1042 // Externally-defined functions with weak linkage should not be
1043 // tail-called on AArch64 when the OS does not support dynamic
1044 // pre-emption of symbols, as the AAELF spec requires normal calls
1045 // to undefined weak functions to be replaced with a NOP or jump to the
1046 // next instruction. The behaviour of branch instructions in this
1047 // situation (as used for tail calls) is implementation-defined, so we
1048 // cannot rely on the linker replacing the tail call with a return.
1049 if (Info.Callee.isGlobal()) {
1050 const GlobalValue *GV = Info.Callee.getGlobal();
1051 const Triple &TT = MF.getTarget().getTargetTriple();
1052 if (GV->hasExternalWeakLinkage() &&
1053 (!TT.isOSWindows() || TT.isOSBinFormatELF() ||
1054 TT.isOSBinFormatMachO())) {
1055 LLVM_DEBUG(dbgs() << "... Cannot tail call externally-defined function "
1056 "with weak linkage for this OS.\n");
1057 return false;
1058 }
1059 }
1060
1061 // If we have -tailcallopt, then we're done.
1063 return CalleeCC == CallerF.getCallingConv();
1064
1065 // We don't have -tailcallopt, so we're allowed to change the ABI (sibcall).
1066 // Try to find cases where we can do that.
1067
1068 // I want anyone implementing a new calling convention to think long and hard
1069 // about this assert.
1070 assert((!Info.IsVarArg || CalleeCC == CallingConv::C) &&
1071 "Unexpected variadic calling convention");
1072
1073 // Verify that the incoming and outgoing arguments from the callee are
1074 // safe to tail call.
1075 if (!doCallerAndCalleePassArgsTheSameWay(Info, MF, InArgs)) {
1076 LLVM_DEBUG(
1077 dbgs()
1078 << "... Caller and callee have incompatible calling conventions.\n");
1079 return false;
1080 }
1081
1082 if (!areCalleeOutgoingArgsTailCallable(Info, MF, OutArgs))
1083 return false;
1084
1085 LLVM_DEBUG(
1086 dbgs() << "... Call is eligible for tail call optimization.\n");
1087 return true;
1088}
1089
1090static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect,
1091 bool IsTailCall,
1092 std::optional<CallLowering::PtrAuthInfo> &PAI,
1093 MachineRegisterInfo &MRI) {
1094 const AArch64FunctionInfo *FuncInfo = CallerF.getInfo<AArch64FunctionInfo>();
1095
1096 if (!IsTailCall) {
1097 if (!PAI)
1098 return IsIndirect ? getBLRCallOpcode(CallerF) : (unsigned)AArch64::BL;
1099
1100 assert(IsIndirect && "Direct call should not be authenticated");
1101 assert((PAI->Key == AArch64PACKey::IA || PAI->Key == AArch64PACKey::IB) &&
1102 "Invalid auth call key");
1103 return AArch64::BLRA;
1104 }
1105
1106 if (!IsIndirect)
1107 return AArch64::TCRETURNdi;
1108
1109 // When BTI or PAuthLR are enabled, there are restrictions on using x16 and
1110 // x17 to hold the function pointer.
1111 if (FuncInfo->branchTargetEnforcement()) {
1112 if (FuncInfo->branchProtectionPAuthLR()) {
1113 assert(!PAI && "ptrauth tail-calls not yet supported with PAuthLR");
1114 return AArch64::TCRETURNrix17;
1115 }
1116 if (PAI)
1117 return AArch64::AUTH_TCRETURN_BTI;
1118 return AArch64::TCRETURNrix16x17;
1119 }
1120
1121 if (FuncInfo->branchProtectionPAuthLR()) {
1122 assert(!PAI && "ptrauth tail-calls not yet supported with PAuthLR");
1123 return AArch64::TCRETURNrinotx16;
1124 }
1125
1126 if (PAI)
1127 return AArch64::AUTH_TCRETURN;
1128 return AArch64::TCRETURNri;
1129}
1130
1131static const uint32_t *
1135 const uint32_t *Mask;
1136 if (!OutArgs.empty() && OutArgs[0].Flags[0].isReturned()) {
1137 // For 'this' returns, use the X0-preserving mask if applicable
1138 Mask = TRI.getThisReturnPreservedMask(MF, Info.CallConv);
1139 if (!Mask) {
1140 OutArgs[0].Flags[0].setReturned(false);
1141 Mask = TRI.getCallPreservedMask(MF, Info.CallConv);
1142 }
1143 } else {
1144 Mask = TRI.getCallPreservedMask(MF, Info.CallConv);
1145 }
1146 return Mask;
1147}
1148
1149bool AArch64CallLowering::lowerTailCall(
1150 MachineIRBuilder &MIRBuilder, CallLoweringInfo &Info,
1151 SmallVectorImpl<ArgInfo> &OutArgs) const {
1152 MachineFunction &MF = MIRBuilder.getMF();
1153 const Function &F = MF.getFunction();
1154 MachineRegisterInfo &MRI = MF.getRegInfo();
1155 const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
1156 AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>();
1157
1158 // True when we're tail calling, but without -tailcallopt.
1159 bool IsSibCall = !MF.getTarget().Options.GuaranteedTailCallOpt &&
1160 Info.CallConv != CallingConv::Tail &&
1161 Info.CallConv != CallingConv::SwiftTail;
1162
1163 // Find out which ABI gets to decide where things go.
1164 CallingConv::ID CalleeCC = Info.CallConv;
1165 CCAssignFn *AssignFnFixed;
1166 CCAssignFn *AssignFnVarArg;
1167 std::tie(AssignFnFixed, AssignFnVarArg) = getAssignFnsForCC(CalleeCC, TLI);
1168
1169 MachineInstrBuilder CallSeqStart;
1170 if (!IsSibCall)
1171 CallSeqStart = MIRBuilder.buildInstr(AArch64::ADJCALLSTACKDOWN);
1172
1173 unsigned Opc = getCallOpcode(MF, Info.Callee.isReg(), true, Info.PAI, MRI);
1174 auto MIB = MIRBuilder.buildInstrNoInsert(Opc);
1175 MIB.add(Info.Callee);
1176
1177 // Tell the call which registers are clobbered.
1178 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
1179 auto TRI = Subtarget.getRegisterInfo();
1180
1181 // Byte offset for the tail call. When we are sibcalling, this will always
1182 // be 0.
1183 MIB.addImm(0);
1184
1185 // Authenticated tail calls always take key/discriminator arguments.
1186 if (Opc == AArch64::AUTH_TCRETURN || Opc == AArch64::AUTH_TCRETURN_BTI) {
1187 assert((Info.PAI->Key == AArch64PACKey::IA ||
1188 Info.PAI->Key == AArch64PACKey::IB) &&
1189 "Invalid auth call key");
1190 MIB.addImm(Info.PAI->Key);
1191
1192 Register AddrDisc = 0;
1193 uint16_t IntDisc = 0;
1194 std::tie(IntDisc, AddrDisc) =
1195 extractPtrauthBlendDiscriminators(Info.PAI->Discriminator, MRI);
1196
1197 MIB.addImm(IntDisc);
1198 MIB.addUse(AddrDisc);
1199 if (AddrDisc != AArch64::NoRegister) {
1200 MIB->getOperand(4).setReg(constrainOperandRegClass(
1201 MF, *TRI, MRI, *MF.getSubtarget().getInstrInfo(),
1202 *MF.getSubtarget().getRegBankInfo(), *MIB, MIB->getDesc(),
1203 MIB->getOperand(4), 4));
1204 }
1205 }
1206
1207 // Tell the call which registers are clobbered.
1208 const uint32_t *Mask = TRI->getCallPreservedMask(MF, CalleeCC);
1209 if (Subtarget.hasCustomCallingConv())
1210 TRI->UpdateCustomCallPreservedMask(MF, &Mask);
1211 MIB.addRegMask(Mask);
1212
1213 if (Info.CFIType)
1214 MIB->setCFIType(MF, Info.CFIType->getZExtValue());
1215
1216 if (TRI->isAnyArgRegReserved(MF))
1217 TRI->emitReservedArgRegCallError(MF);
1218
1219 // FPDiff is the byte offset of the call's argument area from the callee's.
1220 // Stores to callee stack arguments will be placed in FixedStackSlots offset
1221 // by this amount for a tail call. In a sibling call it must be 0 because the
1222 // caller will deallocate the entire stack and the callee still expects its
1223 // arguments to begin at SP+0.
1224 int FPDiff = 0;
1225
1226 // This will be 0 for sibcalls, potentially nonzero for tail calls produced
1227 // by -tailcallopt. For sibcalls, the memory operands for the call are
1228 // already available in the caller's incoming argument space.
1229 unsigned NumBytes = 0;
1230 if (!IsSibCall) {
1231 // We aren't sibcalling, so we need to compute FPDiff. We need to do this
1232 // before handling assignments, because FPDiff must be known for memory
1233 // arguments.
1234 unsigned NumReusableBytes = FuncInfo->getBytesInStackArgArea();
1236 CCState OutInfo(CalleeCC, false, MF, OutLocs, F.getContext());
1237
1238 AArch64OutgoingValueAssigner CalleeAssigner(AssignFnFixed, AssignFnVarArg,
1239 Subtarget, /*IsReturn*/ false);
1240 if (!determineAssignments(CalleeAssigner, OutArgs, OutInfo))
1241 return false;
1242
1243 // The callee will pop the argument stack as a tail call. Thus, we must
1244 // keep it 16-byte aligned.
1245 NumBytes = alignTo(OutInfo.getStackSize(), 16);
1246
1247 // FPDiff will be negative if this tail call requires more space than we
1248 // would automatically have in our incoming argument space. Positive if we
1249 // actually shrink the stack.
1250 FPDiff = NumReusableBytes - NumBytes;
1251
1252 // Update the required reserved area if this is the tail call requiring the
1253 // most argument stack space.
1254 if (FPDiff < 0 && FuncInfo->getTailCallReservedStack() < (unsigned)-FPDiff)
1255 FuncInfo->setTailCallReservedStack(-FPDiff);
1256
1257 // The stack pointer must be 16-byte aligned at all times it's used for a
1258 // memory operation, which in practice means at *all* times and in
1259 // particular across call boundaries. Therefore our own arguments started at
1260 // a 16-byte aligned SP and the delta applied for the tail call should
1261 // satisfy the same constraint.
1262 assert(FPDiff % 16 == 0 && "unaligned stack on tail call");
1263 }
1264
1265 const auto &Forwards = FuncInfo->getForwardedMustTailRegParms();
1266
1267 AArch64OutgoingValueAssigner Assigner(AssignFnFixed, AssignFnVarArg,
1268 Subtarget, /*IsReturn*/ false);
1269
1270 // Do the actual argument marshalling.
1271 OutgoingArgHandler Handler(MIRBuilder, MRI, MIB,
1272 /*IsTailCall*/ true, FPDiff);
1273 if (!determineAndHandleAssignments(Handler, Assigner, OutArgs, MIRBuilder,
1274 CalleeCC, Info.IsVarArg))
1275 return false;
1276
1277 Mask = getMaskForArgs(OutArgs, Info, *TRI, MF);
1278
1279 if (Info.IsVarArg && Info.IsMustTailCall) {
1280 // Now we know what's being passed to the function. Add uses to the call for
1281 // the forwarded registers that we *aren't* passing as parameters. This will
1282 // preserve the copies we build earlier.
1283 for (const auto &F : Forwards) {
1284 Register ForwardedReg = F.PReg;
1285 // If the register is already passed, or aliases a register which is
1286 // already being passed, then skip it.
1287 if (any_of(MIB->uses(), [&ForwardedReg, &TRI](const MachineOperand &Use) {
1288 if (!Use.isReg())
1289 return false;
1290 return TRI->regsOverlap(Use.getReg(), ForwardedReg);
1291 }))
1292 continue;
1293
1294 // We aren't passing it already, so we should add it to the call.
1295 MIRBuilder.buildCopy(ForwardedReg, Register(F.VReg));
1296 MIB.addReg(ForwardedReg, RegState::Implicit);
1297 }
1298 }
1299
1300 // If we have -tailcallopt, we need to adjust the stack. We'll do the call
1301 // sequence start and end here.
1302 if (!IsSibCall) {
1303 MIB->getOperand(1).setImm(FPDiff);
1304 CallSeqStart.addImm(0).addImm(0);
1305 // End the call sequence *before* emitting the call. Normally, we would
1306 // tidy the frame up after the call. However, here, we've laid out the
1307 // parameters so that when SP is reset, they will be in the correct
1308 // location.
1309 MIRBuilder.buildInstr(AArch64::ADJCALLSTACKUP).addImm(0).addImm(0);
1310 }
1311
1312 // Now we can add the actual call instruction to the correct basic block.
1313 MIRBuilder.insertInstr(MIB);
1314
1315 // If Callee is a reg, since it is used by a target specific instruction,
1316 // it must have a register class matching the constraint of that instruction.
1317 if (MIB->getOperand(0).isReg())
1319 *MF.getSubtarget().getRegBankInfo(), *MIB,
1320 MIB->getDesc(), MIB->getOperand(0), 0);
1321
1323 Info.LoweredTailCall = true;
1324 return true;
1325}
1326
1328 CallLoweringInfo &Info) const {
1329 MachineFunction &MF = MIRBuilder.getMF();
1330 const Function &F = MF.getFunction();
1331 MachineRegisterInfo &MRI = MF.getRegInfo();
1332 auto &DL = F.getDataLayout();
1334 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
1335
1336 // Arm64EC has extra requirements for varargs calls; bail out for now.
1337 //
1338 // Arm64EC has special mangling rules for calls; bail out on all calls for
1339 // now.
1340 if (Subtarget.isWindowsArm64EC())
1341 return false;
1342
1343 // Arm64EC thunks have a special calling convention which is only implemented
1344 // in SelectionDAG; bail out for now.
1345 if (Info.CallConv == CallingConv::ARM64EC_Thunk_Native ||
1346 Info.CallConv == CallingConv::ARM64EC_Thunk_X64)
1347 return false;
1348
1350 for (auto &OrigArg : Info.OrigArgs) {
1351 splitToValueTypes(OrigArg, OutArgs, DL, Info.CallConv);
1352 // AAPCS requires that we zero-extend i1 to 8 bits by the caller.
1353 auto &Flags = OrigArg.Flags[0];
1354 if (OrigArg.Ty->isIntegerTy(1) && !Flags.isSExt() && !Flags.isZExt()) {
1355 ArgInfo &OutArg = OutArgs.back();
1356 assert(OutArg.Regs.size() == 1 &&
1357 MRI.getType(OutArg.Regs[0]).getSizeInBits() == 1 &&
1358 "Unexpected registers used for i1 arg");
1359
1360 // We cannot use a ZExt ArgInfo flag here, because it will
1361 // zero-extend the argument to i32 instead of just i8.
1362 OutArg.Regs[0] =
1363 MIRBuilder.buildZExt(LLT::integer(8), OutArg.Regs[0]).getReg(0);
1364 LLVMContext &Ctx = MF.getFunction().getContext();
1365 OutArg.Ty = Type::getInt8Ty(Ctx);
1366 }
1367 }
1368
1370 if (!Info.OrigRet.Ty->isVoidTy())
1371 splitToValueTypes(Info.OrigRet, InArgs, DL, Info.CallConv);
1372
1373 // If we can lower as a tail call, do that instead.
1374 bool CanTailCallOpt =
1375 isEligibleForTailCallOptimization(MIRBuilder, Info, InArgs, OutArgs);
1376
1377 // We must emit a tail call if we have musttail.
1378 if (Info.IsMustTailCall && !CanTailCallOpt) {
1379 // There are types of incoming/outgoing arguments we can't handle yet, so
1380 // it doesn't make sense to actually die here like in ISelLowering. Instead,
1381 // fall back to SelectionDAG and let it try to handle this.
1382 LLVM_DEBUG(dbgs() << "Failed to lower musttail call as tail call\n");
1383 return false;
1384 }
1385
1386 Info.IsTailCall = CanTailCallOpt;
1387 if (CanTailCallOpt)
1388 return lowerTailCall(MIRBuilder, Info, OutArgs);
1389
1390 // Find out which ABI gets to decide where things go.
1391 CCAssignFn *AssignFnFixed;
1392 CCAssignFn *AssignFnVarArg;
1393 std::tie(AssignFnFixed, AssignFnVarArg) =
1394 getAssignFnsForCC(Info.CallConv, TLI);
1395
1396 MachineInstrBuilder CallSeqStart;
1397 CallSeqStart = MIRBuilder.buildInstr(AArch64::ADJCALLSTACKDOWN);
1398
1399 // Create a temporarily-floating call instruction so we can add the implicit
1400 // uses of arg registers.
1401
1402 unsigned Opc = 0;
1403 // Calls with operand bundle "clang.arc.attachedcall" are special. They should
1404 // be expanded to the call, directly followed by a special marker sequence and
1405 // a call to an ObjC library function.
1406 if (Info.CB && objcarc::hasAttachedCallOpBundle(Info.CB))
1407 Opc = Info.PAI ? AArch64::BLRA_RVMARKER : AArch64::BLR_RVMARKER;
1408 // A call to a returns twice function like setjmp must be followed by a bti
1409 // instruction.
1410 else if (Info.CB && Info.CB->hasFnAttr(Attribute::ReturnsTwice) &&
1411 !Subtarget.noBTIAtReturnTwice() &&
1413 Opc = AArch64::BLR_BTI;
1414 else {
1415 // For an intrinsic call (e.g. memset), use GOT if "RtLibUseGOT" (-fno-plt)
1416 // is set.
1417 if (Info.Callee.isSymbol() && F.getParent()->getRtLibUseGOT()) {
1418 auto MIB = MIRBuilder.buildInstr(TargetOpcode::G_GLOBAL_VALUE);
1419 DstOp(getLLTForType(*F.getType(), DL)).addDefToMIB(MRI, MIB);
1420 MIB.addExternalSymbol(Info.Callee.getSymbolName(), AArch64II::MO_GOT);
1421 Info.Callee = MachineOperand::CreateReg(MIB.getReg(0), false);
1422 }
1423 Opc = getCallOpcode(MF, Info.Callee.isReg(), false, Info.PAI, MRI);
1424 }
1425
1426 auto MIB = MIRBuilder.buildInstrNoInsert(Opc);
1427 unsigned CalleeOpNo = 0;
1428
1429 if (Opc == AArch64::BLR_RVMARKER || Opc == AArch64::BLRA_RVMARKER) {
1430 // Add a target global address for the retainRV/claimRV runtime function
1431 // just before the call target.
1432 Function *ARCFn = *objcarc::getAttachedARCFunction(Info.CB);
1433 MIB.addGlobalAddress(ARCFn);
1434 ++CalleeOpNo;
1435
1436 // We may or may not need to emit both the marker and the retain/claim call.
1437 // Tell the pseudo expansion using an additional boolean op.
1438 MIB.addImm(objcarc::attachedCallOpBundleNeedsMarker(Info.CB));
1439 ++CalleeOpNo;
1440 } else if (Info.CFIType) {
1441 MIB->setCFIType(MF, Info.CFIType->getZExtValue());
1442 }
1443 MIB->setDeactivationSymbol(MF, Info.DeactivationSymbol);
1444
1445 MIB.add(Info.Callee);
1446
1447 // Tell the call which registers are clobbered.
1448 const uint32_t *Mask;
1449 const auto *TRI = Subtarget.getRegisterInfo();
1450
1451 AArch64OutgoingValueAssigner Assigner(AssignFnFixed, AssignFnVarArg,
1452 Subtarget, /*IsReturn*/ false);
1453 // Do the actual argument marshalling.
1454 OutgoingArgHandler Handler(MIRBuilder, MRI, MIB, /*IsReturn*/ false);
1455 if (!determineAndHandleAssignments(Handler, Assigner, OutArgs, MIRBuilder,
1456 Info.CallConv, Info.IsVarArg))
1457 return false;
1458
1459 Mask = getMaskForArgs(OutArgs, Info, *TRI, MF);
1460
1461 if (Opc == AArch64::BLRA || Opc == AArch64::BLRA_RVMARKER) {
1462 assert((Info.PAI->Key == AArch64PACKey::IA ||
1463 Info.PAI->Key == AArch64PACKey::IB) &&
1464 "Invalid auth call key");
1465 MIB.addImm(Info.PAI->Key);
1466
1467 Register AddrDisc = 0;
1468 uint16_t IntDisc = 0;
1469 std::tie(IntDisc, AddrDisc) =
1470 extractPtrauthBlendDiscriminators(Info.PAI->Discriminator, MRI);
1471
1472 MIB.addImm(IntDisc);
1473 MIB.addUse(AddrDisc);
1474 if (AddrDisc != AArch64::NoRegister) {
1476 *MF.getSubtarget().getRegBankInfo(), *MIB,
1477 MIB->getDesc(), MIB->getOperand(CalleeOpNo + 3),
1478 CalleeOpNo + 3);
1479 }
1480 }
1481
1482 // Tell the call which registers are clobbered.
1484 TRI->UpdateCustomCallPreservedMask(MF, &Mask);
1485 MIB.addRegMask(Mask);
1486
1487 if (TRI->isAnyArgRegReserved(MF))
1488 TRI->emitReservedArgRegCallError(MF);
1489
1490 // Now we can add the actual call instruction to the correct basic block.
1491 MIRBuilder.insertInstr(MIB);
1492
1493 uint64_t CalleePopBytes =
1494 doesCalleeRestoreStack(Info.CallConv,
1496 ? alignTo(Assigner.StackSize, 16)
1497 : 0;
1498
1499 CallSeqStart.addImm(Assigner.StackSize).addImm(0);
1500 MIRBuilder.buildInstr(AArch64::ADJCALLSTACKUP)
1501 .addImm(Assigner.StackSize)
1502 .addImm(CalleePopBytes);
1503
1504 // If Callee is a reg, since it is used by a target specific
1505 // instruction, it must have a register class matching the
1506 // constraint of that instruction.
1507 if (MIB->getOperand(CalleeOpNo).isReg())
1508 constrainOperandRegClass(MF, *TRI, MRI, *Subtarget.getInstrInfo(),
1509 *Subtarget.getRegBankInfo(), *MIB, MIB->getDesc(),
1510 MIB->getOperand(CalleeOpNo), CalleeOpNo);
1511
1512 // Finally we can copy the returned value back into its virtual-register. In
1513 // symmetry with the arguments, the physical register must be an
1514 // implicit-define of the call instruction.
1515 if (Info.CanLowerReturn && !Info.OrigRet.Ty->isVoidTy()) {
1516 CCAssignFn *RetAssignFn = TLI.CCAssignFnForReturn(Info.CallConv);
1517 CallReturnHandler Handler(MIRBuilder, MRI, MIB);
1518 bool UsingReturnedArg =
1519 !OutArgs.empty() && OutArgs[0].Flags[0].isReturned();
1520
1521 AArch64OutgoingValueAssigner Assigner(RetAssignFn, RetAssignFn, Subtarget,
1522 /*IsReturn*/ false);
1523 ReturnedArgCallReturnHandler ReturnedArgHandler(MIRBuilder, MRI, MIB);
1525 UsingReturnedArg ? ReturnedArgHandler : Handler, Assigner, InArgs,
1526 MIRBuilder, Info.CallConv, Info.IsVarArg,
1527 UsingReturnedArg ? ArrayRef(OutArgs[0].Regs)
1528 : ArrayRef<Register>()))
1529 return false;
1530 }
1531
1532 if (Info.SwiftErrorVReg) {
1533 MIB.addDef(AArch64::X21, RegState::Implicit);
1534 MIRBuilder.buildCopy(Info.SwiftErrorVReg, Register(AArch64::X21));
1535 }
1536
1537 if (!Info.CanLowerReturn) {
1538 insertSRetLoads(MIRBuilder, Info.OrigRet.Ty, Info.OrigRet.Regs,
1539 Info.DemoteRegister, Info.DemoteStackIndex);
1540 }
1541 return true;
1542}
1543
1545 return Ty.getSizeInBits() == 64;
1546}
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 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.
void splitToValueTypes(const ArgInfo &OrigArgInfo, SmallVectorImpl< ArgInfo > &SplitArgs, const DataLayout &DL, CallingConv::ID CallConv, SmallVectorImpl< TypeSize > *Offsets=nullptr) const
Break OrigArgInfo into one or more pieces the calling convention can process, returned in 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:892
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition Function.h:272
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:229
bool hasExternalWeakLinkage() const
constexpr unsigned getScalarSizeInBits() 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.
static LLT integer(unsigned SizeInBits)
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,...
LLVM_ABI MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
LLVM_ABI Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
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:311
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition Type.h:130
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:257
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:255
@ 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.
@ 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:2208
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:1746
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
@ Success
The lock was released successfully.
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:1984
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:840
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, ISD::ArgFlagsTy Flags={}) 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.