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