xref: /llvm-project/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.h (revision fa7f0e582bc25a91d89dab7c488a1619060f9bef)
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