xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AMDGPU/AMDGPULibFunc.h (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
10b57cec5SDimitry Andric //===-- AMDGPULibFunc.h ----------------------------------------*- C++ -*--===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #ifndef _AMDGPU_LIBFUNC_H_
100b57cec5SDimitry Andric #define _AMDGPU_LIBFUNC_H_
110b57cec5SDimitry Andric 
120b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
1304eeddc0SDimitry Andric #include <memory>
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric namespace llvm {
160b57cec5SDimitry Andric 
175ffd83dbSDimitry Andric class FunctionCallee;
180b57cec5SDimitry Andric class FunctionType;
190b57cec5SDimitry Andric class Function;
200b57cec5SDimitry Andric class Module;
21*5f757f3fSDimitry Andric class Type;
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric class AMDGPULibFuncBase {
240b57cec5SDimitry Andric public:
250b57cec5SDimitry Andric   enum EFuncId {
260b57cec5SDimitry Andric     EI_NONE,
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric     // IMPORTANT: enums below should go in ascending by 1 value order
290b57cec5SDimitry Andric     // because they are used as indexes in the mangling rules table.
300b57cec5SDimitry Andric     // don't use explicit value assignment.
310b57cec5SDimitry Andric     //
320b57cec5SDimitry Andric     // There are two types of library functions: those with mangled
330b57cec5SDimitry Andric     // name and those with unmangled name. The enums for the library
340b57cec5SDimitry Andric     // functions with mangled name are defined before enums for the
350b57cec5SDimitry Andric     // library functions with unmangled name. The enum for the last
360b57cec5SDimitry Andric     // library function with mangled name is EI_LAST_MANGLED.
370b57cec5SDimitry Andric     //
380b57cec5SDimitry Andric     // Library functions with mangled name.
390b57cec5SDimitry Andric     EI_ABS,
400b57cec5SDimitry Andric     EI_ABS_DIFF,
410b57cec5SDimitry Andric     EI_ACOS,
420b57cec5SDimitry Andric     EI_ACOSH,
430b57cec5SDimitry Andric     EI_ACOSPI,
440b57cec5SDimitry Andric     EI_ADD_SAT,
450b57cec5SDimitry Andric     EI_ALL,
460b57cec5SDimitry Andric     EI_ANY,
470b57cec5SDimitry Andric     EI_ASIN,
480b57cec5SDimitry Andric     EI_ASINH,
490b57cec5SDimitry Andric     EI_ASINPI,
500b57cec5SDimitry Andric     EI_ASYNC_WORK_GROUP_COPY,
510b57cec5SDimitry Andric     EI_ASYNC_WORK_GROUP_STRIDED_COPY,
520b57cec5SDimitry Andric     EI_ATAN,
530b57cec5SDimitry Andric     EI_ATAN2,
540b57cec5SDimitry Andric     EI_ATAN2PI,
550b57cec5SDimitry Andric     EI_ATANH,
560b57cec5SDimitry Andric     EI_ATANPI,
570b57cec5SDimitry Andric     EI_ATOMIC_ADD,
580b57cec5SDimitry Andric     EI_ATOMIC_AND,
590b57cec5SDimitry Andric     EI_ATOMIC_CMPXCHG,
600b57cec5SDimitry Andric     EI_ATOMIC_DEC,
610b57cec5SDimitry Andric     EI_ATOMIC_INC,
620b57cec5SDimitry Andric     EI_ATOMIC_MAX,
630b57cec5SDimitry Andric     EI_ATOMIC_MIN,
640b57cec5SDimitry Andric     EI_ATOMIC_OR,
650b57cec5SDimitry Andric     EI_ATOMIC_SUB,
660b57cec5SDimitry Andric     EI_ATOMIC_XCHG,
670b57cec5SDimitry Andric     EI_ATOMIC_XOR,
680b57cec5SDimitry Andric     EI_BITSELECT,
690b57cec5SDimitry Andric     EI_CBRT,
700b57cec5SDimitry Andric     EI_CEIL,
710b57cec5SDimitry Andric     EI_CLAMP,
720b57cec5SDimitry Andric     EI_CLZ,
730b57cec5SDimitry Andric     EI_COMMIT_READ_PIPE,
740b57cec5SDimitry Andric     EI_COMMIT_WRITE_PIPE,
750b57cec5SDimitry Andric     EI_COPYSIGN,
760b57cec5SDimitry Andric     EI_COS,
770b57cec5SDimitry Andric     EI_COSH,
780b57cec5SDimitry Andric     EI_COSPI,
790b57cec5SDimitry Andric     EI_CROSS,
800b57cec5SDimitry Andric     EI_CTZ,
810b57cec5SDimitry Andric     EI_DEGREES,
820b57cec5SDimitry Andric     EI_DISTANCE,
830b57cec5SDimitry Andric     EI_DIVIDE,
840b57cec5SDimitry Andric     EI_DOT,
850b57cec5SDimitry Andric     EI_ERF,
860b57cec5SDimitry Andric     EI_ERFC,
870b57cec5SDimitry Andric     EI_EXP,
880b57cec5SDimitry Andric     EI_EXP10,
890b57cec5SDimitry Andric     EI_EXP2,
900b57cec5SDimitry Andric     EI_EXPM1,
910b57cec5SDimitry Andric     EI_FABS,
920b57cec5SDimitry Andric     EI_FAST_DISTANCE,
930b57cec5SDimitry Andric     EI_FAST_LENGTH,
940b57cec5SDimitry Andric     EI_FAST_NORMALIZE,
950b57cec5SDimitry Andric     EI_FDIM,
960b57cec5SDimitry Andric     EI_FLOOR,
970b57cec5SDimitry Andric     EI_FMA,
980b57cec5SDimitry Andric     EI_FMAX,
990b57cec5SDimitry Andric     EI_FMIN,
1000b57cec5SDimitry Andric     EI_FMOD,
1010b57cec5SDimitry Andric     EI_FRACT,
1020b57cec5SDimitry Andric     EI_FREXP,
1030b57cec5SDimitry Andric     EI_GET_IMAGE_ARRAY_SIZE,
1040b57cec5SDimitry Andric     EI_GET_IMAGE_CHANNEL_DATA_TYPE,
1050b57cec5SDimitry Andric     EI_GET_IMAGE_CHANNEL_ORDER,
1060b57cec5SDimitry Andric     EI_GET_IMAGE_DIM,
1070b57cec5SDimitry Andric     EI_GET_IMAGE_HEIGHT,
1080b57cec5SDimitry Andric     EI_GET_IMAGE_WIDTH,
1090b57cec5SDimitry Andric     EI_GET_PIPE_MAX_PACKETS,
1100b57cec5SDimitry Andric     EI_GET_PIPE_NUM_PACKETS,
1110b57cec5SDimitry Andric     EI_HADD,
1120b57cec5SDimitry Andric     EI_HYPOT,
1130b57cec5SDimitry Andric     EI_ILOGB,
1140b57cec5SDimitry Andric     EI_ISEQUAL,
1150b57cec5SDimitry Andric     EI_ISFINITE,
1160b57cec5SDimitry Andric     EI_ISGREATER,
1170b57cec5SDimitry Andric     EI_ISGREATEREQUAL,
1180b57cec5SDimitry Andric     EI_ISINF,
1190b57cec5SDimitry Andric     EI_ISLESS,
1200b57cec5SDimitry Andric     EI_ISLESSEQUAL,
1210b57cec5SDimitry Andric     EI_ISLESSGREATER,
1220b57cec5SDimitry Andric     EI_ISNAN,
1230b57cec5SDimitry Andric     EI_ISNORMAL,
1240b57cec5SDimitry Andric     EI_ISNOTEQUAL,
1250b57cec5SDimitry Andric     EI_ISORDERED,
1260b57cec5SDimitry Andric     EI_ISUNORDERED,
1270b57cec5SDimitry Andric     EI_LDEXP,
1280b57cec5SDimitry Andric     EI_LENGTH,
1290b57cec5SDimitry Andric     EI_LGAMMA,
1300b57cec5SDimitry Andric     EI_LGAMMA_R,
1310b57cec5SDimitry Andric     EI_LOG,
1320b57cec5SDimitry Andric     EI_LOG10,
1330b57cec5SDimitry Andric     EI_LOG1P,
1340b57cec5SDimitry Andric     EI_LOG2,
1350b57cec5SDimitry Andric     EI_LOGB,
1360b57cec5SDimitry Andric     EI_MAD,
1370b57cec5SDimitry Andric     EI_MAD24,
1380b57cec5SDimitry Andric     EI_MAD_HI,
1390b57cec5SDimitry Andric     EI_MAD_SAT,
1400b57cec5SDimitry Andric     EI_MAX,
1410b57cec5SDimitry Andric     EI_MAXMAG,
1420b57cec5SDimitry Andric     EI_MIN,
1430b57cec5SDimitry Andric     EI_MINMAG,
1440b57cec5SDimitry Andric     EI_MIX,
1450b57cec5SDimitry Andric     EI_MODF,
1460b57cec5SDimitry Andric     EI_MUL24,
1470b57cec5SDimitry Andric     EI_MUL_HI,
1480b57cec5SDimitry Andric     EI_NAN,
1490b57cec5SDimitry Andric     EI_NEXTAFTER,
1500b57cec5SDimitry Andric     EI_NORMALIZE,
1510b57cec5SDimitry Andric     EI_POPCOUNT,
1520b57cec5SDimitry Andric     EI_POW,
1530b57cec5SDimitry Andric     EI_POWN,
1540b57cec5SDimitry Andric     EI_POWR,
1550b57cec5SDimitry Andric     EI_PREFETCH,
1560b57cec5SDimitry Andric     EI_RADIANS,
1570b57cec5SDimitry Andric     EI_RECIP,
1580b57cec5SDimitry Andric     EI_REMAINDER,
1590b57cec5SDimitry Andric     EI_REMQUO,
1600b57cec5SDimitry Andric     EI_RESERVE_READ_PIPE,
1610b57cec5SDimitry Andric     EI_RESERVE_WRITE_PIPE,
1620b57cec5SDimitry Andric     EI_RHADD,
1630b57cec5SDimitry Andric     EI_RINT,
1640b57cec5SDimitry Andric     EI_ROOTN,
1650b57cec5SDimitry Andric     EI_ROTATE,
1660b57cec5SDimitry Andric     EI_ROUND,
1670b57cec5SDimitry Andric     EI_RSQRT,
1680b57cec5SDimitry Andric     EI_SELECT,
1690b57cec5SDimitry Andric     EI_SHUFFLE,
1700b57cec5SDimitry Andric     EI_SHUFFLE2,
1710b57cec5SDimitry Andric     EI_SIGN,
1720b57cec5SDimitry Andric     EI_SIGNBIT,
1730b57cec5SDimitry Andric     EI_SIN,
1740b57cec5SDimitry Andric     EI_SINCOS,
1750b57cec5SDimitry Andric     EI_SINH,
1760b57cec5SDimitry Andric     EI_SINPI,
1770b57cec5SDimitry Andric     EI_SMOOTHSTEP,
1780b57cec5SDimitry Andric     EI_SQRT,
1790b57cec5SDimitry Andric     EI_STEP,
1800b57cec5SDimitry Andric     EI_SUB_GROUP_BROADCAST,
1810b57cec5SDimitry Andric     EI_SUB_GROUP_COMMIT_READ_PIPE,
1820b57cec5SDimitry Andric     EI_SUB_GROUP_COMMIT_WRITE_PIPE,
1830b57cec5SDimitry Andric     EI_SUB_GROUP_REDUCE_ADD,
1840b57cec5SDimitry Andric     EI_SUB_GROUP_REDUCE_MAX,
1850b57cec5SDimitry Andric     EI_SUB_GROUP_REDUCE_MIN,
1860b57cec5SDimitry Andric     EI_SUB_GROUP_RESERVE_READ_PIPE,
1870b57cec5SDimitry Andric     EI_SUB_GROUP_RESERVE_WRITE_PIPE,
1880b57cec5SDimitry Andric     EI_SUB_GROUP_SCAN_EXCLUSIVE_ADD,
1890b57cec5SDimitry Andric     EI_SUB_GROUP_SCAN_EXCLUSIVE_MAX,
1900b57cec5SDimitry Andric     EI_SUB_GROUP_SCAN_EXCLUSIVE_MIN,
1910b57cec5SDimitry Andric     EI_SUB_GROUP_SCAN_INCLUSIVE_ADD,
1920b57cec5SDimitry Andric     EI_SUB_GROUP_SCAN_INCLUSIVE_MAX,
1930b57cec5SDimitry Andric     EI_SUB_GROUP_SCAN_INCLUSIVE_MIN,
1940b57cec5SDimitry Andric     EI_SUB_SAT,
1950b57cec5SDimitry Andric     EI_TAN,
1960b57cec5SDimitry Andric     EI_TANH,
1970b57cec5SDimitry Andric     EI_TANPI,
1980b57cec5SDimitry Andric     EI_TGAMMA,
1990b57cec5SDimitry Andric     EI_TRUNC,
2000b57cec5SDimitry Andric     EI_UPSAMPLE,
2010b57cec5SDimitry Andric     EI_VEC_STEP,
2020b57cec5SDimitry Andric     EI_VSTORE,
2030b57cec5SDimitry Andric     EI_VSTORE16,
2040b57cec5SDimitry Andric     EI_VSTORE2,
2050b57cec5SDimitry Andric     EI_VSTORE3,
2060b57cec5SDimitry Andric     EI_VSTORE4,
2070b57cec5SDimitry Andric     EI_VSTORE8,
2080b57cec5SDimitry Andric     EI_WORK_GROUP_COMMIT_READ_PIPE,
2090b57cec5SDimitry Andric     EI_WORK_GROUP_COMMIT_WRITE_PIPE,
2100b57cec5SDimitry Andric     EI_WORK_GROUP_REDUCE_ADD,
2110b57cec5SDimitry Andric     EI_WORK_GROUP_REDUCE_MAX,
2120b57cec5SDimitry Andric     EI_WORK_GROUP_REDUCE_MIN,
2130b57cec5SDimitry Andric     EI_WORK_GROUP_RESERVE_READ_PIPE,
2140b57cec5SDimitry Andric     EI_WORK_GROUP_RESERVE_WRITE_PIPE,
2150b57cec5SDimitry Andric     EI_WORK_GROUP_SCAN_EXCLUSIVE_ADD,
2160b57cec5SDimitry Andric     EI_WORK_GROUP_SCAN_EXCLUSIVE_MAX,
2170b57cec5SDimitry Andric     EI_WORK_GROUP_SCAN_EXCLUSIVE_MIN,
2180b57cec5SDimitry Andric     EI_WORK_GROUP_SCAN_INCLUSIVE_ADD,
2190b57cec5SDimitry Andric     EI_WORK_GROUP_SCAN_INCLUSIVE_MAX,
2200b57cec5SDimitry Andric     EI_WORK_GROUP_SCAN_INCLUSIVE_MIN,
2210b57cec5SDimitry Andric     EI_WRITE_IMAGEF,
2220b57cec5SDimitry Andric     EI_WRITE_IMAGEI,
2230b57cec5SDimitry Andric     EI_WRITE_IMAGEUI,
2240b57cec5SDimitry Andric     EI_NCOS,
2250b57cec5SDimitry Andric     EI_NEXP2,
2260b57cec5SDimitry Andric     EI_NFMA,
2270b57cec5SDimitry Andric     EI_NLOG2,
2280b57cec5SDimitry Andric     EI_NRCP,
2290b57cec5SDimitry Andric     EI_NRSQRT,
2300b57cec5SDimitry Andric     EI_NSIN,
2310b57cec5SDimitry Andric     EI_NSQRT,
2320b57cec5SDimitry Andric     EI_FTZ,
2330b57cec5SDimitry Andric     EI_FLDEXP,
2340b57cec5SDimitry Andric     EI_CLASS,
2350b57cec5SDimitry Andric     EI_RCBRT,
2360b57cec5SDimitry Andric     EI_LAST_MANGLED =
2370b57cec5SDimitry Andric         EI_RCBRT, /* The last library function with mangled name */
2380b57cec5SDimitry Andric 
2390b57cec5SDimitry Andric     // Library functions with unmangled name.
2400b57cec5SDimitry Andric     EI_READ_PIPE_2,
2410b57cec5SDimitry Andric     EI_READ_PIPE_4,
2420b57cec5SDimitry Andric     EI_WRITE_PIPE_2,
2430b57cec5SDimitry Andric     EI_WRITE_PIPE_4,
2440b57cec5SDimitry Andric 
2450b57cec5SDimitry Andric     EX_INTRINSICS_COUNT
2460b57cec5SDimitry Andric   };
2470b57cec5SDimitry Andric 
2480b57cec5SDimitry Andric   enum ENamePrefix {
2490b57cec5SDimitry Andric     NOPFX,
2500b57cec5SDimitry Andric     NATIVE,
2510b57cec5SDimitry Andric     HALF
2520b57cec5SDimitry Andric   };
2530b57cec5SDimitry Andric 
2540b57cec5SDimitry Andric   enum EType {
2550b57cec5SDimitry Andric     B8  = 1,
2560b57cec5SDimitry Andric     B16 = 2,
2570b57cec5SDimitry Andric     B32 = 3,
2580b57cec5SDimitry Andric     B64 = 4,
2590b57cec5SDimitry Andric     SIZE_MASK = 7,
2600b57cec5SDimitry Andric     FLOAT = 0x10,
2610b57cec5SDimitry Andric     INT   = 0x20,
2620b57cec5SDimitry Andric     UINT  = 0x30,
2630b57cec5SDimitry Andric     BASE_TYPE_MASK = 0x30,
2640b57cec5SDimitry Andric     U8  =  UINT | B8,
2650b57cec5SDimitry Andric     U16 =  UINT | B16,
2660b57cec5SDimitry Andric     U32 =  UINT | B32,
2670b57cec5SDimitry Andric     U64 =  UINT | B64,
2680b57cec5SDimitry Andric     I8  =   INT | B8,
2690b57cec5SDimitry Andric     I16 =   INT | B16,
2700b57cec5SDimitry Andric     I32 =   INT | B32,
2710b57cec5SDimitry Andric     I64 =   INT | B64,
2720b57cec5SDimitry Andric     F16 = FLOAT | B16,
2730b57cec5SDimitry Andric     F32 = FLOAT | B32,
2740b57cec5SDimitry Andric     F64 = FLOAT | B64,
2750b57cec5SDimitry Andric     IMG1DA = 0x80,
2760b57cec5SDimitry Andric     IMG1DB,
2770b57cec5SDimitry Andric     IMG2DA,
2780b57cec5SDimitry Andric     IMG1D,
2790b57cec5SDimitry Andric     IMG2D,
2800b57cec5SDimitry Andric     IMG3D,
2810b57cec5SDimitry Andric     SAMPLER,
2820b57cec5SDimitry Andric     EVENT,
2830b57cec5SDimitry Andric     DUMMY
2840b57cec5SDimitry Andric   };
2850b57cec5SDimitry Andric 
2860b57cec5SDimitry Andric   enum EPtrKind {
2870b57cec5SDimitry Andric     BYVALUE = 0,
2880b57cec5SDimitry Andric     ADDR_SPACE = 0xF, // Address space takes value 0x1 ~ 0xF.
2890b57cec5SDimitry Andric     CONST      = 0x10,
2900b57cec5SDimitry Andric     VOLATILE   = 0x20
2910b57cec5SDimitry Andric   };
2920b57cec5SDimitry Andric 
2930b57cec5SDimitry Andric   struct Param {
294*5f757f3fSDimitry Andric     unsigned char ArgType = 0;
295*5f757f3fSDimitry Andric     unsigned char VectorSize = 1;
296*5f757f3fSDimitry Andric     unsigned char PtrKind = 0;
2970b57cec5SDimitry Andric 
298*5f757f3fSDimitry Andric     unsigned char Reserved = 0;
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric     void reset() {
3010b57cec5SDimitry Andric       ArgType = 0;
3020b57cec5SDimitry Andric       VectorSize = 1;
3030b57cec5SDimitry Andric       PtrKind = 0;
3040b57cec5SDimitry Andric     }
305*5f757f3fSDimitry Andric 
306*5f757f3fSDimitry Andric     static Param getIntN(unsigned char NumElts) {
307*5f757f3fSDimitry Andric       return Param{I32, NumElts, 0, 0};
308*5f757f3fSDimitry Andric     }
309*5f757f3fSDimitry Andric 
310*5f757f3fSDimitry Andric     static Param getFromTy(Type *Ty, bool Signed);
3110b57cec5SDimitry Andric 
3120b57cec5SDimitry Andric     template <typename Stream>
3130b57cec5SDimitry Andric     void mangleItanium(Stream& os);
3140b57cec5SDimitry Andric   };
3150b57cec5SDimitry Andric   static bool isMangled(EFuncId Id) {
3160b57cec5SDimitry Andric     return static_cast<unsigned>(Id) <= static_cast<unsigned>(EI_LAST_MANGLED);
3170b57cec5SDimitry Andric   }
3180b57cec5SDimitry Andric 
3190b57cec5SDimitry Andric   static unsigned getEPtrKindFromAddrSpace(unsigned AS) {
3200b57cec5SDimitry Andric     assert(((AS + 1) & ~ADDR_SPACE) == 0);
3210b57cec5SDimitry Andric     return AS + 1;
3220b57cec5SDimitry Andric   }
3230b57cec5SDimitry Andric 
3240b57cec5SDimitry Andric   static unsigned getAddrSpaceFromEPtrKind(unsigned Kind) {
3250b57cec5SDimitry Andric     Kind = Kind & ADDR_SPACE;
3260b57cec5SDimitry Andric     assert(Kind >= 1);
3270b57cec5SDimitry Andric     return Kind - 1;
3280b57cec5SDimitry Andric   }
3290b57cec5SDimitry Andric };
3300b57cec5SDimitry Andric 
3310b57cec5SDimitry Andric class AMDGPULibFuncImpl : public AMDGPULibFuncBase {
3320b57cec5SDimitry Andric public:
33381ad6265SDimitry Andric   AMDGPULibFuncImpl() = default;
33481ad6265SDimitry Andric   virtual ~AMDGPULibFuncImpl() = default;
3350b57cec5SDimitry Andric 
3360b57cec5SDimitry Andric   /// Get unmangled name for mangled library function and name for unmangled
3370b57cec5SDimitry Andric   /// library function.
3380b57cec5SDimitry Andric   virtual std::string getName() const = 0;
3390b57cec5SDimitry Andric   virtual unsigned getNumArgs() const = 0;
3400b57cec5SDimitry Andric   EFuncId getId() const { return FuncId; }
3410b57cec5SDimitry Andric   ENamePrefix getPrefix() const { return FKind; }
3420b57cec5SDimitry Andric 
3430b57cec5SDimitry Andric   bool isMangled() const { return AMDGPULibFuncBase::isMangled(FuncId); }
3440b57cec5SDimitry Andric 
3450b57cec5SDimitry Andric   void setId(EFuncId id) { FuncId = id; }
3460b57cec5SDimitry Andric   virtual bool parseFuncName(StringRef &mangledName) = 0;
3470b57cec5SDimitry Andric 
3480b57cec5SDimitry Andric   /// \return The mangled function name for mangled library functions
3490b57cec5SDimitry Andric   /// and unmangled function name for unmangled library functions.
3500b57cec5SDimitry Andric   virtual std::string mangle() const = 0;
3510b57cec5SDimitry Andric 
3525ffd83dbSDimitry Andric   void setName(StringRef N) { Name = std::string(N); }
3530b57cec5SDimitry Andric   void setPrefix(ENamePrefix pfx) { FKind = pfx; }
3540b57cec5SDimitry Andric 
3550b57cec5SDimitry Andric   virtual FunctionType *getFunctionType(Module &M) const = 0;
3560b57cec5SDimitry Andric 
3570b57cec5SDimitry Andric protected:
3580b57cec5SDimitry Andric   EFuncId FuncId;
3590b57cec5SDimitry Andric   std::string Name;
360*5f757f3fSDimitry Andric   ENamePrefix FKind = NOPFX;
3610b57cec5SDimitry Andric };
3620b57cec5SDimitry Andric 
3630b57cec5SDimitry Andric /// Wrapper class for AMDGPULIbFuncImpl
3640b57cec5SDimitry Andric class AMDGPULibFunc : public AMDGPULibFuncBase {
3650b57cec5SDimitry Andric public:
3660b57cec5SDimitry Andric   explicit AMDGPULibFunc() : Impl(std::unique_ptr<AMDGPULibFuncImpl>()) {}
3670b57cec5SDimitry Andric   AMDGPULibFunc(const AMDGPULibFunc &F);
3680b57cec5SDimitry Andric   /// Clone a mangled library func with the Id \p Id and argument info from \p
3690b57cec5SDimitry Andric   /// CopyFrom.
3700b57cec5SDimitry Andric   explicit AMDGPULibFunc(EFuncId Id, const AMDGPULibFunc &CopyFrom);
371*5f757f3fSDimitry Andric   explicit AMDGPULibFunc(EFuncId Id, FunctionType *FT, bool SignedInts);
372*5f757f3fSDimitry Andric 
3730b57cec5SDimitry Andric   /// Construct an unmangled library function on the fly.
3740b57cec5SDimitry Andric   explicit AMDGPULibFunc(StringRef FName, FunctionType *FT);
3750b57cec5SDimitry Andric 
3760b57cec5SDimitry Andric   AMDGPULibFunc &operator=(const AMDGPULibFunc &F);
3770b57cec5SDimitry Andric 
3780b57cec5SDimitry Andric   /// Get unmangled name for mangled library function and name for unmangled
3790b57cec5SDimitry Andric   /// library function.
3800b57cec5SDimitry Andric   std::string getName() const { return Impl->getName(); }
3810b57cec5SDimitry Andric   unsigned getNumArgs() const { return Impl->getNumArgs(); }
3820b57cec5SDimitry Andric   EFuncId getId() const { return Impl->getId(); }
3830b57cec5SDimitry Andric   ENamePrefix getPrefix() const { return Impl->getPrefix(); }
3840b57cec5SDimitry Andric   /// Get leading parameters for mangled lib functions.
3850b57cec5SDimitry Andric   Param *getLeads();
3860b57cec5SDimitry Andric   const Param *getLeads() const;
3870b57cec5SDimitry Andric 
3880b57cec5SDimitry Andric   bool isMangled() const { return Impl->isMangled(); }
3890b57cec5SDimitry Andric   void setId(EFuncId Id) { Impl->setId(Id); }
3900b57cec5SDimitry Andric   bool parseFuncName(StringRef &MangledName) {
3910b57cec5SDimitry Andric     return Impl->parseFuncName(MangledName);
3920b57cec5SDimitry Andric   }
3930b57cec5SDimitry Andric 
394*5f757f3fSDimitry Andric   // Validate the call type matches the expected libfunc type.
395*5f757f3fSDimitry Andric   bool isCompatibleSignature(const FunctionType *FuncTy) const;
396*5f757f3fSDimitry Andric 
3970b57cec5SDimitry Andric   /// \return The mangled function name for mangled library functions
3980b57cec5SDimitry Andric   /// and unmangled function name for unmangled library functions.
3990b57cec5SDimitry Andric   std::string mangle() const { return Impl->mangle(); }
4000b57cec5SDimitry Andric 
4010b57cec5SDimitry Andric   void setName(StringRef N) { Impl->setName(N); }
4020b57cec5SDimitry Andric   void setPrefix(ENamePrefix PFX) { Impl->setPrefix(PFX); }
4030b57cec5SDimitry Andric 
4040b57cec5SDimitry Andric   FunctionType *getFunctionType(Module &M) const {
4050b57cec5SDimitry Andric     return Impl->getFunctionType(M);
4060b57cec5SDimitry Andric   }
4070b57cec5SDimitry Andric   static Function *getFunction(llvm::Module *M, const AMDGPULibFunc &fInfo);
4080b57cec5SDimitry Andric 
4090b57cec5SDimitry Andric   static FunctionCallee getOrInsertFunction(llvm::Module *M,
4100b57cec5SDimitry Andric                                             const AMDGPULibFunc &fInfo);
4110b57cec5SDimitry Andric   static bool parse(StringRef MangledName, AMDGPULibFunc &Ptr);
4120b57cec5SDimitry Andric 
4130b57cec5SDimitry Andric private:
4140b57cec5SDimitry Andric   /// Initialize as a mangled library function.
4150b57cec5SDimitry Andric   void initMangled();
4160b57cec5SDimitry Andric   std::unique_ptr<AMDGPULibFuncImpl> Impl;
4170b57cec5SDimitry Andric };
4180b57cec5SDimitry Andric 
4190b57cec5SDimitry Andric class AMDGPUMangledLibFunc : public AMDGPULibFuncImpl {
4200b57cec5SDimitry Andric public:
4210b57cec5SDimitry Andric   Param Leads[2];
4220b57cec5SDimitry Andric 
4230b57cec5SDimitry Andric   explicit AMDGPUMangledLibFunc();
4240b57cec5SDimitry Andric   explicit AMDGPUMangledLibFunc(EFuncId id,
4250b57cec5SDimitry Andric                                 const AMDGPUMangledLibFunc &copyFrom);
426*5f757f3fSDimitry Andric   explicit AMDGPUMangledLibFunc(EFuncId id, FunctionType *FT,
427*5f757f3fSDimitry Andric                                 bool SignedInts = true);
4280b57cec5SDimitry Andric 
4290b57cec5SDimitry Andric   std::string getName() const override;
4300b57cec5SDimitry Andric   unsigned getNumArgs() const override;
4310b57cec5SDimitry Andric   FunctionType *getFunctionType(Module &M) const override;
4320b57cec5SDimitry Andric   static StringRef getUnmangledName(StringRef MangledName);
4330b57cec5SDimitry Andric 
4340b57cec5SDimitry Andric   bool parseFuncName(StringRef &mangledName) override;
4350b57cec5SDimitry Andric 
4360b57cec5SDimitry Andric   // Methods for support type inquiry through isa, cast, and dyn_cast:
4370b57cec5SDimitry Andric   static bool classof(const AMDGPULibFuncImpl *F) { return F->isMangled(); }
4380b57cec5SDimitry Andric 
4390b57cec5SDimitry Andric   std::string mangle() const override;
4400b57cec5SDimitry Andric 
4410b57cec5SDimitry Andric private:
4420b57cec5SDimitry Andric   std::string mangleNameItanium() const;
4430b57cec5SDimitry Andric 
4440b57cec5SDimitry Andric   std::string mangleName(StringRef Name) const;
4450b57cec5SDimitry Andric   bool parseUnmangledName(StringRef MangledName);
4460b57cec5SDimitry Andric 
4470b57cec5SDimitry Andric   template <typename Stream> void writeName(Stream &OS) const;
4480b57cec5SDimitry Andric };
4490b57cec5SDimitry Andric 
4500b57cec5SDimitry Andric class AMDGPUUnmangledLibFunc : public AMDGPULibFuncImpl {
4510b57cec5SDimitry Andric   FunctionType *FuncTy;
4520b57cec5SDimitry Andric 
4530b57cec5SDimitry Andric public:
4540b57cec5SDimitry Andric   explicit AMDGPUUnmangledLibFunc();
4550b57cec5SDimitry Andric   explicit AMDGPUUnmangledLibFunc(StringRef FName, FunctionType *FT) {
4565ffd83dbSDimitry Andric     Name = std::string(FName);
4570b57cec5SDimitry Andric     FuncTy = FT;
4580b57cec5SDimitry Andric   }
4590b57cec5SDimitry Andric   std::string getName() const override { return Name; }
4600b57cec5SDimitry Andric   unsigned getNumArgs() const override;
4610b57cec5SDimitry Andric   FunctionType *getFunctionType(Module &M) const override { return FuncTy; }
4620b57cec5SDimitry Andric 
4630b57cec5SDimitry Andric   bool parseFuncName(StringRef &Name) override;
4640b57cec5SDimitry Andric 
4650b57cec5SDimitry Andric   // Methods for support type inquiry through isa, cast, and dyn_cast:
4660b57cec5SDimitry Andric   static bool classof(const AMDGPULibFuncImpl *F) { return !F->isMangled(); }
4670b57cec5SDimitry Andric 
4680b57cec5SDimitry Andric   std::string mangle() const override { return Name; }
4690b57cec5SDimitry Andric 
4700b57cec5SDimitry Andric   void setFunctionType(FunctionType *FT) { FuncTy = FT; }
4710b57cec5SDimitry Andric };
4720b57cec5SDimitry Andric }
4730b57cec5SDimitry Andric #endif // _AMDGPU_LIBFUNC_H_
474