summaryrefslogtreecommitdiff
path: root/lib/Target/NVPTX/NVPTXISelLowering.h
blob: 358f9f8c80e9fe11815302d3848e6d7e426cc376 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
//===-- NVPTXISelLowering.h - NVPTX DAG Lowering Interface ------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the interfaces that NVPTX uses to lower LLVM code into a
// selection DAG.
//
//===----------------------------------------------------------------------===//

#ifndef NVPTXISELLOWERING_H
#define NVPTXISELLOWERING_H

#include "NVPTX.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/Target/TargetLowering.h"

namespace llvm {
namespace NVPTXISD {
enum NodeType {
  // Start the numbering from where ISD NodeType finishes.
  FIRST_NUMBER = ISD::BUILTIN_OP_END,
  Wrapper,
  CALL,
  RET_FLAG,
  LOAD_PARAM,
  DeclareParam,
  DeclareScalarParam,
  DeclareRetParam,
  DeclareRet,
  DeclareScalarRet,
  PrintCall,
  PrintCallUni,
  CallArgBegin,
  CallArg,
  LastCallArg,
  CallArgEnd,
  CallVoid,
  CallVal,
  CallSymbol,
  Prototype,
  MoveParam,
  PseudoUseParam,
  RETURN,
  CallSeqBegin,
  CallSeqEnd,
  CallPrototype,
  FUN_SHFL_CLAMP,
  FUN_SHFR_CLAMP,
  MUL_WIDE_SIGNED,
  MUL_WIDE_UNSIGNED,
  IMAD,
  Dummy,

  LoadV2 = ISD::FIRST_TARGET_MEMORY_OPCODE,
  LoadV4,
  LDGV2, // LDG.v2
  LDGV4, // LDG.v4
  LDUV2, // LDU.v2
  LDUV4, // LDU.v4
  StoreV2,
  StoreV4,
  LoadParam,
  LoadParamV2,
  LoadParamV4,
  StoreParam,
  StoreParamV2,
  StoreParamV4,
  StoreParamS32, // to sext and store a <32bit value, not used currently
  StoreParamU32, // to zext and store a <32bit value, not used currently 
  StoreRetval,
  StoreRetvalV2,
  StoreRetvalV4,

  // Texture intrinsics
  Tex1DFloatI32,
  Tex1DFloatFloat,
  Tex1DFloatFloatLevel,
  Tex1DFloatFloatGrad,
  Tex1DI32I32,
  Tex1DI32Float,
  Tex1DI32FloatLevel,
  Tex1DI32FloatGrad,
  Tex1DArrayFloatI32,
  Tex1DArrayFloatFloat,
  Tex1DArrayFloatFloatLevel,
  Tex1DArrayFloatFloatGrad,
  Tex1DArrayI32I32,
  Tex1DArrayI32Float,
  Tex1DArrayI32FloatLevel,
  Tex1DArrayI32FloatGrad,
  Tex2DFloatI32,
  Tex2DFloatFloat,
  Tex2DFloatFloatLevel,
  Tex2DFloatFloatGrad,
  Tex2DI32I32,
  Tex2DI32Float,
  Tex2DI32FloatLevel,
  Tex2DI32FloatGrad,
  Tex2DArrayFloatI32,
  Tex2DArrayFloatFloat,
  Tex2DArrayFloatFloatLevel,
  Tex2DArrayFloatFloatGrad,
  Tex2DArrayI32I32,
  Tex2DArrayI32Float,
  Tex2DArrayI32FloatLevel,
  Tex2DArrayI32FloatGrad,
  Tex3DFloatI32,
  Tex3DFloatFloat,
  Tex3DFloatFloatLevel,
  Tex3DFloatFloatGrad,
  Tex3DI32I32,
  Tex3DI32Float,
  Tex3DI32FloatLevel,
  Tex3DI32FloatGrad,

  // Surface intrinsics
  Suld1DI8Trap,
  Suld1DI16Trap,
  Suld1DI32Trap,
  Suld1DV2I8Trap,
  Suld1DV2I16Trap,
  Suld1DV2I32Trap,
  Suld1DV4I8Trap,
  Suld1DV4I16Trap,
  Suld1DV4I32Trap,

  Suld1DArrayI8Trap,
  Suld1DArrayI16Trap,
  Suld1DArrayI32Trap,
  Suld1DArrayV2I8Trap,
  Suld1DArrayV2I16Trap,
  Suld1DArrayV2I32Trap,
  Suld1DArrayV4I8Trap,
  Suld1DArrayV4I16Trap,
  Suld1DArrayV4I32Trap,

