Go to the documentation of this file.
28 #define DEBUG_TYPE "call-lowering"
32 void CallLowering::anchor() {}
38 if (AttrFn(Attribute::SExt))
40 if (AttrFn(Attribute::ZExt))
42 if (AttrFn(Attribute::InReg))
44 if (AttrFn(Attribute::StructRet))
46 if (AttrFn(Attribute::Nest))
48 if (AttrFn(Attribute::ByVal))
50 if (AttrFn(Attribute::Preallocated))
51 Flags.setPreallocated();
52 if (AttrFn(Attribute::InAlloca))
54 if (AttrFn(Attribute::Returned))
56 if (AttrFn(Attribute::SwiftSelf))
58 if (AttrFn(Attribute::SwiftAsync))
59 Flags.setSwiftAsync();
60 if (AttrFn(Attribute::SwiftError))
61 Flags.setSwiftError();
65 unsigned ArgIdx)
const {
68 return Call.paramHasAttr(ArgIdx, Attr);
77 return Call.hasRetAttr(Attr);
84 unsigned OpIdx)
const {
86 return Attrs.hasAttributeAtIndex(OpIdx, Attr);
113 if (!
Info.CanLowerReturn) {
119 CanBeTailCalled =
false;
128 for (
const auto &
Arg : CB.
args()) {
135 if (OrigArg.Flags[0].isSRet() && isa<Instruction>(&
Arg))
136 CanBeTailCalled =
false;
138 Info.OrigArgs.push_back(OrigArg);
145 if (
const Function *
F = dyn_cast<Function>(CalleeV))
151 Align ReturnHintAlign;
155 if (!
Info.OrigRet.Ty->isVoidTy()) {
159 if (*Alignment >
Align(1)) {
161 Info.OrigRet.Regs[0] = ReturnHintAlignReg;
162 ReturnHintAlign = *Alignment;
169 Info.CFIType = cast<ConstantInt>(Bundle->Inputs[0]);
170 assert(
Info.CFIType->getType()->isIntegerTy(32) &&
"Invalid CFI type");
175 Info.CallConv = CallConv;
176 Info.SwiftErrorVReg = SwiftErrorVReg;
178 Info.IsTailCall = CanBeTailCalled;
179 Info.IsVarArg = IsVarArg;
183 if (ReturnHintAlignReg && !
Info.IsTailCall) {
191 template <
typename FuncInfoTy>
194 const FuncInfoTy &FuncInfo)
const {
195 auto &Flags =
Arg.Flags[0];
199 PointerType *PtrTy = dyn_cast<PointerType>(
Arg.Ty->getScalarType());
206 if (Flags.isByVal() || Flags.isInAlloca() || Flags.isPreallocated()) {
210 Type *ElementTy = FuncInfo.getParamByValType(ParamIdx);
212 ElementTy = FuncInfo.getParamInAllocaType(ParamIdx);
214 ElementTy = FuncInfo.getParamPreallocatedType(ParamIdx);
215 assert(ElementTy &&
"Must have byval, inalloca or preallocated type");
216 Flags.setByValSize(
DL.getTypeAllocSize(ElementTy));
220 if (
auto ParamAlign = FuncInfo.getParamStackAlign(ParamIdx))
221 MemAlign = *ParamAlign;
222 else if ((ParamAlign = FuncInfo.getParamAlign(ParamIdx)))
223 MemAlign = *ParamAlign;
225 MemAlign =
Align(
getTLI()->getByValTypeAlignment(ElementTy,
DL));
227 if (
auto ParamAlign =
229 MemAlign = *ParamAlign;
231 Flags.setMemAlign(MemAlign);
232 Flags.setOrigAlign(
DL.getABITypeAlign(
Arg.Ty));
236 if (Flags.isSwiftSelf())
237 Flags.setReturned(
false);
260 if (SplitVTs.size() == 0)
263 if (SplitVTs.size() == 1) {
273 assert(OrigArg.
Regs.size() == SplitVTs.size() &&
"Regs / types mismatch");
276 OrigArg.
Ty, CallConv,
false,
DL);
277 for (
unsigned i = 0,
e = SplitVTs.size();
i <
e; ++
i) {
278 Type *SplitTy = SplitVTs[
i].getTypeForEVT(Ctx);
282 SplitArgs.back().Flags[0].setInConsecutiveRegs();
285 SplitArgs.back().Flags[0].setInConsecutiveRegsLast();
301 return B.buildConcatVectors(DstRegs[0], SrcRegs);
307 if (LCMTy != PartLLT) {
309 return B.buildDeleteTrailingVectorElements(
310 DstRegs[0],
B.buildMergeLikeInstr(LCMTy, SrcRegs));
315 UnmergeSrcReg = SrcRegs[0];
324 for (
int I = DstRegs.
size();
I != NumDst; ++
I)
327 if (PadDstRegs.size() == 1)
328 return B.buildDeleteTrailingVectorElements(DstRegs[0], UnmergeSrcReg);
329 return B.buildUnmerge(PadDstRegs, UnmergeSrcReg);
341 if (PartLLT == LLTy) {
344 assert(OrigRegs[0] == Regs[0]);
350 B.buildBitcast(OrigRegs[0], Regs[0]);
360 OrigRegs.
size() == 1 && Regs.
size() == 1) {
365 if (Flags.isSExt()) {
368 }
else if (Flags.isZExt()) {
377 B.buildIntToPtr(OrigRegs[0],
B.buildTrunc(IntPtrTy, SrcReg));
381 B.buildTrunc(OrigRegs[0], SrcReg);
391 B.buildMergeValues(OrigRegs[0], Regs);
393 auto Widened =
B.buildMergeLikeInstr(
LLT::scalar(SrcSize), Regs);
394 B.buildTrunc(OrigRegs[0], Widened);
412 CastRegs[0] =
B.buildBitcast(NewTy, Regs[0]).getReg(0);
426 CastRegs[
I++] =
B.buildBitcast(GCDTy, SrcReg).getReg(0);
443 if (DstEltTy == PartLLT) {
451 B.buildBuildVector(OrigRegs[0], Regs);
462 B.buildMergeLikeInstr(RealDstEltTy, Regs.
take_front(PartsPerElt));
465 EltMerges.push_back(
Merge.getReg(0));
469 B.buildBuildVector(OrigRegs[0], EltMerges);
474 auto BV =
B.buildBuildVector(BVType, Regs);
475 B.buildTrunc(OrigRegs[0], BV);
486 unsigned ExtendOp = TargetOpcode::G_ANYEXT) {
488 assert(SrcTy != PartTy &&
"identical part types shouldn't reach here");
495 B.buildInstr(ExtendOp, {DstRegs[0]}, {SrcReg});
503 for (
int i = 0,
e = DstRegs.
size();
i !=
e; ++
i)
504 B.buildAnyExt(DstRegs[
i], UnmergeToEltTy.getReg(
i));
513 B.buildPadVectorWithUndefElements(DstReg, SrcReg);
518 if (GCDTy == PartTy) {
520 B.buildUnmerge(DstRegs, SrcReg);
528 if (PartTy.
isVector() && LCMTy == PartTy) {
530 B.buildPadVectorWithUndefElements(DstRegs[0], SrcReg);
540 if (!LCMTy.
isVector() && CoveringSize != SrcSize) {
543 CoveringSize =
alignTo(SrcSize, DstSize);
545 UnmergeSrc =
B.buildInstr(ExtendOp, {CoverTy}, {SrcReg}).
getReg(0);
551 for (
unsigned Size = SrcSize; Size != CoveringSize; Size += SrcSize)
552 MergeParts.push_back(
Undef);
553 UnmergeSrc =
B.buildMergeLikeInstr(LCMTy, MergeParts).getReg(0);
557 if (LCMTy.
isVector() && CoveringSize != SrcSize)
558 UnmergeSrc =
B.buildPadVectorWithUndefElements(LCMTy, SrcReg).getReg(0);
560 B.buildUnmerge(DstRegs, UnmergeSrc);
572 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs,
F.getContext());
582 return TargetOpcode::G_SEXT;
584 return TargetOpcode::G_ZEXT;
585 return TargetOpcode::G_ANYEXT;
594 unsigned NumArgs =
Args.size();
595 for (
unsigned i = 0;
i != NumArgs; ++
i) {
608 Args[
i].Flags[0], CCInfo))
625 Args[
i].Flags.clear();
627 for (
unsigned Part = 0; Part < NumParts; ++Part) {
632 Flags.setOrigAlign(
Align(1));
633 if (Part == NumParts - 1)
637 Args[
i].Flags.push_back(Flags);
639 Args[
i].Flags[Part], CCInfo)) {
660 const unsigned NumArgs =
Args.size();
676 for (
unsigned i = 0,
j = 0;
i != NumArgs; ++
i, ++
j) {
677 assert(
j < ArgLocs.size() &&
"Skipped too many arg locs");
679 assert(VA.
getValNo() ==
i &&
"Location doesn't correspond to current arg");
686 DelayedOutgoingRegAssignments.emplace_back(Thunk);
696 const LLT LocTy(LocVT);
697 const LLT ValTy(ValVT);
705 const unsigned NumParts =
Args[
i].Flags.size();
710 if (NumParts != 1 || NewLLT != OrigTy) {
713 Args[
i].Regs.resize(NumParts);
718 for (
unsigned Part = 0; Part < NumParts; ++Part)
722 assert((
j + (NumParts - 1)) < ArgLocs.size() &&
723 "Too many regs for number of args");
733 for (
unsigned Part = 0; Part < NumParts; ++Part) {
736 unsigned Idx = BigEndianPartOrdering ? NumParts - 1 - Part : Part;
740 if (VA.
isMemLoc() && !Flags.isByVal()) {
756 if (VA.
isMemLoc() && Flags.isByVal()) {
758 "didn't expect split byval pointer");
770 uint64_t MemSize = Flags.getByValSize();
778 if (!
Args[
i].OrigValue) {
792 DstMPO, DstAlign, SrcMPO, SrcAlign,
800 if (
i == 0 && !ThisReturnRegs.
empty() &&
810 DelayedOutgoingRegAssignments.emplace_back([=, &Handler]() {
822 LocTy,
Args[
i].Flags[0]);
827 for (
auto &Fn : DelayedOutgoingRegAssignments)
846 unsigned NumValues = SplitVTs.size();
847 Align BaseAlign =
DL.getPrefTypeAlign(RetTy);
853 for (
unsigned I = 0;
I < NumValues; ++
I) {
876 unsigned NumValues = SplitVTs.size();
877 Align BaseAlign =
DL.getPrefTypeAlign(RetTy);
878 unsigned AS =
DL.getAllocaAddrSpace();
884 for (
unsigned I = 0;
I < NumValues; ++
I) {
897 unsigned AS =
DL.getAllocaAddrSpace();
907 assert(ValueVTs.size() == 1);
912 DemoteArg.
Flags[0].setSRet();
913 SplitArgs.
insert(SplitArgs.begin(), DemoteArg);
921 unsigned AS =
DL.getAllocaAddrSpace();
925 DL.getTypeAllocSize(RetTy),
DL.getPrefTypeAlign(RetTy),
false);
931 DemoteArg.
Flags[0].setSRet();
933 Info.OrigArgs.insert(
Info.OrigArgs.begin(), DemoteArg);
934 Info.DemoteStackIndex = FI;
935 Info.DemoteRegister = DemoteReg;
941 for (
unsigned I = 0,
E = Outs.size();
I <
E; ++
I) {
960 for (
EVT VT : SplitVTs) {
966 for (
unsigned I = 0;
I < NumParts; ++
I) {
987 for (
unsigned i = 0;
i < OutLocs.size(); ++
i) {
988 const auto &ArgLoc = OutLocs[
i];
990 if (!ArgLoc.isRegLoc())
1001 <<
"... Call has an argument passed in a callee-saved register.\n");
1004 const ArgInfo &OutInfo = OutArgs[
i];
1006 if (OutInfo.
Regs.size() > 1) {
1008 dbgs() <<
"... Cannot handle arguments in multiple registers.\n");
1016 if (!RegDef || RegDef->
getOpcode() != TargetOpcode::COPY) {
1019 <<
"... Parameter was not copied into a VReg, cannot tail call.\n");
1025 if (CopyRHS != PhysReg) {
1026 LLVM_DEBUG(
dbgs() <<
"... Callee-saved register was not copied into "
1027 "VReg, cannot tail call.\n");
1044 if (CallerCC == CalleeCC)
1048 CCState CCInfo1(CalleeCC,
Info.IsVarArg, MF, ArgLocs1,
F.getContext());
1053 CCState CCInfo2(CallerCC,
F.isVarArg(), MF, ArgLocs2,
F.getContext());
1059 if (ArgLocs1.size() != ArgLocs2.size())
1063 for (
unsigned i = 0,
e = ArgLocs1.size();
i <
e; ++
i) {
1097 if (Flags.isPointer()) {
1108 unsigned AddrSpace = Flags.getPointerAddrSpace();
1132 MIRBuilder.
buildMemCpy(DstPtr, SrcPtr, SizeConst, *DstMMO, *SrcMMO);
1137 unsigned MaxSizeBits) {
1141 if (LocTy.getSizeInBits() == ValTy.getSizeInBits())
1144 if (LocTy.isScalar() && MaxSizeBits && MaxSizeBits < LocTy.getSizeInBits()) {
1145 if (MaxSizeBits <= ValTy.getSizeInBits())
1183 void CallLowering::ValueAssigner::anchor() {}
1189 case CCValAssign::LocInfo::ZExt: {
1195 case CCValAssign::LocInfo::SExt: {
1231 const LLT LocTy(LocVT);
1239 auto Copy = MIRBuilder.
buildCopy(LocTy, PhysReg);
1240 auto Hint = buildExtensionHint(VA, Copy.getReg(0), RegTy);
@ Undef
Value of the register doesn't matter.
Argument handling is mostly uniform between the four places that make these decisions: function forma...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
MachineInstr * getDefIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI)
Find the def instruction for Reg, folding away any trivial copies.
This is an optimization pass for GlobalISel generic memory operations.
A parsed version of the target data layout string in and methods for querying it.
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)
virtual bool functionArgumentNeedsConsecutiveRegisters(Type *Ty, CallingConv::ID CallConv, bool isVarArg, const DataLayout &DL) const
For some targets, an LLVM struct type must be broken down into multiple simple types,...
CCState - This class holds information needed while lowering arguments and return values.
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...
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
void assignValueToReg(Register ValVReg, Register PhysReg, CCValAssign VA) override
Provides a default implementation for argument handling.
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
static constexpr LLT vector(ElementCount EC, unsigned ScalarSizeInBits)
Get a low-level vector of some number of elements and element width.
bool isVector() const
Return true if this is a vector value type.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, 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.
Register extendRegister(Register ValReg, CCValAssign &VA, unsigned MaxSizeBits=0)
Extend a register to the location type given in VA, capped at extending to at most MaxSize bits.
std::optional< MachineInstrBuilder > materializePtrAdd(Register &Res, Register Op0, const LLT ValueTy, uint64_t Value)
Materialize and insert Res = G_PTR_ADD Op0, (G_CONSTANT Value)
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
Reg
All possible values of the reg field in the ModR/M byte.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
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.
The instances of the Type class are immutable: once they are created, they are never changed.
AttributeList getAttributes() const
Return the parameter attributes for this call.
A description of a memory reference used in the backend.
FunctionType * getFunctionType() const
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
static unsigned extendOpFromFlags(llvm::ISD::ArgFlagsTy Flags)
bool isMustTailCall() const
Tests if this call site must be tail call optimized.
void splitToValueTypes(const ArgInfo &OrigArgInfo, SmallVectorImpl< ArgInfo > &SplitArgs, const DataLayout &DL, CallingConv::ID CallConv, SmallVectorImpl< uint64_t > *Offsets=nullptr) const
Break OrigArgInfo into one or more pieces the calling convention can process, returned in SplitArgs.
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
constexpr bool isVector() const
constexpr LLT getElementType() const
Returns the vector's element type. Only valid for vector types.
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 ...
bool empty() const
empty - Check if the array is empty.
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
void ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL, Type *Ty, SmallVectorImpl< EVT > &ValueVTs, SmallVectorImpl< uint64_t > *Offsets=nullptr, uint64_t StartingOffset=0)
ComputeValueVTs - Given an LLVM IR type, compute a sequence of EVTs that represent all the individual...
LLT getLLTForType(Type &Ty, const DataLayout &DL)
Construct a low-level type based on an LLVM type.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr LLT getScalarType() const
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
LLVM_READNONE LLT getGCDType(LLT OrigTy, LLT TargetTy)
Return a type where the total size is the greatest common divisor of OrigTy and TargetTy.
const TargetLowering * getTLI() const
Getter for generic TargetLowering class.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
bool resultsCompatible(CallLoweringInfo &Info, MachineFunction &MF, SmallVectorImpl< ArgInfo > &InArgs, ValueAssigner &CalleeAssigner, ValueAssigner &CallerAssigner) const
CCValAssign - Represent assignment of one arg/retval to a location.
MachineInstrBuilder buildZExt(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_ZEXT Op.
MachineInstrBuilder buildLoad(const DstOp &Res, const SrcOp &Addr, MachineMemOperand &MMO)
Build and insert Res = G_LOAD Addr, MMO.
void setType(Register VReg, LLT Ty)
Set the low-level type of VReg to Ty.
bool checkReturnTypeForCallConv(MachineFunction &MF) const
Toplevel function to check the return type based on the target calling convention.
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Register getLocReg() const
virtual void assignValueToReg(Register ValVReg, Register PhysReg, CCValAssign VA)=0
The specified value has been assigned to a physical register, handle the appropriate COPY (either to ...
const MachineOperand & getOperand(unsigned i) const
MachineInstrBuilder buildPtrToInt(const DstOp &Dst, const SrcOp &Src)
Build and insert a G_PTRTOINT instruction.
static MachineInstrBuilder mergeVectorRegsToResultRegs(MachineIRBuilder &B, ArrayRef< Register > DstRegs, ArrayRef< Register > SrcRegs)
Pack values SrcRegs to cover the vector type result DstRegs.
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.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const DataLayout & getDataLayout() const
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
bool determineAssignments(ValueAssigner &Assigner, SmallVectorImpl< ArgInfo > &Args, CCState &CCInfo) const
Analyze the argument list in Args, using Assigner to populate CCInfo.
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.
MachineFunction & getMF()
Getter for the function we currently build.
constexpr bool isScalar() const
LLVMContext & getContext() const
Analysis containing CSE Info
LocInfo getLocInfo() const
unsigned getLocMemOffset() const
This struct is a compact representation of a valid (non-zero power of two) alignment.
CallingConv::ID getCallingConv() const
bool handleAssignments(ValueHandler &Handler, SmallVectorImpl< ArgInfo > &Args, CCState &CCState, SmallVectorImpl< CCValAssign > &ArgLocs, MachineIRBuilder &MIRBuilder, ArrayRef< Register > ThisReturnRegs=std::nullopt) const
Use Handler to insert code to handle the argument/return values represented by Args.
StringRef getValueAsString() const
Return the attribute's value as a string.
Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Register getReg(unsigned Idx) const
Get the register for the operand index.
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
AttributeList getAttributes() const
Return the attribute list for this Function.
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
virtual bool isTypeIsValidForThisReturn(EVT Ty) const
For targets which support the "returned" parameter attribute, returns true if the given type is a val...
static const unsigned NoArgIndex
Sentinel value for implicit machine-level input arguments.
static bool clobbersPhysReg(const uint32_t *RegMask, MCRegister PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
virtual unsigned getNumRegistersForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const
Certain targets require unusual breakdowns of certain types.
bool isTailCall() const
Tests if this call site is marked as a tail call.
ArrayRef< T > drop_front(size_t N=1) const
Drop the first N elements of the array.
Helper class to build MachineInstr.
Representation of each machine instruction.
MaybeAlign getRetAlign() const
Extract the alignment of the return value.
bool checkReturn(CCState &CCInfo, SmallVectorImpl< BaseArgInfo > &Outs, CCAssignFn *Fn) const
constexpr LLT changeElementCount(ElementCount EC) const
Return a vector or scalar with the same element type and the new element count.
This class contains a discriminated union of information about pointers in memory operands,...
This is an important class for using LLVM in a threaded context.
constexpr ElementCount getElementCount() const
Align inferAlignFromPtrInfo(MachineFunction &MF, const MachinePointerInfo &MPO)
static EVT getEVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
LLVM_READNONE LLT getCoverTy(LLT OrigTy, LLT TargetTy)
Return smallest type that covers both OrigTy and TargetTy and is multiple of TargetTy.
Class to represent pointers.
bool determineAndHandleAssignments(ValueHandler &Handler, ValueAssigner &Assigner, SmallVectorImpl< ArgInfo > &Args, MachineIRBuilder &MIRBuilder, CallingConv::ID CallConv, bool IsVarArg, ArrayRef< Register > ThisReturnRegs=std::nullopt) const
Invoke ValueAssigner::assignArg on each of the given Args and then use Handler to move them to the as...
bool hasBigEndianPartOrdering(EVT VT, const DataLayout &DL) const
When splitting a value of the specified type into parts, does the Lo or Hi part come first?...
constexpr ScalarTy getFixedValue() const
CallingConv::ID getCallingConv() const
constexpr uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ISD::ArgFlagsTy getAttributesForReturn(const CallBase &Call) const
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
static bool isCopyCompatibleType(LLT SrcTy, LLT DstTy)
Check if we can use a basic COPY instruction between the two types.
print Print MemDeps of function
Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
MachineInstrBuilder buildAssertZExt(const DstOp &Res, const SrcOp &Op, unsigned Size)
Build and insert Res = G_ASSERT_ZEXT Op, Size.
Register getReg() const
getReg - Returns the register number.
void addArgFlagsFromAttributes(ISD::ArgFlagsTy &Flags, const AttributeList &Attrs, unsigned OpIdx) const
Adds flags to Flags based off of the attributes in Attrs.
static void addFlagsUsingAttrFn(ISD::ArgFlagsTy &Flags, const std::function< bool(Attribute::AttrKind)> &AttrFn)
Helper function which updates Flags when AttrFn returns true.
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
unsigned getValNo() const
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.
constexpr bool isPointer() const
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
static MachineOperand CreateGA(const GlobalValue *GV, int64_t Offset, unsigned TargetFlags=0)
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.
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.
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.
std::optional< OperandBundleUse > getOperandBundle(StringRef Name) const
Return an operand bundle by name, if present.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
MachineInstrBuilder buildAssertAlign(const DstOp &Res, const SrcOp &Op, Align AlignVal)
Build and insert Res = G_ASSERT_ALIGN Op, AlignVal.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Type * getType() const
All values are typed, get the type of this value.
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.
MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op)
Build and insert Res = COPY Op.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
const T & front() const
front - Get the first element.
@ MOLoad
The memory access reads data.
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder buildAnyExt(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_ANYEXT Op0.
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Wrapper class representing virtual and physical registers.
static unsigned NumFixedArgs
MachineInstrBuilder buildFrameIndex(const DstOp &Res, int Idx)
Build and insert Res = G_FRAME_INDEX Idx.
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.
ISD::ArgFlagsTy getAttributesForArgIdx(const CallBase &Call, unsigned ArgIdx) 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...
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.
MachineInstrBuilder buildTrunc(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_TRUNC Op.
MachineInstrBuilder buildMemCpy(const SrcOp &DstPtr, const SrcOp &SrcPtr, const SrcOp &Size, MachineMemOperand &DstMMO, MachineMemOperand &SrcMMO)
Function & getFunction()
Return the LLVM function that this machine code represents.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
ArrayRef< T > take_front(size_t N=1) const
Return a copy of *this with only the first N elements.
SmallVector< Register, 4 > Regs
bool isIndirectCall() const
Return true if the callsite is an indirect call.
PointerType * getPointerTo(unsigned AddrSpace=0) const
Return a pointer to the current type.
constexpr unsigned getAddressSpace() const
Register buildExtensionHint(CCValAssign &VA, Register SrcReg, LLT NarrowTy)
Insert G_ASSERT_ZEXT/G_ASSERT_SEXT or other hint instruction based on VA, returning the new register ...
Value * getCalledOperand() const
@ MOStore
The memory access writes data.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
Register cloneVirtualRegister(Register VReg, StringRef Name="")
Create and return a new virtual register in the function with the same attributes as the given regist...
MachineInstrBuilder buildSExt(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_SEXT Op.
MachineInstrBuilder buildAssertSExt(const DstOp &Res, const SrcOp &Op, unsigned Size)
Build and insert Res = G_ASSERT_SEXT Op, Size.
virtual MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const
Certain combinations of ABIs, Targets and features require that types are legal for some operations a...
size_t size() const
size - Get the array size.
constexpr TypeSize getSizeInBytes() const
Returns the total size of the type in bytes, i.e.
static MVT getVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
bool isInTailCallPosition(const CallBase &Call, const TargetMachine &TM)
Test if the given instruction is in a position to be optimized with a tail-call.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
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.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
ArrayRef(const T &OneElt) -> ArrayRef< T >
const Value * OrigValue
Optionally track the original IR value for the argument.
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).
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
MachineInstrBuilder buildStore(const SrcOp &Val, const SrcOp &Addr, MachineMemOperand &MMO)
Build and insert G_STORE Val, Addr, MMO.
unsigned OrigArgIndex
Index original Function's argument.
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...
we should consider alternate ways to model stack dependencies Lots of things could be done in WebAssemblyTargetTransformInfo cpp there are numerous optimization related hooks that can be overridden in WebAssemblyTargetLowering Instead of the OptimizeReturned which should consider preserving the returned attribute through to MachineInstrs and extending the MemIntrinsicResults pass to do this optimization on calls too That would also let the WebAssemblyPeephole pass clean up dead defs for such as it does for stores Consider implementing and or getMachineCombinerPatterns Find a clean way to fix the problem which leads to the Shrink Wrapping pass being run after the WebAssembly PEI pass When setting multiple variables to the same we currently get code like const It could be done with a smaller encoding like local tee $pop5 local copy
LLVM Value Representation.
bool isIncomingArgumentHandler() const
Returns true if the handler is dealing with incoming arguments, i.e.
constexpr unsigned getScalarSizeInBits() const
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
virtual void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy, MachinePointerInfo &MPO, CCValAssign &VA)=0
The specified value has been assigned to a stack location.
reference emplace_back(ArgTypes &&... Args)
Wrapper class representing physical registers. Should be passed by value.
iterator insert(iterator I, T &&Elt)
SmallVector< ISD::ArgFlagsTy, 4 > Flags
virtual bool lowerCall(MachineIRBuilder &MIRBuilder, CallLoweringInfo &Info) const
This hook must be implemented to lower the given call instruction, including argument and return valu...
static constexpr LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
void setArgFlags(ArgInfo &Arg, unsigned OpIdx, const DataLayout &DL, const FuncInfoTy &FuncInfo) const