35 #define DEBUG_TYPE "wasm-lower"
51 Subtarget->
hasAddr64() ? WebAssembly::SP64 : WebAssembly::SP32);
146 FastISel *WebAssemblyTargetLowering::createFastISel(
151 bool WebAssemblyTargetLowering::isOffsetFoldingLegal(
157 MVT WebAssemblyTargetLowering::getScalarShiftAmountTy(
const DataLayout & ,
160 if (BitWidth > 1 && BitWidth < 8) BitWidth = 8;
167 "32-bit shift counts ought to be enough for anyone");
172 "Unable to represent scalar shift amount type");
176 const char *WebAssemblyTargetLowering::getTargetNodeName(
177 unsigned Opcode)
const {
178 switch (static_cast<WebAssemblyISD::NodeType>(Opcode)) {
181 #define HANDLE_NODETYPE(NODE) \
182 case WebAssemblyISD::NODE: \
183 return "WebAssemblyISD::" #NODE;
184 #include "WebAssemblyISD.def"
185 #undef HANDLE_NODETYPE
190 std::pair<unsigned, const TargetRegisterClass *>
191 WebAssemblyTargetLowering::getRegForInlineAsmConstraint(
195 if (Constraint.
size() == 1) {
196 switch (Constraint[0]) {
201 return std::make_pair(0U, &WebAssembly::V128RegClass);
205 return std::make_pair(0U, &WebAssembly::I32RegClass);
207 return std::make_pair(0U, &WebAssembly::I64RegClass);
218 bool WebAssemblyTargetLowering::isCheapToSpeculateCttz()
const {
223 bool WebAssemblyTargetLowering::isCheapToSpeculateCtlz()
const {
228 bool WebAssemblyTargetLowering::isLegalAddressingMode(
const DataLayout &DL,
235 if (AM.BaseOffs < 0)
return false;
238 if (AM.Scale != 0)
return false;
244 bool WebAssemblyTargetLowering::allowsMisalignedMemoryAccesses(
245 EVT ,
unsigned ,
unsigned ,
bool *
Fast)
const {
252 if (Fast) *Fast =
true;
256 bool WebAssemblyTargetLowering::isIntDivCheap(
EVT VT,
AttributeSet Attr)
const {
289 SDValue WebAssemblyTargetLowering::LowerCall(
301 "WebAssembly doesn't support language-specific or target-specific "
302 "calling conventions yet");
303 if (CLI.IsPatchPoint)
304 fail(DL, DAG,
"WebAssembly doesn't support patch point yet");
310 (CLI.CS && CLI.CS->isMustTailCall()))
311 fail(DL, DAG,
"WebAssembly doesn't support tail call yet");
312 CLI.IsTailCall =
false;
316 fail(DL, DAG,
"WebAssembly doesn't support more than 1 returned value yet");
320 for (
unsigned i = 0;
i < Outs.
size(); ++
i) {
324 fail(DL, DAG,
"WebAssembly hasn't implemented nest arguments");
326 fail(DL, DAG,
"WebAssembly hasn't implemented inalloca arguments");
328 fail(DL, DAG,
"WebAssembly hasn't implemented cons regs arguments");
330 fail(DL, DAG,
"WebAssembly hasn't implemented cons regs last arguments");
347 bool IsVarArg = CLI.IsVarArg;
361 EVT VT = Arg.getValueType();
364 unsigned Offset = CCInfo.AllocateStack(Layout.getTypeAllocSize(Ty),
365 Layout.getABITypeAlignment(Ty));
372 unsigned NumBytes = CCInfo.getAlignedCallFrameSize();
375 if (IsVarArg && NumBytes) {
379 Layout.getStackAlignment(),
385 assert(ArgLocs[ValNo].getValNo() == ValNo &&
386 "ArgLocs should remain in order and only hold varargs args");
387 unsigned Offset = ArgLocs[ValNo++].getLocMemOffset();
397 }
else if (IsVarArg) {
409 IsVarArg ? OutVals.
begin() + NumFixedArgs : OutVals.
end());
414 for (
const auto &
In : Ins) {
415 assert(!
In.Flags.isByVal() &&
"byval is not valid for return values");
416 assert(!
In.Flags.isNest() &&
"nest is not valid for return values");
417 if (
In.Flags.isInAlloca())
418 fail(DL, DAG,
"WebAssembly hasn't implemented inalloca return values");
419 if (
In.Flags.isInConsecutiveRegs())
420 fail(DL, DAG,
"WebAssembly hasn't implemented cons regs return values");
421 if (
In.Flags.isInConsecutiveRegsLast())
423 "WebAssembly hasn't implemented cons regs last return values");
431 DAG.
getNode(Ins.empty() ? WebAssemblyISD::CALL0 : WebAssemblyISD::CALL1,
443 bool WebAssemblyTargetLowering::CanLowerReturn(
448 return Outs.
size() <= 1;
451 SDValue WebAssemblyTargetLowering::LowerReturn(
456 assert(Outs.
size() <= 1 &&
"WebAssembly can only return up to one value");
458 fail(DL, DAG,
"WebAssembly doesn't support non-C calling conventions");
461 RetOps.append(OutVals.
begin(), OutVals.
end());
468 assert(Out.
IsFixed &&
"non-fixed return value is not valid");
470 fail(DL, DAG,
"WebAssembly hasn't implemented inalloca results");
472 fail(DL, DAG,
"WebAssembly hasn't implemented cons regs results");
474 fail(DL, DAG,
"WebAssembly hasn't implemented cons regs last results");
480 SDValue WebAssemblyTargetLowering::LowerFormalArguments(
485 fail(DL, DAG,
"WebAssembly doesn't support non-C calling conventions");
495 if (
In.Flags.isInAlloca())
496 fail(DL, DAG,
"WebAssembly hasn't implemented inalloca arguments");
497 if (
In.Flags.isNest())
498 fail(DL, DAG,
"WebAssembly hasn't implemented nest arguments");
499 if (
In.Flags.isInConsecutiveRegs())
500 fail(DL, DAG,
"WebAssembly hasn't implemented cons regs arguments");
501 if (
In.Flags.isInConsecutiveRegsLast())
502 fail(DL, DAG,
"WebAssembly hasn't implemented cons regs last arguments");
507 ? DAG.
getNode(WebAssemblyISD::ARGUMENT, DL,
In.VT,
512 MFI->addParam(
In.VT);
519 unsigned VarargVreg =
521 MFI->setVarargBufferVreg(VarargVreg);
523 Chain, DL, VarargVreg,
524 DAG.
getNode(WebAssemblyISD::ARGUMENT, DL, PtrVT,
526 MFI->addParam(PtrVT);
533 for (
MVT VT : Results)
551 return LowerFrameIndex(Op, DAG);
553 return LowerGlobalAddress(Op, DAG);
555 return LowerExternalSymbol(Op, DAG);
557 return LowerJumpTable(Op, DAG);
559 return LowerBR_JT(Op, DAG);
561 return LowerVASTART(Op, DAG);
564 fail(DL, DAG,
"WebAssembly hasn't implemented computed gotos");
567 fail(DL, DAG,
"WebAssembly hasn't implemented __builtin_return_address");
570 return LowerFRAMEADDR(Op, DAG);
572 return LowerCopyToReg(Op, DAG);
579 if (isa<FrameIndexSDNode>(Src.
getNode())) {
591 : WebAssembly::COPY_I64,
605 int FI = cast<FrameIndexSDNode>(
Op)->getIndex();
627 const auto *GA = cast<GlobalAddressSDNode>(
Op);
629 assert(GA->getTargetFlags() == 0 &&
630 "Unexpected target flags on generic GlobalAddressSDNode");
631 if (GA->getAddressSpace() != 0)
632 fail(DL, DAG,
"WebAssembly only expects the 0 address space");
638 SDValue WebAssemblyTargetLowering::LowerExternalSymbol(
641 const auto *
ES = cast<ExternalSymbolSDNode>(
Op);
644 "Unexpected target flags on generic ExternalSymbolSDNode");
669 const auto *JT = cast<JumpTableSDNode>(Op.
getOperand(1));
675 Ops.push_back(Index);
700 MFI->getVarargBufferVreg(), PtrVT);
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, unsigned Alignment=0, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
void setFrameAddressIsTaken(bool T)
static MVT getIntegerVT(unsigned BitWidth)
void push_back(const T &Elt)
unsigned Log2_32_Ceil(uint32_t Value)
Log2_32_Ceil - This function returns the ceil log base 2 of the specified value, 32 if the value is z...
This file defines the interfaces that WebAssembly uses to lower LLVM code into a selection DAG...
A parsed version of the target data layout string in and methods for querying it. ...
SDValue getValue(unsigned R) const
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
LLVMContext * getContext() const
Diagnostic information for unsupported feature in backend.
BR_CC - Conditional branch.
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
void addLiveIn(unsigned Reg, unsigned vreg=0)
addLiveIn - Add the specified register as a live-in.
Carry-setting nodes for multiple precision addition and subtraction.
static void fail(const SDLoc &DL, SelectionDAG &DAG, const char *msg)
const TargetMachine & getTarget() const
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain...
void setHasFloatingPointExceptions(bool FPExceptions=true)
Tells the code generator that this target supports floating point exceptions and cares about preservi...
SDValue getBasicBlock(MachineBasicBlock *MBB)
Function Alias Analysis Results
Type * getTypeForEVT(LLVMContext &Context) const
getTypeForEVT - This method returns an LLVM type corresponding to the specified EVT.
unsigned getSizeInBits() const
unsigned getByValSize() const
unsigned getNumOperands() const
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned char TargetFlags=0)
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations...
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
const std::vector< MachineJumpTableEntry > & getJumpTables() const
FastISel * createFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo)
MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s), MachineInstr opcode, and operands.
MachineFunction & getMachineFunction() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
CopyToReg - This node has three operands: a chain, a register number to set to this value...
Reg
All possible values of the reg field in the ModR/M byte.
void setCondCodeAction(ISD::CondCode CC, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
OutputArg - This struct carries flags and a value for a single outgoing (actual) argument or outgoing...
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
LLVM_NODISCARD bool empty() const
STACKSAVE - STACKSAVE has one operand, an input chain.
bool isInConsecutiveRegs() const
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
This file declares the WebAssembly-specific subclass of TargetMachine.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose...
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
SDValue getTargetFrameIndex(int FI, EVT VT)
Simple integer binary arithmetic operators.
const MachineJumpTableInfo * getJumpTableInfo() const
getJumpTableInfo - Return the jump table info object for the current function.
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
bool isInConsecutiveRegsLast() const
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
bool IsFixed
IsFixed - Is this a "fixed" value, ie not passed through a vararg "...".
SDNode * getNode() const
get the SDNode which holds the desired result
bool isInteger() const
isInteger - Return true if this is an integer, or a vector integer type.
static bool CallingConvSupported(CallingConv::ID CallConv)
MVT - Machine Value Type.
const SDValue & getOperand(unsigned i) const
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important class for using LLVM in a threaded context.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type...
void ComputeSignatureVTs(const Function &F, const TargetMachine &TM, SmallVectorImpl< MVT > &Params, SmallVectorImpl< MVT > &Results)
C - The default llvm calling convention, compatible with C.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE...
bool isVector() const
isVector - Return true if this is a vector value type.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
Carry-using nodes for multiple precision addition and subtraction.
This file provides WebAssembly-specific target descriptions.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
unsigned getOpcode() const
TRAP - Trapping instruction.
unsigned GuaranteedTailCallOpt
GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is specified on the commandline...
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
unsigned char getTargetFlags() const
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
static unsigned NumFixedArgs
EVT - Extended Value Type.
uint64_t NextPowerOf2(uint64_t A)
NextPowerOf2 - Returns the next power of two (in 64-bits) that is strictly greater than A...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
This class contains a discriminated union of information about pointers in memory operands...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned getByValAlign() const
WebAssemblyTargetLowering(const TargetMachine &TM, const WebAssemblySubtarget &STI)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned char TargetFlags=0)
TokenFactor - This node takes multiple tokens as input and produces a single token result...
This file declares the WebAssembly-specific subclass of TargetSubtarget.
CCState - This class holds information needed while lowering arguments and return values...
const DebugLoc & getDebugLoc() const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Provides information about what library functions are available for the current target.
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, unsigned Align, bool isVol, bool AlwaysInline, bool isTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo)
Byte Swap and Counting operators.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
static mvt_range integer_valuetypes()
unsigned getFrameRegister(const MachineFunction &MF) const override
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
virtual const TargetRegisterClass * getRegClassFor(MVT VT) const
Return the register class that should be used for the specified value type.
AddrMode
ARM Addressing Modes.
FMINNAN/FMAXNAN - Behave identically to FMINNUM/FMAXNUM, except that when a single input is NaN...
const WebAssemblyRegisterInfo * getRegisterInfo() const override
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
BR_JT - Jumptable branch.
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer, a SRCVALUE for the destination, and a SRCVALUE for the source.
This class is derived from MachineFunctionInfo and contains private WebAssembly-specific information ...
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
uint64_t getConstantOperandVal(unsigned i) const
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
unsigned getSizeInBits() const
getSizeInBits - Return the size of the specified value type in bits.
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
This file declares WebAssembly-specific per-machine-function information.
void setStackPointerRegisterToSaveRestore(unsigned R)
If set to a physical register, this specifies the register that llvm.savestack/llvm.restorestack should save and restore.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
static CCValAssign getMem(unsigned ValNo, MVT ValVT, unsigned Offset, MVT LocVT, LocInfo HTP)
FSINCOS - Compute both fsin and fcos as a single operation.
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS, const AllocaInst *Alloca=nullptr)
Create a new statically sized stack object, returning a nonnegative identifier to represent it...
EVT getValueType() const
Return the ValueType of the referenced return value.
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
LLVM Value Representation.
FMA - Perform a * b + c with no intermediate rounding step.
Primary interface to the complete machine description for the target machine.
StringRef - Represent a constant reference to a string, i.e.
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
Fast - This calling convention attempts to make calls as fast as possible (e.g.
MVT getSimpleVT() const
getSimpleVT - Return the SimpleValueType held in the specified simple EVT.
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned char TargetFlags=0)
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary...