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 ©From); 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