Coverage Report

Created: 2024-01-17 10:31

/src/llvm-project/llvm/lib/Target/AMDGPU/AMDGPULibFunc.h
Line
Count
Source (jump to first uncovered line)
1
//===-- AMDGPULibFunc.h ----------------------------------------*- C++ -*--===//
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
#ifndef _AMDGPU_LIBFUNC_H_
10
#define _AMDGPU_LIBFUNC_H_
11
12
#include "llvm/ADT/StringRef.h"
13
#include <memory>
14
15
namespace llvm {
16
17
class FunctionCallee;
18
class FunctionType;
19
class Function;
20
class Module;
21
class Type;
22
23
class AMDGPULibFuncBase {
24
public:
25
  enum EFuncId {
26
    EI_NONE,
27
28
    // IMPORTANT: enums below should go in ascending by 1 value order
29
    // because they are used as indexes in the mangling rules table.
30
    // don't use explicit value assignment.
31
    //
32
    // There are two types of library functions: those with mangled
33
    // name and those with unmangled name. The enums for the library
34
    // functions with mangled name are defined before enums for the
35
    // library functions with unmangled name. The enum for the last
36
    // library function with mangled name is EI_LAST_MANGLED.
37
    //
38
    // Library functions with mangled name.
39
    EI_ABS,
40
    EI_ABS_DIFF,
41
    EI_ACOS,
42
    EI_ACOSH,
43
    EI_ACOSPI,
44
    EI_ADD_SAT,
45
    EI_ALL,
46
    EI_ANY,
47
    EI_ASIN,
48
    EI_ASINH,
49
    EI_ASINPI,
50
    EI_ASYNC_WORK_GROUP_COPY,
51
    EI_ASYNC_WORK_GROUP_STRIDED_COPY,
52
    EI_ATAN,
53
    EI_ATAN2,
54
    EI_ATAN2PI,
55
    EI_ATANH,
56
    EI_ATANPI,
57
    EI_ATOMIC_ADD,
58
    EI_ATOMIC_AND,
59
    EI_ATOMIC_CMPXCHG,
60
    EI_ATOMIC_DEC,
61
    EI_ATOMIC_INC,
62
    EI_ATOMIC_MAX,
63
    EI_ATOMIC_MIN,
64
    EI_ATOMIC_OR,
65
    EI_ATOMIC_SUB,
66
    EI_ATOMIC_XCHG,
67
    EI_ATOMIC_XOR,
68
    EI_BITSELECT,
69
    EI_CBRT,
70
    EI_CEIL,
71
    EI_CLAMP,
72
    EI_CLZ,
73
    EI_COMMIT_READ_PIPE,
74
    EI_COMMIT_WRITE_PIPE,
75
    EI_COPYSIGN,
76
    EI_COS,
77
    EI_COSH,
78
    EI_COSPI,
79
    EI_CROSS,
80
    EI_CTZ,
81
    EI_DEGREES,
82
    EI_DISTANCE,
83
    EI_DIVIDE,
84
    EI_DOT,
85
    EI_ERF,
86
    EI_ERFC,
87
    EI_EXP,
88
    EI_EXP10,
89
    EI_EXP2,
90
    EI_EXPM1,
91
    EI_FABS,
92
    EI_FAST_DISTANCE,
93
    EI_FAST_LENGTH,
94
    EI_FAST_NORMALIZE,
95
    EI_FDIM,
96
    EI_FLOOR,
97
    EI_FMA,
98
    EI_FMAX,
99
    EI_FMIN,
100
    EI_FMOD,
101
    EI_FRACT,
102
    EI_FREXP,
103
    EI_GET_IMAGE_ARRAY_SIZE,
104
    EI_GET_IMAGE_CHANNEL_DATA_TYPE,
105
    EI_GET_IMAGE_CHANNEL_ORDER,
106
    EI_GET_IMAGE_DIM,
107
    EI_GET_IMAGE_HEIGHT,
108
    EI_GET_IMAGE_WIDTH,
109
    EI_GET_PIPE_MAX_PACKETS,
110
    EI_GET_PIPE_NUM_PACKETS,
111
    EI_HADD,
112
    EI_HYPOT,
113
    EI_ILOGB,
114
    EI_ISEQUAL,
115
    EI_ISFINITE,
116
    EI_ISGREATER,
117
    EI_ISGREATEREQUAL,
118
    EI_ISINF,
119
    EI_ISLESS,
120
    EI_ISLESSEQUAL,
121
    EI_ISLESSGREATER,
122
    EI_ISNAN,
123
    EI_ISNORMAL,
124
    EI_ISNOTEQUAL,
125
    EI_ISORDERED,
126
    EI_ISUNORDERED,
127
    EI_LDEXP,
128
    EI_LENGTH,
129
    EI_LGAMMA,
130
    EI_LGAMMA_R,
131
    EI_LOG,
132
    EI_LOG10,
133
    EI_LOG1P,
134
    EI_LOG2,
135
    EI_LOGB,
136
    EI_MAD,
137
    EI_MAD24,
138
    EI_MAD_HI,
139
    EI_MAD_SAT,
140
    EI_MAX,
141
    EI_MAXMAG,
142
    EI_MIN,
143
    EI_MINMAG,
144
    EI_MIX,
145
    EI_MODF,
146
    EI_MUL24,
147
    EI_MUL_HI,
148
    EI_NAN,
149
    EI_NEXTAFTER,
150
    EI_NORMALIZE,
151
    EI_POPCOUNT,
152
    EI_POW,
153
    EI_POWN,
154
    EI_POWR,
155
    EI_PREFETCH,
156
    EI_RADIANS,
157
    EI_RECIP,
158
    EI_REMAINDER,
159
    EI_REMQUO,
160
    EI_RESERVE_READ_PIPE,
161
    EI_RESERVE_WRITE_PIPE,
162
    EI_RHADD,
163
    EI_RINT,
164
    EI_ROOTN,
165
    EI_ROTATE,
166
    EI_ROUND,
167
    EI_RSQRT,
168
    EI_SELECT,
169
    EI_SHUFFLE,
170
    EI_SHUFFLE2,
171
    EI_SIGN,
172
    EI_SIGNBIT,
173
    EI_SIN,
174
    EI_SINCOS,
175
    EI_SINH,
176
    EI_SINPI,
177
    EI_SMOOTHSTEP,
178
    EI_SQRT,
179
    EI_STEP,
180
    EI_SUB_GROUP_BROADCAST,
181
    EI_SUB_GROUP_COMMIT_READ_PIPE,
182
    EI_SUB_GROUP_COMMIT_WRITE_PIPE,
183
    EI_SUB_GROUP_REDUCE_ADD,
184
    EI_SUB_GROUP_REDUCE_MAX,
185
    EI_SUB_GROUP_REDUCE_MIN,
186
    EI_SUB_GROUP_RESERVE_READ_PIPE,
187
    EI_SUB_GROUP_RESERVE_WRITE_PIPE,
188
    EI_SUB_GROUP_SCAN_EXCLUSIVE_ADD,
189
    EI_SUB_GROUP_SCAN_EXCLUSIVE_MAX,
190
    EI_SUB_GROUP_SCAN_EXCLUSIVE_MIN,
191
    EI_SUB_GROUP_SCAN_INCLUSIVE_ADD,
192
    EI_SUB_GROUP_SCAN_INCLUSIVE_MAX,
193
    EI_SUB_GROUP_SCAN_INCLUSIVE_MIN,
194
    EI_SUB_SAT,
195
    EI_TAN,
196
    EI_TANH,
197
    EI_TANPI,
198
    EI_TGAMMA,
199
    EI_TRUNC,
200
    EI_UPSAMPLE,
201
    EI_VEC_STEP,
202
    EI_VSTORE,
203
    EI_VSTORE16,
204
    EI_VSTORE2,
205
    EI_VSTORE3,
206
    EI_VSTORE4,
207
    EI_VSTORE8,
208
    EI_WORK_GROUP_COMMIT_READ_PIPE,
209
    EI_WORK_GROUP_COMMIT_WRITE_PIPE,
210
    EI_WORK_GROUP_REDUCE_ADD,
211
    EI_WORK_GROUP_REDUCE_MAX,
212
    EI_WORK_GROUP_REDUCE_MIN,
213
    EI_WORK_GROUP_RESERVE_READ_PIPE,
214
    EI_WORK_GROUP_RESERVE_WRITE_PIPE,
215
    EI_WORK_GROUP_SCAN_EXCLUSIVE_ADD,
216
    EI_WORK_GROUP_SCAN_EXCLUSIVE_MAX,
217
    EI_WORK_GROUP_SCAN_EXCLUSIVE_MIN,
218
    EI_WORK_GROUP_SCAN_INCLUSIVE_ADD,
219
    EI_WORK_GROUP_SCAN_INCLUSIVE_MAX,
220
    EI_WORK_GROUP_SCAN_INCLUSIVE_MIN,
221
    EI_WRITE_IMAGEF,
222
    EI_WRITE_IMAGEI,
223
    EI_WRITE_IMAGEUI,
224
    EI_NCOS,
225
    EI_NEXP2,
226
    EI_NFMA,
227
    EI_NLOG2,
228
    EI_NRCP,
229
    EI_NRSQRT,
230
    EI_NSIN,
231
    EI_NSQRT,
232
    EI_FTZ,
233
    EI_FLDEXP,
234
    EI_CLASS,
235
    EI_RCBRT,
236
    EI_LAST_MANGLED =
237
        EI_RCBRT, /* The last library function with mangled name */
238
239
    // Library functions with unmangled name.
240
    EI_READ_PIPE_2,
241
    EI_READ_PIPE_4,
242
    EI_WRITE_PIPE_2,
243
    EI_WRITE_PIPE_4,
244
245
    EX_INTRINSICS_COUNT
246
  };
247
248
  enum ENamePrefix {
249
    NOPFX,
250
    NATIVE,
251
    HALF
252
  };
253
254
  enum EType {
255
    B8  = 1,
256
    B16 = 2,
257
    B32 = 3,
258
    B64 = 4,
259
    SIZE_MASK = 7,
260
    FLOAT = 0x10,
261
    INT   = 0x20,
262
    UINT  = 0x30,
263
    BASE_TYPE_MASK = 0x30,
264
    U8  =  UINT | B8,
265
    U16 =  UINT | B16,
266
    U32 =  UINT | B32,
267
    U64 =  UINT | B64,
268
    I8  =   INT | B8,
269
    I16 =   INT | B16,
270
    I32 =   INT | B32,
271
    I64 =   INT | B64,
272
    F16 = FLOAT | B16,
273
    F32 = FLOAT | B32,
274
    F64 = FLOAT | B64,
275
    IMG1DA = 0x80,
276
    IMG1DB,
277
    IMG2DA,
278
    IMG1D,
279
    IMG2D,
280
    IMG3D,
281
    SAMPLER,
282
    EVENT,
283
    DUMMY
284
  };
285
286
  enum EPtrKind {
287
    BYVALUE = 0,
288
    ADDR_SPACE = 0xF, // Address space takes value 0x1 ~ 0xF.
289
    CONST      = 0x10,
290
    VOLATILE   = 0x20
291
  };
292
293
  struct Param {
294
    unsigned char ArgType = 0;
295
    unsigned char VectorSize = 1;
296
    unsigned char PtrKind = 0;
297
298
    unsigned char Reserved = 0;
299
300
0
    void reset() {
301
0
      ArgType = 0;
302
0
      VectorSize = 1;
303
0
      PtrKind = 0;
304
0
    }
305
306
0
    static Param getIntN(unsigned char NumElts) {
307
0
      return Param{I32, NumElts, 0, 0};
308
0
    }
309
310
    static Param getFromTy(Type *Ty, bool Signed);
311
312
    template <typename Stream>
313
    void mangleItanium(Stream& os);
314
  };
315
0
  static bool isMangled(EFuncId Id) {
316
0
    return static_cast<unsigned>(Id) <= static_cast<unsigned>(EI_LAST_MANGLED);
317
0
  }
318
319
0
  static unsigned getEPtrKindFromAddrSpace(unsigned AS) {
320
0
    assert(((AS + 1) & ~ADDR_SPACE) == 0);
321
0
    return AS + 1;
322
0
  }
323
324
0
  static unsigned getAddrSpaceFromEPtrKind(unsigned Kind) {
325
0
    Kind = Kind & ADDR_SPACE;
326
0
    assert(Kind >= 1);
327
0
    return Kind - 1;
328
0
  }
329
};
330
331
class AMDGPULibFuncImpl : public AMDGPULibFuncBase {
332
public:
333
0
  AMDGPULibFuncImpl() = default;
334
0
  virtual ~AMDGPULibFuncImpl() = default;
335
336
  /// Get unmangled name for mangled library function and name for unmangled
337
  /// library function.
338
  virtual std::string getName() const = 0;
339
  virtual unsigned getNumArgs() const = 0;
340
0
  EFuncId getId() const { return FuncId; }
341
0
  ENamePrefix getPrefix() const { return FKind; }
342
343
0
  bool isMangled() const { return AMDGPULibFuncBase::isMangled(FuncId); }
344
345
0
  void setId(EFuncId id) { FuncId = id; }
346
  virtual bool parseFuncName(StringRef &mangledName) = 0;
347
348
  /// \return The mangled function name for mangled library functions
349
  /// and unmangled function name for unmangled library functions.
350
  virtual std::string mangle() const = 0;
351
352
0
  void setName(StringRef N) { Name = std::string(N); }
353
0
  void setPrefix(ENamePrefix pfx) { FKind = pfx; }
354
355
  virtual FunctionType *getFunctionType(Module &M) const = 0;
356
357
protected:
358
  EFuncId FuncId;
359
  std::string Name;
360
  ENamePrefix FKind = NOPFX;
361
};
362
363
/// Wrapper class for AMDGPULIbFuncImpl
364
class AMDGPULibFunc : public AMDGPULibFuncBase {
365
public:
366
0
  explicit AMDGPULibFunc() : Impl(std::unique_ptr<AMDGPULibFuncImpl>()) {}
367
  AMDGPULibFunc(const AMDGPULibFunc &F);
368
  /// Clone a mangled library func with the Id \p Id and argument info from \p
369
  /// CopyFrom.
370
  explicit AMDGPULibFunc(EFuncId Id, const AMDGPULibFunc &CopyFrom);
371
  explicit AMDGPULibFunc(EFuncId Id, FunctionType *FT, bool SignedInts);
372
373
  /// Construct an unmangled library function on the fly.
374
  explicit AMDGPULibFunc(StringRef FName, FunctionType *FT);
375
376
  AMDGPULibFunc &operator=(const AMDGPULibFunc &F);
377
378
  /// Get unmangled name for mangled library function and name for unmangled
379
  /// library function.
380
0
  std::string getName() const { return Impl->getName(); }
381
0
  unsigned getNumArgs() const { return Impl->getNumArgs(); }
382
0
  EFuncId getId() const { return Impl->getId(); }
383
0
  ENamePrefix getPrefix() const { return Impl->getPrefix(); }
384
  /// Get leading parameters for mangled lib functions.
385
  Param *getLeads();
386
  const Param *getLeads() const;
387
388
0
  bool isMangled() const { return Impl->isMangled(); }
389
0
  void setId(EFuncId Id) { Impl->setId(Id); }
390
0
  bool parseFuncName(StringRef &MangledName) {
391
0
    return Impl->parseFuncName(MangledName);
392
0
  }
393
394
  // Validate the call type matches the expected libfunc type.
395
  bool isCompatibleSignature(const FunctionType *FuncTy) const;
396
397
  /// \return The mangled function name for mangled library functions
398
  /// and unmangled function name for unmangled library functions.
399
0
  std::string mangle() const { return Impl->mangle(); }
400
401
0
  void setName(StringRef N) { Impl->setName(N); }
402
0
  void setPrefix(ENamePrefix PFX) { Impl->setPrefix(PFX); }
403
404
0
  FunctionType *getFunctionType(Module &M) const {
405
0
    return Impl->getFunctionType(M);
406
0
  }
407
  static Function *getFunction(llvm::Module *M, const AMDGPULibFunc &fInfo);
408
409
  static FunctionCallee getOrInsertFunction(llvm::Module *M,
410
                                            const AMDGPULibFunc &fInfo);
411
  static bool parse(StringRef MangledName, AMDGPULibFunc &Ptr);
412
413
private:
414
  /// Initialize as a mangled library function.
415
  void initMangled();
416
  std::unique_ptr<AMDGPULibFuncImpl> Impl;
417
};
418
419
class AMDGPUMangledLibFunc : public AMDGPULibFuncImpl {
420
public:
421
  Param Leads[2];
422
423
  explicit AMDGPUMangledLibFunc();
424
  explicit AMDGPUMangledLibFunc(EFuncId id,
425
                                const AMDGPUMangledLibFunc &copyFrom);
426
  explicit AMDGPUMangledLibFunc(EFuncId id, FunctionType *FT,
427
                                bool SignedInts = true);
428
429
  std::string getName() const override;
430
  unsigned getNumArgs() const override;
431
  FunctionType *getFunctionType(Module &M) const override;
432
  static StringRef getUnmangledName(StringRef MangledName);
433
434
  bool parseFuncName(StringRef &mangledName) override;
435
436
  // Methods for support type inquiry through isa, cast, and dyn_cast:
437
0
  static bool classof(const AMDGPULibFuncImpl *F) { return F->isMangled(); }
438
439
  std::string mangle() const override;
440
441
private:
442
  std::string mangleNameItanium() const;
443
444
  std::string mangleName(StringRef Name) const;
445
  bool parseUnmangledName(StringRef MangledName);
446
447
  template <typename Stream> void writeName(Stream &OS) const;
448
};
449
450
class AMDGPUUnmangledLibFunc : public AMDGPULibFuncImpl {
451
  FunctionType *FuncTy;
452
453
public:
454
  explicit AMDGPUUnmangledLibFunc();
455
0
  explicit AMDGPUUnmangledLibFunc(StringRef FName, FunctionType *FT) {
456
0
    Name = std::string(FName);
457
0
    FuncTy = FT;
458
0
  }
459
0
  std::string getName() const override { return Name; }
460
  unsigned getNumArgs() const override;
461
0
  FunctionType *getFunctionType(Module &M) const override { return FuncTy; }
462
463
  bool parseFuncName(StringRef &Name) override;
464
465
  // Methods for support type inquiry through isa, cast, and dyn_cast:
466
0
  static bool classof(const AMDGPULibFuncImpl *F) { return !F->isMangled(); }
467
468
0
  std::string mangle() const override { return Name; }
469
470
0
  void setFunctionType(FunctionType *FT) { FuncTy = FT; }
471
};
472
}
473
#endif // _AMDGPU_LIBFUNC_H_