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