1 //===-- NVPTXISelDAGToDAG.h - A dag to dag inst selector for NVPTX --------===// 2 // 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 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines an instruction selector for the NVPTX target. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_LIB_TARGET_NVPTX_NVPTXISELDAGTODAG_H 14 #define LLVM_LIB_TARGET_NVPTX_NVPTXISELDAGTODAG_H 15 16 #include "MCTargetDesc/NVPTXBaseInfo.h" 17 #include "NVPTX.h" 18 #include "NVPTXISelLowering.h" 19 #include "NVPTXRegisterInfo.h" 20 #include "NVPTXTargetMachine.h" 21 #include "llvm/ADT/MapVector.h" 22 #include "llvm/CodeGen/SelectionDAGISel.h" 23 #include "llvm/IR/InlineAsm.h" 24 #include "llvm/IR/Intrinsics.h" 25 #include "llvm/IR/LLVMContext.h" 26 #include "llvm/Support/Compiler.h" 27 28 namespace llvm { 29 30 struct NVPTXScopes { 31 NVPTXScopes() = default; 32 NVPTXScopes(LLVMContext &C); 33 NVPTX::Scope operator[](SyncScope::ID ID) const; 34 bool empty() const; 35 36 private: 37 SmallMapVector<SyncScope::ID, NVPTX::Scope, 8> Scopes{}; 38 }; 39 40 class LLVM_LIBRARY_VISIBILITY NVPTXDAGToDAGISel : public SelectionDAGISel { 41 const NVPTXTargetMachine &TM; 42 43 // If true, generate mul.wide from sext and mul 44 bool doMulWide; 45 46 int getDivF32Level() const; 47 bool usePrecSqrtF32() const; 48 bool useF32FTZ() const; 49 bool allowFMA() const; 50 bool allowUnsafeFPMath() const; 51 bool doRsqrtOpt() const; 52 53 NVPTXScopes Scopes{}; 54 55 public: 56 NVPTXDAGToDAGISel() = delete; 57 58 explicit NVPTXDAGToDAGISel(NVPTXTargetMachine &tm, CodeGenOptLevel OptLevel); 59 60 bool runOnMachineFunction(MachineFunction &MF) override; 61 const NVPTXSubtarget *Subtarget = nullptr; 62 63 bool SelectInlineAsmMemoryOperand(const SDValue &Op, 64 InlineAsm::ConstraintCode ConstraintID, 65 std::vector<SDValue> &OutOps) override; 66 67 private: 68 // Include the pieces autogenerated from the target description. 69 #include "NVPTXGenDAGISel.inc" 70 71 void Select(SDNode *N) override; 72 bool tryIntrinsicNoChain(SDNode *N); 73 bool tryIntrinsicChain(SDNode *N); 74 bool tryIntrinsicVoid(SDNode *N); 75 void SelectTexSurfHandle(SDNode *N); 76 bool tryLoad(SDNode *N); 77 bool tryLoadVector(SDNode *N); 78 bool tryLDGLDU(SDNode *N); 79 bool tryStore(SDNode *N); 80 bool tryStoreVector(SDNode *N); 81 bool tryLoadParam(SDNode *N); 82 bool tryStoreRetval(SDNode *N); 83 bool tryStoreParam(SDNode *N); 84 bool tryFence(SDNode *N); 85 void SelectAddrSpaceCast(SDNode *N); 86 bool tryBFE(SDNode *N); 87 bool tryBF16ArithToFMA(SDNode *N); 88 bool tryConstantFP(SDNode *N); 89 bool SelectSETP_F16X2(SDNode *N); 90 bool SelectSETP_BF16X2(SDNode *N); 91 bool tryEXTRACT_VECTOR_ELEMENT(SDNode *N); 92 void SelectV2I64toI128(SDNode *N); 93 void SelectI128toV2I64(SDNode *N); 94 void SelectCpAsyncBulkG2S(SDNode *N); 95 void SelectCpAsyncBulkS2G(SDNode *N); 96 void SelectCpAsyncBulkPrefetchL2(SDNode *N); 97 void SelectCpAsyncBulkTensorG2SCommon(SDNode *N, bool IsIm2Col = false); 98 void SelectCpAsyncBulkTensorS2GCommon(SDNode *N, bool IsIm2Col = false); 99 void SelectCpAsyncBulkTensorPrefetchCommon(SDNode *N, bool IsIm2Col = false); 100 void SelectCpAsyncBulkTensorReduceCommon(SDNode *N, unsigned RedOp, 101 bool IsIm2Col = false); 102 103 inline SDValue getI32Imm(unsigned Imm, const SDLoc &DL) { 104 return CurDAG->getTargetConstant(Imm, DL, MVT::i32); 105 } 106 107 // Match direct address complex pattern. 108 bool SelectDirectAddr(SDValue N, SDValue &Address); 109 110 bool SelectADDRri_imp(SDNode *OpNode, SDValue Addr, SDValue &Base, 111 SDValue &Offset, MVT VT); 112 bool SelectADDRri(SDNode *OpNode, SDValue Addr, SDValue &Base, 113 SDValue &Offset); 114 bool SelectADDRri64(SDNode *OpNode, SDValue Addr, SDValue &Base, 115 SDValue &Offset); 116 bool SelectADDRsi_imp(SDNode *OpNode, SDValue Addr, SDValue &Base, 117 SDValue &Offset, MVT VT); 118 bool SelectADDRsi(SDNode *OpNode, SDValue Addr, SDValue &Base, 119 SDValue &Offset); 120 bool SelectADDRsi64(SDNode *OpNode, SDValue Addr, SDValue &Base, 121 SDValue &Offset); 122 123 bool ChkMemSDNodeAddressSpace(SDNode *N, unsigned int spN) const; 124 125 static unsigned GetConvertOpcode(MVT DestTy, MVT SrcTy, LoadSDNode *N); 126 127 // Returns the Memory Order and Scope that the PTX memory instruction should 128 // use, and inserts appropriate fence instruction before the memory 129 // instruction, if needed to implement the instructions memory order. Required 130 // fences after the instruction need to be handled elsewhere. 131 std::pair<NVPTX::Ordering, NVPTX::Scope> 132 insertMemoryInstructionFence(SDLoc DL, SDValue &Chain, MemSDNode *N); 133 NVPTX::Scope getOperationScope(MemSDNode *N, NVPTX::Ordering O) const; 134 }; 135 136 class NVPTXDAGToDAGISelLegacy : public SelectionDAGISelLegacy { 137 public: 138 static char ID; 139 explicit NVPTXDAGToDAGISelLegacy(NVPTXTargetMachine &tm, 140 CodeGenOptLevel OptLevel); 141 }; 142 } // end namespace llvm 143 144 #endif 145