1 //===-- AMDGPULibFunc.h ---------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef _AMDGPU_LIBFUNC_H_
11 #define _AMDGPU_LIBFUNC_H_
12 
13 #include "llvm/ADT/StringRef.h"
14 
15 namespace llvm {
16 
17 class FunctionType;
18 class Function;
19 class Module;
20 
21 class AMDGPULibFuncBase {
22 public:
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     PRIVATE,
287     GLOBAL,
288     READONLY,
289     LOCAL,
290     GENERIC,
291     OTHER,
292 
293     ADDR_SPACE = 0xF,
294     CONST      = 0x10,
295     VOLATILE   = 0x20
296   };
297 
298   struct Param {
299     unsigned char ArgType;
300     unsigned char VectorSize;
301     unsigned char PtrKind;
302 
303     unsigned char Reserved;
304 
305     void reset() {
306       ArgType = 0;
307       VectorSize = 1;
308       PtrKind = 0;
309     }
310     Param() { reset(); }
311 
312     template <typename Stream>
313     void mangleItanium(Stream& os);
314   };
315   static bool isMangled(EFuncId Id) {
316     return static_cast<unsigned>(Id) <= static_cast<unsigned>(EI_LAST_MANGLED);
317   }
318 };
319 
320 class AMDGPULibFuncImpl : public AMDGPULibFuncBase {
321 public:
322   AMDGPULibFuncImpl() {}
323   virtual ~AMDGPULibFuncImpl() {}
324 
325   /// Get unmangled name for mangled library function and name for unmangled
326   /// library function.
327   virtual std::string getName() const = 0;
328   virtual unsigned getNumArgs() const = 0;
329   EFuncId getId() const { return FuncId; }
330   ENamePrefix getPrefix() const { return FKind; }
331 
332   bool isMangled() const { return AMDGPULibFuncBase::isMangled(FuncId); }
333 
334   void setId(EFuncId id) { FuncId = id; }
335   virtual bool parseFuncName(StringRef &mangledName) = 0;
336 
337   /// \return The mangled function name for mangled library functions
338   /// and unmangled function name for unmangled library functions.
339   virtual std::string mangle() const = 0;
340 
341   void setName(StringRef N) { Name = N; }
342   void setPrefix(ENamePrefix pfx) { FKind = pfx; }
343 
344   virtual FunctionType *getFunctionType(Module &M) const = 0;
345 
346 protected:
347   EFuncId FuncId;
348   std::string Name;
349   ENamePrefix FKind;
350 };
351 
352 /// Wrapper class for AMDGPULIbFuncImpl
353 class AMDGPULibFunc : public AMDGPULibFuncBase {
354 public:
355   explicit AMDGPULibFunc() : Impl(std::unique_ptr<AMDGPULibFuncImpl>()) {}
356   AMDGPULibFunc(const AMDGPULibFunc &F);
357   /// Clone a mangled library func with the Id \p Id and argument info from \p
358   /// CopyFrom.
359   explicit AMDGPULibFunc(EFuncId Id, const AMDGPULibFunc &CopyFrom);
360   /// Construct an unmangled library function on the fly.
361   explicit AMDGPULibFunc(StringRef FName, FunctionType *FT);
362 
363   AMDGPULibFunc &operator=(const AMDGPULibFunc &F);
364 
365   /// Get unmangled name for mangled library function and name for unmangled
366   /// library function.
367   std::string getName() const { return Impl->getName(); }
368   unsigned getNumArgs() const { return Impl->getNumArgs(); }
369   EFuncId getId() const { return Impl->getId(); }
370   ENamePrefix getPrefix() const { return Impl->getPrefix(); }
371   /// Get leading parameters for mangled lib functions.
372   Param *getLeads();
373   const Param *getLeads() const;
374 
375   bool isMangled() const { return Impl->isMangled(); }
376   void setId(EFuncId Id) { Impl->setId(Id); }
377   bool parseFuncName(StringRef &MangledName) {
378     return Impl->parseFuncName(MangledName);
379   }
380 
381   /// \return The mangled function name for mangled library functions
382   /// and unmangled function name for unmangled library functions.
383   std::string mangle() const { return Impl->mangle(); }
384 
385   void setName(StringRef N) { Impl->setName(N); }
386   void setPrefix(ENamePrefix PFX) { Impl->setPrefix(PFX); }
387 
388   FunctionType *getFunctionType(Module &M) const {
389     return Impl->getFunctionType(M);
390   }
391   static Function *getFunction(llvm::Module *M, const AMDGPULibFunc &fInfo);
392 
393   static Function *getOrInsertFunction(llvm::Module *M,
394                                        const AMDGPULibFunc &fInfo);
395   static bool parse(StringRef MangledName, AMDGPULibFunc &Ptr);
396 
397 private:
398   /// Initialize as a mangled library function.
399   void initMangled();
400   std::unique_ptr<AMDGPULibFuncImpl> Impl;
401 };
402 
403 class AMDGPUMangledLibFunc : public AMDGPULibFuncImpl {
404 public:
405   Param Leads[2];
406 
407   explicit AMDGPUMangledLibFunc();
408   explicit AMDGPUMangledLibFunc(EFuncId id,
409                                 const AMDGPUMangledLibFunc &copyFrom);
410 
411   std::string getName() const override;
412   unsigned getNumArgs() const override;
413   FunctionType *getFunctionType(Module &M) const override;
414   static StringRef getUnmangledName(StringRef MangledName);
415 
416   bool parseFuncName(StringRef &mangledName) override;
417 
418   // Methods for support type inquiry through isa, cast, and dyn_cast:
419   static bool classof(const AMDGPULibFuncImpl *F) { return F->isMangled(); }
420 
421   std::string mangle() const override;
422 
423 private:
424   std::string mangleNameItanium() const;
425 
426   std::string mangleName(StringRef Name) const;
427   bool parseUnmangledName(StringRef MangledName);
428 
429   template <typename Stream> void writeName(Stream &OS) const;
430 };
431 
432 class AMDGPUUnmangledLibFunc : public AMDGPULibFuncImpl {
433   FunctionType *FuncTy;
434 
435 public:
436   explicit AMDGPUUnmangledLibFunc();
437   explicit AMDGPUUnmangledLibFunc(StringRef FName, FunctionType *FT) {
438     Name = FName;
439     FuncTy = FT;
440   }
441   std::string getName() const override { return Name; }
442   unsigned getNumArgs() const override;
443   FunctionType *getFunctionType(Module &M) const override { return FuncTy; }
444 
445   bool parseFuncName(StringRef &Name) override;
446 
447   // Methods for support type inquiry through isa, cast, and dyn_cast:
448   static bool classof(const AMDGPULibFuncImpl *F) { return !F->isMangled(); }
449 
450   std::string mangle() const override { return Name; }
451 
452   void setFunctionType(FunctionType *FT) { FuncTy = FT; }
453 };
454 }
455 #endif // _AMDGPU_LIBFUNC_H_
456