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