34#define DEBUG_TYPE "wasm-call-lowering"
55 return TargetOpcode::G_SEXT;
57 return TargetOpcode::G_ZEXT;
58 return TargetOpcode::G_ANYEXT;
62 if (Ty == MVT::externref) {
65 DL.getPointerSizeInBits(
69 if (Ty == MVT::funcref) {
72 DL.getPointerSizeInBits(
86 bool IsVarArg)
const {
108 "Return value without a vreg or vice versa");
119 "For each split Type there should be exactly one VReg.");
125 for (
EVT SplitEVT : SplitEVTs) {
127 ArgInfo CurRetInfo =
ArgInfo{CurVReg, SplitEVT.getTypeForEVT(Ctx), 0};
134 for (
ArgInfo &Ret : SplitRets) {
135 const EVT OrigVT = TLI.getValueType(
DL, Ret.Ty);
137 TLI.getRegisterTypeForCallingConv(Ctx, CallConv, OrigVT);
146 const unsigned NumParts =
147 TLI.getNumRegistersForCallingConv(Ctx, CallConv, OrigVT);
152 for (
unsigned Part = 0; Part < NumParts; ++Part) {
158 Flags.setOrigAlign(
Align(1));
159 if (Part == NumParts - 1)
163 Ret.Flags.push_back(Flags);
166 Ret.OrigRegs.assign(Ret.Regs.begin(), Ret.Regs.end());
167 if (NumParts != 1 || OrigLLT != NewLLT) {
170 Ret.Regs.resize(NumParts);
175 for (
unsigned Part = 0; Part < NumParts; ++Part) {
178 if (!RBI.constrainGenericRegister(NewOutReg, NewRegClass, MRI))
180 "Couldn't constrain brand-new register?");
184 Ret.Regs[Part] = NewOutReg;
196 if (SwiftErrorVReg) {
198 "Wasm does not `supportSwiftError`, yet SwiftErrorVReg is "
199 "improperly valid.");
209 return WebAssembly::ARGUMENT_i32;
211 return WebAssembly::ARGUMENT_i64;
213 return WebAssembly::ARGUMENT_f32;
215 return WebAssembly::ARGUMENT_f64;
218 return WebAssembly::ARGUMENT_funcref;
220 return WebAssembly::ARGUMENT_externref;
222 return WebAssembly::ARGUMENT_exnref;
225 return WebAssembly::ARGUMENT_v16i8;
227 return WebAssembly::ARGUMENT_v8i16;
229 return WebAssembly::ARGUMENT_v4i32;
231 return WebAssembly::ARGUMENT_v2i64;
233 return WebAssembly::ARGUMENT_v8f16;
235 return WebAssembly::ARGUMENT_v4f32;
237 return WebAssembly::ARGUMENT_v2f64;
275 bool HasSwiftErrorArg =
false;
276 bool HasSwiftSelfArg =
false;
278 ArgInfo OrigArg{VRegs[ArgIdx], Arg.getType(), ArgIdx};
279 setArgFlags(OrigArg, ArgIdx + AttributeList::FirstArgIndex,
DL,
F);
281 HasSwiftSelfArg |= Arg.hasSwiftSelfAttr();
282 HasSwiftErrorArg |= Arg.hasSwiftErrorAttr();
283 if (Arg.hasInAllocaAttr()) {
286 if (Arg.hasNestAttr()) {
293 unsigned FinalArgIdx = 0;
294 for (
ArgInfo &Arg : SplitArgs) {
295 const EVT OrigVT = TLI.getValueType(
DL, Arg.Ty);
296 const MVT NewVT = TLI.getRegisterTypeForCallingConv(Ctx, CallConv, OrigVT);
303 const unsigned NumParts =
304 TLI.getNumRegistersForCallingConv(Ctx, CallConv, OrigVT);
309 for (
unsigned Part = 0; Part < NumParts; ++Part) {
314 Flags.setOrigAlign(
Align(1));
315 if (Part == NumParts - 1)
319 Arg.Flags.push_back(Flags);
322 Arg.OrigRegs.assign(Arg.Regs.begin(), Arg.Regs.end());
323 if (NumParts != 1 || OrigLLT != NewLLT) {
326 Arg.Regs.resize(NumParts);
331 for (
unsigned Part = 0; Part < NumParts; ++Part) {
336 for (
unsigned Part = 0; Part < NumParts; ++Part) {
348 if (OrigVT != NewVT) {
359 const MVT PtrVT = TLI.getPointerTy(
DL);
361 if (!HasSwiftSelfArg) {
364 if (!HasSwiftErrorArg) {
372 const MVT PtrVT = TLI.getPointerTy(
DL, 0);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
static unsigned extendOpFromFlags(llvm::ISD::ArgFlagsTy Flags)
const HexagonInstrInfo * TII
Implement a low-level type suitable for MachineInstr level instruction selection.
This file declares the MachineIRBuilder class.
Register const TargetRegisterInfo * TRI
static bool callingConvSupported(CallingConv::ID CallConv)
static unsigned getWasmArgumentOpcode(MVT ArgType)
static LLT getLLTForWasmMVT(MVT Ty, const DataLayout &DL)
static unsigned extendOpFromFlags(ISD::ArgFlagsTy Flags)
This file describes how to lower LLVM calls to machine code calls.
This file defines the interfaces that WebAssembly uses to lower LLVM code into a selection DAG.
This file provides WebAssembly-specific target descriptions.
This file declares WebAssembly-specific per-machine-function information.
This file contains the WebAssembly implementation of the WebAssemblyRegisterInfo class.
This file declares the WebAssembly-specific subclass of TargetSubtarget.
This file contains the declaration of the WebAssembly-specific utility functions.
This class represents an incoming formal argument to a Function.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
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...
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 ...
CallLowering(const TargetLowering *TLI)
const TargetLowering * getTLI() const
Getter for generic TargetLowering class.
void setArgFlags(ArgInfo &Arg, unsigned OpIdx, const DataLayout &DL, const FuncInfoTy &FuncInfo) const
A parsed version of the target data layout string in and methods for querying it.
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
Register DemoteRegister
DemoteRegister - if CanLowerReturn is false, DemoteRegister is a vreg allocated to hold a pointer to ...
bool CanLowerReturn
CanLowerReturn - true iff the function's return value can be lowered to registers.
FunctionType * getFunctionType() const
Returns the FunctionType for me.
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
This is an important class for using LLVM in a threaded context.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineBasicBlock & front() const
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Helper class to build MachineInstr.
MachineInstrBuilder insertInstr(MachineInstrBuilder MIB)
Insert an existing instruction at the insertion point.
LLVMContext & getContext() const
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
MachineFunction & getMF()
Getter for the function we currently build.
MachineInstrBuilder buildInstrNoInsert(unsigned Opcode)
Build but don't insert <empty> = Opcode <empty>.
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
Holds all the information related to register banks.
Wrapper class representing virtual and physical registers.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val, ArrayRef< Register > VRegs, FunctionLoweringInfo &FLI, Register SwiftErrorVReg) const override
This hook must be implemented to lower outgoing return values, described by Val, into the specified v...
WebAssemblyCallLowering(const WebAssemblyTargetLowering &TLI)
bool lowerCall(MachineIRBuilder &MIRBuilder, CallLoweringInfo &Info) const override
This hook must be implemented to lower the given call instruction, including argument and return valu...
bool canLowerReturn(MachineFunction &MF, CallingConv::ID CallConv, SmallVectorImpl< BaseArgInfo > &Outs, bool IsVarArg) const override
This hook must be implemented to check whether the return values described by Outs can fit into the r...
bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F, ArrayRef< ArrayRef< Register > > VRegs, FunctionLoweringInfo &FLI) const override
This hook must be implemented to lower the incoming (formal) arguments, described by VRegs,...
This class is derived from MachineFunctionInfo and contains private WebAssembly-specific information ...
void setVarargBufferVreg(unsigned Reg)
const std::vector< MVT > & getParams() const
const WebAssemblyInstrInfo * getInstrInfo() const override
const WebAssemblyRegisterInfo * getRegisterInfo() const override
const RegisterBankInfo * getRegBankInfo() const override
#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.
@ Swift
Calling convention for Swift.
@ PreserveMost
Used for runtime calls that preserves most registers.
@ CXX_FAST_TLS
Used for access functions.
@ WASM_EmscriptenInvoke
For emscripten __invoke_* functions.
@ Cold
Attempts to make code in the caller as efficient as possible under the assumption that the call is no...
@ PreserveAll
Used for runtime calls that preserves (almost) all registers.
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
@ WASM_ADDRESS_SPACE_EXTERNREF
@ WASM_ADDRESS_SPACE_FUNCREF
bool canLowerReturn(size_t ResultSize, const WebAssemblySubtarget *Subtarget)
Returns true if the function's return value(s) can be lowered directly, i.e., not indirectly via a po...
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI Register constrainOperandRegClass(const MachineFunction &MF, const TargetRegisterInfo &TRI, MachineRegisterInfo &MRI, const TargetInstrInfo &TII, const RegisterBankInfo &RBI, MachineInstr &InsertPt, const TargetRegisterClass &RegClass, MachineOperand &RegMO)
Constrain the Register operand OpIdx, so that it is now constrained to the TargetRegisterClass passed...
void computeSignatureVTs(const FunctionType *Ty, const Function *TargetFunc, const Function &ContextFunc, const TargetMachine &TM, SmallVectorImpl< MVT > &Params, SmallVectorImpl< MVT > &Results)
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...
LLVM_ABI LLT getLLTForMVT(MVT Ty)
Get a rough equivalent of an LLT for a given MVT.
LLVM_ABI void reportFatalInternalError(Error Err)
Report a fatal error that indicates a bug in LLVM.
LLVM_ABI LLT getLLTForType(Type &Ty, const DataLayout &DL)
Construct a low-level type based on an LLVM type.
This struct is a compact representation of a valid (non-zero power of two) alignment.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.