1 //- WebAssemblyISelLowering.h - WebAssembly DAG Lowering Interface -*- C++ -*-//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 /// This file defines the interfaces that WebAssembly uses to lower LLVM
11 /// code into a selection DAG.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYISELLOWERING_H
16 #define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYISELLOWERING_H
18 #include "llvm/CodeGen/TargetLowering.h"
22 namespace WebAssemblyISD
{
24 enum NodeType
: unsigned {
25 FIRST_NUMBER
= ISD::BUILTIN_OP_END
,
26 #define HANDLE_NODETYPE(NODE) NODE,
27 #define HANDLE_MEM_NODETYPE(NODE)
28 #include "WebAssemblyISD.def"
29 FIRST_MEM_OPCODE
= ISD::FIRST_TARGET_MEMORY_OPCODE
,
30 #undef HANDLE_NODETYPE
31 #undef HANDLE_MEM_NODETYPE
32 #define HANDLE_NODETYPE(NODE)
33 #define HANDLE_MEM_NODETYPE(NODE) NODE,
34 #include "WebAssemblyISD.def"
35 #undef HANDLE_NODETYPE
36 #undef HANDLE_MEM_NODETYPE
39 } // end namespace WebAssemblyISD
41 class WebAssemblySubtarget
;
43 class WebAssemblyTargetLowering final
: public TargetLowering
{
45 WebAssemblyTargetLowering(const TargetMachine
&TM
,
46 const WebAssemblySubtarget
&STI
);
48 enum WasmAddressSpace
: unsigned {
49 // WebAssembly uses the following address spaces:
50 // AS 0 : is the default address space for values in linear memory
52 // AS 1 : is a non-integral address space for global variables
54 // AS 10 : is a non-integral address space for externref values
56 // AS 20 : is a non-integral address space for funcref values
60 MVT
getPointerTy(const DataLayout
&DL
, uint32_t AS
= 0) const override
{
61 if (AS
== WasmAddressSpace::EXTERNREF
)
62 return MVT::externref
;
63 if (AS
== WasmAddressSpace::FUNCREF
)
65 return TargetLowering::getPointerTy(DL
, AS
);
67 MVT
getPointerMemTy(const DataLayout
&DL
, uint32_t AS
= 0) const override
{
68 if (AS
== WasmAddressSpace::EXTERNREF
)
69 return MVT::externref
;
70 if (AS
== WasmAddressSpace::FUNCREF
)
72 return TargetLowering::getPointerMemTy(DL
, AS
);
75 static bool isFuncrefType(const Type
*Ty
);
76 static bool isExternrefType(const Type
*Ty
);
79 /// Keep a pointer to the WebAssemblySubtarget around so that we can make the
80 /// right decision when generating code for different targets.
81 const WebAssemblySubtarget
*Subtarget
;
83 AtomicExpansionKind
shouldExpandAtomicRMWInIR(AtomicRMWInst
*) const override
;
84 bool shouldScalarizeBinop(SDValue VecOp
) const override
;
85 FastISel
*createFastISel(FunctionLoweringInfo
&FuncInfo
,
86 const TargetLibraryInfo
*LibInfo
) const override
;
87 MVT
getScalarShiftAmountTy(const DataLayout
&DL
, EVT
) const override
;
89 EmitInstrWithCustomInserter(MachineInstr
&MI
,
90 MachineBasicBlock
*MBB
) const override
;
91 const char *getTargetNodeName(unsigned Opcode
) const override
;
92 std::pair
<unsigned, const TargetRegisterClass
*>
93 getRegForInlineAsmConstraint(const TargetRegisterInfo
*TRI
,
94 StringRef Constraint
, MVT VT
) const override
;
95 bool isCheapToSpeculateCttz() const override
;
96 bool isCheapToSpeculateCtlz() const override
;
97 bool isLegalAddressingMode(const DataLayout
&DL
, const AddrMode
&AM
, Type
*Ty
,
99 Instruction
*I
= nullptr) const override
;
100 bool allowsMisalignedMemoryAccesses(EVT
, unsigned AddrSpace
, Align Alignment
,
101 MachineMemOperand::Flags Flags
,
102 bool *Fast
) const override
;
103 bool isIntDivCheap(EVT VT
, AttributeList Attr
) const override
;
104 bool isVectorLoadExtDesirable(SDValue ExtVal
) const override
;
105 bool isOffsetFoldingLegal(const GlobalAddressSDNode
*GA
) const override
;
106 EVT
getSetCCResultType(const DataLayout
&DL
, LLVMContext
&Context
,
107 EVT VT
) const override
;
108 bool getTgtMemIntrinsic(IntrinsicInfo
&Info
, const CallInst
&I
,
110 unsigned Intrinsic
) const override
;
112 void computeKnownBitsForTargetNode(const SDValue Op
, KnownBits
&Known
,
113 const APInt
&DemandedElts
,
114 const SelectionDAG
&DAG
,
115 unsigned Depth
) const override
;
117 TargetLoweringBase::LegalizeTypeAction
118 getPreferredVectorAction(MVT VT
) const override
;
120 SDValue
LowerCall(CallLoweringInfo
&CLI
,
121 SmallVectorImpl
<SDValue
> &InVals
) const override
;
122 bool CanLowerReturn(CallingConv::ID CallConv
, MachineFunction
&MF
,
124 const SmallVectorImpl
<ISD::OutputArg
> &Outs
,
125 LLVMContext
&Context
) const override
;
126 SDValue
LowerReturn(SDValue Chain
, CallingConv::ID CallConv
, bool isVarArg
,
127 const SmallVectorImpl
<ISD::OutputArg
> &Outs
,
128 const SmallVectorImpl
<SDValue
> &OutVals
, const SDLoc
&dl
,
129 SelectionDAG
&DAG
) const override
;
130 SDValue
LowerFormalArguments(SDValue Chain
, CallingConv::ID CallConv
,
132 const SmallVectorImpl
<ISD::InputArg
> &Ins
,
133 const SDLoc
&DL
, SelectionDAG
&DAG
,
134 SmallVectorImpl
<SDValue
> &InVals
) const override
;
136 void ReplaceNodeResults(SDNode
*N
, SmallVectorImpl
<SDValue
> &Results
,
137 SelectionDAG
&DAG
) const override
;
139 const char *getClearCacheBuiltinName() const override
{
140 report_fatal_error("llvm.clear_cache is not supported on wasm");
143 // Custom lowering hooks.
144 SDValue
LowerOperation(SDValue Op
, SelectionDAG
&DAG
) const override
;
145 SDValue
LowerFrameIndex(SDValue Op
, SelectionDAG
&DAG
) const;
146 SDValue
LowerRETURNADDR(SDValue Op
, SelectionDAG
&DAG
) const;
147 SDValue
LowerFRAMEADDR(SDValue Op
, SelectionDAG
&DAG
) const;
148 SDValue
LowerGlobalAddress(SDValue Op
, SelectionDAG
&DAG
) const;
149 SDValue
LowerGlobalTLSAddress(SDValue Op
, SelectionDAG
&DAG
) const;
150 SDValue
LowerExternalSymbol(SDValue Op
, SelectionDAG
&DAG
) const;
151 SDValue
LowerBR_JT(SDValue Op
, SelectionDAG
&DAG
) const;
152 SDValue
LowerJumpTable(SDValue Op
, SelectionDAG
&DAG
) const;
153 SDValue
LowerVASTART(SDValue Op
, SelectionDAG
&DAG
) const;
154 SDValue
LowerCopyToReg(SDValue Op
, SelectionDAG
&DAG
) const;
155 SDValue
LowerIntrinsic(SDValue Op
, SelectionDAG
&DAG
) const;
156 SDValue
LowerSIGN_EXTEND_INREG(SDValue Op
, SelectionDAG
&DAG
) const;
157 SDValue
LowerBUILD_VECTOR(SDValue Op
, SelectionDAG
&DAG
) const;
158 SDValue
LowerVECTOR_SHUFFLE(SDValue Op
, SelectionDAG
&DAG
) const;
159 SDValue
LowerSETCC(SDValue Op
, SelectionDAG
&DAG
) const;
160 SDValue
LowerAccessVectorElement(SDValue Op
, SelectionDAG
&DAG
) const;
161 SDValue
LowerShift(SDValue Op
, SelectionDAG
&DAG
) const;
162 SDValue
LowerFP_TO_INT_SAT(SDValue Op
, SelectionDAG
&DAG
) const;
163 SDValue
LowerLoad(SDValue Op
, SelectionDAG
&DAG
) const;
164 SDValue
LowerStore(SDValue Op
, SelectionDAG
&DAG
) const;
166 // Custom DAG combine hooks
168 PerformDAGCombine(SDNode
*N
,
169 TargetLowering::DAGCombinerInfo
&DCI
) const override
;
172 namespace WebAssembly
{
173 FastISel
*createFastISel(FunctionLoweringInfo
&funcInfo
,
174 const TargetLibraryInfo
*libInfo
);
175 } // end namespace WebAssembly
177 } // end namespace llvm