Go to the documentation of this file.
27 #define DEBUG_TYPE "call-lowering"
31 void CallLowering::anchor() {}
37 if (AttrFn(Attribute::SExt))
39 if (AttrFn(Attribute::ZExt))
41 if (AttrFn(Attribute::InReg))
43 if (AttrFn(Attribute::StructRet))
45 if (AttrFn(Attribute::Nest))
47 if (AttrFn(Attribute::ByVal))
49 if (AttrFn(Attribute::Preallocated))
51 if (AttrFn(Attribute::InAlloca))
53 if (AttrFn(Attribute::Returned))
55 if (AttrFn(Attribute::SwiftSelf))
57 if (AttrFn(Attribute::SwiftError))
62 unsigned ArgIdx)
const {
65 return Call.paramHasAttr(ArgIdx, Attr);
72 unsigned OpIdx)
const {
100 if (!
Info.CanLowerReturn) {
106 CanBeTailCalled =
false;
121 if (OrigArg.Flags[0].isSRet() && isa<Instruction>(&
Arg))
122 CanBeTailCalled =
false;
124 Info.OrigArgs.push_back(OrigArg);
131 if (
const Function *
F = dyn_cast<Function>(CalleeV))
137 if (!
Info.OrigRet.Ty->isVoidTy())
141 Info.CallConv = CallConv;
142 Info.SwiftErrorVReg = SwiftErrorVReg;
144 Info.IsTailCall = CanBeTailCalled;
145 Info.IsVarArg = IsVarArg;
149 template <
typename FuncInfoTy>
152 const FuncInfoTy &FuncInfo)
const {
153 auto &Flags =
Arg.Flags[0];
158 Type *ElementTy = cast<PointerType>(
Arg.Ty)->getElementType();
166 if (
auto ParamAlign = FuncInfo.getParamAlign(OpIdx - 1))
167 FrameAlign = *ParamAlign;
169 FrameAlign =
Align(
getTLI()->getByValTypeAlignment(ElementTy,
DL));
200 if (SplitVTs.size() == 0)
203 if (SplitVTs.size() == 1) {
213 assert(OrigArg.
Regs.size() == SplitVTs.size() &&
"Regs / types mismatch");
216 OrigArg.
Ty, CallConv,
false);
217 for (
unsigned i = 0,
e = SplitVTs.size();
i <
e; ++
i) {
218 Type *SplitTy = SplitVTs[
i].getTypeForEVT(Ctx);
222 SplitArgs.back().Flags[0].setInConsecutiveRegs();
225 SplitArgs.back().Flags[0].setInConsecutiveRegsLast();
231 assert(DstRegs.
size() > 1 &&
"Nothing to unpack");
238 assert(LLTs.size() == DstRegs.
size() &&
"Regs / types mismatch");
240 for (
unsigned i = 0;
i < DstRegs.
size(); ++
i)
257 return B.buildConcatVectors(DstRegs[0], SrcRegs);
263 if (LCMTy != PartLLT) {
278 UnmergeSrcReg =
B.buildConcatVectors(LCMTy, WidenedSrcs).getReg(0);
283 UnmergeSrcReg = SrcRegs[0];
292 for (
int I = DstRegs.
size();
I != NumDst; ++
I)
295 return B.buildUnmerge(PadDstRegs, UnmergeSrcReg);
307 assert(LLTy != PartLLT &&
"identical part types shouldn't reach here");
312 B.buildTrunc(OrigRegs[0], Regs[0]);
322 B.buildMerge(OrigRegs[0], Regs);
324 auto Widened =
B.buildMerge(
LLT::scalar(SrcSize), Regs);
325 B.buildTrunc(OrigRegs[0], Widened);
348 if (DstEltTy == PartLLT) {
356 B.buildBuildVector(OrigRegs[0], Regs);
369 EltMerges.push_back(
Merge.getReg(0));
373 B.buildBuildVector(OrigRegs[0], EltMerges);
378 auto BV =
B.buildBuildVector(BVType, Regs);
379 B.buildTrunc(OrigRegs[0], BV);
390 unsigned ExtendOp = TargetOpcode::G_ANYEXT) {
392 assert(SrcTy != PartTy &&
"identical part types shouldn't reach here");
399 B.buildInstr(ExtendOp, {DstRegs[0]}, {SrcReg});
407 for (
int i = 0,
e = DstRegs.
size();
i !=
e; ++
i)
408 B.buildAnyExt(DstRegs[
i], UnmergeToEltTy.getReg(
i));
413 if (GCDTy == PartTy) {
415 B.buildUnmerge(DstRegs, SrcReg);
428 if (LCMSize != SrcSize) {
432 for (
unsigned Size = SrcSize;
Size != LCMSize;
Size += SrcSize)
433 MergeParts.push_back(
Undef);
435 UnmergeSrc =
B.buildMerge(LCMTy, MergeParts).getReg(0);
440 for (
unsigned Size = DstSize * DstRegs.
size();
Size != LCMSize;
445 B.buildUnmerge(UnmergeResults, UnmergeSrc);
457 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs,
F.getContext());
464 return TargetOpcode::G_SEXT;
466 return TargetOpcode::G_ZEXT;
467 return TargetOpcode::G_ANYEXT;
481 unsigned NumArgs =
Args.size();
482 for (
unsigned i = 0;
i != NumArgs; ++
i) {
501 Args[
i].Flags[0], CCInfo))
511 const LLT VATy(NewVT);
516 const LLT NewLLT(NewVT);
531 Args[
i].Regs.clear();
532 Args[
i].Flags.clear();
536 for (
unsigned Part = 0; Part < NumParts; ++Part) {
543 if (Part == NumParts - 1)
547 Args[
i].Flags.push_back(Flags);
549 Args[
i].Flags[Part], CCInfo)) {
564 Args[
i].Regs.clear();
565 Args[
i].Flags.clear();
566 for (
unsigned PartIdx = 0; PartIdx < NumParts; ++PartIdx) {
572 if (PartIdx == NumParts - 1)
586 Args[
i].Regs.push_back(NewReg);
587 Args[
i].Flags.push_back(Flags);
595 for (
unsigned i = 0,
e =
Args.size(),
j = 0;
i !=
e; ++
i, ++
j) {
596 assert(
j < ArgLocs.size() &&
"Skipped too many arg locs");
599 assert(VA.
getValNo() ==
i &&
"Location doesn't correspond to current arg");
602 unsigned NumArgRegs =
616 unsigned NumArgRegs =
Args[
i].Regs.size();
617 assert((
j + (NumArgRegs - 1)) < ArgLocs.size() &&
618 "Too many regs for number of args");
627 for (
unsigned Part = 0; Part < NumArgRegs; ++Part) {
630 VA = ArgLocs[
j + Part];
639 unsigned MemSize = LocVT ==
MVT::iPTR ?
DL.getPointerSize()
652 "didn't expect split byval pointer");
672 if (!
Args[
i].OrigValue) {
686 DstMPO, DstAlign, SrcMPO, SrcAlign,
694 if (
i == 0 && ThisReturnReg.
isValid() &&
732 unsigned NumValues = SplitVTs.size();
733 Align BaseAlign =
DL.getPrefTypeAlign(RetTy);
739 for (
unsigned I = 0;
I < NumValues; ++
I) {
762 unsigned NumValues = SplitVTs.size();
763 Align BaseAlign =
DL.getPrefTypeAlign(RetTy);
764 unsigned AS =
DL.getAllocaAddrSpace();
770 for (
unsigned I = 0;
I < NumValues; ++
I) {
783 unsigned AS =
DL.getAllocaAddrSpace();
793 assert(ValueVTs.size() == 1);
797 DemoteArg.
Flags[0].setSRet();
798 SplitArgs.
insert(SplitArgs.begin(), DemoteArg);
806 unsigned AS =
DL.getAllocaAddrSpace();
810 DL.getTypeAllocSize(RetTy),
DL.getPrefTypeAlign(RetTy),
false);
815 DemoteArg.
Flags[0].setSRet();
817 Info.OrigArgs.insert(
Info.OrigArgs.begin(), DemoteArg);
818 Info.DemoteStackIndex = FI;
819 Info.DemoteRegister = DemoteReg;
825 for (
unsigned I = 0,
E = Outs.size();
I <
E; ++
I) {
844 for (
EVT VT : SplitVTs) {
850 for (
unsigned I = 0;
I < NumParts; ++
I) {
871 for (
unsigned i = 0,
e =
Args.size();
i <
e; ++
i) {
877 <<
" (arg number = " <<
i <<
"\n");
888 for (
unsigned i = 0;
i < OutLocs.size(); ++
i) {
889 auto &ArgLoc = OutLocs[
i];
891 if (!ArgLoc.isRegLoc())
902 <<
"... Call has an argument passed in a callee-saved register.\n");
905 const ArgInfo &OutInfo = OutArgs[
i];
907 if (OutInfo.
Regs.size() > 1) {
909 dbgs() <<
"... Cannot handle arguments in multiple registers.\n");
917 if (!RegDef || RegDef->
getOpcode() != TargetOpcode::COPY) {
920 <<
"... Parameter was not copied into a VReg, cannot tail call.\n");
926 if (CopyRHS != PhysReg) {
927 LLVM_DEBUG(
dbgs() <<
"... Callee-saved register was not copied into "
928 "VReg, cannot tail call.\n");
947 if (CallerCC == CalleeCC)
951 CCState CCInfo1(CalleeCC,
false, MF, ArgLocs1,
F.getContext());
953 CalleeAssignFnVarArg))
957 CCState CCInfo2(CallerCC,
false, MF, ArgLocs2,
F.getContext());
959 CalleeAssignFnVarArg))
964 if (ArgLocs1.size() != ArgLocs2.size())
968 for (
unsigned i = 0,
e = ArgLocs1.size();
i <
e; ++
i) {
1019 unsigned MaxSizeBits) {
1025 if (LocTy.isScalar() && MaxSizeBits && MaxSizeBits < LocTy.getSizeInBits()) {
1056 void CallLowering::ValueHandler::anchor() {}
1062 case CCValAssign::LocInfo::ZExt: {
1068 case CCValAssign::LocInfo::SExt: {
1091 auto Copy = MIRBuilder.
buildCopy(LocTy, PhysReg);
1092 auto Hint = buildExtensionHint(VA, Copy.getReg(0), ValTy);
MachineInstr * getDefIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI)
Find the def instruction for Reg, folding away any trivial copies.
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
For some targets, an LLVM struct type must be broken down into multiple simple types,...
unsigned getScalarSizeInBits() const
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,...
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.
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.
Argument handling is mostly uniform between the four places that make these decisions: function forma...
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.
LLT getScalarType() const
The instances of the Type class are immutable: once they are created, they are never changed.
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 ...
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.
virtual unsigned assignCustomValue(const ArgInfo &Arg, ArrayRef< CCValAssign > VAs)
Handle custom values, which may be passed into one or more of VAs.
static void buildCopyFromRegs(MachineIRBuilder &B, ArrayRef< Register > OrigRegs, ArrayRef< Register > Regs, LLT LLTy, LLT PartLLT)
Create a sequence of instructions to combine pieces split into register typed values to the original ...
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
virtual Register getStackAddress(uint64_t Size, int64_t Offset, MachinePointerInfo &MPO, ISD::ArgFlagsTy Flags)=0
Materialize a VReg containing the address of the specified stack-based object.
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
virtual bool assignArg(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, const ArgInfo &Info, ISD::ArgFlagsTy Flags, CCState &State)
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...
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
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.
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.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
const TargetLowering * getTLI() const
Getter for generic TargetLowering class.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
bool analyzeArgInfo(CCState &CCState, SmallVectorImpl< ArgInfo > &Args, CCAssignFn &AssignFnFixed, CCAssignFn &AssignFnVarArg) const
Analyze passed or returned values from a call, supplied in ArgInfo, incorporating info about the pass...
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 setReturned(bool V=true)
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 GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Register getLocReg() const
virtual void assignValueToAddress(Register ValVReg, Register Addr, uint64_t Size, MachinePointerInfo &MPO, CCValAssign &VA)=0
The specified value has been assigned to a stack location.
unsigned getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
const MachineOperand & getOperand(unsigned i) const
static MachineInstrBuilder mergeVectorRegsToResultRegs(MachineIRBuilder &B, ArrayRef< Register > DstRegs, ArrayRef< Register > SrcRegs)
Pack values SrcRegs to cover the vector type result DstRegs.
unsigned getSizeInBytes() const
Returns the total size of the type in bytes, i.e.
bool handleAssignments(MachineIRBuilder &MIRBuilder, SmallVectorImpl< ArgInfo > &Args, ValueHandler &Handler, CallingConv::ID CallConv, bool IsVarArg, Register ThisReturnReg=Register()) const
Invoke Handler::assignArg on each of the given Args and then use Handler to move them to the assigned...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const DataLayout & getDataLayout() const
MachineFunction & getMF()
Getter for the function we currently build.
static LLT vector(uint16_t NumElements, unsigned ScalarSizeInBits)
Get a low-level vector of some number of elements and element width.
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
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.
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.
static LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
unsigned getAddressSpace() const
LLVM_READNONE LLT getLCMType(LLT OrigTy, LLT TargetTy)
Return the least common multiple type of OrigTy and TargetTy, by changing the number of vector elemen...
virtual bool isTypeIsValidForThisReturn(EVT Ty) const
For targets which support the "returned" parameter attribute, returns true if the given type is a val...
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.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Representation of each machine instruction.
MachineInstrBuilder buildAssertSExt(const DstOp &Res, const SrcOp &Op, unsigned Size)
Build and insert Res = G_ASSERT_SEXT Op, Size.
bool checkReturn(CCState &CCInfo, SmallVectorImpl< BaseArgInfo > &Outs, CCAssignFn *Fn) const
MachineInstrBuilder buildAssertZExt(const DstOp &Res, const SrcOp &Op, unsigned Size)
Build and insert Res = G_ASSERT_ZEXT Op, Size.
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.
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,...
uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
void setOrigAlign(Align A)
CallingConv::ID getCallingConv() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
bool hasAttribute(unsigned i, Attribute::AttrKind Kind) const
check if an attributes is in the list of attributes.
print Print MemDeps of function
Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
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.
void setByValSize(unsigned S)
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.
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.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
#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.
bool isPreallocated() const
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineInstrBuilder buildExtract(const DstOp &Res, const SrcOp &Src, uint64_t Index)
Build and insert Res0, ...
void setByValAlign(Align A)
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
@ 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.
Optional< MachineInstrBuilder > materializePtrAdd(Register &Res, Register Op0, const LLT ValueTy, uint64_t Value)
Materialize and insert Res = G_PTR_ADD Op0, (G_CONSTANT Value)
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.
void unpackRegs(ArrayRef< Register > DstRegs, Register SrcReg, Type *PackedTy, MachineIRBuilder &MIRBuilder) const
Generate instructions for unpacking SrcReg into the DstRegs corresponding to the aggregate type Packe...
ISD::ArgFlagsTy getAttributesForArgIdx(const CallBase &Call, unsigned ArgIdx) const
void computeValueLLTs(const DataLayout &DL, Type &Ty, SmallVectorImpl< LLT > &ValueTys, SmallVectorImpl< uint64_t > *Offsets=nullptr, uint64_t StartingOffset=0)
computeValueLLTs - Given an LLVM IR type, compute a sequence of LLTs that represent all the individua...
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.
Align commonAlignment(Align A, Align B)
Returns the alignment that satisfies both alignments.
unsigned getByValSize() const
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.
MachineRegisterInfo & MRI
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.
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
@ Undef
Value of the register doesn't matter.
void assignValueToReg(Register ValVReg, Register PhysReg, CCValAssign &VA) override
Provides a default implementation for argument handling.
Type * getValueAsType() const
Return the attribute's value as a Type.
SmallVector< Register, 4 > Regs
PointerType * getPointerTo(unsigned AddrSpace=0) const
Return a pointer to the current type.
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 ...
MachineIRBuilder & MIRBuilder
Value * getCalledOperand() const
@ MOStore
The memory access writes data.
bool resultsCompatible(CallLoweringInfo &Info, MachineFunction &MF, SmallVectorImpl< ArgInfo > &InArgs, CCAssignFn &CalleeAssignFnFixed, CCAssignFn &CalleeAssignFnVarArg, CCAssignFn &CallerAssignFnFixed, CCAssignFn &CallerAssignFnVarArg) const
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
void splitToValueTypes(const ArgInfo &OrigArgInfo, SmallVectorImpl< ArgInfo > &SplitArgs, const DataLayout &DL, CallingConv::ID CallConv) const
Break OrigArgInfo into one or more pieces the calling convention can process, returned in SplitArgs.
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...
Align getNonZeroByValAlign() const
MachineInstrBuilder buildSExt(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_SEXT Op.
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.
Align max(MaybeAlign Lhs, Align Rhs)
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.
Attribute getAttribute(unsigned i, Attribute::AttrKind Kind) const
gets the attribute from the list of attributes.
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...
const Value * OrigValue
Optionally track the original IR value for the argument.
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.
LLT getElementType() const
Returns the vector's element type. Only valid for vector types.
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
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
LLVM Value Representation.
bool isIncomingArgumentHandler() const
Returns true if the handler is dealing with incoming arguments, i.e.
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
reference emplace_back(ArgTypes &&... Args)
Wrapper class representing physical registers. Should be passed by value.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
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...
void setArgFlags(ArgInfo &Arg, unsigned OpIdx, const DataLayout &DL, const FuncInfoTy &FuncInfo) const