| 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 | NVPTX::DivPrecisionLevel getDivF32Level(const SDNode *N) const; |
| 47 | bool usePrecSqrtF32(const SDNode *N) 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 tryIntrinsicChain(SDNode *N); |
| 73 | bool tryIntrinsicVoid(SDNode *N); |
| 74 | void SelectTexSurfHandle(SDNode *N); |
| 75 | bool tryLoad(SDNode *N); |
| 76 | bool tryLoadVector(SDNode *N); |
| 77 | bool tryLDU(SDNode *N); |
| 78 | bool tryLDG(MemSDNode *N); |
| 79 | bool tryStore(SDNode *N); |
| 80 | bool tryStoreVector(SDNode *N); |
| 81 | bool tryLoadParam(SDNode *N); |
| 82 | bool tryStoreParam(SDNode *N); |
| 83 | bool tryFence(SDNode *N); |
| 84 | void SelectAddrSpaceCast(SDNode *N); |
| 85 | bool tryBFE(SDNode *N); |
| 86 | bool tryBF16ArithToFMA(SDNode *N); |
| 87 | bool tryConstantFP(SDNode *N); |
| 88 | bool SelectSETP_F16X2(SDNode *N); |
| 89 | bool SelectSETP_BF16X2(SDNode *N); |
| 90 | bool tryUNPACK_VECTOR(SDNode *N); |
| 91 | bool (SDNode *N); |
| 92 | void SelectV2I64toI128(SDNode *N); |
| 93 | void SelectI128toV2I64(SDNode *N); |
| 94 | void SelectCpAsyncBulkTensorG2SCommon(SDNode *N, bool IsIm2Col = false); |
| 95 | void SelectCpAsyncBulkTensorS2GCommon(SDNode *N, bool IsIm2Col = false); |
| 96 | void SelectCpAsyncBulkTensorPrefetchCommon(SDNode *N, bool IsIm2Col = false); |
| 97 | void SelectCpAsyncBulkTensorReduceCommon(SDNode *N, unsigned RedOp, |
| 98 | bool IsIm2Col = false); |
| 99 | void SelectTcgen05Ld(SDNode *N, bool hasOffset = false); |
| 100 | void SelectTcgen05St(SDNode *N, bool hasOffset = false); |
| 101 | |
| 102 | inline SDValue getI32Imm(unsigned Imm, const SDLoc &DL) { |
| 103 | return CurDAG->getTargetConstant(Val: Imm, DL, VT: MVT::i32); |
| 104 | } |
| 105 | |
| 106 | bool SelectADDR(SDValue Addr, SDValue &Base, SDValue &Offset); |
| 107 | SDValue selectPossiblyImm(SDValue V); |
| 108 | |
| 109 | bool ChkMemSDNodeAddressSpace(SDNode *N, unsigned int spN) const; |
| 110 | |
| 111 | static unsigned GetConvertOpcode(MVT DestTy, MVT SrcTy, LoadSDNode *N); |
| 112 | |
| 113 | // Returns the Memory Order and Scope that the PTX memory instruction should |
| 114 | // use, and inserts appropriate fence instruction before the memory |
| 115 | // instruction, if needed to implement the instructions memory order. Required |
| 116 | // fences after the instruction need to be handled elsewhere. |
| 117 | std::pair<NVPTX::Ordering, NVPTX::Scope> |
| 118 | insertMemoryInstructionFence(SDLoc DL, SDValue &Chain, MemSDNode *N); |
| 119 | NVPTX::Scope getOperationScope(MemSDNode *N, NVPTX::Ordering O) const; |
| 120 | }; |
| 121 | |
| 122 | class NVPTXDAGToDAGISelLegacy : public SelectionDAGISelLegacy { |
| 123 | public: |
| 124 | static char ID; |
| 125 | explicit NVPTXDAGToDAGISelLegacy(NVPTXTargetMachine &tm, |
| 126 | CodeGenOptLevel OptLevel); |
| 127 | }; |
| 128 | } // end namespace llvm |
| 129 | |
| 130 | #endif |
| 131 | |