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