55#define DEBUG_TYPE "aarch64-call-lowering"
62 auto FlagVals = Flags.getFlags();
63 return FlagVals != ISD::ArgFlagsTy::NoFlags &&
64 FlagVals != ISD::ArgFlagsTy::Pointer;
69 return Ty->
isPointerTy() || Ty->isIntegerTy(32) || Ty->isIntegerTy(64);
84 for (
unsigned I = 0,
E = Args.size();
I !=
E; ++
I) {
123 if (OrigVT == MVT::i1 || OrigVT == MVT::i8)
124 ValVT = LocVT = MVT::i8;
125 else if (OrigVT == MVT::i16)
126 ValVT = LocVT = MVT::i16;
132 return (ValVT == MVT::i8 || ValVT == MVT::i16) ?
LLT(ValVT)
138struct AArch64IncomingValueAssigner
140 AArch64IncomingValueAssigner(
CCAssignFn *AssignFn_,
142 : IncomingValueAssigner(AssignFn_, AssignFnVarArg_) {}
144 bool assignArg(
unsigned ValNo, EVT OrigVT, MVT ValVT, MVT LocVT,
146 const CallLowering::ArgInfo &Info, ISD::ArgFlagsTy Flags,
147 CCState &State)
override {
149 return IncomingValueAssigner::assignArg(ValNo, OrigVT, ValVT, LocVT,
150 LocInfo, Info, Flags, State);
154struct AArch64OutgoingValueAssigner
156 const AArch64Subtarget &Subtarget;
163 AArch64OutgoingValueAssigner(
CCAssignFn *AssignFn_,
165 const AArch64Subtarget &Subtarget_,
167 : OutgoingValueAssigner(AssignFn_, AssignFnVarArg_),
168 Subtarget(Subtarget_), IsReturn(IsReturn) {}
170 bool assignArg(
unsigned ValNo, EVT OrigVT, MVT ValVT, MVT LocVT,
172 const CallLowering::ArgInfo &Info, ISD::ArgFlagsTy Flags,
173 CCState &State)
override {
177 bool UseVarArgsCCForFixed = IsCalleeWin && State.
isVarArg();
180 if (!
Flags.isVarArg() && !UseVarArgsCCForFixed) {
183 Res = AssignFn(ValNo, ValVT, LocVT, LocInfo, Flags,
Info.Ty, State);
185 Res = AssignFnVarArg(ValNo, ValVT, LocVT, LocInfo, Flags,
Info.Ty, State);
193 IncomingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
194 : IncomingValueHandler(MIRBuilder, MRI) {}
197 MachinePointerInfo &MPO,
198 ISD::ArgFlagsTy Flags)
override {
199 auto &MFI = MIRBuilder.getMF().getFrameInfo();
203 const bool IsImmutable = !
Flags.isByVal();
205 int FI = MFI.CreateFixedObject(
Size,
Offset, IsImmutable);
207 auto AddrReg = MIRBuilder.buildFrameIndex(
LLT::pointer(0, 64), FI);
208 return AddrReg.getReg(0);
211 LLT getStackValueStoreType(
const DataLayout &
DL,
const CCValAssign &VA,
212 ISD::ArgFlagsTy Flags)
const override {
215 if (
Flags.isPointer())
221 const CCValAssign &VA,
222 ISD::ArgFlagsTy Flags = {})
override {
223 markRegUsed(PhysReg);
224 IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA);
228 const MachinePointerInfo &MPO,
229 const CCValAssign &VA)
override {
250 case CCValAssign::LocInfo::ZExt:
251 MIRBuilder.buildLoadInstr(TargetOpcode::G_ZEXTLOAD, ValVReg, Addr, *MMO);
253 case CCValAssign::LocInfo::SExt:
254 MIRBuilder.buildLoadInstr(TargetOpcode::G_SEXTLOAD, ValVReg, Addr, *MMO);
257 MIRBuilder.buildLoad(ValVReg, Addr, *MMO);
278struct CallReturnHandler :
public IncomingArgHandler {
279 CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
280 MachineInstrBuilder MIB)
281 : IncomingArgHandler(MIRBuilder, MRI), MIB(MIB) {}
287 MachineInstrBuilder MIB;
291struct ReturnedArgCallReturnHandler :
public CallReturnHandler {
292 ReturnedArgCallReturnHandler(MachineIRBuilder &MIRBuilder,
293 MachineRegisterInfo &MRI,
294 MachineInstrBuilder MIB)
295 : CallReturnHandler(MIRBuilder, MRI, MIB) {}
301 OutgoingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
302 MachineInstrBuilder MIB,
bool IsTailCall =
false,
304 : OutgoingValueHandler(MIRBuilder, MRI), MIB(MIB), IsTailCall(IsTailCall),
306 Subtarget(MIRBuilder.getMF().getSubtarget<AArch64Subtarget>()) {}
309 MachinePointerInfo &MPO,
310 ISD::ArgFlagsTy Flags)
override {
316 assert(!
Flags.isByVal() &&
"byval unhandled with tail calls");
320 auto FIReg = MIRBuilder.buildFrameIndex(p0, FI);
322 return FIReg.getReg(0);
326 SPReg = MIRBuilder.buildCopy(p0,
Register(AArch64::SP)).getReg(0);
328 auto OffsetReg = MIRBuilder.buildConstant(s64,
Offset);
330 auto AddrReg = MIRBuilder.buildPtrAdd(p0,
SPReg, OffsetReg);
333 return AddrReg.getReg(0);
340 LLT getStackValueStoreType(
const DataLayout &
DL,
const CCValAssign &VA,
341 ISD::ArgFlagsTy Flags)
const override {
342 if (
Flags.isPointer())
348 const CCValAssign &VA, ISD::ArgFlagsTy Flags)
override {
349 MIB.addUse(PhysReg, RegState::Implicit);
350 Register ExtReg = extendRegister(ValVReg, VA);
351 MIRBuilder.buildCopy(PhysReg, ExtReg);
356 const CCValAssign &VA,
359 const MachineRegisterInfo &MRI = MF.
getRegInfo();
366 if (
Op == TargetOpcode::G_ZEXT ||
Op == TargetOpcode::G_ANYEXT ||
379 if (LoadAddrDef->getOpcode() != TargetOpcode::G_FRAME_INDEX)
382 int LoadFI = LoadAddrDef->getOperand(1).getIndex();
384 auto *StoreAddrDef = MRI.
getVRegDef(StoreAddr);
385 if (StoreAddrDef->getOpcode() != TargetOpcode::G_FRAME_INDEX)
400 const MachinePointerInfo &MPO,
401 const CCValAssign &VA)
override {
407 MIRBuilder.buildStore(ValVReg, Addr, *MMO);
410 void assignValueToAddress(
const CallLowering::ArgInfo &Arg,
unsigned RegIndex,
412 const MachinePointerInfo &MPO,
413 const CCValAssign &VA)
override {
417 if (Arg.
Flags[0].isVarArg())
421 if (VA.
getLocInfo() != CCValAssign::LocInfo::FPExt) {
430 ValVReg = extendRegister(ValVReg, VA, MaxSize);
436 assignValueToAddress(ValVReg, Addr, MemTy, MPO, VA);
439 MachineInstrBuilder MIB;
450 const AArch64Subtarget &Subtarget;
466 "Return value without a vreg");
471 }
else if (!VRegs.
empty()) {
478 CCAssignFn *AssignFn = TLI.CCAssignFnForReturn(
F.getCallingConv());
479 auto &
DL =
F.getDataLayout();
485 "For each split Type there should be exactly one VReg.");
490 for (
unsigned i = 0; i < SplitEVTs.
size(); ++i) {
492 ArgInfo CurArgInfo =
ArgInfo{CurVReg, SplitEVTs[i].getTypeForEVT(Ctx), 0};
497 auto &Flags = CurArgInfo.
Flags[0];
499 !Flags.isSExt() && !Flags.isZExt()) {
501 }
else if (TLI.getNumRegistersForCallingConv(Ctx, CC, SplitEVTs[i]) ==
504 MVT NewVT = TLI.getRegisterTypeForCallingConv(Ctx, CC, SplitEVTs[i]);
505 if (
EVT(NewVT) != SplitEVTs[i]) {
506 unsigned ExtendOp = TargetOpcode::G_ANYEXT;
507 if (
F.getAttributes().hasRetAttr(Attribute::SExt))
508 ExtendOp = TargetOpcode::G_SEXT;
509 else if (
F.getAttributes().hasRetAttr(Attribute::ZExt))
510 ExtendOp = TargetOpcode::G_ZEXT;
525 CurVReg = MIRBuilder.
buildInstr(ExtendOp, {NewLLT}, {CurVReg})
545 MRI.getType(CurVReg).getScalarSizeInBits()) {
547 CurVReg = MIRBuilder.
buildInstr(ExtendOp, {NewLLT}, {CurVReg})
553 if (CurVReg != CurArgInfo.
Regs[0]) {
554 CurArgInfo.
Regs[0] = CurVReg;
561 AArch64OutgoingValueAssigner Assigner(AssignFn, AssignFn, Subtarget,
563 OutgoingArgHandler Handler(MIRBuilder, MRI, MIB);
565 MIRBuilder, CC,
F.isVarArg());
568 if (SwiftErrorVReg) {
570 MIRBuilder.
buildCopy(AArch64::X21, SwiftErrorVReg);
580 bool IsVarArg)
const {
583 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs,
586 return checkReturn(CCInfo, Outs, TLI.CCAssignFnForReturn(CallConv));
603 assert(
F.isVarArg() &&
"Expected F to be vararg?");
607 CCState CCInfo(
F.getCallingConv(),
true, MF, ArgLocs,
626 for (
const auto &
F : Forwards) {
627 MBB.addLiveIn(
F.PReg);
636 if (!TM.getCLOpts().enable_gisel_sve &&
637 (
F.getReturnType()->isScalableTy() ||
639 return A.getType()->isScalableTy();
643 if (!ST.hasNEON() || !ST.hasFPARMv8()) {
644 LLVM_DEBUG(
dbgs() <<
"Falling back to SDAG because we don't support no-NEON\n");
649 if (Attrs.hasZAState() || Attrs.hasZT0State() ||
650 Attrs.hasStreamingInterfaceOrBody() ||
651 Attrs.hasStreamingCompatibleInterface())
655 bool IsGlobalISelPreferred =
658 static_cast<unsigned>(OptLevel) <= TM.getEnableGlobalISelAtO() ||
660 return !IsGlobalISelPreferred;
663void AArch64CallLowering::saveVarArgRegisters(
674 bool IsWin64CC = Subtarget.isCallingConvWin64(CCInfo.
getCallingConv(),
680 unsigned NumVariadicGPRArgRegs =
GPRArgRegs.size() - FirstVariadicGPR + 1;
682 unsigned GPRSaveSize = 8 * (
GPRArgRegs.size() - FirstVariadicGPR);
684 if (GPRSaveSize != 0) {
687 -
static_cast<int>(GPRSaveSize),
false);
688 if (GPRSaveSize & 15)
691 -
static_cast<int>(
alignTo(GPRSaveSize, 16)),
700 for (
unsigned i = FirstVariadicGPR; i <
GPRArgRegs.size(); ++i) {
707 MF, GPRIdx, (i - FirstVariadicGPR) * 8)
718 if (Subtarget.hasFPARMv8() && !IsWin64CC) {
721 unsigned FPRSaveSize = 16 * (
FPRArgRegs.size() - FirstVariadicFPR);
723 if (FPRSaveSize != 0) {
730 for (
unsigned i = FirstVariadicFPR; i <
FPRArgRegs.size(); ++i) {
756 auto &
DL =
F.getDataLayout();
761 if (
F.isVarArg() && Subtarget.isWindowsArm64EC())
770 bool IsWin64 = Subtarget.isCallingConvWin64(
F.getCallingConv(),
F.isVarArg());
775 return A.hasStructRetAttr() && A.hasInRegAttr();
788 for (
auto &Arg :
F.args()) {
789 if (
DL.getTypeStoreSize(Arg.getType()).isZero())
792 ArgInfo OrigArg{VRegs[i], Arg, i};
800 "Unexpected registers used for i1 arg");
802 auto &Flags = OrigArg.
Flags[0];
803 if (!Flags.isZExt() && !Flags.isSExt()) {
807 OrigArg.
Regs[0] = WideReg;
812 if (Arg.hasAttribute(Attribute::SwiftAsync))
823 CCAssignFn *AssignFn = TLI.CCAssignFnForCall(
F.getCallingConv(), IsWin64 &&
F.isVarArg());
825 AArch64IncomingValueAssigner Assigner(AssignFn, AssignFn);
828 CCState CCInfo(
F.getCallingConv(),
F.isVarArg(), MF, ArgLocs,
F.getContext());
833 if (!BoolArgs.
empty()) {
834 for (
auto &KV : BoolArgs) {
839 "Unexpected bit size of a bool arg");
846 uint64_t StackSize = Assigner.StackSize;
848 if ((!Subtarget.isTargetDarwin() && !Subtarget.isWindowsArm64EC()) || IsWin64) {
854 saveVarArgRegisters(MIRBuilder, Handler, CCInfo);
855 }
else if (Subtarget.isWindowsArm64EC()) {
860 StackSize =
alignTo(Assigner.StackSize, Subtarget.isTargetILP32() ? 4 : 8);
870 StackSize =
alignTo(StackSize, 16);
886 if (Subtarget.hasCustomCallingConv())
887 Subtarget.getRegisterInfo()->UpdateCustomCalleeSavedRegs(MF);
922static std::pair<CCAssignFn *, CCAssignFn *>
927bool AArch64CallLowering::doCallerAndCalleePassArgsTheSameWay(
935 if (CalleeCC == CallerCC)
942 std::tie(CalleeAssignFnFixed, CalleeAssignFnVarArg) =
947 std::tie(CallerAssignFnFixed, CallerAssignFnVarArg) =
950 AArch64IncomingValueAssigner CalleeAssigner(CalleeAssignFnFixed,
951 CalleeAssignFnVarArg);
952 AArch64IncomingValueAssigner CallerAssigner(CallerAssignFnFixed,
953 CallerAssignFnVarArg);
960 const uint32_t *CallerPreserved =
TRI->getCallPreservedMask(MF, CallerCC);
961 const uint32_t *CalleePreserved =
TRI->getCallPreservedMask(MF, CalleeCC);
962 if (MF.
getSubtarget<AArch64Subtarget>().hasCustomCallingConv()) {
963 TRI->UpdateCustomCallPreservedMask(MF, &CallerPreserved);
964 TRI->UpdateCustomCallPreservedMask(MF, &CalleePreserved);
967 return TRI->regmaskSubsetEqual(CallerPreserved, CalleePreserved);
970bool AArch64CallLowering::areCalleeOutgoingArgsTailCallable(
974 if (OrigOutArgs.
empty())
982 const AArch64Subtarget &Subtarget = MF.
getSubtarget<AArch64Subtarget>();
990 CCState OutInfo(CalleeCC,
false, MF, OutLocs, Ctx);
992 AArch64OutgoingValueAssigner CalleeAssigner(AssignFnFixed, AssignFnVarArg,
1003 const AArch64FunctionInfo *FuncInfo = MF.
getInfo<AArch64FunctionInfo>();
1005 LLVM_DEBUG(
dbgs() <<
"... Cannot fit call operands on caller's stack.\n");
1013 const uint32_t *CallerPreservedMask =
TRI->getCallPreservedMask(MF, CallerCC);
1016 if (
Info.IsVarArg) {
1022 for (
unsigned i = 0; i < OutLocs.
size(); ++i) {
1023 auto &ArgLoc = OutLocs[i];
1024 if (ArgLoc.isRegLoc())
1029 <<
"... Cannot tail call vararg function with stack arguments\n");
1043 if (!Info.IsTailCall)
1052 if (Info.SwiftErrorVReg) {
1057 LLVM_DEBUG(
dbgs() <<
"... Cannot handle tail calls with swifterror yet.\n");
1062 LLVM_DEBUG(
dbgs() <<
"... Calling convention cannot be tail called.\n");
1084 return A.hasByValAttr() || A.hasInRegAttr() || A.hasSwiftErrorAttr();
1086 LLVM_DEBUG(
dbgs() <<
"... Cannot tail call from callers with byval, "
1087 "inreg, or swifterror arguments\n");
1098 if (Info.Callee.isGlobal()) {
1102 (!TT.isOSWindows() || TT.isOSBinFormatELF() ||
1103 TT.isOSBinFormatMachO())) {
1104 LLVM_DEBUG(
dbgs() <<
"... Cannot tail call externally-defined function "
1105 "with weak linkage for this OS.\n");
1120 "Unexpected variadic calling convention");
1124 if (!doCallerAndCalleePassArgsTheSameWay(Info, MF, InArgs)) {
1127 <<
"... Caller and callee have incompatible calling conventions.\n");
1131 if (!areCalleeOutgoingArgsTailCallable(Info, MF, OutArgs))
1135 dbgs() <<
"... Call is eligible for tail call optimization.\n");
1141 std::optional<CallLowering::PtrAuthInfo> &PAI,
1149 assert(IsIndirect &&
"Direct call should not be authenticated");
1151 "Invalid auth call key");
1152 return AArch64::BLRA;
1156 return AArch64::TCRETURNdi;
1162 assert(!PAI &&
"ptrauth tail-calls not yet supported with PAuthLR");
1163 return AArch64::TCRETURNrix17;
1166 return AArch64::AUTH_TCRETURN_BTI;
1167 return AArch64::TCRETURNrix16x17;
1171 assert(!PAI &&
"ptrauth tail-calls not yet supported with PAuthLR");
1172 return AArch64::TCRETURNrinotx16;
1176 return AArch64::AUTH_TCRETURN;
1177 return AArch64::TCRETURNri;
1180static const uint32_t *
1185 if (!OutArgs.
empty() && OutArgs[0].Flags[0].isReturned()) {
1187 Mask =
TRI.getThisReturnPreservedMask(MF, Info.CallConv);
1189 OutArgs[0].Flags[0].setReturned(
false);
1190 Mask =
TRI.getCallPreservedMask(MF, Info.CallConv);
1193 Mask =
TRI.getCallPreservedMask(MF, Info.CallConv);
1198bool AArch64CallLowering::lowerTailCall(
1205 AArch64FunctionInfo *FuncInfo = MF.
getInfo<AArch64FunctionInfo>();
1218 MachineInstrBuilder CallSeqStart;
1220 CallSeqStart = MIRBuilder.
buildInstr(AArch64::ADJCALLSTACKDOWN);
1227 const AArch64Subtarget &Subtarget = MF.
getSubtarget<AArch64Subtarget>();
1235 if (
Opc == AArch64::AUTH_TCRETURN ||
Opc == AArch64::AUTH_TCRETURN_BTI) {
1238 "Invalid auth call key");
1239 MIB.addImm(
Info.PAI->Key);
1242 uint16_t IntDisc = 0;
1243 std::tie(IntDisc, AddrDisc) =
1246 MIB.addImm(IntDisc);
1247 MIB.addUse(AddrDisc);
1252 MIB->getOperand(4), 4));
1257 const uint32_t *
Mask =
TRI->getCallPreservedMask(MF, CalleeCC);
1259 TRI->UpdateCustomCallPreservedMask(MF, &Mask);
1260 MIB.addRegMask(Mask);
1263 MIB->setCFIType(MF,
Info.CFIType->getZExtValue());
1265 if (
TRI->isAnyArgRegReserved(MF))
1266 TRI->emitReservedArgRegCallError(MF);
1278 unsigned NumBytes = 0;
1285 CCState OutInfo(CalleeCC,
false, MF, OutLocs,
F.getContext());
1287 AArch64OutgoingValueAssigner CalleeAssigner(AssignFnFixed, AssignFnVarArg,
1294 NumBytes =
alignTo(OutInfo.getStackSize(), 16);
1299 FPDiff = NumReusableBytes - NumBytes;
1303 if (FPDiff < 0 && FuncInfo->getTailCallReservedStack() < (
unsigned)-FPDiff)
1311 assert(FPDiff % 16 == 0 &&
"unaligned stack on tail call");
1316 AArch64OutgoingValueAssigner Assigner(AssignFnFixed, AssignFnVarArg,
1320 OutgoingArgHandler Handler(MIRBuilder, MRI, MIB,
1323 CalleeCC,
Info.IsVarArg))
1328 if (
Info.IsVarArg &&
Info.IsMustTailCall) {
1332 for (
const auto &
F : Forwards) {
1336 if (
any_of(MIB->uses(), [&ForwardedReg, &
TRI](
const MachineOperand &Use) {
1339 return TRI->regsOverlap(Use.getReg(), ForwardedReg);
1352 MIB->getOperand(1).setImm(FPDiff);
1366 if (MIB->getOperand(0).isReg())
1369 MIB->getDesc(), MIB->getOperand(0), 0);
1372 Info.LoweredTailCall =
true;
1381 auto &
DL =
F.getDataLayout();
1399 for (
auto &OrigArg : Info.OrigArgs) {
1402 auto &Flags = OrigArg.Flags[0];
1403 if (OrigArg.Ty->isIntegerTy(1) && !Flags.isSExt() && !Flags.isZExt()) {
1407 "Unexpected registers used for i1 arg");
1419 if (!Info.OrigRet.Ty->isVoidTy())
1423 bool CanTailCallOpt =
1427 if (Info.IsMustTailCall && !CanTailCallOpt) {
1431 LLVM_DEBUG(
dbgs() <<
"Failed to lower musttail call as tail call\n");
1435 Info.IsTailCall = CanTailCallOpt;
1437 return lowerTailCall(MIRBuilder, Info, OutArgs);
1442 std::tie(AssignFnFixed, AssignFnVarArg) =
1446 CallSeqStart = MIRBuilder.
buildInstr(AArch64::ADJCALLSTACKDOWN);
1456 Opc = Info.PAI ? AArch64::BLRA_RVMARKER : AArch64::BLR_RVMARKER;
1459 else if (Info.CB && Info.CB->hasFnAttr(Attribute::ReturnsTwice) &&
1460 !Subtarget.noBTIAtReturnTwice() &&
1462 Opc = AArch64::BLR_BTI;
1466 if (Info.Callee.isSymbol() &&
F.getParent()->getRtLibUseGOT()) {
1467 auto MIB = MIRBuilder.
buildInstr(TargetOpcode::G_GLOBAL_VALUE);
1476 unsigned CalleeOpNo = 0;
1478 if (
Opc == AArch64::BLR_RVMARKER ||
Opc == AArch64::BLRA_RVMARKER) {
1482 MIB.addGlobalAddress(ARCFn);
1489 }
else if (Info.CFIType) {
1490 MIB->setCFIType(MF, Info.CFIType->getZExtValue());
1494 MIB.add(Info.Callee);
1500 AArch64OutgoingValueAssigner Assigner(AssignFnFixed, AssignFnVarArg,
1503 OutgoingArgHandler Handler(MIRBuilder, MRI, MIB,
false);
1506 if (!AssignedCallArgs &&
1508 Info.CallConv, Info.IsVarArg))
1513 if (
Opc == AArch64::BLRA ||
Opc == AArch64::BLRA_RVMARKER) {
1516 "Invalid auth call key");
1517 MIB.addImm(Info.PAI->Key);
1520 uint16_t IntDisc = 0;
1521 std::tie(IntDisc, AddrDisc) =
1524 MIB.addImm(IntDisc);
1525 MIB.addUse(AddrDisc);
1529 MIB->getDesc(), MIB->getOperand(CalleeOpNo + 3),
1536 TRI->UpdateCustomCallPreservedMask(MF, &Mask);
1537 MIB.addRegMask(Mask);
1539 if (
TRI->isAnyArgRegReserved(MF))
1540 TRI->emitReservedArgRegCallError(MF);
1548 uint64_t CalleePopBytes =
1551 ?
alignTo(Assigner.StackSize, 16)
1555 MIRBuilder.
buildInstr(AArch64::ADJCALLSTACKUP)
1556 .
addImm(Assigner.StackSize)
1562 if (MIB->getOperand(CalleeOpNo).isReg())
1565 MIB->getOperand(CalleeOpNo), CalleeOpNo);
1570 if (Info.CanLowerReturn && !Info.OrigRet.Ty->isVoidTy()) {
1571 CCAssignFn *RetAssignFn = TLI.CCAssignFnForReturn(Info.CallConv);
1572 CallReturnHandler Handler(MIRBuilder, MRI, MIB);
1573 bool UsingReturnedArg =
1574 !OutArgs.
empty() && OutArgs[0].Flags[0].isReturned();
1576 AArch64OutgoingValueAssigner Assigner(RetAssignFn, RetAssignFn, Subtarget,
1578 ReturnedArgCallReturnHandler ReturnedArgHandler(MIRBuilder, MRI, MIB);
1579 bool AssignedCallReturn =
1582 if (!AssignedCallReturn &&
1584 UsingReturnedArg ? ReturnedArgHandler : Handler, Assigner, InArgs,
1585 MIRBuilder, Info.CallConv, Info.IsVarArg,
1586 UsingReturnedArg ?
ArrayRef(OutArgs[0].Regs)
1591 if (Info.SwiftErrorVReg) {
1596 if (!Info.CanLowerReturn) {
1598 Info.DemoteRegister, Info.DemoteStackIndex);
1604 return Ty.getSizeInBits() == 64;
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[]
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!")
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.
This file declares the MachineIRBuilder class.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
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.
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...
bool branchTargetEnforcement() const
void setVarArgsStackIndex(int Index)
void setTailCallReservedStack(unsigned bytes)
SmallVectorImpl< ForwardedRegister > & getForwardedMustTailRegParms()
void setBytesInStackArgArea(unsigned bytes)
void setVarArgsGPRIndex(int Index)
bool branchProtectionPAuthLR() const
void setVarArgsFPRSize(unsigned Size)
unsigned getBytesInStackArgArea() const
void setVarArgsFPRIndex(int Index)
void setVarArgsGPRSize(unsigned Size)
void setArgumentStackToRestore(unsigned bytes)
const AArch64RegisterInfo * getRegisterInfo() const override
const AArch64InstrInfo * getInstrInfo() const override
bool isWindowsArm64EC() const
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.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
bool empty() const
Check if the array is empty.
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 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
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()
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
bool hasExternalWeakLinkage() const
Module * getParent()
Get the module that this global value is contained inside of...
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.
Wrapper class representing physical registers. Should be passed by value.
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.
const Triple & getTargetTriple() const
Get the target triple which is a string describing the target host.
Wrapper class representing virtual and physical registers.
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
constexpr bool isValid() const
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.
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.
static constexpr TypeSize getFixed(ScalarTy ExactSize)
The instances of the Type class are immutable: once they are created, they are never changed.
bool isPointerTy() const
True if this is an instance of PointerType.
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
bool isIntegerTy() const
True if this is an instance of IntegerType.
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
@ 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.
@ ARM64EC_Thunk_Native
Calling convention used in the ARM64EC ABI to implement calls between ARM64 code and thunks.
@ Swift
Calling convention for Swift.
@ PreserveMost
Used for runtime calls that preserves most registers.
@ PreserveAll
Used for runtime calls that preserves (almost) all registers.
@ Fast
Attempts to make calls as fast as possible (e.g.
@ PreserveNone
Used for runtime calls that preserves none general registers.
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
@ SwiftTail
This follows the Swift calling convention in how arguments are passed but guarantees tail calls will ...
@ 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.
std::optional< Function * > getAttachedARCFunction(const CallBase *CB)
This function returns operand bundle clang_arc_attachedcall's argument, which is the address of the A...
bool attachedCallOpBundleNeedsMarker(const CallBase *CB)
This function determines whether the clang_arc_attachedcall should be emitted with or without the mar...
bool hasAttachedCallOpBundle(const CallBase *CB)
This is an optimization pass for GlobalISel generic memory operations.
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...
@ 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...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
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.
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.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
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.
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)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
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.
MachineIRBuilder & MIRBuilder
MachineRegisterInfo & MRI
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.
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.