25#include "llvm/IR/IntrinsicsAMDGPU.h"
27#define DEBUG_TYPE "amdgpu-call-lowering"
48 : OutgoingValueHandler(
B, MRI), MIB(MIB) {}
67 Register ExtReg = extendRegisterMin32(*
this, ValVReg, VA);
74 if (
TRI->isSGPRReg(MRI, PhysReg)) {
80 assert(Ty.getSizeInBits() == 32);
82 ExtReg = MIRBuilder.buildPtrToInt(I32, ExtReg).getReg(0);
84 ExtReg = MIRBuilder.buildBitcast(I32, ExtReg).getReg(0);
87 auto ToSGPR = MIRBuilder
88 .buildIntrinsic(Intrinsic::amdgcn_readfirstlane,
91 ExtReg = ToSGPR.getReg(0);
94 MIRBuilder.buildCopy(PhysReg, ExtReg);
103 : IncomingValueHandler(
B, MRI) {}
108 auto &MFI = MIRBuilder.getMF().getFrameInfo();
112 const bool IsImmutable = !Flags.isByVal();
113 int FI = MFI.CreateFixedObject(
Size,
Offset, IsImmutable);
115 auto AddrReg = MIRBuilder.buildFrameIndex(
117 StackUsed = std::max(StackUsed,
Size +
Offset);
118 return AddrReg.getReg(0);
126 auto Copy = MIRBuilder.buildCopy(
LLT::integer(32), PhysReg);
131 buildExtensionHint(VA, Copy.getReg(0),
LLT(VA.
getLocVT()));
134 MIRBuilder.buildTrunc(ValVReg, Extended);
138 MIRBuilder.buildBitcast(ValVReg, Trunc);
143 IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA);
160 auto Copy = MIRBuilder.buildCopy(
LLT::integer(32), PhysReg);
161 auto ToSGPR = MIRBuilder
162 .buildIntrinsic(Intrinsic::amdgcn_readfirstlane,
164 .addReg(Copy.getReg(0));
169 MIRBuilder.buildTrunc(ValVReg, Extended);
173 MIRBuilder.buildBitcast(ValVReg, Trunc);
178 auto Copy = MIRBuilder.buildCopy(MRI.
getType(ValVReg), PhysReg);
179 MIRBuilder.buildIntrinsic(Intrinsic::amdgcn_readfirstlane, ValVReg)
180 .addReg(Copy.getReg(0));
186 markPhysRegUsed(PhysReg);
192 if (Flags.isInReg() &&
TRI->isVGPR(MRI, PhysReg))
193 readLaneToSGPR(ValVReg, PhysReg, VA);
195 copyToReg(ValVReg, PhysReg, VA);
206 MIRBuilder.buildLoad(ValVReg, Addr, *MMO);
212 virtual void markPhysRegUsed(
unsigned PhysReg) = 0;
215struct FormalArgHandler :
public AMDGPUIncomingArgHandler {
217 : AMDGPUIncomingArgHandler(
B, MRI) {}
219 void markPhysRegUsed(
unsigned PhysReg)
override {
220 MIRBuilder.getMBB().addLiveIn(PhysReg);
224struct CallReturnHandler :
public AMDGPUIncomingArgHandler {
227 : AMDGPUIncomingArgHandler(MIRBuilder, MRI), MIB(MIB) {}
229 void markPhysRegUsed(
unsigned PhysReg)
override {
236struct AMDGPUOutgoingArgHandler :
public AMDGPUOutgoingValueHandler {
248 bool IsTailCall =
false,
int FPDiff = 0)
249 : AMDGPUOutgoingValueHandler(MIRBuilder, MRI, MIB), FPDiff(FPDiff),
250 IsTailCall(IsTailCall) {}
264 return FIReg.getReg(0);
271 if (ST.hasFlatScratchEnabled()) {
288 return AddrReg.getReg(0);
309 ? extendRegister(Arg.
Regs[ValRegIndex], VA)
310 : Arg.
Regs[ValRegIndex];
311 assignValueToAddress(ValVReg, Addr, MemTy, MPO, VA);
322 case TargetOpcode::G_SEXT:
324 case TargetOpcode::G_ZEXT:
326 case TargetOpcode::G_ANYEXT:
336 bool IsVarArg)
const {
343 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs,
346 return checkReturn(CCInfo, Outs, TLI.CCAssignFnForReturn(CallConv, IsVarArg));
357 auto &MF =
B.getMF();
360 MachineRegisterInfo *MRI =
B.getMRI();
361 LLVMContext &Ctx =
F.getContext();
369 "For each split Type there should be exactly one VReg.");
373 for (
unsigned i = 0; i < SplitEVTs.
size(); ++i) {
374 EVT VT = SplitEVTs[i];
380 unsigned ExtendOp = TargetOpcode::G_ANYEXT;
381 if (RetInfo.Flags[0].isSExt()) {
382 assert(RetInfo.Regs.size() == 1 &&
"expect only simple return values");
383 ExtendOp = TargetOpcode::G_SEXT;
384 }
else if (RetInfo.Flags[0].isZExt()) {
385 assert(RetInfo.Regs.size() == 1 &&
"expect only simple return values");
386 ExtendOp = TargetOpcode::G_ZEXT;
389 EVT ExtVT = TLI.getTypeForExtReturn(Ctx, VT,
398 if (
Reg != RetInfo.Regs[0]) {
399 RetInfo.Regs[0] =
Reg;
407 CCAssignFn *AssignFn = TLI.CCAssignFnForReturn(CC,
F.isVarArg());
410 AMDGPUOutgoingValueHandler RetHandler(
B, *MRI, Ret);
423 assert(!Val == VRegs.
empty() &&
"Return value without a vreg");
427 const bool IsWaveEnd =
430 B.buildInstr(AMDGPU::S_ENDPGM)
436 unsigned ReturnOpc = IsWholeWave ? AMDGPU::G_AMDGPU_WHOLE_WAVE_FUNC_RETURN
437 : IsShader ? AMDGPU::SI_RETURN_TO_EPILOG
439 auto Ret =
B.buildInstrNoInsert(ReturnOpc);
443 else if (!lowerReturnVal(
B, Val, VRegs, Ret))
447 addOriginalExecToReturn(
B.getMF(), Ret);
462 Register KernArgSegmentVReg = MRI.getLiveInVirtReg(KernArgSegmentPtr);
466 B.buildPtrAdd(DstReg, KernArgSegmentVReg, OffsetReg);
471 Align Alignment)
const {
485 for (
ArgInfo &SplitArg : SplitArgs) {
486 Register PtrReg =
B.getMRI()->createGenericVirtualRegister(PtrTy);
487 lowerParameterPtr(PtrReg,
B,
Offset + FieldOffsets[Idx]);
490 if (SplitArg.Flags[0].isPointer()) {
504 assert(SplitArg.Regs.size() == 1);
506 B.buildLoad(SplitArg.Regs[0], PtrReg, *MMO);
520 Register PrivateSegmentBufferReg = Info.addPrivateSegmentBuffer(
TRI);
521 MF.
addLiveIn(PrivateSegmentBufferReg, &AMDGPU::SGPR_128RegClass);
526 Register DispatchPtrReg = Info.addDispatchPtr(
TRI);
527 MF.
addLiveIn(DispatchPtrReg, &AMDGPU::SGPR_64RegClass);
533 MF.
addLiveIn(QueuePtrReg, &AMDGPU::SGPR_64RegClass);
539 Register InputPtrReg = Info.addKernargSegmentPtr(
TRI);
543 B.getMBB().addLiveIn(InputPtrReg);
544 B.buildCopy(VReg, InputPtrReg);
550 MF.
addLiveIn(DispatchIDReg, &AMDGPU::SGPR_64RegClass);
555 Register FlatScratchInitReg = Info.addFlatScratchInit(
TRI);
556 MF.
addLiveIn(FlatScratchInitReg, &AMDGPU::SGPR_64RegClass);
561 Register PrivateSegmentSizeReg = Info.addPrivateSegmentSize(
TRI);
562 MF.
addLiveIn(PrivateSegmentSizeReg, &AMDGPU::SGPR_32RegClass);
582 CCState CCInfo(
F.getCallingConv(),
F.isVarArg(), MF, ArgLocs,
F.getContext());
587 const Align KernArgBaseAlign(16);
592 for (
auto &Arg :
F.args()) {
594 if (Arg.hasAttribute(
"amdgpu-hidden-argument")) {
595 LLVM_DEBUG(
dbgs() <<
"Preloading hidden arguments is not supported\n");
599 const bool IsByRef = Arg.hasByRefAttr();
600 Type *ArgTy = IsByRef ? Arg.getParamByRefType() : Arg.getType();
601 unsigned AllocSize =
DL.getTypeAllocSize(ArgTy);
605 MaybeAlign ParamAlign = IsByRef ? Arg.getParamAlign() : std::nullopt;
606 Align ABIAlign =
DL.getValueOrABITypeAlignment(ParamAlign, ArgTy);
608 uint64_t ArgOffset =
alignTo(ExplicitArgOffset, ABIAlign) + BaseOffset;
609 ExplicitArgOffset =
alignTo(ExplicitArgOffset, ABIAlign) + AllocSize;
611 if (Arg.use_empty()) {
622 "expected only one register for byval pointers");
624 lowerParameterPtr(VRegs[i][0],
B, ArgOffset);
627 Register PtrReg = MRI.createGenericVirtualRegister(ConstPtrTy);
628 lowerParameterPtr(PtrReg,
B, ArgOffset);
630 B.buildAddrSpaceCast(VRegs[i][0], PtrReg);
633 ArgInfo OrigArg(VRegs[i], Arg, i);
634 const unsigned OrigArgIdx = i + AttributeList::FirstArgIndex;
636 lowerParameter(
B, OrigArg, ArgOffset, Alignment);
642 if (Info->getNumKernargPreloadedSGPRs())
643 Info->setNumWaveDispatchSGPRs(Info->getNumUserSGPRs());
645 TLI.allocateSpecialEntryInputVGPRs(CCInfo, MF, *
TRI, *Info);
646 TLI.allocateSystemSGPRs(CCInfo, MF, *Info,
F.getCallingConv(),
false);
673 CCState CCInfo(CC,
F.isVarArg(), MF, ArgLocs,
F.getContext());
677 Register ImplicitBufferPtrReg = Info->addImplicitBufferPtr(*
TRI);
678 MF.
addLiveIn(ImplicitBufferPtrReg, &AMDGPU::SGPR_64RegClass);
684 Register FlatScratchInitReg = Info->addFlatScratchInit(*
TRI);
685 MF.
addLiveIn(FlatScratchInitReg, &AMDGPU::SGPR_64RegClass);
691 unsigned PSInputNum = 0;
698 for (
auto &Arg :
F.args()) {
699 if (
DL.getTypeStoreSize(Arg.getType()) == 0)
702 if (Info->isWholeWaveFunction() && Idx == 0) {
703 assert(VRegs[Idx].
size() == 1 &&
"Expected only one register");
706 B.buildInstr(AMDGPU::G_AMDGPU_WHOLE_WAVE_FUNC_SETUP)
707 .addDef(VRegs[Idx][0]);
713 const bool InReg = Arg.hasAttribute(Attribute::InReg);
715 if (Arg.hasAttribute(Attribute::SwiftSelf) ||
716 Arg.hasAttribute(Attribute::SwiftError) ||
717 Arg.hasAttribute(Attribute::Nest))
721 const bool ArgUsed = !Arg.use_empty();
722 bool SkipArg = !ArgUsed && !Info->isPSInputAllocated(PSInputNum);
725 Info->markPSInputAllocated(PSInputNum);
727 Info->markPSInputEnabled(PSInputNum);
741 ArgInfo OrigArg(VRegs[Idx], Arg, Idx);
742 const unsigned OrigArgIdx = Idx + AttributeList::FirstArgIndex;
763 if ((Info->getPSInputAddr() & 0x7F) == 0 ||
764 ((Info->getPSInputAddr() & 0xF) == 0 &&
765 Info->isPSInputAllocated(11))) {
768 Info->markPSInputAllocated(0);
769 Info->markPSInputEnabled(0);
772 if (Subtarget.isAmdPalOS()) {
781 unsigned PsInputBits = Info->getPSInputAddr() & Info->getPSInputEnable();
782 if ((PsInputBits & 0x7F) == 0 ||
783 ((PsInputBits & 0xF) == 0 &&
784 (PsInputBits >> 11 & 1)))
790 CCAssignFn *AssignFn = TLI.CCAssignFnForCall(CC,
F.isVarArg());
793 B.setInstr(*
MBB.begin());
795 if (!IsEntryFunc && !IsGraphics) {
797 TLI.allocateSpecialInputVGPRsFixed(CCInfo, MF, *
TRI, *Info);
799 if (!Subtarget.hasFlatScratchEnabled())
801 TLI.allocateSpecialInputSGPRs(CCInfo, MF, *
TRI, *Info);
811 Info->setNumWaveDispatchSGPRs(
813 Info->setNumWaveDispatchVGPRs(
825 TLI.allocateSystemSGPRs(CCInfo, MF, *Info, CC, IsGraphics);
831 Info->setBytesInStackArgArea(StackSize);
872 {
"amdgpu-no-dispatch-ptr",
""},
873 {
"amdgpu-no-queue-ptr",
""},
874 {
"amdgpu-no-implicitarg-ptr",
""},
875 {
"amdgpu-no-dispatch-id",
""},
876 {
"amdgpu-no-workgroup-id-x",
"amdgpu-no-cluster-id-x"},
877 {
"amdgpu-no-workgroup-id-y",
"amdgpu-no-cluster-id-y"},
878 {
"amdgpu-no-workgroup-id-z",
"amdgpu-no-cluster-id-z"},
879 {
"amdgpu-no-lds-kernel-id",
""},
889 for (
auto InputID : InputRegs) {
896 return AttrName.
empty() || Info.CB->hasFnAttr(AttrName);
900 std::tie(OutgoingArg, ArgRC, ArgTy) =
907 std::tie(IncomingArg, IncomingArgRC, ArgTy) =
908 CallerArgInfo.getPreloadedValue(InputID);
909 assert(IncomingArgRC == ArgRC);
914 LI->buildLoadInputValue(InputReg, MIRBuilder, IncomingArg, ArgRC, ArgTy);
916 LI->getImplicitArgPtr(InputReg, MRI, MIRBuilder);
918 std::optional<uint32_t> Id =
932 ArgRegs.emplace_back(OutgoingArg->
getRegister(), InputReg);
936 LLVM_DEBUG(
dbgs() <<
"Unhandled stack passed implicit input argument\n");
947 std::tie(OutgoingArg, ArgRC, ArgTy) =
950 std::tie(OutgoingArg, ArgRC, ArgTy) =
953 std::tie(OutgoingArg, ArgRC, ArgTy) =
965 const ArgDescriptor *IncomingArgX = std::get<0>(WorkitemIDX);
966 const ArgDescriptor *IncomingArgY = std::get<0>(WorkitemIDY);
967 const ArgDescriptor *IncomingArgZ = std::get<0>(WorkitemIDZ);
970 const bool NeedWorkItemIDX = !Info.CB->hasFnAttr(
"amdgpu-no-workitem-id-x");
971 const bool NeedWorkItemIDY = !Info.CB->hasFnAttr(
"amdgpu-no-workitem-id-y");
972 const bool NeedWorkItemIDZ = !Info.CB->hasFnAttr(
"amdgpu-no-workitem-id-z");
979 if (ST.getMaxWorkitemID(MF.
getFunction(), 0) != 0) {
981 LI->buildLoadInputValue(InputReg, MIRBuilder, IncomingArgX,
982 std::get<1>(WorkitemIDX),
983 std::get<2>(WorkitemIDX));
990 NeedWorkItemIDY && ST.getMaxWorkitemID(MF.
getFunction(), 1) != 0) {
992 LI->buildLoadInputValue(
Y, MIRBuilder, IncomingArgY,
993 std::get<1>(WorkitemIDY), std::get<2>(WorkitemIDY));
997 InputReg = InputReg ? MIRBuilder.
buildOr(I32, InputReg,
Y).
getReg(0) :
Y;
1001 NeedWorkItemIDZ && ST.getMaxWorkitemID(MF.
getFunction(), 2) != 0) {
1003 LI->buildLoadInputValue(Z, MIRBuilder, IncomingArgZ,
1004 std::get<1>(WorkitemIDZ), std::get<2>(WorkitemIDZ));
1008 InputReg = InputReg ? MIRBuilder.
buildOr(I32, InputReg, Z).
getReg(0) : Z;
1012 (NeedWorkItemIDX || NeedWorkItemIDY || NeedWorkItemIDZ)) {
1014 if (!IncomingArgX && !IncomingArgY && !IncomingArgZ) {
1024 IncomingArgX ? *IncomingArgX :
1025 IncomingArgY ? *IncomingArgY : *IncomingArgZ, ~0u);
1026 LI->buildLoadInputValue(InputReg, MIRBuilder, &IncomingArg,
1027 &AMDGPU::VGPR_32RegClass, I32);
1033 ArgRegs.emplace_back(OutgoingArg->
getRegister(), InputReg);
1038 LLVM_DEBUG(
dbgs() <<
"Unhandled stack passed implicit input argument\n");
1047static std::pair<CCAssignFn *, CCAssignFn *>
1053 bool IsTailCall,
bool IsWave32,
1055 bool IsDynamicVGPRChainCall =
false) {
1058 "Indirect calls can't be tail calls, "
1059 "because the address can be divergent");
1061 return AMDGPU::G_SI_CALL;
1064 if (IsDynamicVGPRChainCall)
1065 return IsWave32 ? AMDGPU::SI_CS_CHAIN_TC_W32_DVGPR
1066 : AMDGPU::SI_CS_CHAIN_TC_W64_DVGPR;
1067 return IsWave32 ? AMDGPU::SI_CS_CHAIN_TC_W32 : AMDGPU::SI_CS_CHAIN_TC_W64;
1072 return AMDGPU::SI_TCRETURN_GFX_WholeWave;
1075 return AMDGPU::SI_TCRETURN_GFX;
1077 return AMDGPU::SI_TCRETURN;
1084 bool IsDynamicVGPRChainCall =
false) {
1085 if (Info.Callee.isReg()) {
1086 CallInst.addReg(Info.Callee.getReg());
1088 }
else if (Info.Callee.isGlobal() && Info.Callee.getOffset() == 0) {
1096 if (IsDynamicVGPRChainCall) {
1115 if (CalleeCC == CallerCC)
1121 const auto *
TRI = ST.getRegisterInfo();
1123 const uint32_t *CallerPreserved =
TRI->getCallPreservedMask(MF, CallerCC);
1124 const uint32_t *CalleePreserved =
TRI->getCallPreservedMask(MF, CalleeCC);
1125 if (!
TRI->regmaskSubsetEqual(CallerPreserved, CalleePreserved))
1132 std::tie(CalleeAssignFnFixed, CalleeAssignFnVarArg) =
1137 std::tie(CallerAssignFnFixed, CallerAssignFnVarArg) =
1143 CalleeAssignFnVarArg);
1145 CallerAssignFnVarArg);
1153 if (OutArgs.
empty())
1178 LLVM_DEBUG(
dbgs() <<
"... Cannot fit call operands on caller's stack.\n");
1185 const uint32_t *CallerPreservedMask =
TRI->getCallPreservedMask(MF, CallerCC);
1194 if (!Info.IsTailCall)
1199 if (Info.Callee.isReg())
1208 const uint32_t *CallerPreserved =
TRI->getCallPreservedMask(MF, CallerCC);
1211 if (!CallerPreserved)
1215 LLVM_DEBUG(
dbgs() <<
"... Calling convention cannot be tail called.\n");
1220 return A.hasByValAttr() || A.hasSwiftErrorAttr();
1222 LLVM_DEBUG(
dbgs() <<
"... Cannot tail call from callers with byval "
1223 "or swifterror arguments\n");
1238 <<
"... Caller and callee have incompatible calling conventions.\n");
1248 LLVM_DEBUG(
dbgs() <<
"... Call is eligible for tail call optimization.\n");
1259 ArrayRef<std::pair<MCRegister, Register>> ImplicitArgRegs)
const {
1260 if (!ST.hasFlatScratchEnabled()) {
1267 ? AMDGPU::SGPR48_SGPR49_SGPR50_SGPR51
1268 : AMDGPU::SGPR0_SGPR1_SGPR2_SGPR3;
1270 MIRBuilder.
buildCopy(CalleeRSrcReg, ScratchRSrcReg);
1274 for (std::pair<MCRegister, Register> ArgReg : ImplicitArgRegs) {
1283enum ChainCallArgIdx {
1315 CallSeqStart = MIRBuilder.
buildInstr(AMDGPU::ADJCALLSTACKUP);
1318 bool IsDynamicVGPRChainCall =
false;
1321 ArgInfo FlagsArg = Info.OrigArgs[ChainCallArgIdx::Flags];
1323 if (FlagsValue.
isZero()) {
1324 if (Info.OrigArgs.size() != 5) {
1325 LLVM_DEBUG(
dbgs() <<
"No additional args allowed if flags == 0\n");
1329 IsDynamicVGPRChainCall =
true;
1331 if (Info.OrigArgs.size() != 8) {
1337 if (!ST.isWave32()) {
1339 F,
"dynamic VGPR mode is only supported for wave32"));
1343 ArgInfo FallbackExecArg = Info.OrigArgs[ChainCallArgIdx::FallbackExec];
1345 "Expected single register for fallback EXEC");
1346 if (!FallbackExecArg.
Ty->
isIntegerTy(ST.getWavefrontSize())) {
1354 ST.isWave32(), CalleeCC, IsDynamicVGPRChainCall);
1357 if (FuncInfo->isWholeWaveFunction())
1358 addOriginalExecToReturn(MF, MIB);
1361 unsigned CalleeIdx = MIB->getNumOperands();
1373 auto AddRegOrImm = [&](
const ArgInfo &Arg) {
1375 MIB.addImm(CI->getSExtValue());
1377 MIB.addReg(Arg.Regs[0]);
1378 unsigned Idx = MIB->getNumOperands() - 1;
1380 MF, *
TRI, MRI, *
TII, *ST.getRegBankInfo(), *MIB, MIB->getDesc(),
1381 MIB->getOperand(Idx), Idx));
1385 ArgInfo ExecArg = Info.OrigArgs[ChainCallArgIdx::Exec];
1386 assert(ExecArg.
Regs.size() == 1 &&
"Too many regs for EXEC");
1393 AddRegOrImm(ExecArg);
1394 if (IsDynamicVGPRChainCall)
1395 std::for_each(Info.OrigArgs.begin() + ChainCallArgIdx::NumVGPRs,
1396 Info.OrigArgs.end(), AddRegOrImm);
1400 const uint32_t *Mask =
TRI->getCallPreservedMask(MF, CalleeCC);
1401 MIB.addRegMask(Mask);
1413 unsigned NumBytes = 0;
1418 unsigned NumReusableBytes = FuncInfo->getBytesInStackArgArea();
1420 CCState OutInfo(CalleeCC,
false, MF, OutLocs,
F.getContext());
1434 FPDiff = NumReusableBytes - NumBytes;
1442 "unaligned stack on tail call");
1446 CCState CCInfo(Info.CallConv, Info.IsVarArg, MF, ArgLocs,
F.getContext());
1463 if (!ST.hasFlatScratchEnabled())
1464 CCInfo.
AllocateReg(FuncInfo->getScratchRSrcReg());
1472 AMDGPUOutgoingArgHandler Handler(MIRBuilder, MRI, MIB,
true, FPDiff);
1476 if (Info.ConvergenceCtrlToken) {
1485 MIB->getOperand(CalleeIdx + 1).setImm(FPDiff);
1499 if (MIB->getOpcode() == AMDGPU::SI_TCRETURN_GFX_WholeWave) {
1500 MIB->getOperand(0).setReg(
1502 *MIB, MIB->getDesc(), MIB->getOperand(0), 0));
1511 if (MIB->getOperand(CalleeIdx).isReg()) {
1513 MF, *
TRI, MRI, *
TII, *ST.getRegBankInfo(), *MIB, MIB->getDesc(),
1514 MIB->getOperand(CalleeIdx), CalleeIdx));
1518 Info.LoweredTailCall =
true;
1525 ArgInfo Callee = Info.OrigArgs[0];
1526 ArgInfo SGPRArgs = Info.OrigArgs[2];
1527 ArgInfo VGPRArgs = Info.OrigArgs[3];
1535 const Value *CalleeV = Callee.OrigValue->stripPointerCasts();
1538 Info.CallConv =
F->getCallingConv();
1540 assert(Callee.Regs.size() == 1 &&
"Too many regs for the callee");
1541 Register CalleeReg = Callee.Regs[0];
1544 MIRBuilder.
buildIntrinsic(Intrinsic::amdgcn_readfirstlane, {CalleeTy})
1553 Info.IsVarArg =
false;
1557 "SGPR arguments should be marked inreg");
1560 "VGPR arguments should not be marked inreg");
1566 Info.IsMustTailCall =
true;
1572 if (
Function *
F = Info.CB->getCalledFunction())
1573 if (
F->isIntrinsic()) {
1574 switch (
F->getIntrinsicID()) {
1575 case Intrinsic::amdgcn_cs_chain:
1577 case Intrinsic::amdgcn_call_whole_wave:
1584 Info.OrigArgs.erase(Info.OrigArgs.begin());
1585 Info.IsVarArg =
false;
1592 if (Info.IsVarArg) {
1607 for (
auto &OrigArg : Info.OrigArgs)
1611 if (Info.CanLowerReturn && !Info.OrigRet.Ty->isVoidTy())
1615 bool CanTailCallOpt =
1619 if (Info.IsMustTailCall && !CanTailCallOpt) {
1620 LLVM_DEBUG(
dbgs() <<
"Failed to lower musttail call as tail call\n");
1624 Info.IsTailCall = CanTailCallOpt;
1631 std::tie(AssignFnFixed, AssignFnVarArg) =
1634 MIRBuilder.
buildInstr(AMDGPU::ADJCALLSTACKUP)
1640 unsigned Opc =
getCallOpcode(MF, Info.Callee.isReg(),
false, ST.isWave32(),
1644 MIB.
addDef(
TRI->getReturnAddressReg(MF));
1646 if (!Info.IsConvergent)
1653 const uint32_t *Mask =
TRI->getCallPreservedMask(MF, Info.CallConv);
1654 MIB.addRegMask(Mask);
1657 CCState CCInfo(Info.CallConv, Info.IsVarArg, MF, ArgLocs,
F.getContext());
1673 if (!ST.hasFlatScratchEnabled()) {
1683 AMDGPUOutgoingArgHandler Handler(MIRBuilder, MRI, MIB,
false);
1689 if (Info.ConvergenceCtrlToken) {
1704 if (MIB->getOperand(1).isReg()) {
1706 MF, *
TRI, MRI, *ST.getInstrInfo(),
1707 *ST.getRegBankInfo(), *MIB, MIB->getDesc(), MIB->getOperand(1),
1717 if (Info.CanLowerReturn && !Info.OrigRet.Ty->isVoidTy()) {
1718 CCAssignFn *RetAssignFn = TLI.CCAssignFnForReturn(Info.CallConv,
1721 CallReturnHandler Handler(MIRBuilder, MRI, MIB);
1723 Info.CallConv, Info.IsVarArg))
1727 uint64_t CalleePopBytes = NumBytes;
1729 MIRBuilder.
buildInstr(AMDGPU::ADJCALLSTACKDOWN)
1733 if (!Info.CanLowerReturn) {
1735 Info.DemoteRegister, Info.DemoteStackIndex);
1741void AMDGPUCallLowering::addOriginalExecToReturn(
1746 Ret.
addReg(Setup->getOperand(0).getReg());
static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect, bool IsTailCall, std::optional< CallLowering::PtrAuthInfo > &PAI, MachineRegisterInfo &MRI)
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.
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static ISD::NodeType extOpcodeToISDExtOpcode(unsigned MIOpc)
static void allocateHSAUserSGPRs(CCState &CCInfo, MachineIRBuilder &B, MachineFunction &MF, const SIRegisterInfo &TRI, SIMachineFunctionInfo &Info)
static bool addCallTargetOperands(MachineInstrBuilder &CallInst, MachineIRBuilder &MIRBuilder, AMDGPUCallLowering::CallLoweringInfo &Info, bool IsDynamicVGPRChainCall=false)
This file describes how to lower LLVM calls to machine code calls.
This file declares the targeting of the Machinelegalizer class for AMDGPU.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const HexagonInstrInfo * TII
This file declares the MachineIRBuilder class.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static constexpr MCPhysReg SPReg
Interface definition for SIRegisterInfo.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
AMDGPUCallLowering(const TargetLowering &TLI)
bool lowerTailCall(MachineIRBuilder &MIRBuilder, CallLoweringInfo &Info, SmallVectorImpl< ArgInfo > &OutArgs) const
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.
bool lowerFormalArgumentsKernel(MachineIRBuilder &B, const Function &F, ArrayRef< ArrayRef< Register > > VRegs) const
bool lowerReturn(MachineIRBuilder &B, const Value *Val, ArrayRef< Register > VRegs, FunctionLoweringInfo &FLI) const override
This hook behaves as the extended lowerReturn function, but for targets that do not support swifterro...
void handleImplicitCallArguments(MachineIRBuilder &MIRBuilder, MachineInstrBuilder &CallInst, const GCNSubtarget &ST, const SIMachineFunctionInfo &MFI, CallingConv::ID CalleeCC, ArrayRef< std::pair< MCRegister, Register > > ImplicitArgRegs) const
bool areCalleeOutgoingArgsTailCallable(CallLoweringInfo &Info, MachineFunction &MF, SmallVectorImpl< ArgInfo > &OutArgs) const
bool lowerChainCall(MachineIRBuilder &MIRBuilder, CallLoweringInfo &Info) const
Lower a call to the @llvm.amdgcn.cs.chain intrinsic.
bool passSpecialInputs(MachineIRBuilder &MIRBuilder, CCState &CCInfo, SmallVectorImpl< std::pair< MCRegister, Register > > &ArgRegs, CallLoweringInfo &Info) const
bool lowerFormalArguments(MachineIRBuilder &B, 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,...
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 doCallerAndCalleePassArgsTheSameWay(CallLoweringInfo &Info, MachineFunction &MF, SmallVectorImpl< ArgInfo > &InArgs) const
static std::optional< uint32_t > getLDSKernelIdMetadata(const Function &F)
unsigned getExplicitKernelArgOffset() const
Returns the offset in bytes from the start of the input buffer of the first explicit kernel argument.
static CCAssignFn * CCAssignFnForCall(CallingConv::ID CC, bool IsVarArg)
Selects the correct CCAssignFn for a given CallingConvention value.
Class for arbitrary precision integers.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
bool isOneBitSet(unsigned BitNo) const
Determine if this APInt Value only has the specified bit set.
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.
unsigned getFirstUnallocated(ArrayRef< MCPhysReg > Regs) const
getFirstUnallocated - Return the index of the first unallocated register in the set,...
MCRegister AllocateReg(MCPhysReg Reg)
AllocateReg - Attempt to allocate one register.
uint64_t getStackSize() const
Returns the size of the currently allocated portion of the stack.
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)
int64_t getLocMemOffset() const
This class represents a function call, abstracting a target machine's calling convention.
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
A parsed version of the target data layout string in and methods for querying it.
Diagnostic information for unsupported feature in backend.
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.
const SIRegisterInfo * getRegisterInfo() const override
bool hasKernargSegmentPtr() const
bool hasDispatchID() const
bool hasPrivateSegmentBuffer() const
bool hasImplicitBufferPtr() const
bool hasPrivateSegmentSize() const
bool hasDispatchPtr() const
bool hasFlatScratchInit() const
unsigned getAddressSpace() const
constexpr unsigned getScalarSizeInBits() const
static constexpr LLT vector(ElementCount EC, unsigned ScalarSizeInBits)
Get a low-level vector of some number of elements and element width.
constexpr bool isInteger() const
constexpr bool isVector() const
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
constexpr ElementCount getElementCount() const
static constexpr LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
static LLT integer(unsigned SizeInBits)
static constexpr LLT float32()
Get a 32-bit IEEE float value.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
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.
void setHasTailCall(bool V=true)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Helper class to build MachineInstr.
MachineInstrBuilder insertInstr(MachineInstrBuilder MIB)
Insert an existing instruction at the insertion point.
MachineInstrBuilder buildGlobalValue(const DstOp &Res, const GlobalValue *GV)
Build and insert Res = G_GLOBAL_VALUE GV.
MachineInstrBuilder buildUndef(const DstOp &Res)
Build and insert Res = IMPLICIT_DEF.
MachineInstrBuilder buildIntrinsic(Intrinsic::ID ID, ArrayRef< Register > Res, bool HasSideEffects, bool isConvergent)
Build and insert a G_INTRINSIC instruction.
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 buildShl(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
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 buildFrameIndex(const DstOp &Res, int Idx)
Build and insert Res = G_FRAME_INDEX Idx.
MachineFunction & getMF()
Getter for the function we currently build.
MachineInstrBuilder buildAnyExt(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_ANYEXT Op0.
MachineRegisterInfo * getMRI()
Getter for MRI.
MachineInstrBuilder buildOr(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_OR Op0, Op1.
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 & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
static MachineOperand CreateGA(const GlobalValue *GV, int64_t Offset, unsigned TargetFlags=0)
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,...
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 TargetRegisterInfo * getTargetRegisterInfo() const
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
Wrapper class representing virtual and physical registers.
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
bool isWholeWaveFunction() const
Register getStackPtrOffsetReg() const
Register getScratchRSrcReg() const
Returns the physical register reserved for use as the resource descriptor for scratch accesses.
unsigned getBytesInStackArgArea() const
void setIfReturnsVoid(bool Value)
MCRegister getPreloadedReg(AMDGPUFunctionArgInfo::PreloadedValue Value) const
AMDGPUFunctionArgInfo & getArgInfo()
MachinePointerInfo getKernargSegmentPtrInfo(MachineFunction &MF) const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Represent a constant reference to a string, i.e.
constexpr bool empty() const
Check if the string is empty.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
unsigned GuaranteedTailCallOpt
GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is specified on the commandline.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isIntegerTy() const
True if this is an instance of IntegerType.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ CONSTANT_ADDRESS
Address space for constant memory (VTX2).
@ PRIVATE_ADDRESS
Address space for private memory.
LLVM_READNONE constexpr bool isShader(CallingConv::ID CC)
LLVM_READNONE constexpr bool mayTailCallThisCC(CallingConv::ID CC)
Return true if we might ever do TCO for calls with this calling convention.
LLVM_READNONE constexpr bool isKernel(CallingConv::ID CC)
LLVM_READNONE constexpr bool isEntryFunctionCC(CallingConv::ID CC)
LLVM_READNONE constexpr bool isChainCC(CallingConv::ID CC)
LLVM_READNONE constexpr bool canGuaranteeTCO(CallingConv::ID CC)
LLVM_READNONE constexpr bool isGraphics(CallingConv::ID CC)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ AMDGPU_KERNEL
Used for AMDGPU code object kernels.
@ AMDGPU_Gfx
Used for AMD graphics targets.
@ AMDGPU_CS_Chain
Used on AMDGPUs to give the middle-end more control over argument placement.
@ AMDGPU_PS
Used for Mesa/AMDPAL pixel shaders.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ SIGN_EXTEND
Conversion operators.
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
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...
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
@ 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.
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
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.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
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...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
LLVM_ABI LLT getLLTForType(Type &Ty, const DataLayout &DL)
Construct a low-level type based on an LLVM type.
MCRegisterClass TargetRegisterClass
LLVM_ABI Align inferAlignFromPtrInfo(MachineFunction &MF, const MachinePointerInfo &MPO)
ArgDescriptor WorkItemIDZ
ArgDescriptor WorkItemIDY
std::tuple< const ArgDescriptor *, const TargetRegisterClass *, LLT > getPreloadedValue(PreloadedValue Value) const
ArgDescriptor WorkItemIDX
static const AMDGPUFunctionArgInfo FixedABIFunctionInfo
This struct is a compact representation of a valid (non-zero power of two) alignment.
MCRegister getRegister() const
static ArgDescriptor createArg(const ArgDescriptor &Arg, unsigned Mask)
Helper struct shared between Function Specialization and SCCP Solver.
const Value * OrigValue
Optionally track the original IR value for the argument.
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...
Base class for ValueHandlers used for arguments passed to a function call, or for return values.
uint64_t StackSize
The size of the currently allocated portion of the stack.
MachineIRBuilder & MIRBuilder
Register extendRegister(Register ValReg, const CCValAssign &VA, unsigned MaxSizeBits=0)
Extend a register to the location type given in VA, capped at extending to at most MaxSize bits.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
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.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.