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