28#define DEBUG_TYPE "call-lowering"
32void CallLowering::anchor() {}
36 if (!Attrs.hasAttributes())
41 if (Attr.isStringAttribute())
44 switch (Attr.getKindAsEnum()) {
51 case Attribute::InReg:
54 case Attribute::StructRet:
60 case Attribute::ByVal:
63 case Attribute::ByRef:
66 case Attribute::InAlloca:
75 case Attribute::Preallocated:
76 Flags.setPreallocated();
84 case Attribute::Returned:
87 case Attribute::SwiftSelf:
90 case Attribute::SwiftAsync:
91 Flags.setSwiftAsync();
93 case Attribute::SwiftError:
94 Flags.setSwiftError();
104 unsigned OpIdx)
const {
112 std::optional<PtrAuthInfo> PAI,
114 std::function<
Register()> GetCalleeReg)
const {
122 .getFnAttribute(
"disable-tail-calls")
123 .getValueAsString() !=
"true");
131 Info.CanLowerReturn =
true;
135 Info.CanLowerReturn =
canLowerReturn(MF, CallConv, SplitArgs, IsVarArg);
140 if (!Info.CanLowerReturn) {
146 CanBeTailCalled =
false;
154 for (
const auto &Arg : CB.
args()) {
157 if (Callee && Callee->hasParamAttribute(i, Attribute::Returned))
159 ArgInfo OrigArg{ArgRegs[i], *Arg.get(), i, Flags};
160 setArgFlags(OrigArg, i + AttributeList::FirstArgIndex,
DL, CB);
161 if (i >= NumFixedArgs)
162 OrigArg.
Flags[0].setVarArg();
167 CanBeTailCalled =
false;
169 Info.OrigArgs.push_back(OrigArg);
185 if (
F->hasFnAttribute(Attribute::NonLazyBind)) {
201 Align ReturnHintAlign;
204 Info.OrigRet =
ArgInfo{ResRegs, RetTy, 0, RetFlags};
206 if (!Info.OrigRet.Ty->isVoidTy()) {
207 setArgFlags(Info.OrigRet, AttributeList::ReturnIndex,
DL, CB);
210 if (*Alignment >
Align(1)) {
212 Info.OrigRet.Regs[0] = ReturnHintAlignReg;
213 ReturnHintAlign = *Alignment;
221 assert(Info.CFIType->getType()->isIntegerTy(32) &&
"Invalid CFI type");
229 Info.KnownCallees = CB.
getMetadata(LLVMContext::MD_callees);
230 Info.CallConv = CallConv;
231 Info.SwiftErrorVReg = SwiftErrorVReg;
233 Info.ConvergenceCtrlToken = ConvergenceCtrlToken;
235 Info.IsTailCall = CanBeTailCalled;
236 Info.IsVarArg = IsVarArg;
240 if (ReturnHintAlignReg && !Info.LoweredTailCall) {
248template <
typename FuncInfoTy>
251 const FuncInfoTy &FuncInfo)
const {
252 auto &Flags = Arg.
Flags[0];
262 Align MemAlign =
DL.getABITypeAlign(Arg.
Ty);
263 if (Flags.isByVal() || Flags.isInAlloca() || Flags.isPreallocated() ||
265 assert(OpIdx >= AttributeList::FirstArgIndex);
266 unsigned ParamIdx = OpIdx - AttributeList::FirstArgIndex;
268 Type *ElementTy = FuncInfo.getParamByValType(ParamIdx);
270 ElementTy = FuncInfo.getParamByRefType(ParamIdx);
272 ElementTy = FuncInfo.getParamInAllocaType(ParamIdx);
274 ElementTy = FuncInfo.getParamPreallocatedType(ParamIdx);
276 assert(ElementTy &&
"Must have byval, inalloca or preallocated type");
278 uint64_t MemSize =
DL.getTypeAllocSize(ElementTy);
280 Flags.setByRefSize(MemSize);
282 Flags.setByValSize(MemSize);
286 if (
auto ParamAlign = FuncInfo.getParamStackAlign(ParamIdx))
287 MemAlign = *ParamAlign;
288 else if ((ParamAlign = FuncInfo.getParamAlign(ParamIdx)))
289 MemAlign = *ParamAlign;
292 }
else if (OpIdx >= AttributeList::FirstArgIndex) {
293 if (
auto ParamAlign =
294 FuncInfo.getParamStackAlign(OpIdx - AttributeList::FirstArgIndex))
295 MemAlign = *ParamAlign;
297 Flags.setMemAlign(MemAlign);
298 Flags.setOrigAlign(
DL.getABITypeAlign(Arg.
Ty));
302 if (Flags.isSwiftSelf())
303 Flags.setReturned(
false);
324 if (SplitTys.
size() == 0)
327 if (SplitTys.
size() == 1) {
336 assert(OrigArg.
Regs.size() == SplitTys.
size() &&
"Regs / types mismatch");
338 bool NeedsRegBlock = TLI->functionArgumentNeedsConsecutiveRegisters(
339 OrigArg.
Ty, CallConv,
false,
DL);
340 for (
unsigned i = 0, e = SplitTys.
size(); i < e; ++i) {
344 SplitArgs.
back().Flags[0].setInConsecutiveRegs();
347 SplitArgs.
back().Flags[0].setInConsecutiveRegsLast();
368 for (
size_t I = 0,
E = SrcRegs.
size();
I !=
E; ++
I) {
371 ConcatRegs[
I] =
B.buildBitcast(BitcastDst, SrcRegs[
I]).getReg(0);
374 return B.buildConcatVectors(DstRegs[0], ConcatRegs);
382 return B.buildDeleteTrailingVectorElements(
383 DstRegs[0],
B.buildMergeLikeInstr(LCMTy, SrcRegs));
388 UnmergeSrcReg = SrcRegs[0];
397 for (
size_t I = DstRegs.
size();
I != NumDst; ++
I)
400 if (PartLLT != LCMTy)
401 UnmergeSrcReg =
B.buildBitcast(LCMTy, UnmergeSrcReg).getReg(0);
403 if (PadDstRegs.
size() == 1)
404 return B.buildDeleteTrailingVectorElements(DstRegs[0], UnmergeSrcReg);
405 return B.buildUnmerge(PadDstRegs, UnmergeSrcReg);
414 if (PartLLT == LLTy) {
417 assert(OrigRegs[0] == Regs[0]);
423 B.buildBitcast(OrigRegs[0], Regs[0]);
433 OrigRegs.
size() == 1 && Regs.
size() == 1) {
438 if (Flags.isSExt()) {
441 }
else if (Flags.isZExt()) {
450 B.buildIntToPtr(OrigRegs[0],
B.buildTrunc(
IntPtrTy, SrcReg));
454 B.buildTrunc(OrigRegs[0], SrcReg);
464 B.buildMergeValues(OrigRegs[0], Regs);
466 auto Widened =
B.buildMergeLikeInstr(
LLT::integer(SrcSize), Regs);
467 B.buildTrunc(OrigRegs[0], Widened);
486 CastRegs[0] =
B.buildBitcast(NewTy, Regs[0]).getReg(0);
500 CastRegs[
I++] =
B.buildBitcast(GCDTy, SrcReg).getReg(0);
517 if (DstEltTy == PartLLT) {
522 MRI.
setType(Reg, RealDstEltTy);
525 B.buildBuildVector(OrigRegs[0], Regs);
536 B.buildMergeLikeInstr(ExtendedPartTy, Regs.
take_front(PartsPerElt));
545 B.buildBuildVector(OrigRegs[0], EltMerges);
553 if (NumElts == Regs.
size())
554 BuildVec =
B.buildBuildVector(BVType, Regs).getReg(0);
572 auto Unmerge =
B.buildUnmerge(OriginalEltTy, R);
573 for (
unsigned K = 0;
K < EltPerReg; ++
K)
574 BVRegs.
push_back(
B.buildAnyExt(PartLLT, Unmerge.getReg(
K)).getReg(0));
579 if (BVRegs.
size() > NumElts) {
580 assert((BVRegs.
size() - NumElts) < EltPerReg);
583 BuildVec =
B.buildBuildVector(BVType, BVRegs).getReg(0);
585 B.buildTrunc(OrigRegs[0], BuildVec);
591 LLT SrcTy,
LLT PartTy,
unsigned ExtendOp) {
593 assert(SrcTy != PartTy &&
"identical part types shouldn't reach here");
597 if (PartSize == SrcTy.getSizeInBits() && DstRegs.
size() == 1) {
600 B.buildBitcast(DstRegs[0], SrcReg);
604 if (PartTy.
isVector() == SrcTy.isVector() &&
607 B.buildInstr(ExtendOp, {DstRegs[0]}, {SrcReg});
611 if (SrcTy.isVector() && !PartTy.
isVector() &&
615 auto UnmergeToEltTy =
B.buildUnmerge(SrcTy.getElementType(), SrcReg);
616 for (
int i = 0, e = DstRegs.
size(); i != e; ++i)
617 B.buildAnyExt(DstRegs[i], UnmergeToEltTy.getReg(i));
621 if (SrcTy.isVector() && PartTy.
isVector() &&
627 B.buildPadVectorWithUndefElements(DstReg, SrcReg);
632 if (GCDTy == PartTy) {
634 B.buildUnmerge(DstRegs, SrcReg);
638 if (SrcTy.isVector() && !PartTy.
isVector() &&
643 SrcTy.getNumElements()));
644 auto Ext =
B.buildAnyExt(ExtTy, SrcReg);
645 B.buildUnmerge(DstRegs, Ext);
652 if (SrcTy.isVector() && DstRegs.
size() > 1) {
664 if (PartTy.
isVector() && CoverTy == PartTy) {
666 B.buildPadVectorWithUndefElements(DstRegs[0], SrcReg);
671 const unsigned SrcSize = SrcTy.getSizeInBits();
676 if (!CoverTy.
isVector() && CoveringSize != SrcSize) {
678 if (SrcTy.isScalar() && DstTy.
isScalar()) {
679 CoveringSize =
alignTo(SrcSize, DstSize);
681 UnmergeSrc =
B.buildInstr(ExtendOp, {CoverTy}, {SrcReg}).
getReg(0);
687 for (
unsigned Size = SrcSize;
Size != CoveringSize;
Size += SrcSize)
689 UnmergeSrc =
B.buildMergeLikeInstr(CoverTy, MergeParts).getReg(0);
693 if (CoverTy.
isVector() && CoveringSize != SrcSize)
694 UnmergeSrc =
B.buildPadVectorWithUndefElements(CoverTy, SrcReg).getReg(0);
696 B.buildUnmerge(DstRegs, UnmergeSrc);
708 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs,
F.getContext());
718 return TargetOpcode::G_SEXT;
720 return TargetOpcode::G_ZEXT;
721 return TargetOpcode::G_ANYEXT;
731 unsigned NumArgs = Args.size();
732 for (
unsigned i = 0; i != NumArgs; ++i) {
733 EVT CurVT = TLI->getValueType(
DL, Args[i].Ty);
735 MVT NewVT = TLI->getRegisterTypeForCallingConv(Ctx, CallConv, CurVT);
740 TLI->getNumRegistersForCallingConv(Ctx, CallConv, CurVT);
745 Args[i].Flags[0], CCInfo))
762 Args[i].Flags.clear();
764 for (
unsigned Part = 0; Part < NumParts; ++Part) {
769 Flags.setOrigAlign(
Align(1));
770 if (Part == NumParts - 1)
774 Args[i].Flags.push_back(Flags);
776 Args[i].Flags[Part], CCInfo)) {
797 const unsigned NumArgs = Args.size();
811 SmallVector<std::function<void()>> DelayedOutgoingRegAssignments;
813 for (
unsigned i = 0, j = 0; i != NumArgs; ++i, ++j) {
814 assert(j < ArgLocs.
size() &&
"Skipped too many arg locs");
816 assert(VA.
getValNo() == i &&
"Location doesn't correspond to current arg");
819 std::function<void()> Thunk;
821 Args[i],
ArrayRef(ArgLocs).slice(j), &Thunk);
823 DelayedOutgoingRegAssignments.emplace_back(Thunk);
826 j += (NumArgRegs - 1);
838 const EVT OrigVT = TLI->getValueType(
DL, Args[i].Ty);
842 AllocaAddressSpace,
DL.getPointerSizeInBits(AllocaAddressSpace));
847 const unsigned NumParts = Args[i].Flags.size();
850 Args[i].OrigRegs.assign(Args[i].Regs.begin(), Args[i].Regs.end());
852 if (NumParts != 1 || NewLLT != OrigTy) {
855 Args[i].Regs.resize(NumParts);
866 for (
unsigned Part = 0; Part < NumParts; ++Part)
871 assert((j + (NumParts - 1)) < ArgLocs.
size() &&
872 "Too many regs for number of args");
877 assert(Args[i].OrigRegs.size() == 1);
882 bool IndirectParameterPassingHandled =
false;
883 bool BigEndianPartOrdering = TLI->hasBigEndianPartOrdering(OrigVT,
DL);
884 for (
unsigned Part = 0; Part < NumParts; ++Part) {
886 "Only the first parameter should be processed when "
887 "handling indirect passing!");
888 Register ArgReg = Args[i].Regs[Part];
890 unsigned Idx = BigEndianPartOrdering ? NumParts - 1 - Part : Part;
908 Align AlignmentForStored =
DL.getPrefTypeAlign(Args[i].Ty);
913 AlignmentForStored,
false);
919 MIRBuilder.
buildStore(Args[i].OrigRegs[Part], PointerToStackReg,
923 ArgReg = PointerToStackReg;
924 IndirectParameterPassingHandled =
true;
927 if (VA.
isMemLoc() && !Flags.isByVal()) {
951 }
else if (VA.
isMemLoc() && Flags.isByVal()) {
952 assert(Args[i].Regs.size() == 1 &&
"didn't expect split byval pointer");
959 MIRBuilder.
buildCopy(Args[i].Regs[0], StackAddr);
964 uint64_t MemSize = Flags.getByValSize();
972 if (!Args[i].OrigValue) {
979 Align DstAlign = std::max(Flags.getNonZeroByValAlign(),
982 Align SrcAlign = std::max(Flags.getNonZeroByValAlign(),
986 DstMPO, DstAlign, SrcMPO, SrcAlign,
989 }
else if (i == 0 && !ThisReturnRegs.
empty() &&
996 DelayedOutgoingRegAssignments.emplace_back([=, &Handler]() {
1006 Align Alignment =
DL.getABITypeAlign(Args[i].Ty);
1013 MIRBuilder.
buildLoad(Args[i].OrigRegs[0], Args[i].Regs[0], MPO,
1016 IndirectParameterPassingHandled =
true;
1019 if (IndirectParameterPassingHandled)
1027 !IndirectParameterPassingHandled) {
1031 LocTy, Args[i].Flags[0]);
1036 for (
auto &Fn : DelayedOutgoingRegAssignments)
1055 unsigned NumValues = SplitVTs.
size();
1056 Align BaseAlign =
DL.getPrefTypeAlign(RetTy);
1063 for (
unsigned I = 0;
I < NumValues; ++
I) {
1087 unsigned NumValues = SplitVTs.
size();
1088 Align BaseAlign =
DL.getPrefTypeAlign(RetTy);
1089 unsigned AS =
DL.getAllocaAddrSpace();
1094 for (
unsigned I = 0;
I < NumValues; ++
I) {
1108 unsigned AS =
DL.getAllocaAddrSpace();
1123 DemoteArg.
Flags[0].setSRet();
1132 unsigned AS =
DL.getAllocaAddrSpace();
1136 DL.getTypeAllocSize(RetTy),
DL.getPrefTypeAlign(RetTy),
false);
1142 DemoteArg.
Flags[0].setSRet();
1144 Info.OrigArgs.insert(Info.OrigArgs.begin(), DemoteArg);
1145 Info.DemoteStackIndex = FI;
1146 Info.DemoteRegister = DemoteReg;
1152 for (
unsigned I = 0, E = Outs.
size();
I < E; ++
I) {
1171 for (
EVT VT : SplitVTs) {
1173 TLI->getNumRegistersForCallingConv(Context, CallConv, VT);
1174 MVT RegVT = TLI->getRegisterTypeForCallingConv(Context, CallConv, VT);
1177 for (
unsigned I = 0;
I < NumParts; ++
I) {
1185 Type *ReturnType =
F.getReturnType();
1189 getReturnInfo(CallConv, ReturnType,
F.getAttributes(), SplitArgs,
1198 for (
unsigned i = 0; i < OutLocs.
size(); ++i) {
1199 const auto &ArgLoc = OutLocs[i];
1201 if (!ArgLoc.isRegLoc())
1212 <<
"... Call has an argument passed in a callee-saved register.\n");
1215 const ArgInfo &OutInfo = OutArgs[i];
1217 if (OutInfo.
Regs.size() > 1) {
1219 dbgs() <<
"... Cannot handle arguments in multiple registers.\n");
1227 if (!RegDef || RegDef->
getOpcode() != TargetOpcode::COPY) {
1230 <<
"... Parameter was not copied into a VReg, cannot tail call.\n");
1236 if (CopyRHS != PhysReg) {
1237 LLVM_DEBUG(
dbgs() <<
"... Callee-saved register was not copied into "
1238 "VReg, cannot tail call.\n");
1255 if (CallerCC == CalleeCC)
1259 CCState CCInfo1(CalleeCC, Info.IsVarArg, MF, ArgLocs1,
F.getContext());
1264 CCState CCInfo2(CallerCC,
F.isVarArg(), MF, ArgLocs2,
F.getContext());
1270 if (ArgLocs1.
size() != ArgLocs2.
size())
1274 for (
unsigned i = 0, e = ArgLocs1.
size(); i < e; ++i) {
1303 if (ValVT != MVT::iPTR) {
1308 if (Flags.isPointer()) {
1319 unsigned AddrSpace = Flags.getPointerAddrSpace();
1339 const LLT PtrTy =
MRI.getType(DstPtr);
1342 auto SizeConst =
MIRBuilder.buildConstant(SizeTy, MemSize);
1343 MIRBuilder.buildMemCpy(DstPtr, SrcPtr, SizeConst, *DstMMO, *SrcMMO);
1348 unsigned MaxSizeBits) {
1361 const LLT ValRegTy =
MRI.getType(ValReg);
1379 auto MIB =
MIRBuilder.buildAnyExt(LocTy, ValReg);
1380 return MIB.getReg(0);
1383 Register NewReg =
MRI.createGenericVirtualRegister(LocTy);
1388 Register NewReg =
MRI.createGenericVirtualRegister(LocTy);
1396void CallLowering::ValueAssigner::anchor() {}
1403 .buildAssertZExt(
MRI.cloneVirtualRegister(SrcReg), SrcReg,
1409 .buildAssertSExt(
MRI.cloneVirtualRegister(SrcReg), SrcReg,
1432 SrcTy = SrcTy.getScalarType();
1435 return (SrcTy.isPointer() && DstTy.
isScalar()) ||
1436 (DstTy.
isPointer() && SrcTy.isScalar());
1444 const LLT RegTy =
MRI.getType(ValVReg);
1451 auto Copy =
MIRBuilder.buildCopy(LocTy, PhysReg);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static void addFlagsFromAttrSet(ISD::ArgFlagsTy &Flags, AttributeSet Attrs)
Helper function which updates Flags based on the contents of Attrs.
static MachineInstrBuilder mergeVectorRegsToResultRegs(MachineIRBuilder &B, ArrayRef< Register > DstRegs, ArrayRef< Register > SrcRegs)
Pack values SrcRegs to cover the vector type result DstRegs.
static bool isCopyCompatibleType(LLT SrcTy, LLT DstTy)
Check if we can use a basic COPY instruction between the two types.
static unsigned extendOpFromFlags(llvm::ISD::ArgFlagsTy Flags)
This file describes how to lower LLVM calls to machine code calls.
Module.h This file contains the declarations for the Module class.
This file declares the MachineIRBuilder class.
Promote Memory to Register
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
This file describes how to lower LLVM code to machine code.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
ArrayRef< T > take_front(size_t N=1) const
Return a copy of *this with only the first N elements.
ArrayRef< T > drop_front(size_t N=1) const
Drop the first N elements of the array.
const T & front() const
Get the first element.
size_t size() const
Get the array size.
bool empty() const
Check if the array is empty.
This class holds the attributes for a particular argument, parameter, function, or return value.
Functions, function parameters, and return types can have attributes to indicate how they should be t...
CCState - This class holds information needed while lowering arguments and return values.
MachineFunction & getMachineFunction() const
CallingConv::ID getCallingConv() const
LLVMContext & getContext() const
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
LocInfo getLocInfo() const
int64_t getLocMemOffset() const
unsigned getValNo() const
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
MaybeAlign getRetAlign() const
Extract the alignment of the return value.
std::optional< OperandBundleUse > getOperandBundle(StringRef Name) const
Return an operand bundle by name, if present.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
CallingConv::ID getCallingConv() const
LLVM_ABI bool isMustTailCall() const
Tests if this call site must be tail call optimized.
LLVM_ABI bool isIndirectCall() const
Return true if the callsite is an indirect call.
unsigned countOperandBundlesOfType(StringRef Name) const
Return the number of operand bundles with the tag Name attached to this instruction.
Value * getCalledOperand() const
bool isConvergent() const
Determine if the invoke is convergent.
FunctionType * getFunctionType() const
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
AttributeList getAttributes() const
Return the attributes for this call.
LLVM_ABI bool isTailCall() const
Tests if this call site is marked as a tail call.
void insertSRetOutgoingArgument(MachineIRBuilder &MIRBuilder, const CallBase &CB, CallLoweringInfo &Info) const
For the call-base described by CB, insert the hidden sret ArgInfo to the OrigArgs field of Info.
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 checkReturnTypeForCallConv(MachineFunction &MF) const
Toplevel function to check the return type based on the target calling convention.
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
virtual bool canLowerReturn(MachineFunction &MF, CallingConv::ID CallConv, SmallVectorImpl< BaseArgInfo > &Outs, bool IsVarArg) const
This hook must be implemented to check whether the return values described by Outs can fit into the r...
virtual bool isTypeIsValidForThisReturn(EVT Ty) const
For targets which support the "returned" parameter attribute, returns true if the given type is a val...
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.
static void buildCopyToRegs(MachineIRBuilder &B, ArrayRef< Register > DstRegs, Register SrcReg, LLT SrcTy, LLT PartTy, unsigned ExtendOp=TargetOpcode::G_ANYEXT)
Create a sequence of instructions to expand the value in SrcReg (of type SrcTy) to the types in DstRe...
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.
static void buildCopyFromRegs(MachineIRBuilder &B, ArrayRef< Register > OrigRegs, ArrayRef< Register > Regs, LLT LLTy, LLT PartLLT, const ISD::ArgFlagsTy Flags)
Create a sequence of instructions to combine pieces split into register typed values to the original ...
void addArgFlagsFromAttributes(ISD::ArgFlagsTy &Flags, const AttributeList &Attrs, unsigned OpIdx) const
Adds flags to Flags based off of the attributes in Attrs.
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...
void getReturnInfo(CallingConv::ID CallConv, Type *RetTy, AttributeList Attrs, SmallVectorImpl< BaseArgInfo > &Outs, const DataLayout &DL) const
Get the type and the ArgFlags for the split components of RetTy as returned by ComputeValueVTs.
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
const TargetLowering * getTLI() const
Getter for generic TargetLowering class.
virtual bool lowerCall(MachineIRBuilder &MIRBuilder, CallLoweringInfo &Info) const
This hook must be implemented to lower the given call instruction, including argument and return valu...
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.
unsigned getAllocaAddrSpace() const
static constexpr ElementCount getFixed(ScalarTy MinVal)
static constexpr ElementCount get(ScalarTy MinVal, bool Scalable)
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
LLT changeElementCount(ElementCount EC) const
Return a vector or scalar with the same element type and the new element count.
constexpr unsigned getScalarSizeInBits() const
constexpr bool isScalar() const
constexpr LLT changeElementType(LLT NewEltTy) const
If this type is a vector, return a vector with the same number of elements but the new element type.
static constexpr LLT vector(ElementCount EC, unsigned ScalarSizeInBits)
Get a low-level vector of some number of elements and element width.
LLT getScalarType() const
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
constexpr uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
constexpr bool isVector() const
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
constexpr bool isPointer() const
constexpr ElementCount getElementCount() const
constexpr unsigned getAddressSpace() 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)
constexpr TypeSize getSizeInBytes() const
Returns the total size of the type in bytes, i.e.
LLT getElementType() const
Returns the vector's element type. Only valid for vector types.
This is an important class for using LLVM in a threaded context.
Wrapper class representing physical registers. Should be passed by value.
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
static LLVM_ABI MVT getVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
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.
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.
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 buildGlobalValue(const DstOp &Res, const GlobalValue *GV)
Build and insert Res = G_GLOBAL_VALUE GV.
std::optional< MachineInstrBuilder > materializeObjectPtrOffset(Register &Res, Register Op0, const LLT ValueTy, uint64_t Value)
Materialize and insert an instruction with appropriate flags for addressing some offset of an object,...
MachineInstrBuilder buildLoad(const DstOp &Res, const SrcOp &Addr, MachineMemOperand &MMO)
Build and insert Res = G_LOAD Addr, MMO.
MachineInstrBuilder buildStore(const SrcOp &Val, const SrcOp &Addr, MachineMemOperand &MMO)
Build and insert G_STORE Val, Addr, MMO.
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 buildAssertAlign(const DstOp &Res, const SrcOp &Op, Align AlignVal)
Build and insert Res = G_ASSERT_ALIGN Op, AlignVal.
MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op)
Build and insert Res = COPY Op.
const DataLayout & getDataLayout() const
Register getReg(unsigned Idx) const
Get the register for the operand index.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
A description of a memory reference used in the backend.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
Register getReg() const
getReg - Returns the register number.
static MachineOperand CreateGA(const GlobalValue *GV, int64_t Offset, unsigned TargetFlags=0)
static bool clobbersPhysReg(const uint32_t *RegMask, MCRegister PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
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 void setType(Register VReg, LLT Ty)
Set the low-level type of VReg to Ty.
LLVM_ABI Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
LLVM_ABI Register cloneVirtualRegister(Register VReg, StringRef Name="")
Create and return a new virtual register in the function with the same attributes as the given regist...
Class to represent pointers.
static LLVM_ABI PointerType * get(LLVMContext &C, unsigned AddressSpace)
This constructs an opaque pointer to an object in a numbered address space.
Wrapper class representing virtual and physical registers.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
iterator insert(iterator I, T &&Elt)
void truncate(size_type N)
Like resize, but requires that N is less than size().
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
virtual Align getByValTypeAlignment(Type *Ty, const DataLayout &DL) const
Returns the desired alignment for ByVal or InAlloca aggregate function arguments in the caller parame...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
bool isVoidTy() const
Return true if this is 'void'.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
constexpr bool isKnownMultipleOf(ScalarTy RHS) const
This function tells the caller whether the element count is known at compile time to be a multiple of...
constexpr ScalarTy getFixedValue() const
static constexpr bool isKnownLT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
static constexpr bool isKnownGT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr LeafTy divideCoefficientBy(ScalarTy RHS) const
We do not provide the '/' operator here because division for polynomial types does not work in the sa...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
@ Undef
Value of the register doesn't matter.
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.
LLVM_ABI LLT getLLTForMVT(MVT Ty)
Get a rough equivalent of an LLT for a given MVT.
LLVM_ABI MachineInstr * getDefIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI)
Find the def instruction for Reg, folding away any trivial copies.
LLVM_ABI void ComputeValueTypes(const DataLayout &DL, Type *Ty, SmallVectorImpl< Type * > &Types, SmallVectorImpl< TypeSize > *Offsets=nullptr, TypeSize StartingOffset=TypeSize::getZero())
Given an LLVM IR type, compute non-aggregate subtypes.
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.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
LLVM_ABI LLVM_READNONE LLT getCoverTy(LLT OrigTy, LLT TargetTy)
Return smallest type that covers both OrigTy and TargetTy and is multiple of TargetTy.
LLVM_ABI bool isInTailCallPosition(const CallBase &Call, const TargetMachine &TM, bool ReturnsFirstArg=false)
Test if the given instruction is in a position to be optimized with a tail-call.
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
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 LLVM_READNONE LLT getGCDType(LLT OrigTy, LLT TargetTy)
Return a type where the total size is the greatest common divisor of OrigTy and TargetTy.
LLVM_ABI LLT getLLTForType(Type &Ty, const DataLayout &DL)
Construct a low-level type based on an LLVM type.
LLVM_ABI Align inferAlignFromPtrInfo(MachineFunction &MF, const MachinePointerInfo &MPO)
This struct is a compact representation of a valid (non-zero power of two) alignment.
const Value * OrigValue
Optionally track the original IR value for the argument.
SmallVector< Register, 4 > Regs
unsigned OrigArgIndex
Index original Function's argument.
static const unsigned NoArgIndex
Sentinel value for implicit machine-level input arguments.
SmallVector< ISD::ArgFlagsTy, 4 > Flags
void assignValueToReg(Register ValVReg, Register PhysReg, const CCValAssign &VA, ISD::ArgFlagsTy Flags={}) override
Provides a default implementation for argument handling.
Register buildExtensionHint(const CCValAssign &VA, Register SrcReg, LLT NarrowTy)
Insert G_ASSERT_ZEXT/G_ASSERT_SEXT or other hint instruction based on VA, returning the new register ...
Argument handling is mostly uniform between the four places that make these decisions: function forma...
virtual bool assignArg(unsigned ValNo, EVT OrigVT, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, const ArgInfo &Info, ISD::ArgFlagsTy Flags, CCState &State)
Wrap call to (typically tablegenerated CCAssignFn).
MachineIRBuilder & MIRBuilder
void copyArgumentMemory(const ArgInfo &Arg, Register DstPtr, Register SrcPtr, const MachinePointerInfo &DstPtrInfo, Align DstAlign, const MachinePointerInfo &SrcPtrInfo, Align SrcAlign, uint64_t MemSize, CCValAssign &VA) const
Do a memory copy of MemSize bytes from SrcPtr to DstPtr.
MachineRegisterInfo & MRI
virtual Register getStackAddress(uint64_t MemSize, int64_t Offset, MachinePointerInfo &MPO, ISD::ArgFlagsTy Flags)=0
Materialize a VReg containing the address of the specified stack-based object.
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.
virtual void assignValueToReg(Register ValVReg, Register PhysReg, const CCValAssign &VA, ISD::ArgFlagsTy Flags)=0
The specified value has been assigned to a physical register, handle the appropriate COPY (either to ...
bool isIncomingArgumentHandler() const
Returns true if the handler is dealing with incoming arguments, i.e.
virtual void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy, const MachinePointerInfo &MPO, const CCValAssign &VA)=0
The specified value has been assigned to a stack location.
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.
virtual unsigned assignCustomValue(ArgInfo &Arg, ArrayRef< CCValAssign > VAs, std::function< void()> *Thunk=nullptr)
Handle custom values, which may be passed into one or more of VAs.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
void setReturned(bool V=true)
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getUnknownStack(MachineFunction &MF)
Stack memory without other information.
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.