blob: 8f4297b4a4911aa9f19bb509829193546ba9fb37 [file] [log] [blame]
Stanislav Mekhanoshin7f377942017-08-11 16:42:09 +00001//===-- 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
15namespace llvm {
16
17class FunctionType;
18class Function;
19class Module;
20
Yaxun Liufc5121a2017-09-06 00:30:27 +000021class AMDGPULibFuncBase {
Stanislav Mekhanoshin7f377942017-08-11 16:42:09 +000022public:
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.
Yaxun Liufc5121a2017-09-06 00:30:27 +000029 //
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.
Stanislav Mekhanoshin7f377942017-08-11 16:42:09 +000037 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,
Stanislav Mekhanoshin7f377942017-08-11 16:42:09 +0000155 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,
Stanislav Mekhanoshin7f377942017-08-11 16:42:09 +0000222 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,
Yaxun Liufc5121a2017-09-06 00:30:27 +0000234 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,
Stanislav Mekhanoshin7f377942017-08-11 16:42:09 +0000242
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 };
Yaxun Liufc5121a2017-09-06 00:30:27 +0000315 static bool isMangled(EFuncId Id) {
316 return static_cast<unsigned>(Id) <= static_cast<unsigned>(EI_LAST_MANGLED);
317 }
Stanislav Mekhanoshin7f377942017-08-11 16:42:09 +0000318};
319
Yaxun Liufc5121a2017-09-06 00:30:27 +0000320class AMDGPULibFuncImpl : public AMDGPULibFuncBase {
321public:
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
346protected:
347 EFuncId FuncId;
348 std::string Name;
349 ENamePrefix FKind;
350};
351
352/// Wrapper class for AMDGPULIbFuncImpl
353class AMDGPULibFunc : public AMDGPULibFuncBase {
354public:
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
397private:
398 /// Initialize as a mangled library function.
399 void initMangled();
400 std::unique_ptr<AMDGPULibFuncImpl> Impl;
401};
402
403class AMDGPUMangledLibFunc : public AMDGPULibFuncImpl {
404public:
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
423private:
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
432class AMDGPUUnmangledLibFunc : public AMDGPULibFuncImpl {
433 FunctionType *FuncTy;
434
435public:
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};
Stanislav Mekhanoshin7f377942017-08-11 16:42:09 +0000454}
455#endif // _AMDGPU_LIBFUNC_H_