Line data Source code
1 : //===-- AMDGPULibFunc.h ----------------------------------------*- C++ -*--===//
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 : 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 1996 : ArgType = 0;
300 1996 : VectorSize = 1;
301 0 : PtrKind = 0;
302 : }
303 1507 : Param() { reset(); }
304 :
305 : template <typename Stream>
306 : void mangleItanium(Stream& os);
307 : };
308 : static bool isMangled(EFuncId Id) {
309 0 : 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 0 : return AS + 1;
315 : }
316 :
317 : static unsigned getAddrSpaceFromEPtrKind(unsigned Kind) {
318 12 : Kind = Kind & ADDR_SPACE;
319 : assert(Kind >= 1);
320 12 : return Kind - 1;
321 : }
322 : };
323 :
324 : class AMDGPULibFuncImpl : public AMDGPULibFuncBase {
325 : public:
326 353 : AMDGPULibFuncImpl() {}
327 0 : 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 0 : EFuncId getId() const { return FuncId; }
334 0 : ENamePrefix getPrefix() const { return FKind; }
335 :
336 0 : bool isMangled() const { return AMDGPULibFuncBase::isMangled(FuncId); }
337 :
338 28 : 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 104 : void setName(StringRef N) { Name = N; }
346 27 : void setPrefix(ENamePrefix pfx) { FKind = pfx; }
347 :
348 : virtual FunctionType *getFunctionType(Module &M) const = 0;
349 :
350 : protected:
351 : EFuncId FuncId;
352 : std::string Name;
353 : ENamePrefix FKind;
354 : };
355 :
356 : /// Wrapper class for AMDGPULIbFuncImpl
357 48 : class AMDGPULibFunc : public AMDGPULibFuncBase {
358 : public:
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 0 : std::string getName() const { return Impl->getName(); }
372 210 : unsigned getNumArgs() const { return Impl->getNumArgs(); }
373 559 : EFuncId getId() const { return Impl->getId(); }
374 99 : ENamePrefix getPrefix() const { return Impl->getPrefix(); }
375 : /// Get leading parameters for mangled lib functions.
376 : Param *getLeads();
377 : const Param *getLeads() const;
378 :
379 69 : 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 143 : 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 99 : return Impl->getFunctionType(M);
394 : }
395 : static Function *getFunction(llvm::Module *M, const AMDGPULibFunc &fInfo);
396 :
397 : static Function *getOrInsertFunction(llvm::Module *M,
398 : const AMDGPULibFunc &fInfo);
399 : static bool parse(StringRef MangledName, AMDGPULibFunc &Ptr);
400 :
401 : private:
402 : /// Initialize as a mangled library function.
403 : void initMangled();
404 : std::unique_ptr<AMDGPULibFuncImpl> Impl;
405 : };
406 :
407 : class AMDGPUMangledLibFunc : public AMDGPULibFuncImpl {
408 : public:
409 : Param Leads[2];
410 :
411 : explicit AMDGPUMangledLibFunc();
412 : explicit AMDGPUMangledLibFunc(EFuncId id,
413 : const AMDGPUMangledLibFunc ©From);
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 2 : static bool classof(const AMDGPULibFuncImpl *F) { return F->isMangled(); }
424 :
425 : std::string mangle() const override;
426 :
427 : private:
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 :
436 : class AMDGPUUnmangledLibFunc : public AMDGPULibFuncImpl {
437 : FunctionType *FuncTy;
438 :
439 : public:
440 : explicit AMDGPUUnmangledLibFunc();
441 72 : explicit AMDGPUUnmangledLibFunc(StringRef FName, FunctionType *FT) {
442 36 : Name = FName;
443 36 : FuncTy = FT;
444 36 : }
445 0 : std::string getName() const override { return Name; }
446 : unsigned getNumArgs() const override;
447 36 : 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 0 : static bool classof(const AMDGPULibFuncImpl *F) { return !F->isMangled(); }
453 :
454 36 : std::string mangle() const override { return Name; }
455 :
456 : void setFunctionType(FunctionType *FT) { FuncTy = FT; }
457 : };
458 : }
459 : #endif // _AMDGPU_LIBFUNC_H_
|