1*0b57cec5SDimitry Andric //===-- AMDGPULibFunc.h ----------------------------------------*- C++ -*--===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric 9*0b57cec5SDimitry Andric #ifndef _AMDGPU_LIBFUNC_H_ 10*0b57cec5SDimitry Andric #define _AMDGPU_LIBFUNC_H_ 11*0b57cec5SDimitry Andric 12*0b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 13*0b57cec5SDimitry Andric 14*0b57cec5SDimitry Andric namespace llvm { 15*0b57cec5SDimitry Andric 16*0b57cec5SDimitry Andric class FunctionType; 17*0b57cec5SDimitry Andric class Function; 18*0b57cec5SDimitry Andric class Module; 19*0b57cec5SDimitry Andric 20*0b57cec5SDimitry Andric class AMDGPULibFuncBase { 21*0b57cec5SDimitry Andric public: 22*0b57cec5SDimitry Andric enum EFuncId { 23*0b57cec5SDimitry Andric EI_NONE, 24*0b57cec5SDimitry Andric 25*0b57cec5SDimitry Andric // IMPORTANT: enums below should go in ascending by 1 value order 26*0b57cec5SDimitry Andric // because they are used as indexes in the mangling rules table. 27*0b57cec5SDimitry Andric // don't use explicit value assignment. 28*0b57cec5SDimitry Andric // 29*0b57cec5SDimitry Andric // There are two types of library functions: those with mangled 30*0b57cec5SDimitry Andric // name and those with unmangled name. The enums for the library 31*0b57cec5SDimitry Andric // functions with mangled name are defined before enums for the 32*0b57cec5SDimitry Andric // library functions with unmangled name. The enum for the last 33*0b57cec5SDimitry Andric // library function with mangled name is EI_LAST_MANGLED. 34*0b57cec5SDimitry Andric // 35*0b57cec5SDimitry Andric // Library functions with mangled name. 36*0b57cec5SDimitry Andric EI_ABS, 37*0b57cec5SDimitry Andric EI_ABS_DIFF, 38*0b57cec5SDimitry Andric EI_ACOS, 39*0b57cec5SDimitry Andric EI_ACOSH, 40*0b57cec5SDimitry Andric EI_ACOSPI, 41*0b57cec5SDimitry Andric EI_ADD_SAT, 42*0b57cec5SDimitry Andric EI_ALL, 43*0b57cec5SDimitry Andric EI_ANY, 44*0b57cec5SDimitry Andric EI_ASIN, 45*0b57cec5SDimitry Andric EI_ASINH, 46*0b57cec5SDimitry Andric EI_ASINPI, 47*0b57cec5SDimitry Andric EI_ASYNC_WORK_GROUP_COPY, 48*0b57cec5SDimitry Andric EI_ASYNC_WORK_GROUP_STRIDED_COPY, 49*0b57cec5SDimitry Andric EI_ATAN, 50*0b57cec5SDimitry Andric EI_ATAN2, 51*0b57cec5SDimitry Andric EI_ATAN2PI, 52*0b57cec5SDimitry Andric EI_ATANH, 53*0b57cec5SDimitry Andric EI_ATANPI, 54*0b57cec5SDimitry Andric EI_ATOMIC_ADD, 55*0b57cec5SDimitry Andric EI_ATOMIC_AND, 56*0b57cec5SDimitry Andric EI_ATOMIC_CMPXCHG, 57*0b57cec5SDimitry Andric EI_ATOMIC_DEC, 58*0b57cec5SDimitry Andric EI_ATOMIC_INC, 59*0b57cec5SDimitry Andric EI_ATOMIC_MAX, 60*0b57cec5SDimitry Andric EI_ATOMIC_MIN, 61*0b57cec5SDimitry Andric EI_ATOMIC_OR, 62*0b57cec5SDimitry Andric EI_ATOMIC_SUB, 63*0b57cec5SDimitry Andric EI_ATOMIC_XCHG, 64*0b57cec5SDimitry Andric EI_ATOMIC_XOR, 65*0b57cec5SDimitry Andric EI_BITSELECT, 66*0b57cec5SDimitry Andric EI_CBRT, 67*0b57cec5SDimitry Andric EI_CEIL, 68*0b57cec5SDimitry Andric EI_CLAMP, 69*0b57cec5SDimitry Andric EI_CLZ, 70*0b57cec5SDimitry Andric EI_COMMIT_READ_PIPE, 71*0b57cec5SDimitry Andric EI_COMMIT_WRITE_PIPE, 72*0b57cec5SDimitry Andric EI_COPYSIGN, 73*0b57cec5SDimitry Andric EI_COS, 74*0b57cec5SDimitry Andric EI_COSH, 75*0b57cec5SDimitry Andric EI_COSPI, 76*0b57cec5SDimitry Andric EI_CROSS, 77*0b57cec5SDimitry Andric EI_CTZ, 78*0b57cec5SDimitry Andric EI_DEGREES, 79*0b57cec5SDimitry Andric EI_DISTANCE, 80*0b57cec5SDimitry Andric EI_DIVIDE, 81*0b57cec5SDimitry Andric EI_DOT, 82*0b57cec5SDimitry Andric EI_ERF, 83*0b57cec5SDimitry Andric EI_ERFC, 84*0b57cec5SDimitry Andric EI_EXP, 85*0b57cec5SDimitry Andric EI_EXP10, 86*0b57cec5SDimitry Andric EI_EXP2, 87*0b57cec5SDimitry Andric EI_EXPM1, 88*0b57cec5SDimitry Andric EI_FABS, 89*0b57cec5SDimitry Andric EI_FAST_DISTANCE, 90*0b57cec5SDimitry Andric EI_FAST_LENGTH, 91*0b57cec5SDimitry Andric EI_FAST_NORMALIZE, 92*0b57cec5SDimitry Andric EI_FDIM, 93*0b57cec5SDimitry Andric EI_FLOOR, 94*0b57cec5SDimitry Andric EI_FMA, 95*0b57cec5SDimitry Andric EI_FMAX, 96*0b57cec5SDimitry Andric EI_FMIN, 97*0b57cec5SDimitry Andric EI_FMOD, 98*0b57cec5SDimitry Andric EI_FRACT, 99*0b57cec5SDimitry Andric EI_FREXP, 100*0b57cec5SDimitry Andric EI_GET_IMAGE_ARRAY_SIZE, 101*0b57cec5SDimitry Andric EI_GET_IMAGE_CHANNEL_DATA_TYPE, 102*0b57cec5SDimitry Andric EI_GET_IMAGE_CHANNEL_ORDER, 103*0b57cec5SDimitry Andric EI_GET_IMAGE_DIM, 104*0b57cec5SDimitry Andric EI_GET_IMAGE_HEIGHT, 105*0b57cec5SDimitry Andric EI_GET_IMAGE_WIDTH, 106*0b57cec5SDimitry Andric EI_GET_PIPE_MAX_PACKETS, 107*0b57cec5SDimitry Andric EI_GET_PIPE_NUM_PACKETS, 108*0b57cec5SDimitry Andric EI_HADD, 109*0b57cec5SDimitry Andric EI_HYPOT, 110*0b57cec5SDimitry Andric EI_ILOGB, 111*0b57cec5SDimitry Andric EI_ISEQUAL, 112*0b57cec5SDimitry Andric EI_ISFINITE, 113*0b57cec5SDimitry Andric EI_ISGREATER, 114*0b57cec5SDimitry Andric EI_ISGREATEREQUAL, 115*0b57cec5SDimitry Andric EI_ISINF, 116*0b57cec5SDimitry Andric EI_ISLESS, 117*0b57cec5SDimitry Andric EI_ISLESSEQUAL, 118*0b57cec5SDimitry Andric EI_ISLESSGREATER, 119*0b57cec5SDimitry Andric EI_ISNAN, 120*0b57cec5SDimitry Andric EI_ISNORMAL, 121*0b57cec5SDimitry Andric EI_ISNOTEQUAL, 122*0b57cec5SDimitry Andric EI_ISORDERED, 123*0b57cec5SDimitry Andric EI_ISUNORDERED, 124*0b57cec5SDimitry Andric EI_LDEXP, 125*0b57cec5SDimitry Andric EI_LENGTH, 126*0b57cec5SDimitry Andric EI_LGAMMA, 127*0b57cec5SDimitry Andric EI_LGAMMA_R, 128*0b57cec5SDimitry Andric EI_LOG, 129*0b57cec5SDimitry Andric EI_LOG10, 130*0b57cec5SDimitry Andric EI_LOG1P, 131*0b57cec5SDimitry Andric EI_LOG2, 132*0b57cec5SDimitry Andric EI_LOGB, 133*0b57cec5SDimitry Andric EI_MAD, 134*0b57cec5SDimitry Andric EI_MAD24, 135*0b57cec5SDimitry Andric EI_MAD_HI, 136*0b57cec5SDimitry Andric EI_MAD_SAT, 137*0b57cec5SDimitry Andric EI_MAX, 138*0b57cec5SDimitry Andric EI_MAXMAG, 139*0b57cec5SDimitry Andric EI_MIN, 140*0b57cec5SDimitry Andric EI_MINMAG, 141*0b57cec5SDimitry Andric EI_MIX, 142*0b57cec5SDimitry Andric EI_MODF, 143*0b57cec5SDimitry Andric EI_MUL24, 144*0b57cec5SDimitry Andric EI_MUL_HI, 145*0b57cec5SDimitry Andric EI_NAN, 146*0b57cec5SDimitry Andric EI_NEXTAFTER, 147*0b57cec5SDimitry Andric EI_NORMALIZE, 148*0b57cec5SDimitry Andric EI_POPCOUNT, 149*0b57cec5SDimitry Andric EI_POW, 150*0b57cec5SDimitry Andric EI_POWN, 151*0b57cec5SDimitry Andric EI_POWR, 152*0b57cec5SDimitry Andric EI_PREFETCH, 153*0b57cec5SDimitry Andric EI_RADIANS, 154*0b57cec5SDimitry Andric EI_RECIP, 155*0b57cec5SDimitry Andric EI_REMAINDER, 156*0b57cec5SDimitry Andric EI_REMQUO, 157*0b57cec5SDimitry Andric EI_RESERVE_READ_PIPE, 158*0b57cec5SDimitry Andric EI_RESERVE_WRITE_PIPE, 159*0b57cec5SDimitry Andric EI_RHADD, 160*0b57cec5SDimitry Andric EI_RINT, 161*0b57cec5SDimitry Andric EI_ROOTN, 162*0b57cec5SDimitry Andric EI_ROTATE, 163*0b57cec5SDimitry Andric EI_ROUND, 164*0b57cec5SDimitry Andric EI_RSQRT, 165*0b57cec5SDimitry Andric EI_SELECT, 166*0b57cec5SDimitry Andric EI_SHUFFLE, 167*0b57cec5SDimitry Andric EI_SHUFFLE2, 168*0b57cec5SDimitry Andric EI_SIGN, 169*0b57cec5SDimitry Andric EI_SIGNBIT, 170*0b57cec5SDimitry Andric EI_SIN, 171*0b57cec5SDimitry Andric EI_SINCOS, 172*0b57cec5SDimitry Andric EI_SINH, 173*0b57cec5SDimitry Andric EI_SINPI, 174*0b57cec5SDimitry Andric EI_SMOOTHSTEP, 175*0b57cec5SDimitry Andric EI_SQRT, 176*0b57cec5SDimitry Andric EI_STEP, 177*0b57cec5SDimitry Andric EI_SUB_GROUP_BROADCAST, 178*0b57cec5SDimitry Andric EI_SUB_GROUP_COMMIT_READ_PIPE, 179*0b57cec5SDimitry Andric EI_SUB_GROUP_COMMIT_WRITE_PIPE, 180*0b57cec5SDimitry Andric EI_SUB_GROUP_REDUCE_ADD, 181*0b57cec5SDimitry Andric EI_SUB_GROUP_REDUCE_MAX, 182*0b57cec5SDimitry Andric EI_SUB_GROUP_REDUCE_MIN, 183*0b57cec5SDimitry Andric EI_SUB_GROUP_RESERVE_READ_PIPE, 184*0b57cec5SDimitry Andric EI_SUB_GROUP_RESERVE_WRITE_PIPE, 185*0b57cec5SDimitry Andric EI_SUB_GROUP_SCAN_EXCLUSIVE_ADD, 186*0b57cec5SDimitry Andric EI_SUB_GROUP_SCAN_EXCLUSIVE_MAX, 187*0b57cec5SDimitry Andric EI_SUB_GROUP_SCAN_EXCLUSIVE_MIN, 188*0b57cec5SDimitry Andric EI_SUB_GROUP_SCAN_INCLUSIVE_ADD, 189*0b57cec5SDimitry Andric EI_SUB_GROUP_SCAN_INCLUSIVE_MAX, 190*0b57cec5SDimitry Andric EI_SUB_GROUP_SCAN_INCLUSIVE_MIN, 191*0b57cec5SDimitry Andric EI_SUB_SAT, 192*0b57cec5SDimitry Andric EI_TAN, 193*0b57cec5SDimitry Andric EI_TANH, 194*0b57cec5SDimitry Andric EI_TANPI, 195*0b57cec5SDimitry Andric EI_TGAMMA, 196*0b57cec5SDimitry Andric EI_TRUNC, 197*0b57cec5SDimitry Andric EI_UPSAMPLE, 198*0b57cec5SDimitry Andric EI_VEC_STEP, 199*0b57cec5SDimitry Andric EI_VSTORE, 200*0b57cec5SDimitry Andric EI_VSTORE16, 201*0b57cec5SDimitry Andric EI_VSTORE2, 202*0b57cec5SDimitry Andric EI_VSTORE3, 203*0b57cec5SDimitry Andric EI_VSTORE4, 204*0b57cec5SDimitry Andric EI_VSTORE8, 205*0b57cec5SDimitry Andric EI_WORK_GROUP_COMMIT_READ_PIPE, 206*0b57cec5SDimitry Andric EI_WORK_GROUP_COMMIT_WRITE_PIPE, 207*0b57cec5SDimitry Andric EI_WORK_GROUP_REDUCE_ADD, 208*0b57cec5SDimitry Andric EI_WORK_GROUP_REDUCE_MAX, 209*0b57cec5SDimitry Andric EI_WORK_GROUP_REDUCE_MIN, 210*0b57cec5SDimitry Andric EI_WORK_GROUP_RESERVE_READ_PIPE, 211*0b57cec5SDimitry Andric EI_WORK_GROUP_RESERVE_WRITE_PIPE, 212*0b57cec5SDimitry Andric EI_WORK_GROUP_SCAN_EXCLUSIVE_ADD, 213*0b57cec5SDimitry Andric EI_WORK_GROUP_SCAN_EXCLUSIVE_MAX, 214*0b57cec5SDimitry Andric EI_WORK_GROUP_SCAN_EXCLUSIVE_MIN, 215*0b57cec5SDimitry Andric EI_WORK_GROUP_SCAN_INCLUSIVE_ADD, 216*0b57cec5SDimitry Andric EI_WORK_GROUP_SCAN_INCLUSIVE_MAX, 217*0b57cec5SDimitry Andric EI_WORK_GROUP_SCAN_INCLUSIVE_MIN, 218*0b57cec5SDimitry Andric EI_WRITE_IMAGEF, 219*0b57cec5SDimitry Andric EI_WRITE_IMAGEI, 220*0b57cec5SDimitry Andric EI_WRITE_IMAGEUI, 221*0b57cec5SDimitry Andric EI_NCOS, 222*0b57cec5SDimitry Andric EI_NEXP2, 223*0b57cec5SDimitry Andric EI_NFMA, 224*0b57cec5SDimitry Andric EI_NLOG2, 225*0b57cec5SDimitry Andric EI_NRCP, 226*0b57cec5SDimitry Andric EI_NRSQRT, 227*0b57cec5SDimitry Andric EI_NSIN, 228*0b57cec5SDimitry Andric EI_NSQRT, 229*0b57cec5SDimitry Andric EI_FTZ, 230*0b57cec5SDimitry Andric EI_FLDEXP, 231*0b57cec5SDimitry Andric EI_CLASS, 232*0b57cec5SDimitry Andric EI_RCBRT, 233*0b57cec5SDimitry Andric EI_LAST_MANGLED = 234*0b57cec5SDimitry Andric EI_RCBRT, /* The last library function with mangled name */ 235*0b57cec5SDimitry Andric 236*0b57cec5SDimitry Andric // Library functions with unmangled name. 237*0b57cec5SDimitry Andric EI_READ_PIPE_2, 238*0b57cec5SDimitry Andric EI_READ_PIPE_4, 239*0b57cec5SDimitry Andric EI_WRITE_PIPE_2, 240*0b57cec5SDimitry Andric EI_WRITE_PIPE_4, 241*0b57cec5SDimitry Andric 242*0b57cec5SDimitry Andric EX_INTRINSICS_COUNT 243*0b57cec5SDimitry Andric }; 244*0b57cec5SDimitry Andric 245*0b57cec5SDimitry Andric enum ENamePrefix { 246*0b57cec5SDimitry Andric NOPFX, 247*0b57cec5SDimitry Andric NATIVE, 248*0b57cec5SDimitry Andric HALF 249*0b57cec5SDimitry Andric }; 250*0b57cec5SDimitry Andric 251*0b57cec5SDimitry Andric enum EType { 252*0b57cec5SDimitry Andric B8 = 1, 253*0b57cec5SDimitry Andric B16 = 2, 254*0b57cec5SDimitry Andric B32 = 3, 255*0b57cec5SDimitry Andric B64 = 4, 256*0b57cec5SDimitry Andric SIZE_MASK = 7, 257*0b57cec5SDimitry Andric FLOAT = 0x10, 258*0b57cec5SDimitry Andric INT = 0x20, 259*0b57cec5SDimitry Andric UINT = 0x30, 260*0b57cec5SDimitry Andric BASE_TYPE_MASK = 0x30, 261*0b57cec5SDimitry Andric U8 = UINT | B8, 262*0b57cec5SDimitry Andric U16 = UINT | B16, 263*0b57cec5SDimitry Andric U32 = UINT | B32, 264*0b57cec5SDimitry Andric U64 = UINT | B64, 265*0b57cec5SDimitry Andric I8 = INT | B8, 266*0b57cec5SDimitry Andric I16 = INT | B16, 267*0b57cec5SDimitry Andric I32 = INT | B32, 268*0b57cec5SDimitry Andric I64 = INT | B64, 269*0b57cec5SDimitry Andric F16 = FLOAT | B16, 270*0b57cec5SDimitry Andric F32 = FLOAT | B32, 271*0b57cec5SDimitry Andric F64 = FLOAT | B64, 272*0b57cec5SDimitry Andric IMG1DA = 0x80, 273*0b57cec5SDimitry Andric IMG1DB, 274*0b57cec5SDimitry Andric IMG2DA, 275*0b57cec5SDimitry Andric IMG1D, 276*0b57cec5SDimitry Andric IMG2D, 277*0b57cec5SDimitry Andric IMG3D, 278*0b57cec5SDimitry Andric SAMPLER, 279*0b57cec5SDimitry Andric EVENT, 280*0b57cec5SDimitry Andric DUMMY 281*0b57cec5SDimitry Andric }; 282*0b57cec5SDimitry Andric 283*0b57cec5SDimitry Andric enum EPtrKind { 284*0b57cec5SDimitry Andric BYVALUE = 0, 285*0b57cec5SDimitry Andric ADDR_SPACE = 0xF, // Address space takes value 0x1 ~ 0xF. 286*0b57cec5SDimitry Andric CONST = 0x10, 287*0b57cec5SDimitry Andric VOLATILE = 0x20 288*0b57cec5SDimitry Andric }; 289*0b57cec5SDimitry Andric 290*0b57cec5SDimitry Andric struct Param { 291*0b57cec5SDimitry Andric unsigned char ArgType; 292*0b57cec5SDimitry Andric unsigned char VectorSize; 293*0b57cec5SDimitry Andric unsigned char PtrKind; 294*0b57cec5SDimitry Andric 295*0b57cec5SDimitry Andric unsigned char Reserved; 296*0b57cec5SDimitry Andric 297*0b57cec5SDimitry Andric void reset() { 298*0b57cec5SDimitry Andric ArgType = 0; 299*0b57cec5SDimitry Andric VectorSize = 1; 300*0b57cec5SDimitry Andric PtrKind = 0; 301*0b57cec5SDimitry Andric } 302*0b57cec5SDimitry Andric Param() { reset(); } 303*0b57cec5SDimitry Andric 304*0b57cec5SDimitry Andric template <typename Stream> 305*0b57cec5SDimitry Andric void mangleItanium(Stream& os); 306*0b57cec5SDimitry Andric }; 307*0b57cec5SDimitry Andric static bool isMangled(EFuncId Id) { 308*0b57cec5SDimitry Andric return static_cast<unsigned>(Id) <= static_cast<unsigned>(EI_LAST_MANGLED); 309*0b57cec5SDimitry Andric } 310*0b57cec5SDimitry Andric 311*0b57cec5SDimitry Andric static unsigned getEPtrKindFromAddrSpace(unsigned AS) { 312*0b57cec5SDimitry Andric assert(((AS + 1) & ~ADDR_SPACE) == 0); 313*0b57cec5SDimitry Andric return AS + 1; 314*0b57cec5SDimitry Andric } 315*0b57cec5SDimitry Andric 316*0b57cec5SDimitry Andric static unsigned getAddrSpaceFromEPtrKind(unsigned Kind) { 317*0b57cec5SDimitry Andric Kind = Kind & ADDR_SPACE; 318*0b57cec5SDimitry Andric assert(Kind >= 1); 319*0b57cec5SDimitry Andric return Kind - 1; 320*0b57cec5SDimitry Andric } 321*0b57cec5SDimitry Andric }; 322*0b57cec5SDimitry Andric 323*0b57cec5SDimitry Andric class AMDGPULibFuncImpl : public AMDGPULibFuncBase { 324*0b57cec5SDimitry Andric public: 325*0b57cec5SDimitry Andric AMDGPULibFuncImpl() {} 326*0b57cec5SDimitry Andric virtual ~AMDGPULibFuncImpl() {} 327*0b57cec5SDimitry Andric 328*0b57cec5SDimitry Andric /// Get unmangled name for mangled library function and name for unmangled 329*0b57cec5SDimitry Andric /// library function. 330*0b57cec5SDimitry Andric virtual std::string getName() const = 0; 331*0b57cec5SDimitry Andric virtual unsigned getNumArgs() const = 0; 332*0b57cec5SDimitry Andric EFuncId getId() const { return FuncId; } 333*0b57cec5SDimitry Andric ENamePrefix getPrefix() const { return FKind; } 334*0b57cec5SDimitry Andric 335*0b57cec5SDimitry Andric bool isMangled() const { return AMDGPULibFuncBase::isMangled(FuncId); } 336*0b57cec5SDimitry Andric 337*0b57cec5SDimitry Andric void setId(EFuncId id) { FuncId = id; } 338*0b57cec5SDimitry Andric virtual bool parseFuncName(StringRef &mangledName) = 0; 339*0b57cec5SDimitry Andric 340*0b57cec5SDimitry Andric /// \return The mangled function name for mangled library functions 341*0b57cec5SDimitry Andric /// and unmangled function name for unmangled library functions. 342*0b57cec5SDimitry Andric virtual std::string mangle() const = 0; 343*0b57cec5SDimitry Andric 344*0b57cec5SDimitry Andric void setName(StringRef N) { Name = N; } 345*0b57cec5SDimitry Andric void setPrefix(ENamePrefix pfx) { FKind = pfx; } 346*0b57cec5SDimitry Andric 347*0b57cec5SDimitry Andric virtual FunctionType *getFunctionType(Module &M) const = 0; 348*0b57cec5SDimitry Andric 349*0b57cec5SDimitry Andric protected: 350*0b57cec5SDimitry Andric EFuncId FuncId; 351*0b57cec5SDimitry Andric std::string Name; 352*0b57cec5SDimitry Andric ENamePrefix FKind; 353*0b57cec5SDimitry Andric }; 354*0b57cec5SDimitry Andric 355*0b57cec5SDimitry Andric /// Wrapper class for AMDGPULIbFuncImpl 356*0b57cec5SDimitry Andric class AMDGPULibFunc : public AMDGPULibFuncBase { 357*0b57cec5SDimitry Andric public: 358*0b57cec5SDimitry Andric explicit AMDGPULibFunc() : Impl(std::unique_ptr<AMDGPULibFuncImpl>()) {} 359*0b57cec5SDimitry Andric AMDGPULibFunc(const AMDGPULibFunc &F); 360*0b57cec5SDimitry Andric /// Clone a mangled library func with the Id \p Id and argument info from \p 361*0b57cec5SDimitry Andric /// CopyFrom. 362*0b57cec5SDimitry Andric explicit AMDGPULibFunc(EFuncId Id, const AMDGPULibFunc &CopyFrom); 363*0b57cec5SDimitry Andric /// Construct an unmangled library function on the fly. 364*0b57cec5SDimitry Andric explicit AMDGPULibFunc(StringRef FName, FunctionType *FT); 365*0b57cec5SDimitry Andric 366*0b57cec5SDimitry Andric AMDGPULibFunc &operator=(const AMDGPULibFunc &F); 367*0b57cec5SDimitry Andric 368*0b57cec5SDimitry Andric /// Get unmangled name for mangled library function and name for unmangled 369*0b57cec5SDimitry Andric /// library function. 370*0b57cec5SDimitry Andric std::string getName() const { return Impl->getName(); } 371*0b57cec5SDimitry Andric unsigned getNumArgs() const { return Impl->getNumArgs(); } 372*0b57cec5SDimitry Andric EFuncId getId() const { return Impl->getId(); } 373*0b57cec5SDimitry Andric ENamePrefix getPrefix() const { return Impl->getPrefix(); } 374*0b57cec5SDimitry Andric /// Get leading parameters for mangled lib functions. 375*0b57cec5SDimitry Andric Param *getLeads(); 376*0b57cec5SDimitry Andric const Param *getLeads() const; 377*0b57cec5SDimitry Andric 378*0b57cec5SDimitry Andric bool isMangled() const { return Impl->isMangled(); } 379*0b57cec5SDimitry Andric void setId(EFuncId Id) { Impl->setId(Id); } 380*0b57cec5SDimitry Andric bool parseFuncName(StringRef &MangledName) { 381*0b57cec5SDimitry Andric return Impl->parseFuncName(MangledName); 382*0b57cec5SDimitry Andric } 383*0b57cec5SDimitry Andric 384*0b57cec5SDimitry Andric /// \return The mangled function name for mangled library functions 385*0b57cec5SDimitry Andric /// and unmangled function name for unmangled library functions. 386*0b57cec5SDimitry Andric std::string mangle() const { return Impl->mangle(); } 387*0b57cec5SDimitry Andric 388*0b57cec5SDimitry Andric void setName(StringRef N) { Impl->setName(N); } 389*0b57cec5SDimitry Andric void setPrefix(ENamePrefix PFX) { Impl->setPrefix(PFX); } 390*0b57cec5SDimitry Andric 391*0b57cec5SDimitry Andric FunctionType *getFunctionType(Module &M) const { 392*0b57cec5SDimitry Andric return Impl->getFunctionType(M); 393*0b57cec5SDimitry Andric } 394*0b57cec5SDimitry Andric static Function *getFunction(llvm::Module *M, const AMDGPULibFunc &fInfo); 395*0b57cec5SDimitry Andric 396*0b57cec5SDimitry Andric static FunctionCallee getOrInsertFunction(llvm::Module *M, 397*0b57cec5SDimitry Andric const AMDGPULibFunc &fInfo); 398*0b57cec5SDimitry Andric static bool parse(StringRef MangledName, AMDGPULibFunc &Ptr); 399*0b57cec5SDimitry Andric 400*0b57cec5SDimitry Andric private: 401*0b57cec5SDimitry Andric /// Initialize as a mangled library function. 402*0b57cec5SDimitry Andric void initMangled(); 403*0b57cec5SDimitry Andric std::unique_ptr<AMDGPULibFuncImpl> Impl; 404*0b57cec5SDimitry Andric }; 405*0b57cec5SDimitry Andric 406*0b57cec5SDimitry Andric class AMDGPUMangledLibFunc : public AMDGPULibFuncImpl { 407*0b57cec5SDimitry Andric public: 408*0b57cec5SDimitry Andric Param Leads[2]; 409*0b57cec5SDimitry Andric 410*0b57cec5SDimitry Andric explicit AMDGPUMangledLibFunc(); 411*0b57cec5SDimitry Andric explicit AMDGPUMangledLibFunc(EFuncId id, 412*0b57cec5SDimitry Andric const AMDGPUMangledLibFunc ©From); 413*0b57cec5SDimitry Andric 414*0b57cec5SDimitry Andric std::string getName() const override; 415*0b57cec5SDimitry Andric unsigned getNumArgs() const override; 416*0b57cec5SDimitry Andric FunctionType *getFunctionType(Module &M) const override; 417*0b57cec5SDimitry Andric static StringRef getUnmangledName(StringRef MangledName); 418*0b57cec5SDimitry Andric 419*0b57cec5SDimitry Andric bool parseFuncName(StringRef &mangledName) override; 420*0b57cec5SDimitry Andric 421*0b57cec5SDimitry Andric // Methods for support type inquiry through isa, cast, and dyn_cast: 422*0b57cec5SDimitry Andric static bool classof(const AMDGPULibFuncImpl *F) { return F->isMangled(); } 423*0b57cec5SDimitry Andric 424*0b57cec5SDimitry Andric std::string mangle() const override; 425*0b57cec5SDimitry Andric 426*0b57cec5SDimitry Andric private: 427*0b57cec5SDimitry Andric std::string mangleNameItanium() const; 428*0b57cec5SDimitry Andric 429*0b57cec5SDimitry Andric std::string mangleName(StringRef Name) const; 430*0b57cec5SDimitry Andric bool parseUnmangledName(StringRef MangledName); 431*0b57cec5SDimitry Andric 432*0b57cec5SDimitry Andric template <typename Stream> void writeName(Stream &OS) const; 433*0b57cec5SDimitry Andric }; 434*0b57cec5SDimitry Andric 435*0b57cec5SDimitry Andric class AMDGPUUnmangledLibFunc : public AMDGPULibFuncImpl { 436*0b57cec5SDimitry Andric FunctionType *FuncTy; 437*0b57cec5SDimitry Andric 438*0b57cec5SDimitry Andric public: 439*0b57cec5SDimitry Andric explicit AMDGPUUnmangledLibFunc(); 440*0b57cec5SDimitry Andric explicit AMDGPUUnmangledLibFunc(StringRef FName, FunctionType *FT) { 441*0b57cec5SDimitry Andric Name = FName; 442*0b57cec5SDimitry Andric FuncTy = FT; 443*0b57cec5SDimitry Andric } 444*0b57cec5SDimitry Andric std::string getName() const override { return Name; } 445*0b57cec5SDimitry Andric unsigned getNumArgs() const override; 446*0b57cec5SDimitry Andric FunctionType *getFunctionType(Module &M) const override { return FuncTy; } 447*0b57cec5SDimitry Andric 448*0b57cec5SDimitry Andric bool parseFuncName(StringRef &Name) override; 449*0b57cec5SDimitry Andric 450*0b57cec5SDimitry Andric // Methods for support type inquiry through isa, cast, and dyn_cast: 451*0b57cec5SDimitry Andric static bool classof(const AMDGPULibFuncImpl *F) { return !F->isMangled(); } 452*0b57cec5SDimitry Andric 453*0b57cec5SDimitry Andric std::string mangle() const override { return Name; } 454*0b57cec5SDimitry Andric 455*0b57cec5SDimitry Andric void setFunctionType(FunctionType *FT) { FuncTy = FT; } 456*0b57cec5SDimitry Andric }; 457*0b57cec5SDimitry Andric } 458*0b57cec5SDimitry Andric #endif // _AMDGPU_LIBFUNC_H_ 459