10b57cec5SDimitry Andric //- WebAssemblyISelLowering.h - WebAssembly DAG Lowering Interface -*- C++ -*-// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric /// 90b57cec5SDimitry Andric /// \file 100b57cec5SDimitry Andric /// This file defines the interfaces that WebAssembly uses to lower LLVM 110b57cec5SDimitry Andric /// code into a selection DAG. 120b57cec5SDimitry Andric /// 130b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYISELLOWERING_H 160b57cec5SDimitry Andric #define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYISELLOWERING_H 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric #include "llvm/CodeGen/TargetLowering.h" 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric namespace llvm { 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric namespace WebAssemblyISD { 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric enum NodeType : unsigned { 250b57cec5SDimitry Andric FIRST_NUMBER = ISD::BUILTIN_OP_END, 260b57cec5SDimitry Andric #define HANDLE_NODETYPE(NODE) NODE, 27480093f4SDimitry Andric #define HANDLE_MEM_NODETYPE(NODE) 28480093f4SDimitry Andric #include "WebAssemblyISD.def" 29480093f4SDimitry Andric FIRST_MEM_OPCODE = ISD::FIRST_TARGET_MEMORY_OPCODE, 30480093f4SDimitry Andric #undef HANDLE_NODETYPE 31480093f4SDimitry Andric #undef HANDLE_MEM_NODETYPE 32480093f4SDimitry Andric #define HANDLE_NODETYPE(NODE) 33480093f4SDimitry Andric #define HANDLE_MEM_NODETYPE(NODE) NODE, 340b57cec5SDimitry Andric #include "WebAssemblyISD.def" 350b57cec5SDimitry Andric #undef HANDLE_NODETYPE 36480093f4SDimitry Andric #undef HANDLE_MEM_NODETYPE 370b57cec5SDimitry Andric }; 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric } // end namespace WebAssemblyISD 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric class WebAssemblySubtarget; 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric class WebAssemblyTargetLowering final : public TargetLowering { 440b57cec5SDimitry Andric public: 450b57cec5SDimitry Andric WebAssemblyTargetLowering(const TargetMachine &TM, 460b57cec5SDimitry Andric const WebAssemblySubtarget &STI); 470b57cec5SDimitry Andric 48349cc55cSDimitry Andric MVT getPointerTy(const DataLayout &DL, uint32_t AS = 0) const override; 49349cc55cSDimitry Andric MVT getPointerMemTy(const DataLayout &DL, uint32_t AS = 0) const override; 50fe6060f1SDimitry Andric 510b57cec5SDimitry Andric private: 520b57cec5SDimitry Andric /// Keep a pointer to the WebAssemblySubtarget around so that we can make the 530b57cec5SDimitry Andric /// right decision when generating code for different targets. 540b57cec5SDimitry Andric const WebAssemblySubtarget *Subtarget; 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *) const override; 57fe6060f1SDimitry Andric bool shouldScalarizeBinop(SDValue VecOp) const override; 580b57cec5SDimitry Andric FastISel *createFastISel(FunctionLoweringInfo &FuncInfo, 590b57cec5SDimitry Andric const TargetLibraryInfo *LibInfo) const override; 600b57cec5SDimitry Andric MVT getScalarShiftAmountTy(const DataLayout &DL, EVT) const override; 610b57cec5SDimitry Andric MachineBasicBlock * 620b57cec5SDimitry Andric EmitInstrWithCustomInserter(MachineInstr &MI, 630b57cec5SDimitry Andric MachineBasicBlock *MBB) const override; 640b57cec5SDimitry Andric const char *getTargetNodeName(unsigned Opcode) const override; 650b57cec5SDimitry Andric std::pair<unsigned, const TargetRegisterClass *> 660b57cec5SDimitry Andric getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, 670b57cec5SDimitry Andric StringRef Constraint, MVT VT) const override; 68bdd1243dSDimitry Andric bool isCheapToSpeculateCttz(Type *Ty) const override; 69bdd1243dSDimitry Andric bool isCheapToSpeculateCtlz(Type *Ty) const override; 700b57cec5SDimitry Andric bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, 710b57cec5SDimitry Andric unsigned AS, 720b57cec5SDimitry Andric Instruction *I = nullptr) const override; 73fe6060f1SDimitry Andric bool allowsMisalignedMemoryAccesses(EVT, unsigned AddrSpace, Align Alignment, 740b57cec5SDimitry Andric MachineMemOperand::Flags Flags, 75bdd1243dSDimitry Andric unsigned *Fast) const override; 760b57cec5SDimitry Andric bool isIntDivCheap(EVT VT, AttributeList Attr) const override; 778bcb0991SDimitry Andric bool isVectorLoadExtDesirable(SDValue ExtVal) const override; 78349cc55cSDimitry Andric bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; 79*5f757f3fSDimitry Andric bool shouldSinkOperands(Instruction *I, 80*5f757f3fSDimitry Andric SmallVectorImpl<Use *> &Ops) const override; 810b57cec5SDimitry Andric EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, 820b57cec5SDimitry Andric EVT VT) const override; 830b57cec5SDimitry Andric bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I, 840b57cec5SDimitry Andric MachineFunction &MF, 850b57cec5SDimitry Andric unsigned Intrinsic) const override; 860b57cec5SDimitry Andric 87349cc55cSDimitry Andric void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, 88349cc55cSDimitry Andric const APInt &DemandedElts, 89349cc55cSDimitry Andric const SelectionDAG &DAG, 90349cc55cSDimitry Andric unsigned Depth) const override; 91349cc55cSDimitry Andric 92349cc55cSDimitry Andric TargetLoweringBase::LegalizeTypeAction 93349cc55cSDimitry Andric getPreferredVectorAction(MVT VT) const override; 94349cc55cSDimitry Andric 950b57cec5SDimitry Andric SDValue LowerCall(CallLoweringInfo &CLI, 960b57cec5SDimitry Andric SmallVectorImpl<SDValue> &InVals) const override; 970b57cec5SDimitry Andric bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, 980b57cec5SDimitry Andric bool isVarArg, 990b57cec5SDimitry Andric const SmallVectorImpl<ISD::OutputArg> &Outs, 1000b57cec5SDimitry Andric LLVMContext &Context) const override; 1010b57cec5SDimitry Andric SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, 1020b57cec5SDimitry Andric const SmallVectorImpl<ISD::OutputArg> &Outs, 1030b57cec5SDimitry Andric const SmallVectorImpl<SDValue> &OutVals, const SDLoc &dl, 1040b57cec5SDimitry Andric SelectionDAG &DAG) const override; 1050b57cec5SDimitry Andric SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, 1060b57cec5SDimitry Andric bool IsVarArg, 1070b57cec5SDimitry Andric const SmallVectorImpl<ISD::InputArg> &Ins, 1080b57cec5SDimitry Andric const SDLoc &DL, SelectionDAG &DAG, 1090b57cec5SDimitry Andric SmallVectorImpl<SDValue> &InVals) const override; 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results, 1120b57cec5SDimitry Andric SelectionDAG &DAG) const override; 1130b57cec5SDimitry Andric 11481ad6265SDimitry Andric bool 11581ad6265SDimitry Andric shouldSimplifyDemandedVectorElts(SDValue Op, 11681ad6265SDimitry Andric const TargetLoweringOpt &TLO) const override; 11781ad6265SDimitry Andric 1180b57cec5SDimitry Andric // Custom lowering hooks. 1190b57cec5SDimitry Andric SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; 1200b57cec5SDimitry Andric SDValue LowerFrameIndex(SDValue Op, SelectionDAG &DAG) const; 1210b57cec5SDimitry Andric SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const; 1220b57cec5SDimitry Andric SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; 1230b57cec5SDimitry Andric SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; 124e8d8bef9SDimitry Andric SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; 1250b57cec5SDimitry Andric SDValue LowerExternalSymbol(SDValue Op, SelectionDAG &DAG) const; 1260b57cec5SDimitry Andric SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG) const; 1270b57cec5SDimitry Andric SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const; 1280b57cec5SDimitry Andric SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const; 1290b57cec5SDimitry Andric SDValue LowerCopyToReg(SDValue Op, SelectionDAG &DAG) const; 1300b57cec5SDimitry Andric SDValue LowerIntrinsic(SDValue Op, SelectionDAG &DAG) const; 1310b57cec5SDimitry Andric SDValue LowerSIGN_EXTEND_INREG(SDValue Op, SelectionDAG &DAG) const; 13206c3fb27SDimitry Andric SDValue LowerEXTEND_VECTOR_INREG(SDValue Op, SelectionDAG &DAG) const; 1330b57cec5SDimitry Andric SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const; 1340b57cec5SDimitry Andric SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const; 135480093f4SDimitry Andric SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const; 1360b57cec5SDimitry Andric SDValue LowerAccessVectorElement(SDValue Op, SelectionDAG &DAG) const; 1370b57cec5SDimitry Andric SDValue LowerShift(SDValue Op, SelectionDAG &DAG) const; 138fe6060f1SDimitry Andric SDValue LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const; 139fe6060f1SDimitry Andric SDValue LowerLoad(SDValue Op, SelectionDAG &DAG) const; 140fe6060f1SDimitry Andric SDValue LowerStore(SDValue Op, SelectionDAG &DAG) const; 1415ffd83dbSDimitry Andric 1425ffd83dbSDimitry Andric // Custom DAG combine hooks 1435ffd83dbSDimitry Andric SDValue 1445ffd83dbSDimitry Andric PerformDAGCombine(SDNode *N, 1455ffd83dbSDimitry Andric TargetLowering::DAGCombinerInfo &DCI) const override; 1460b57cec5SDimitry Andric }; 1470b57cec5SDimitry Andric 1480b57cec5SDimitry Andric namespace WebAssembly { 1490b57cec5SDimitry Andric FastISel *createFastISel(FunctionLoweringInfo &funcInfo, 1500b57cec5SDimitry Andric const TargetLibraryInfo *libInfo); 1510b57cec5SDimitry Andric } // end namespace WebAssembly 1520b57cec5SDimitry Andric 1530b57cec5SDimitry Andric } // end namespace llvm 1540b57cec5SDimitry Andric 1550b57cec5SDimitry Andric #endif 156