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 "NVPTXSelectionDAGInfo.h"
21#include "NVPTXTargetMachine.h"
22#include "llvm/ADT/MapVector.h"
23#include "llvm/CodeGen/SelectionDAGISel.h"
24#include "llvm/IR/InlineAsm.h"
25#include "llvm/IR/Intrinsics.h"
26#include "llvm/IR/LLVMContext.h"
27#include "llvm/Support/Compiler.h"
28
29namespace llvm {
30
31struct NVPTXScopes {
32 NVPTXScopes() = default;
33 NVPTXScopes(LLVMContext &C);
34 NVPTX::Scope operator[](SyncScope::ID ID) const;
35 bool empty() const;
36
37private:
38 SmallMapVector<SyncScope::ID, NVPTX::Scope, 8> Scopes{};
39 LLVMContext *Context = nullptr;
40};
41
42class LLVM_LIBRARY_VISIBILITY NVPTXDAGToDAGISel : public SelectionDAGISel {
43 const NVPTXTargetMachine &TM;
44
45 NVPTX::DivPrecisionLevel getDivF32Level(const SDNode *N) const;
46 bool usePrecSqrtF32(const SDNode *N) const;
47 bool useF32FTZ() const;
48 bool allowFMA() const;
49 bool doRsqrtOpt() const;
50 bool doMADWideOpt() const;
51
52 NVPTXScopes Scopes{};
53
54public:
55 NVPTXDAGToDAGISel() = delete;
56
57 explicit NVPTXDAGToDAGISel(NVPTXTargetMachine &tm, CodeGenOptLevel OptLevel);
58
59 bool runOnMachineFunction(MachineFunction &MF) override;
60 const NVPTXSubtarget *Subtarget = nullptr;
61
62 bool SelectInlineAsmMemoryOperand(const SDValue &Op,
63 InlineAsm::ConstraintCode ConstraintID,
64 std::vector<SDValue> &OutOps) override;
65
66private:
67// Include the pieces autogenerated from the target description.
68#include "NVPTXGenDAGISel.inc"
69
70 void Select(SDNode *N) override;
71 bool tryIntrinsicChain(SDNode *N);
72 bool tryIntrinsicVoid(SDNode *N);
73 void SelectTexSurfHandle(SDNode *N);
74 bool tryLoad(SDNode *N);
75 bool tryLoadVector(SDNode *N);
76 bool tryLDU(SDNode *N);
77 bool tryLDG(MemSDNode *N);
78 bool tryStore(SDNode *N);
79 bool tryStoreVector(SDNode *N);
80 bool tryFence(SDNode *N);
81 void SelectAddrSpaceCast(SDNode *N);
82 bool tryBFE(SDNode *N);
83 bool tryBF16ArithToFMA(SDNode *N);
84 bool tryConstantFP(SDNode *N);
85 bool SelectSETP_F16X2(SDNode *N);
86 bool SelectSETP_BF16X2(SDNode *N);
87 bool tryUNPACK_VECTOR(SDNode *N);
88 bool tryEXTRACT_VECTOR_ELEMENT(SDNode *N);
89 void SelectV2I64toI128(SDNode *N);
90 void SelectI128toV2I64(SDNode *N);
91 void SelectCpAsyncBulkTensorReduceCommon(SDNode *N, unsigned RedOp,
92 bool IsIm2Col = false);
93 void SelectTcgen05Ld(SDNode *N, bool hasOffset = false);
94 void SelectTcgen05St(SDNode *N, bool hasOffset = false);
95 void selectAtomicSwap128(SDNode *N);
96 void selectBR_JT(SDNode *N);
97
98 inline SDValue getI32Imm(unsigned Imm, const SDLoc &DL) {
99 return CurDAG->getTargetConstant(Val: Imm, DL, VT: MVT::i32);
100 }
101 NVPTX::Ordering getMemOrder(const MemSDNode *N) const;
102 NVPTX::Scope getAtomicScope(const MemSDNode *N) const;
103
104 bool SelectADDR(SDValue Addr, SDValue &Base, SDValue &Offset);
105 SDValue getPTXCmpMode(const CondCodeSDNode &CondCode);
106 SDValue selectPossiblyImm(SDValue V);
107
108 // Returns the Memory Order and Scope that the PTX memory instruction should
109 // use, and inserts appropriate fence instruction before the memory
110 // instruction, if needed to implement the instructions memory order. Required
111 // fences after the instruction need to be handled elsewhere.
112 std::pair<NVPTX::Ordering, NVPTX::Scope>
113 insertMemoryInstructionFence(SDLoc DL, SDValue &Chain, MemSDNode *N);
114 NVPTX::Scope getOperationScope(MemSDNode *N, NVPTX::Ordering O) const;
115
116public:
117 static NVPTX::AddressSpace getAddrSpace(const MemSDNode *N);
118 static unsigned getFromTypeWidthForLoad(const MemSDNode *Mem);
119};
120
121class NVPTXDAGToDAGISelLegacy : public SelectionDAGISelLegacy {
122public:
123 static char ID;
124 explicit NVPTXDAGToDAGISelLegacy(NVPTXTargetMachine &tm,
125 CodeGenOptLevel OptLevel);
126};
127} // end namespace llvm
128
129#endif
130