28#define DEBUG_TYPE "call-lowering"
32void 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);
94 std::function<
unsigned()> GetCalleeReg)
const {
115 if (!
Info.CanLowerReturn) {
121 CanBeTailCalled =
false;
130 for (
const auto &Arg : CB.
args()) {
137 if (OrigArg.Flags[0].isSRet() && isa<Instruction>(&Arg))
138 CanBeTailCalled =
false;
140 Info.OrigArgs.push_back(OrigArg);
147 if (
const Function *
F = dyn_cast<Function>(CalleeV))
153 Align ReturnHintAlign;
157 if (!
Info.OrigRet.Ty->isVoidTy()) {
161 if (*Alignment >
Align(1)) {
162 ReturnHintAlignReg =
MRI.cloneVirtualRegister(ResRegs[0]);
163 Info.OrigRet.Regs[0] = ReturnHintAlignReg;
164 ReturnHintAlign = *Alignment;
171 Info.CFIType = cast<ConstantInt>(Bundle->Inputs[0]);
172 assert(
Info.CFIType->getType()->isIntegerTy(32) &&
"Invalid CFI type");
177 Info.CallConv = CallConv;
178 Info.SwiftErrorVReg = SwiftErrorVReg;
180 Info.IsTailCall = CanBeTailCalled;
181 Info.IsVarArg = IsVarArg;
185 if (ReturnHintAlignReg && !
Info.IsTailCall) {
193template <
typename FuncInfoTy>
196 const FuncInfoTy &FuncInfo)
const {
197 auto &Flags = Arg.
Flags[0];
207 Align MemAlign =
DL.getABITypeAlign(Arg.
Ty);
208 if (Flags.isByVal() || Flags.isInAlloca() || Flags.isPreallocated()) {
212 Type *ElementTy = FuncInfo.getParamByValType(ParamIdx);
214 ElementTy = FuncInfo.getParamInAllocaType(ParamIdx);
216 ElementTy = FuncInfo.getParamPreallocatedType(ParamIdx);
217 assert(ElementTy &&
"Must have byval, inalloca or preallocated type");
218 Flags.setByValSize(
DL.getTypeAllocSize(ElementTy));
222 if (
auto ParamAlign = FuncInfo.getParamStackAlign(ParamIdx))
223 MemAlign = *ParamAlign;
224 else if ((ParamAlign = FuncInfo.getParamAlign(ParamIdx)))
225 MemAlign = *ParamAlign;
227 MemAlign =
Align(
getTLI()->getByValTypeAlignment(ElementTy,
DL));
229 if (
auto ParamAlign =
231 MemAlign = *ParamAlign;
233 Flags.setMemAlign(MemAlign);
234 Flags.setOrigAlign(
DL.getABITypeAlign(Arg.
Ty));
238 if (Flags.isSwiftSelf())
239 Flags.setReturned(
false);
262 if (SplitVTs.
size() == 0)
265 if (SplitVTs.
size() == 1) {
275 assert(OrigArg.
Regs.size() == SplitVTs.
size() &&
"Regs / types mismatch");
278 OrigArg.
Ty, CallConv,
false,
DL);
279 for (
unsigned i = 0, e = SplitVTs.
size(); i < e; ++i) {
280 Type *SplitTy = SplitVTs[i].getTypeForEVT(Ctx);
284 SplitArgs.
back().Flags[0].setInConsecutiveRegs();
287 SplitArgs.
back().Flags[0].setInConsecutiveRegsLast();
295 LLT LLTy =
MRI.getType(DstRegs[0]);
296 LLT PartLLT =
MRI.getType(SrcRegs[0]);
303 return B.buildConcatVectors(DstRegs[0], SrcRegs);
309 if (LCMTy != PartLLT) {
311 return B.buildDeleteTrailingVectorElements(
312 DstRegs[0],
B.buildMergeLikeInstr(LCMTy, SrcRegs));
317 UnmergeSrcReg = SrcRegs[0];
323 std::copy(DstRegs.
begin(), DstRegs.
end(), PadDstRegs.
begin());
326 for (
int I = DstRegs.
size();
I != NumDst; ++
I)
327 PadDstRegs[
I] =
MRI.createGenericVirtualRegister(LLTy);
329 if (PadDstRegs.
size() == 1)
330 return B.buildDeleteTrailingVectorElements(DstRegs[0], UnmergeSrcReg);
331 return B.buildUnmerge(PadDstRegs, UnmergeSrcReg);
343 if (PartLLT == LLTy) {
346 assert(OrigRegs[0] == Regs[0]);
352 B.buildBitcast(OrigRegs[0], Regs[0]);
362 OrigRegs.
size() == 1 && Regs.
size() == 1) {
365 LLT LocTy =
MRI.getType(SrcReg);
367 if (Flags.isSExt()) {
370 }
else if (Flags.isZExt()) {
376 LLT OrigTy =
MRI.getType(OrigRegs[0]);
379 B.buildIntToPtr(OrigRegs[0],
B.buildTrunc(IntPtrTy, SrcReg));
383 B.buildTrunc(OrigRegs[0], SrcReg);
389 LLT OrigTy =
MRI.getType(OrigRegs[0]);
393 B.buildMergeValues(OrigRegs[0], Regs);
395 auto Widened =
B.buildMergeLikeInstr(
LLT::scalar(SrcSize), Regs);
396 B.buildTrunc(OrigRegs[0], Widened);
414 CastRegs[0] =
B.buildBitcast(NewTy, Regs[0]).getReg(0);
428 CastRegs[
I++] =
B.buildBitcast(GCDTy, SrcReg).getReg(0);
441 LLT RealDstEltTy =
MRI.getType(OrigRegs[0]).getElementType();
445 if (DstEltTy == PartLLT) {
450 MRI.setType(Reg, RealDstEltTy);
453 B.buildBuildVector(OrigRegs[0], Regs);
464 B.buildMergeLikeInstr(RealDstEltTy, Regs.
take_front(PartsPerElt));
466 MRI.setType(
Merge.getReg(0), RealDstEltTy);
471 B.buildBuildVector(OrigRegs[0], EltMerges);
476 auto BV =
B.buildBuildVector(BVType, Regs);
477 B.buildTrunc(OrigRegs[0], BV);
488 unsigned ExtendOp = TargetOpcode::G_ANYEXT) {
490 assert(SrcTy != PartTy &&
"identical part types shouldn't reach here");
497 B.buildInstr(ExtendOp, {DstRegs[0]}, {SrcReg});
505 for (
int i = 0, e = DstRegs.
size(); i != e; ++i)
506 B.buildAnyExt(DstRegs[i], UnmergeToEltTy.getReg(i));
515 B.buildPadVectorWithUndefElements(DstReg, SrcReg);
520 if (GCDTy == PartTy) {
522 B.buildUnmerge(DstRegs, SrcReg);
527 LLT DstTy =
MRI.getType(DstRegs[0]);
530 if (PartTy.
isVector() && LCMTy == PartTy) {
532 B.buildPadVectorWithUndefElements(DstRegs[0], SrcReg);
542 if (!LCMTy.
isVector() && CoveringSize != SrcSize) {
545 CoveringSize =
alignTo(SrcSize, DstSize);
547 UnmergeSrc =
B.buildInstr(ExtendOp, {CoverTy}, {SrcReg}).
getReg(0);
551 Register Undef =
B.buildUndef(SrcTy).getReg(0);
553 for (
unsigned Size = SrcSize;
Size != CoveringSize;
Size += SrcSize)
555 UnmergeSrc =
B.buildMergeLikeInstr(LCMTy, MergeParts).getReg(0);
559 if (LCMTy.
isVector() && CoveringSize != SrcSize)
560 UnmergeSrc =
B.buildPadVectorWithUndefElements(LCMTy, SrcReg).getReg(0);
562 B.buildUnmerge(DstRegs, UnmergeSrc);
574 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs,
F.getContext());
584 return TargetOpcode::G_SEXT;
586 return TargetOpcode::G_ZEXT;
587 return TargetOpcode::G_ANYEXT;
596 unsigned NumArgs = Args.size();
597 for (
unsigned i = 0; i != NumArgs; ++i) {
610 Args[i].Flags[0], CCInfo))
627 Args[i].Flags.clear();
629 for (
unsigned Part = 0; Part < NumParts; ++Part) {
634 Flags.setOrigAlign(
Align(1));
635 if (Part == NumParts - 1)
639 Args[i].Flags.push_back(Flags);
641 Args[i].Flags[Part], CCInfo)) {
662 const unsigned NumArgs = Args.size();
676 SmallVector<std::function<void()>> DelayedOutgoingRegAssignments;
678 for (
unsigned i = 0, j = 0; i != NumArgs; ++i, ++j) {
679 assert(j < ArgLocs.
size() &&
"Skipped too many arg locs");
681 assert(VA.
getValNo() == i &&
"Location doesn't correspond to current arg");
684 std::function<void()> Thunk;
686 Args[i],
ArrayRef(ArgLocs).slice(j), &Thunk);
688 DelayedOutgoingRegAssignments.emplace_back(Thunk);
698 const LLT LocTy(LocVT);
699 const LLT ValTy(ValVT);
707 const unsigned NumParts = Args[i].Flags.size();
710 Args[i].OrigRegs.assign(Args[i].Regs.begin(), Args[i].Regs.end());
712 if (NumParts != 1 || NewLLT != OrigTy) {
715 Args[i].Regs.resize(NumParts);
720 for (
unsigned Part = 0; Part < NumParts; ++Part)
721 Args[i].Regs[Part] =
MRI.createGenericVirtualRegister(NewLLT);
724 assert((j + (NumParts - 1)) < ArgLocs.
size() &&
725 "Too many regs for number of args");
729 assert(Args[i].OrigRegs.size() == 1);
735 for (
unsigned Part = 0; Part < NumParts; ++Part) {
736 Register ArgReg = Args[i].Regs[Part];
738 unsigned Idx = BigEndianPartOrdering ? NumParts - 1 - Part : Part;
742 if (VA.
isMemLoc() && !Flags.isByVal()) {
758 if (VA.
isMemLoc() && Flags.isByVal()) {
759 assert(Args[i].Regs.size() == 1 &&
760 "didn't expect split byval pointer");
767 MIRBuilder.
buildCopy(Args[i].Regs[0], StackAddr);
772 uint64_t MemSize = Flags.getByValSize();
780 if (!Args[i].OrigValue) {
783 const LLT PtrTy =
MRI.getType(StackAddr);
787 Align DstAlign = std::max(Flags.getNonZeroByValAlign(),
790 Align SrcAlign = std::max(Flags.getNonZeroByValAlign(),
794 DstMPO, DstAlign, SrcMPO, SrcAlign,
802 if (i == 0 && !ThisReturnRegs.
empty() &&
812 DelayedOutgoingRegAssignments.emplace_back([=, &Handler]() {
824 LocTy, Args[i].Flags[0]);
829 for (
auto &Fn : DelayedOutgoingRegAssignments)
848 unsigned NumValues = SplitVTs.
size();
850 Type *RetPtrTy =
RetTy->getPointerTo(
DL.getAllocaAddrSpace());
855 for (
unsigned I = 0;
I < NumValues; ++
I) {
859 MRI.getType(VRegs[
I]),
878 unsigned NumValues = SplitVTs.
size();
880 unsigned AS =
DL.getAllocaAddrSpace();
885 for (
unsigned I = 0;
I < NumValues; ++
I) {
889 MRI.getType(VRegs[
I]),
898 unsigned AS =
DL.getAllocaAddrSpace();
899 DemoteReg =
MRI.createGenericVirtualRegister(
913 DemoteArg.
Flags[0].setSRet();
922 unsigned AS =
DL.getAllocaAddrSpace();
932 DemoteArg.
Flags[0].setSRet();
934 Info.OrigArgs.insert(
Info.OrigArgs.begin(), DemoteArg);
935 Info.DemoteStackIndex = FI;
936 Info.DemoteRegister = DemoteReg;
942 for (
unsigned I = 0,
E = Outs.
size();
I <
E; ++
I) {
961 for (
EVT VT : SplitVTs) {
967 for (
unsigned I = 0;
I < NumParts; ++
I) {
975 Type *ReturnType =
F.getReturnType();
988 for (
unsigned i = 0; i < OutLocs.
size(); ++i) {
989 const auto &ArgLoc = OutLocs[i];
991 if (!ArgLoc.isRegLoc())
1002 <<
"... Call has an argument passed in a callee-saved register.\n");
1005 const ArgInfo &OutInfo = OutArgs[i];
1007 if (OutInfo.
Regs.size() > 1) {
1009 dbgs() <<
"... Cannot handle arguments in multiple registers.\n");
1017 if (!RegDef || RegDef->
getOpcode() != TargetOpcode::COPY) {
1020 <<
"... Parameter was not copied into a VReg, cannot tail call.\n");
1026 if (CopyRHS != PhysReg) {
1027 LLVM_DEBUG(
dbgs() <<
"... Callee-saved register was not copied into "
1028 "VReg, cannot tail call.\n");
1045 if (CallerCC == CalleeCC)
1049 CCState CCInfo1(CalleeCC,
Info.IsVarArg, MF, ArgLocs1,
F.getContext());
1054 CCState CCInfo2(CallerCC,
F.isVarArg(), MF, ArgLocs2,
F.getContext());
1060 if (ArgLocs1.
size() != ArgLocs2.
size())
1064 for (
unsigned i = 0, e = ArgLocs1.
size(); i < e; ++i) {
1093 if (ValVT != MVT::iPTR) {
1098 if (Flags.isPointer()) {
1109 unsigned AddrSpace = Flags.getPointerAddrSpace();
1129 const LLT PtrTy =
MRI.getType(DstPtr);
1133 MIRBuilder.
buildMemCpy(DstPtr, SrcPtr, SizeConst, *DstMMO, *SrcMMO);
1138 unsigned MaxSizeBits) {
1142 if (LocTy.getSizeInBits() == ValTy.getSizeInBits())
1145 if (LocTy.isScalar() && MaxSizeBits && MaxSizeBits < LocTy.getSizeInBits()) {
1146 if (MaxSizeBits <= ValTy.getSizeInBits())
1151 const LLT ValRegTy =
MRI.getType(ValReg);
1171 Register NewReg =
MRI.createGenericVirtualRegister(LocTy);
1176 Register NewReg =
MRI.createGenericVirtualRegister(LocTy);
1184void CallLowering::ValueAssigner::anchor() {}
1232 const LLT LocTy(LocVT);
1233 const LLT RegTy =
MRI.getType(ValVReg);
1240 auto Copy = MIRBuilder.
buildCopy(LocTy, PhysReg);
1241 auto Hint = buildExtensionHint(VA, Copy.getReg(0), RegTy);
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
static void addFlagsUsingAttrFn(ISD::ArgFlagsTy &Flags, const std::function< bool(Attribute::AttrKind)> &AttrFn)
Helper function which updates Flags when AttrFn returns true.
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...
static MachineInstrBuilder mergeVectorRegsToResultRegs(MachineIRBuilder &B, ArrayRef< Register > DstRegs, ArrayRef< Register > SrcRegs)
Pack values SrcRegs to cover the vector type result DstRegs.
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 ...
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.
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static unsigned NumFixedArgs
This file declares the MachineIRBuilder class.
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
Module.h This file contains the declarations for the Module class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file describes how to lower LLVM code to machine code.
ArrayRef - 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
front - Get the first element.
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
StringRef getValueAsString() const
Return the attribute's value as a string.
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
CCState - This class holds information needed while lowering arguments and return values.
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.
CallingConv::ID getCallingConv() const
bool isMustTailCall() const
Tests if this call site must be tail call optimized.
bool isIndirectCall() const
Return true if the callsite is an indirect call.
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 parameter attributes for this call.
bool isTailCall() const
Tests if this call site is marked as a tail call.
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.
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 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 resultsCompatible(CallLoweringInfo &Info, MachineFunction &MF, SmallVectorImpl< ArgInfo > &InArgs, ValueAssigner &CalleeAssigner, ValueAssigner &CallerAssigner) const
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.
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.
ISD::ArgFlagsTy getAttributesForArgIdx(const CallBase &Call, unsigned ArgIdx) const
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.
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
ISD::ArgFlagsTy getAttributesForReturn(const CallBase &Call) const
A parsed version of the target data layout string in and methods for querying it.
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
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.
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 LLT getElementType() const
Returns the vector's element type. Only valid for vector types.
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.
constexpr LLT changeElementCount(ElementCount EC) const
Return a vector or scalar with the same element type and the new element count.
constexpr LLT getScalarType() const
constexpr TypeSize getSizeInBytes() const
Returns the total size of the type in bytes, i.e.
This is an important class for using LLVM in a threaded context.
Wrapper class representing physical registers. Should be passed by value.
bool isVector() const
Return true if this is a vector value type.
static MVT getVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
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.
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.
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.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Helper class to build MachineInstr.
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)
MachineInstrBuilder buildSExt(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_SEXT Op.
MachineInstrBuilder buildAssertZExt(const DstOp &Res, const SrcOp &Op, unsigned Size)
Build and insert Res = G_ASSERT_ZEXT Op, Size.
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.
MachineInstrBuilder buildZExt(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_ZEXT Op.
MachineFunction & getMF()
Getter for the function we currently build.
MachineInstrBuilder buildMemCpy(const SrcOp &DstPtr, const SrcOp &SrcPtr, const SrcOp &Size, MachineMemOperand &DstMMO, MachineMemOperand &SrcMMO)
MachineInstrBuilder buildAssertAlign(const DstOp &Res, const SrcOp &Op, Align AlignVal)
Build and insert Res = G_ASSERT_ALIGN Op, AlignVal.
MachineInstrBuilder buildAnyExt(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_ANYEXT Op0.
MachineInstrBuilder buildTrunc(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_TRUNC Op.
MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op)
Build and insert Res = COPY Op.
const DataLayout & getDataLayout() const
MachineInstrBuilder buildAssertSExt(const DstOp &Res, const SrcOp &Op, unsigned Size)
Build and insert Res = G_ASSERT_SEXT Op, Size.
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
MachineInstrBuilder buildPtrToInt(const DstOp &Dst, const SrcOp &Src)
Build and insert a G_PTRTOINT instruction.
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,...
Class to represent pointers.
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type 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)
iterator insert(iterator I, T &&Elt)
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 unsigned getNumRegistersForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const
Certain targets require unusual breakdowns of certain types.
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...
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?...
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,...
The instances of the Type class are immutable: once they are created, they are never changed.
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
constexpr ScalarTy getFixedValue() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
void ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL, Type *Ty, SmallVectorImpl< EVT > &ValueVTs, SmallVectorImpl< TypeSize > *Offsets, TypeSize StartingOffset)
ComputeValueVTs - Given an LLVM IR type, compute a sequence of EVTs that represent all the individual...
MachineInstr * getDefIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI)
Find the def instruction for Reg, folding away any trivial copies.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_READNONE LLT getCoverTy(LLT OrigTy, LLT TargetTy)
Return smallest type that covers both OrigTy and TargetTy and is multiple of TargetTy.
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.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
bool isInTailCallPosition(const CallBase &Call, const TargetMachine &TM)
Test if the given instruction is in a position to be optimized with a tail-call.
LLVM_READNONE LLT getGCDType(LLT OrigTy, LLT TargetTy)
Return a type where the total size is the greatest common divisor of OrigTy and TargetTy.
LLT getLLTForType(Type &Ty, const DataLayout &DL)
Construct a low-level type based on an LLVM type.
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
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 ...
void assignValueToReg(Register ValVReg, Register PhysReg, CCValAssign VA) override
Provides a default implementation for argument handling.
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).
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.
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.
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 assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy, MachinePointerInfo &MPO, CCValAssign &VA)=0
The specified value has been assigned to a stack location.
bool isIncomingArgumentHandler() const
Returns true if the handler is dealing with incoming arguments, i.e.
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.
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 ...
static EVT getEVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
This class contains a discriminated union of information about pointers in memory operands,...
static 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.