55#define DEBUG_TYPE "aarch64-call-lowering"
64 auto FlagVals = Flags.getFlags();
65 return FlagVals != ISD::ArgFlagsTy::NoFlags &&
66 FlagVals != ISD::ArgFlagsTy::Pointer;
71 return Ty->
isPointerTy() || Ty->isIntegerTy(32) || Ty->isIntegerTy(64);
86 for (
unsigned I = 0,
E = Args.size();
I !=
E; ++
I) {
101 if (Rets.
size() != 1)
125 if (OrigVT == MVT::i1 || OrigVT == MVT::i8)
126 ValVT = LocVT = MVT::i8;
127 else if (OrigVT == MVT::i16)
128 ValVT = LocVT = MVT::i16;
134 return (ValVT == MVT::i8 || ValVT == MVT::i16) ?
LLT(ValVT)
140struct AArch64IncomingValueAssigner
142 AArch64IncomingValueAssigner(
CCAssignFn *AssignFn_,
144 : IncomingValueAssigner(AssignFn_, AssignFnVarArg_) {}
146 bool assignArg(
unsigned ValNo, EVT OrigVT, MVT ValVT, MVT LocVT,
148 const CallLowering::ArgInfo &Info, ISD::ArgFlagsTy Flags,
149 CCState &State)
override {
151 return IncomingValueAssigner::assignArg(ValNo, OrigVT, ValVT, LocVT,
152 LocInfo, Info, Flags, State);
156struct AArch64OutgoingValueAssigner
158 const AArch64Subtarget &Subtarget;
165 AArch64OutgoingValueAssigner(
CCAssignFn *AssignFn_,
167 const AArch64Subtarget &Subtarget_,
169 : OutgoingValueAssigner(AssignFn_, AssignFnVarArg_),
170 Subtarget(Subtarget_), IsReturn(IsReturn) {}
172 bool assignArg(
unsigned ValNo, EVT OrigVT, MVT ValVT, MVT LocVT,
174 const CallLowering::ArgInfo &Info, ISD::ArgFlagsTy Flags,
175 CCState &State)
override {
179 bool UseVarArgsCCForFixed = IsCalleeWin && State.
isVarArg();
182 if (!
Flags.isVarArg() && !UseVarArgsCCForFixed) {
185 Res = AssignFn(ValNo, ValVT, LocVT, LocInfo, Flags,
Info.Ty, State);
187 Res = AssignFnVarArg(ValNo, ValVT, LocVT, LocInfo, Flags,
Info.Ty, State);
195 IncomingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
196 : IncomingValueHandler(MIRBuilder, MRI) {}
199 MachinePointerInfo &MPO,
200 ISD::ArgFlagsTy Flags)
override {
201 auto &MFI = MIRBuilder.getMF().getFrameInfo();
205 const bool IsImmutable = !
Flags.isByVal();
207 int FI = MFI.CreateFixedObject(
Size,
Offset, IsImmutable);
209 auto AddrReg = MIRBuilder.buildFrameIndex(
LLT::pointer(0, 64), FI);
210 return AddrReg.getReg(0);
213 LLT getStackValueStoreType(
const DataLayout &
DL,
const CCValAssign &VA,
214 ISD::ArgFlagsTy Flags)
const override {
217 if (
Flags.isPointer())
223 const CCValAssign &VA,
224 ISD::ArgFlagsTy Flags = {})
override {
225 markRegUsed(PhysReg);
226 IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA);
230 const MachinePointerInfo &MPO,
231 const CCValAssign &VA)
override {
252 case CCValAssign::LocInfo::ZExt:
253 MIRBuilder.buildLoadInstr(TargetOpcode::G_ZEXTLOAD, ValVReg, Addr, *MMO);
255 case CCValAssign::LocInfo::SExt:
256 MIRBuilder.buildLoadInstr(TargetOpcode::G_SEXTLOAD, ValVReg, Addr, *MMO);
259 MIRBuilder.buildLoad(ValVReg, Addr, *MMO);
280struct CallReturnHandler :
public IncomingArgHandler {
281 CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
282 MachineInstrBuilder MIB)
283 : IncomingArgHandler(MIRBuilder, MRI), MIB(MIB) {}
289 MachineInstrBuilder MIB;
293struct ReturnedArgCallReturnHandler :
public CallReturnHandler {
294 ReturnedArgCallReturnHandler(MachineIRBuilder &MIRBuilder,
295 MachineRegisterInfo &MRI,
296 MachineInstrBuilder MIB)
297 : CallReturnHandler(MIRBuilder, MRI, MIB) {}
303 OutgoingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
304 MachineInstrBuilder MIB,
bool IsTailCall =
false,
306 : OutgoingValueHandler(MIRBuilder, MRI), MIB(MIB), IsTailCall(IsTailCall),
308 Subtarget(MIRBuilder.getMF().getSubtarget<AArch64Subtarget>()) {}
311 MachinePointerInfo &MPO,
312 ISD::ArgFlagsTy Flags)
override {
318 assert(!
Flags.isByVal() &&
"byval unhandled with tail calls");
322 auto FIReg = MIRBuilder.buildFrameIndex(p0, FI);
324 return FIReg.getReg(0);
328 SPReg = MIRBuilder.buildCopy(p0,
Register(AArch64::SP)).getReg(0);
330 auto OffsetReg = MIRBuilder.buildConstant(s64,
Offset);
332 auto AddrReg = MIRBuilder.buildPtrAdd(p0,
SPReg, OffsetReg);
335 return AddrReg.getReg(0);
342 LLT getStackValueStoreType(
const DataLayout &
DL,
const CCValAssign &VA,
343 ISD::ArgFlagsTy Flags)
const override {
344 if (
Flags.isPointer())
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);
358 const CCValAssign &VA,
361 const MachineRegisterInfo &MRI = MF.
getRegInfo();
368 if (
Op == TargetOpcode::G_ZEXT ||
Op == TargetOpcode::G_ANYEXT ||
381 if (LoadAddrDef->getOpcode() != TargetOpcode::G_FRAME_INDEX)
384 int LoadFI = LoadAddrDef->getOperand(1).getIndex();
386 auto *StoreAddrDef = MRI.
getVRegDef(StoreAddr);
387 if (StoreAddrDef->getOpcode() != TargetOpcode::G_FRAME_INDEX)
402 const MachinePointerInfo &MPO,
403 const CCValAssign &VA)
override {
409 MIRBuilder.buildStore(ValVReg, Addr, *MMO);
412 void assignValueToAddress(
const CallLowering::ArgInfo &Arg,
unsigned RegIndex,
414 const MachinePointerInfo &MPO,
415 const CCValAssign &VA)
override {
419 if (Arg.
Flags[0].isVarArg())
423 if (VA.
getLocInfo() != CCValAssign::LocInfo::FPExt) {
432 ValVReg = extendRegister(ValVReg, VA, MaxSize);
438 assignValueToAddress(ValVReg, Addr, MemTy, MPO, VA);
441 MachineInstrBuilder MIB;
452 const AArch64Subtarget &Subtarget;
468 "Return value without a vreg");
473 }
else if (!VRegs.
empty()) {
480 CCAssignFn *AssignFn = TLI.CCAssignFnForReturn(
F.getCallingConv());
481 auto &
DL =
F.getDataLayout();
487 "For each split Type there should be exactly one VReg.");
492 for (
unsigned i = 0; i < SplitEVTs.
size(); ++i) {
494 ArgInfo CurArgInfo =
ArgInfo{CurVReg, SplitEVTs[i].getTypeForEVT(Ctx), 0};
499 auto &Flags = CurArgInfo.
Flags[0];
501 !Flags.isSExt() && !Flags.isZExt()) {
503 }
else if (TLI.getNumRegistersForCallingConv(Ctx, CC, SplitEVTs[i]) ==
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;
527 CurVReg = MIRBuilder.
buildInstr(ExtendOp, {NewLLT}, {CurVReg})
547 MRI.getType(CurVReg).getScalarSizeInBits()) {
549 CurVReg = MIRBuilder.
buildInstr(ExtendOp, {NewLLT}, {CurVReg})
555 if (CurVReg != CurArgInfo.
Regs[0]) {
556 CurArgInfo.
Regs[0] = CurVReg;
563 AArch64OutgoingValueAssigner Assigner(AssignFn, AssignFn, Subtarget,
565 OutgoingArgHandler Handler(MIRBuilder, MRI, MIB);
567 MIRBuilder, CC,
F.isVarArg());
570 if (SwiftErrorVReg) {
572 MIRBuilder.
buildCopy(AArch64::X21, SwiftErrorVReg);
582 bool IsVarArg)
const {
585 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs,
588 return checkReturn(CCInfo, Outs, TLI.CCAssignFnForReturn(CallConv));
605 assert(
F.isVarArg() &&
"Expected F to be vararg?");
609 CCState CCInfo(
F.getCallingConv(),
true, MF, ArgLocs,
628 for (
const auto &
F : Forwards) {
629 MBB.addLiveIn(
F.PReg);
640 return A.getType()->isScalableTy();
644 if (!ST.hasNEON() || !ST.hasFPARMv8()) {
645 LLVM_DEBUG(
dbgs() <<
"Falling back to SDAG because we don't support no-NEON\n");
650 if (Attrs.hasZAState() || Attrs.hasZT0State() ||
651 Attrs.hasStreamingInterfaceOrBody() ||
652 Attrs.hasStreamingCompatibleInterface())
656 bool IsGlobalISelPreferred =
659 static_cast<unsigned>(OptLevel) <= TM.getEnableGlobalISelAtO() ||
661 return !IsGlobalISelPreferred;
664void AArch64CallLowering::saveVarArgRegisters(
675 bool IsWin64CC = Subtarget.isCallingConvWin64(CCInfo.
getCallingConv(),
681 unsigned NumVariadicGPRArgRegs =
GPRArgRegs.size() - FirstVariadicGPR + 1;
683 unsigned GPRSaveSize = 8 * (
GPRArgRegs.size() - FirstVariadicGPR);
685 if (GPRSaveSize != 0) {
688 -
static_cast<int>(GPRSaveSize),
false);
689 if (GPRSaveSize & 15)
692 -
static_cast<int>(
alignTo(GPRSaveSize, 16)),
701 for (
unsigned i = FirstVariadicGPR; i <
GPRArgRegs.size(); ++i) {
708 MF, GPRIdx, (i - FirstVariadicGPR) * 8)
719 if (Subtarget.hasFPARMv8() && !IsWin64CC) {
722 unsigned FPRSaveSize = 16 * (
FPRArgRegs.size() - FirstVariadicFPR);
724 if (FPRSaveSize != 0) {
731 for (
unsigned i = FirstVariadicFPR; i <
FPRArgRegs.size(); ++i) {
757 auto &
DL =
F.getDataLayout();
762 if (
F.isVarArg() && Subtarget.isWindowsArm64EC())
772 Subtarget.isCallingConvWin64(
F.getCallingConv(),
F.isVarArg()) &&
773 !Subtarget.isWindowsArm64EC();
784 for (
auto &Arg :
F.args()) {
785 if (
DL.getTypeStoreSize(Arg.getType()).isZero())
788 ArgInfo OrigArg{VRegs[i], Arg, i};
796 "Unexpected registers used for i1 arg");
798 auto &Flags = OrigArg.
Flags[0];
799 if (!Flags.isZExt() && !Flags.isSExt()) {
803 OrigArg.
Regs[0] = WideReg;
808 if (Arg.hasAttribute(Attribute::SwiftAsync))
819 CCAssignFn *AssignFn = TLI.CCAssignFnForCall(
F.getCallingConv(), IsWin64 &&
F.isVarArg());
821 AArch64IncomingValueAssigner Assigner(AssignFn, AssignFn);
824 CCState CCInfo(
F.getCallingConv(),
F.isVarArg(), MF, ArgLocs,
F.getContext());
829 if (!BoolArgs.
empty()) {
830 for (
auto &KV : BoolArgs) {
835 "Unexpected bit size of a bool arg");
842 uint64_t StackSize = Assigner.StackSize;
844 if ((!Subtarget.isTargetDarwin() && !Subtarget.isWindowsArm64EC()) || IsWin64) {
850 saveVarArgRegisters(MIRBuilder, Handler, CCInfo);
851 }
else if (Subtarget.isWindowsArm64EC()) {
856 StackSize =
alignTo(Assigner.StackSize, Subtarget.isTargetILP32() ? 4 : 8);
866 StackSize =
alignTo(StackSize, 16);
882 if (Subtarget.hasCustomCallingConv())
883 Subtarget.getRegisterInfo()->UpdateCustomCalleeSavedRegs(MF);
918static std::pair<CCAssignFn *, CCAssignFn *>
923bool AArch64CallLowering::doCallerAndCalleePassArgsTheSameWay(
931 if (CalleeCC == CallerCC)
938 std::tie(CalleeAssignFnFixed, CalleeAssignFnVarArg) =
943 std::tie(CallerAssignFnFixed, CallerAssignFnVarArg) =
946 AArch64IncomingValueAssigner CalleeAssigner(CalleeAssignFnFixed,
947 CalleeAssignFnVarArg);
948 AArch64IncomingValueAssigner CallerAssigner(CallerAssignFnFixed,
949 CallerAssignFnVarArg);
956 const uint32_t *CallerPreserved =
TRI->getCallPreservedMask(MF, CallerCC);
957 const uint32_t *CalleePreserved =
TRI->getCallPreservedMask(MF, CalleeCC);
958 if (MF.
getSubtarget<AArch64Subtarget>().hasCustomCallingConv()) {
959 TRI->UpdateCustomCallPreservedMask(MF, &CallerPreserved);
960 TRI->UpdateCustomCallPreservedMask(MF, &CalleePreserved);
963 return TRI->regmaskSubsetEqual(CallerPreserved, CalleePreserved);
966bool AArch64CallLowering::areCalleeOutgoingArgsTailCallable(
970 if (OrigOutArgs.
empty())
978 const AArch64Subtarget &Subtarget = MF.
getSubtarget<AArch64Subtarget>();
986 CCState OutInfo(CalleeCC,
false, MF, OutLocs, Ctx);
988 AArch64OutgoingValueAssigner CalleeAssigner(AssignFnFixed, AssignFnVarArg,
999 const AArch64FunctionInfo *FuncInfo = MF.
getInfo<AArch64FunctionInfo>();
1001 LLVM_DEBUG(
dbgs() <<
"... Cannot fit call operands on caller's stack.\n");
1009 const uint32_t *CallerPreservedMask =
TRI->getCallPreservedMask(MF, CallerCC);
1012 if (
Info.IsVarArg) {
1018 for (
unsigned i = 0; i < OutLocs.
size(); ++i) {
1019 auto &ArgLoc = OutLocs[i];
1020 if (ArgLoc.isRegLoc())
1025 <<
"... Cannot tail call vararg function with stack arguments\n");
1039 if (!Info.IsTailCall)
1048 if (Info.SwiftErrorVReg) {
1053 LLVM_DEBUG(
dbgs() <<
"... Cannot handle tail calls with swifterror yet.\n");
1058 LLVM_DEBUG(
dbgs() <<
"... Calling convention cannot be tail called.\n");
1080 return A.hasByValAttr() || A.hasInRegAttr() || A.hasSwiftErrorAttr();
1082 LLVM_DEBUG(
dbgs() <<
"... Cannot tail call from callers with byval, "
1083 "inreg, or swifterror arguments\n");
1094 if (Info.Callee.isGlobal()) {
1098 (!TT.isOSWindows() || TT.isOSBinFormatELF() ||
1099 TT.isOSBinFormatMachO())) {
1100 LLVM_DEBUG(
dbgs() <<
"... Cannot tail call externally-defined function "
1101 "with weak linkage for this OS.\n");
1116 "Unexpected variadic calling convention");
1120 if (!doCallerAndCalleePassArgsTheSameWay(Info, MF, InArgs)) {
1123 <<
"... Caller and callee have incompatible calling conventions.\n");
1127 if (!areCalleeOutgoingArgsTailCallable(Info, MF, OutArgs))
1131 dbgs() <<
"... Call is eligible for tail call optimization.\n");
1137 std::optional<CallLowering::PtrAuthInfo> &PAI,
1145 assert(IsIndirect &&
"Direct call should not be authenticated");
1147 "Invalid auth call key");
1148 return AArch64::BLRA;
1152 return AArch64::TCRETURNdi;
1158 assert(!PAI &&
"ptrauth tail-calls not yet supported with PAuthLR");
1159 return AArch64::TCRETURNrix17;
1162 return AArch64::AUTH_TCRETURN_BTI;
1163 return AArch64::TCRETURNrix16x17;
1167 assert(!PAI &&
"ptrauth tail-calls not yet supported with PAuthLR");
1168 return AArch64::TCRETURNrinotx16;
1172 return AArch64::AUTH_TCRETURN;
1173 return AArch64::TCRETURNri;
1176static const uint32_t *
1181 if (!OutArgs.
empty() && OutArgs[0].Flags[0].isReturned()) {
1183 Mask =
TRI.getThisReturnPreservedMask(MF, Info.CallConv);
1185 OutArgs[0].Flags[0].setReturned(
false);
1186 Mask =
TRI.getCallPreservedMask(MF, Info.CallConv);
1189 Mask =
TRI.getCallPreservedMask(MF, Info.CallConv);
1194bool AArch64CallLowering::lowerTailCall(
1201 AArch64FunctionInfo *FuncInfo = MF.
getInfo<AArch64FunctionInfo>();
1214 MachineInstrBuilder CallSeqStart;
1216 CallSeqStart = MIRBuilder.
buildInstr(AArch64::ADJCALLSTACKDOWN);
1223 const AArch64Subtarget &Subtarget = MF.
getSubtarget<AArch64Subtarget>();
1231 if (
Opc == AArch64::AUTH_TCRETURN ||
Opc == AArch64::AUTH_TCRETURN_BTI) {
1234 "Invalid auth call key");
1235 MIB.addImm(
Info.PAI->Key);
1238 uint16_t IntDisc = 0;
1239 std::tie(IntDisc, AddrDisc) =
1242 MIB.addImm(IntDisc);
1243 MIB.addUse(AddrDisc);
1244 if (AddrDisc != AArch64::NoRegister) {
1248 MIB->getOperand(4), 4));
1253 const uint32_t *
Mask =
TRI->getCallPreservedMask(MF, CalleeCC);
1255 TRI->UpdateCustomCallPreservedMask(MF, &Mask);
1256 MIB.addRegMask(Mask);
1259 MIB->setCFIType(MF,
Info.CFIType->getZExtValue());
1261 if (
TRI->isAnyArgRegReserved(MF))
1262 TRI->emitReservedArgRegCallError(MF);
1274 unsigned NumBytes = 0;
1281 CCState OutInfo(CalleeCC,
false, MF, OutLocs,
F.getContext());
1283 AArch64OutgoingValueAssigner CalleeAssigner(AssignFnFixed, AssignFnVarArg,
1290 NumBytes =
alignTo(OutInfo.getStackSize(), 16);
1295 FPDiff = NumReusableBytes - NumBytes;
1299 if (FPDiff < 0 && FuncInfo->getTailCallReservedStack() < (
unsigned)-FPDiff)
1307 assert(FPDiff % 16 == 0 &&
"unaligned stack on tail call");
1312 AArch64OutgoingValueAssigner Assigner(AssignFnFixed, AssignFnVarArg,
1316 OutgoingArgHandler Handler(MIRBuilder, MRI, MIB,
1319 CalleeCC,
Info.IsVarArg))
1324 if (
Info.IsVarArg &&
Info.IsMustTailCall) {
1328 for (
const auto &
F : Forwards) {
1332 if (
any_of(MIB->uses(), [&ForwardedReg, &
TRI](
const MachineOperand &Use) {
1335 return TRI->regsOverlap(Use.getReg(), ForwardedReg);
1348 MIB->getOperand(1).setImm(FPDiff);
1362 if (MIB->getOperand(0).isReg())
1365 MIB->getDesc(), MIB->getOperand(0), 0);
1368 Info.LoweredTailCall =
true;
1377 auto &
DL =
F.getDataLayout();
1395 for (
auto &OrigArg : Info.OrigArgs) {
1398 auto &Flags = OrigArg.Flags[0];
1399 if (OrigArg.Ty->isIntegerTy(1) && !Flags.isSExt() && !Flags.isZExt()) {
1403 "Unexpected registers used for i1 arg");
1415 if (!Info.OrigRet.Ty->isVoidTy())
1419 bool CanTailCallOpt =
1423 if (Info.IsMustTailCall && !CanTailCallOpt) {
1427 LLVM_DEBUG(
dbgs() <<
"Failed to lower musttail call as tail call\n");
1431 Info.IsTailCall = CanTailCallOpt;
1433 return lowerTailCall(MIRBuilder, Info, OutArgs);
1438 std::tie(AssignFnFixed, AssignFnVarArg) =
1442 CallSeqStart = MIRBuilder.
buildInstr(AArch64::ADJCALLSTACKDOWN);
1452 Opc = Info.PAI ? AArch64::BLRA_RVMARKER : AArch64::BLR_RVMARKER;
1455 else if (Info.CB && Info.CB->hasFnAttr(Attribute::ReturnsTwice) &&
1456 !Subtarget.noBTIAtReturnTwice() &&
1458 Opc = AArch64::BLR_BTI;
1462 if (Info.Callee.isSymbol() &&
F.getParent()->getRtLibUseGOT()) {
1463 auto MIB = MIRBuilder.
buildInstr(TargetOpcode::G_GLOBAL_VALUE);
1472 unsigned CalleeOpNo = 0;
1474 if (
Opc == AArch64::BLR_RVMARKER ||
Opc == AArch64::BLRA_RVMARKER) {
1478 MIB.addGlobalAddress(ARCFn);
1485 }
else if (Info.CFIType) {
1486 MIB->setCFIType(MF, Info.CFIType->getZExtValue());
1490 MIB.add(Info.Callee);
1496 AArch64OutgoingValueAssigner Assigner(AssignFnFixed, AssignFnVarArg,
1499 OutgoingArgHandler Handler(MIRBuilder, MRI, MIB,
false);
1502 if (!AssignedCallArgs &&
1504 Info.CallConv, Info.IsVarArg))
1509 if (
Opc == AArch64::BLRA ||
Opc == AArch64::BLRA_RVMARKER) {
1512 "Invalid auth call key");
1513 MIB.addImm(Info.PAI->Key);
1516 uint16_t IntDisc = 0;
1517 std::tie(IntDisc, AddrDisc) =
1520 MIB.addImm(IntDisc);
1521 MIB.addUse(AddrDisc);
1522 if (AddrDisc != AArch64::NoRegister) {
1525 MIB->getDesc(), MIB->getOperand(CalleeOpNo + 3),
1532 TRI->UpdateCustomCallPreservedMask(MF, &Mask);
1533 MIB.addRegMask(Mask);
1535 if (
TRI->isAnyArgRegReserved(MF))
1536 TRI->emitReservedArgRegCallError(MF);
1541 uint64_t CalleePopBytes =
1544 ?
alignTo(Assigner.StackSize, 16)
1548 MIRBuilder.
buildInstr(AArch64::ADJCALLSTACKUP)
1549 .
addImm(Assigner.StackSize)
1555 if (MIB->getOperand(CalleeOpNo).isReg())
1558 MIB->getOperand(CalleeOpNo), CalleeOpNo);
1563 if (Info.CanLowerReturn && !Info.OrigRet.Ty->isVoidTy()) {
1564 CCAssignFn *RetAssignFn = TLI.CCAssignFnForReturn(Info.CallConv);
1565 CallReturnHandler Handler(MIRBuilder, MRI, MIB);
1566 bool UsingReturnedArg =
1567 !OutArgs.
empty() && OutArgs[0].Flags[0].isReturned();
1569 AArch64OutgoingValueAssigner Assigner(RetAssignFn, RetAssignFn, Subtarget,
1571 ReturnedArgCallReturnHandler ReturnedArgHandler(MIRBuilder, MRI, MIB);
1572 bool AssignedCallReturn =
1575 if (!AssignedCallReturn &&
1577 UsingReturnedArg ? ReturnedArgHandler : Handler, Assigner, InArgs,
1578 MIRBuilder, Info.CallConv, Info.IsVarArg,
1579 UsingReturnedArg ?
ArrayRef(OutArgs[0].Regs)
1584 if (Info.SwiftErrorVReg) {
1589 if (!Info.CanLowerReturn) {
1591 Info.DemoteRegister, Info.DemoteStackIndex);
1597 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[]
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!")
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
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)
@ 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.
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
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
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.