  Suld2DI8Trap,
  Suld2DI16Trap,
  Suld2DI32Trap,
  Suld2DV2I8Trap,
  Suld2DV2I16Trap,
  Suld2DV2I32Trap,
  Suld2DV4I8Trap,
  Suld2DV4I16Trap,
  Suld2DV4I32Trap,

  Suld2DArrayI8Trap,
  Suld2DArrayI16Trap,
  Suld2DArrayI32Trap,
  Suld2DArrayV2I8Trap,
  Suld2DArrayV2I16Trap,
  Suld2DArrayV2I32Trap,
  Suld2DArrayV4I8Trap,
  Suld2DArrayV4I16Trap,
  Suld2DArrayV4I32Trap,

  Suld3DI8Trap,
  Suld3DI16Trap,
  Suld3DI32Trap,
  Suld3DV2I8Trap,
  Suld3DV2I16Trap,
  Suld3DV2I32Trap,
  Suld3DV4I8Trap,
  Suld3DV4I16Trap,
  Suld3DV4I32Trap
};
}

class NVPTXSubtarget;

//===--------------------------------------------------------------------===//
// TargetLowering Implementation
//===--------------------------------------------------------------------===//
class NVPTXTargetLowering : public TargetLowering {
public:
  explicit NVPTXTargetLowering(NVPTXTargetMachine &TM);
  SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;

  SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
  SDValue LowerGlobalAddress(const GlobalValue *GV, int64_t Offset,
                             SelectionDAG &DAG) const;

  const char *getTargetNodeName(unsigned Opcode) const override;

  bool isTypeSupportedInIntrinsic(MVT VT) const;

  bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I,
                          unsigned Intrinsic) const override;

  /// isLegalAddressingMode - Return true if the addressing mode represented
  /// by AM is legal for this target, for a load/store of the specified type
  /// Used to guide target specific optimizations, like loop strength
  /// reduction (LoopStrengthReduce.cpp) and memory optimization for
  /// address mode (CodeGenPrepare.cpp)
  bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) const override;

  /// getFunctionAlignment - Return the Log2 alignment of this function.
  unsigned getFunctionAlignment(const Function *F) const;

  EVT getSetCCResultType(LLVMContext &, EVT VT) const override {
    if (VT.isVector())
      return MVT::getVectorVT(MVT::i1, VT.getVectorNumElements());
    return MVT::i1;
  }

  ConstraintType
  getConstraintType(const std::string &Constraint) const override;
  std::pair<unsigned, const TargetRegisterClass *>
  getRegForInlineAsmConstraint(const std::string &Constraint,
                               MVT VT) const override;

  SDValue LowerFormalArguments(
      SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
      const SmallVectorImpl<ISD::InputArg> &Ins, SDLoc dl, SelectionDAG &DAG,
      SmallVectorImpl<SDValue> &InVals) const override;

  SDValue LowerCall(CallLoweringInfo &CLI,
                    SmallVectorImpl<SDValue> &InVals) const override;

  std::string getPrototype(Type *, const ArgListTy &,
                           const SmallVectorImpl<ISD::OutputArg> &,
                           unsigned retAlignment,
                           const ImmutableCallSite *CS) const;

  SDValue
  LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
              const SmallVectorImpl<ISD::OutputArg> &Outs,
              const SmallVectorImpl<SDValue> &OutVals, SDLoc dl,
              SelectionDAG &DAG) const override;

  void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint,
                                    std::vector<SDValue> &Ops,
                                    SelectionDAG &DAG) const override;

  NVPTXTargetMachine *nvTM;

  // PTX always uses 32-bit shift amounts
  MVT getScalarShiftAmountTy(EVT LHSTy) const override { return MVT::i32; }

  bool shouldSplitVectorType(EVT VT) const override;

private:
  const NVPTXSubtarget &nvptxSubtarget; // cache the subtarget here

  SDValue getExtSymb(SelectionDAG &DAG, const char *name, int idx,
                     EVT = MVT::i32) const;
  SDValue getParamSymbol(SelectionDAG &DAG, int idx, EVT) const;
  SDValue getParamHelpSymbol(SelectionDAG &DAG, int idx);

  SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const;

  SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG) const;
  SDValue LowerLOADi1(SDValue Op, SelectionDAG &DAG) const;

  SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG) const;
  SDValue LowerSTOREi1(SDValue Op, SelectionDAG &DAG) const;
  SDValue LowerSTOREVector(SDValue Op, SelectionDAG &DAG) const;

  SDValue LowerShiftRightParts(SDValue Op, SelectionDAG &DAG) const;
  SDValue LowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const;

  void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
                          SelectionDAG &DAG) const override;
  SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;

  unsigned getArgumentAlignment(SDValue Callee, const ImmutableCallSite *CS,
                                Type *Ty, unsigned Idx) const;
};
} // namespace llvm

#endif // NVPTXISELLOWERING_H