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
28namespace llvm {
29
30struct NVPTXScopes {
31 NVPTXScopes() = default;
32 NVPTXScopes(LLVMContext &C);
33 NVPTX::Scope operator[](SyncScope::ID ID) const;
34 bool empty() const;
35
36private:
37 SmallMapVector<SyncScope::ID, NVPTX::Scope, 8> Scopes{};
38};
39
40class 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
55public:
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
67private:
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 tryEXTRACT_VECTOR_ELEMENT(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
122class NVPTXDAGToDAGISelLegacy : public SelectionDAGISelLegacy {
123public:
124 static char ID;
125 explicit NVPTXDAGToDAGISelLegacy(NVPTXTargetMachine &tm,
126 CodeGenOptLevel OptLevel);
127};
128} // end namespace llvm
129
130#endif
131