17f37794eSStanislav Mekhanoshin //===-- AMDGPULibFunc.cpp -------------------------------------------------===// 27f37794eSStanislav Mekhanoshin // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 67f37794eSStanislav Mekhanoshin // 77f37794eSStanislav Mekhanoshin //===----------------------------------------------------------------------===// 87f37794eSStanislav Mekhanoshin // 97f37794eSStanislav Mekhanoshin // This file contains utility functions to work with Itanium mangled names 107f37794eSStanislav Mekhanoshin // 117f37794eSStanislav Mekhanoshin //===----------------------------------------------------------------------===// 127f37794eSStanislav Mekhanoshin 137f37794eSStanislav Mekhanoshin #include "AMDGPULibFunc.h" 14a6502560SSimon Pilgrim #include "AMDGPU.h" 158105935dSSander de Smalen #include "llvm/ADT/StringExtras.h" 166a87e9b0Sdfukalov #include "llvm/ADT/StringMap.h" 17a6502560SSimon Pilgrim #include "llvm/ADT/StringSwitch.h" 187f37794eSStanislav Mekhanoshin #include "llvm/IR/DerivedTypes.h" 197f37794eSStanislav Mekhanoshin #include "llvm/IR/Function.h" 207f37794eSStanislav Mekhanoshin #include "llvm/IR/Module.h" 217f37794eSStanislav Mekhanoshin #include "llvm/IR/ValueSymbolTable.h" 2227332968SMichael Liao #include "llvm/Support/CommandLine.h" 23a6502560SSimon Pilgrim #include "llvm/Support/raw_ostream.h" 247f37794eSStanislav Mekhanoshin 257f37794eSStanislav Mekhanoshin using namespace llvm; 267f37794eSStanislav Mekhanoshin 2727332968SMichael Liao static cl::opt<bool> EnableOCLManglingMismatchWA( 2827332968SMichael Liao "amdgpu-enable-ocl-mangling-mismatch-workaround", cl::init(true), 2927332968SMichael Liao cl::ReallyHidden, 3027332968SMichael Liao cl::desc("Enable the workaround for OCL name mangling mismatch.")); 3127332968SMichael Liao 327f37794eSStanislav Mekhanoshin namespace { 337f37794eSStanislav Mekhanoshin 347f37794eSStanislav Mekhanoshin enum EManglingParam { 357f37794eSStanislav Mekhanoshin E_NONE, 367f37794eSStanislav Mekhanoshin EX_EVENT, 377f37794eSStanislav Mekhanoshin EX_FLOAT4, 387f37794eSStanislav Mekhanoshin EX_INTV4, 397f37794eSStanislav Mekhanoshin EX_RESERVEDID, 407f37794eSStanislav Mekhanoshin EX_SAMPLER, 417f37794eSStanislav Mekhanoshin EX_SIZET, 427f37794eSStanislav Mekhanoshin EX_UINT, 437f37794eSStanislav Mekhanoshin EX_UINTV4, 447f37794eSStanislav Mekhanoshin E_ANY, 457f37794eSStanislav Mekhanoshin E_CONSTPTR_ANY, 467f37794eSStanislav Mekhanoshin E_CONSTPTR_SWAPGL, 477f37794eSStanislav Mekhanoshin E_COPY, 487f37794eSStanislav Mekhanoshin E_IMAGECOORDS, 497f37794eSStanislav Mekhanoshin E_POINTEE, 507f37794eSStanislav Mekhanoshin E_SETBASE_I32, 517f37794eSStanislav Mekhanoshin E_SETBASE_U32, 527f37794eSStanislav Mekhanoshin E_MAKEBASE_UNS, 537f37794eSStanislav Mekhanoshin E_V16_OF_POINTEE, 547f37794eSStanislav Mekhanoshin E_V2_OF_POINTEE, 557f37794eSStanislav Mekhanoshin E_V3_OF_POINTEE, 567f37794eSStanislav Mekhanoshin E_V4_OF_POINTEE, 577f37794eSStanislav Mekhanoshin E_V8_OF_POINTEE, 587f37794eSStanislav Mekhanoshin E_VLTLPTR_ANY, 597f37794eSStanislav Mekhanoshin }; 607f37794eSStanislav Mekhanoshin 617f37794eSStanislav Mekhanoshin struct ManglingRule { 6255e8c91dSBenjamin Kramer const char *Name; 637f37794eSStanislav Mekhanoshin unsigned char Lead[2]; 647f37794eSStanislav Mekhanoshin unsigned char Param[5]; 657f37794eSStanislav Mekhanoshin 667f37794eSStanislav Mekhanoshin int maxLeadIndex() const { return (std::max)(Lead[0], Lead[1]); } 677f37794eSStanislav Mekhanoshin int getNumLeads() const { return (Lead[0] ? 1 : 0) + (Lead[1] ? 1 : 0); } 687f37794eSStanislav Mekhanoshin 697f37794eSStanislav Mekhanoshin unsigned getNumArgs() const; 7085e2cdacSReid Kleckner 7185e2cdacSReid Kleckner static StringMap<int> buildManglingRulesMap(); 727f37794eSStanislav Mekhanoshin }; 737f37794eSStanislav Mekhanoshin 74fc5121a7SYaxun Liu // Information about library functions with unmangled names. 75fc5121a7SYaxun Liu class UnmangledFuncInfo { 7655e8c91dSBenjamin Kramer const char *Name; 77fc5121a7SYaxun Liu unsigned NumArgs; 78fc5121a7SYaxun Liu 79fc5121a7SYaxun Liu // Table for all lib functions with unmangled names. 80fc5121a7SYaxun Liu static const UnmangledFuncInfo Table[]; 81fc5121a7SYaxun Liu 82fc5121a7SYaxun Liu // Number of entries in Table. 83fc5121a7SYaxun Liu static const unsigned TableSize; 84fc5121a7SYaxun Liu 8585e2cdacSReid Kleckner static StringMap<unsigned> buildNameMap(); 86fc5121a7SYaxun Liu 87fc5121a7SYaxun Liu public: 88fc5121a7SYaxun Liu using ID = AMDGPULibFunc::EFuncId; 8955e8c91dSBenjamin Kramer constexpr UnmangledFuncInfo(const char *_Name, unsigned _NumArgs) 90fc5121a7SYaxun Liu : Name(_Name), NumArgs(_NumArgs) {} 91fc5121a7SYaxun Liu // Get index to Table by function name. 92fc5121a7SYaxun Liu static bool lookup(StringRef Name, ID &Id); 93fc5121a7SYaxun Liu static unsigned toIndex(ID Id) { 94fc5121a7SYaxun Liu assert(static_cast<unsigned>(Id) > 95fc5121a7SYaxun Liu static_cast<unsigned>(AMDGPULibFunc::EI_LAST_MANGLED) && 96fc5121a7SYaxun Liu "Invalid unmangled library function"); 97fc5121a7SYaxun Liu return static_cast<unsigned>(Id) - 1 - 98fc5121a7SYaxun Liu static_cast<unsigned>(AMDGPULibFunc::EI_LAST_MANGLED); 99fc5121a7SYaxun Liu } 100fc5121a7SYaxun Liu static ID toFuncId(unsigned Index) { 10185e2cdacSReid Kleckner assert(Index < TableSize && 10285e2cdacSReid Kleckner "Invalid unmangled library function"); 103fc5121a7SYaxun Liu return static_cast<ID>( 104fc5121a7SYaxun Liu Index + 1 + static_cast<unsigned>(AMDGPULibFunc::EI_LAST_MANGLED)); 105fc5121a7SYaxun Liu } 106fc5121a7SYaxun Liu static unsigned getNumArgs(ID Id) { return Table[toIndex(Id)].NumArgs; } 107fc5121a7SYaxun Liu static StringRef getName(ID Id) { return Table[toIndex(Id)].Name; } 108fc5121a7SYaxun Liu }; 109fc5121a7SYaxun Liu 1107f37794eSStanislav Mekhanoshin unsigned ManglingRule::getNumArgs() const { 1117f37794eSStanislav Mekhanoshin unsigned I=0; 1127f37794eSStanislav Mekhanoshin while (I < (sizeof Param/sizeof Param[0]) && Param[I]) ++I; 1137f37794eSStanislav Mekhanoshin return I; 1147f37794eSStanislav Mekhanoshin } 1157f37794eSStanislav Mekhanoshin 1167f37794eSStanislav Mekhanoshin // This table describes function formal argument type rules. The order of rules 1177f37794eSStanislav Mekhanoshin // corresponds to the EFuncId enum at AMDGPULibFunc.h 1187f37794eSStanislav Mekhanoshin // 1197f37794eSStanislav Mekhanoshin // "<func name>", { <leads> }, { <param rules> } 1207f37794eSStanislav Mekhanoshin // where: 1217f37794eSStanislav Mekhanoshin // <leads> - list of integers that are one-based indexes of formal argument 1227f37794eSStanislav Mekhanoshin // used to mangle a function name. Other argument types are derived from types 1237f37794eSStanislav Mekhanoshin // of these 'leads'. The order of integers in this list correspond to the 1247f37794eSStanislav Mekhanoshin // order in which these arguments are mangled in the EDG mangling scheme. The 1257f37794eSStanislav Mekhanoshin // same order should be preserved for arguments in the AMDGPULibFunc structure 1267f37794eSStanislav Mekhanoshin // when it is used for mangling. For example: 1277f37794eSStanislav Mekhanoshin // { "vstorea_half", {3,1}, {E_ANY,EX_SIZET,E_ANY}}, 1287f37794eSStanislav Mekhanoshin // will be mangled in EDG scheme as vstorea_half_<3dparam>_<1stparam> 1297f37794eSStanislav Mekhanoshin // When mangling from code use: 1307f37794eSStanislav Mekhanoshin // AMDGPULibFunc insc; 1317f37794eSStanislav Mekhanoshin // insc.param[0] = ... // describe 3rd parameter 1327f37794eSStanislav Mekhanoshin // insc.param[1] = ... // describe 1rd parameter 1337f37794eSStanislav Mekhanoshin // 1347f37794eSStanislav Mekhanoshin // <param rules> - list of rules used to derive all of the function formal 1357f37794eSStanislav Mekhanoshin // argument types. EX_ prefixed are simple types, other derived from the 1367f37794eSStanislav Mekhanoshin // latest 'lead' argument type in the order of encoding from first to last. 1377f37794eSStanislav Mekhanoshin // E_ANY - use prev lead type, E_CONSTPTR_ANY - make const pointer out of 1387f37794eSStanislav Mekhanoshin // prev lead type, etc. see ParamIterator::getNextParam() for details. 1397f37794eSStanislav Mekhanoshin 14070434770SBenjamin Kramer static constexpr ManglingRule manglingRules[] = { 14170434770SBenjamin Kramer { "", {0}, {0} }, 1427f37794eSStanislav Mekhanoshin { "abs" , {1}, {E_ANY}}, 1437f37794eSStanislav Mekhanoshin { "abs_diff" , {1}, {E_ANY,E_COPY}}, 1447f37794eSStanislav Mekhanoshin { "acos" , {1}, {E_ANY}}, 1457f37794eSStanislav Mekhanoshin { "acosh" , {1}, {E_ANY}}, 1467f37794eSStanislav Mekhanoshin { "acospi" , {1}, {E_ANY}}, 1477f37794eSStanislav Mekhanoshin { "add_sat" , {1}, {E_ANY,E_COPY}}, 1487f37794eSStanislav Mekhanoshin { "all" , {1}, {E_ANY}}, 1497f37794eSStanislav Mekhanoshin { "any" , {1}, {E_ANY}}, 1507f37794eSStanislav Mekhanoshin { "asin" , {1}, {E_ANY}}, 1517f37794eSStanislav Mekhanoshin { "asinh" , {1}, {E_ANY}}, 1527f37794eSStanislav Mekhanoshin { "asinpi" , {1}, {E_ANY}}, 1537f37794eSStanislav Mekhanoshin { "async_work_group_copy" , {1}, {E_ANY,E_CONSTPTR_SWAPGL,EX_SIZET,EX_EVENT}}, 1547f37794eSStanislav Mekhanoshin { "async_work_group_strided_copy" , {1}, {E_ANY,E_CONSTPTR_SWAPGL,EX_SIZET,EX_SIZET,EX_EVENT}}, 1557f37794eSStanislav Mekhanoshin { "atan" , {1}, {E_ANY}}, 1567f37794eSStanislav Mekhanoshin { "atan2" , {1}, {E_ANY,E_COPY}}, 1577f37794eSStanislav Mekhanoshin { "atan2pi" , {1}, {E_ANY,E_COPY}}, 1587f37794eSStanislav Mekhanoshin { "atanh" , {1}, {E_ANY}}, 1597f37794eSStanislav Mekhanoshin { "atanpi" , {1}, {E_ANY}}, 1607f37794eSStanislav Mekhanoshin { "atomic_add" , {1}, {E_VLTLPTR_ANY,E_POINTEE}}, 1617f37794eSStanislav Mekhanoshin { "atomic_and" , {1}, {E_VLTLPTR_ANY,E_POINTEE}}, 1627f37794eSStanislav Mekhanoshin { "atomic_cmpxchg" , {1}, {E_VLTLPTR_ANY,E_POINTEE,E_POINTEE}}, 1637f37794eSStanislav Mekhanoshin { "atomic_dec" , {1}, {E_VLTLPTR_ANY}}, 1647f37794eSStanislav Mekhanoshin { "atomic_inc" , {1}, {E_VLTLPTR_ANY}}, 1657f37794eSStanislav Mekhanoshin { "atomic_max" , {1}, {E_VLTLPTR_ANY,E_POINTEE}}, 1667f37794eSStanislav Mekhanoshin { "atomic_min" , {1}, {E_VLTLPTR_ANY,E_POINTEE}}, 1677f37794eSStanislav Mekhanoshin { "atomic_or" , {1}, {E_VLTLPTR_ANY,E_POINTEE}}, 1687f37794eSStanislav Mekhanoshin { "atomic_sub" , {1}, {E_VLTLPTR_ANY,E_POINTEE}}, 1697f37794eSStanislav Mekhanoshin { "atomic_xchg" , {1}, {E_VLTLPTR_ANY,E_POINTEE}}, 1707f37794eSStanislav Mekhanoshin { "atomic_xor" , {1}, {E_VLTLPTR_ANY,E_POINTEE}}, 1717f37794eSStanislav Mekhanoshin { "bitselect" , {1}, {E_ANY,E_COPY,E_COPY}}, 1727f37794eSStanislav Mekhanoshin { "cbrt" , {1}, {E_ANY}}, 1737f37794eSStanislav Mekhanoshin { "ceil" , {1}, {E_ANY}}, 1747f37794eSStanislav Mekhanoshin { "clamp" , {1}, {E_ANY,E_COPY,E_COPY}}, 1757f37794eSStanislav Mekhanoshin { "clz" , {1}, {E_ANY}}, 1767f37794eSStanislav Mekhanoshin { "commit_read_pipe" , {1}, {E_ANY,EX_RESERVEDID}}, 1777f37794eSStanislav Mekhanoshin { "commit_write_pipe" , {1}, {E_ANY,EX_RESERVEDID}}, 1787f37794eSStanislav Mekhanoshin { "copysign" , {1}, {E_ANY,E_COPY}}, 1797f37794eSStanislav Mekhanoshin { "cos" , {1}, {E_ANY}}, 1807f37794eSStanislav Mekhanoshin { "cosh" , {1}, {E_ANY}}, 1817f37794eSStanislav Mekhanoshin { "cospi" , {1}, {E_ANY}}, 1827f37794eSStanislav Mekhanoshin { "cross" , {1}, {E_ANY,E_COPY}}, 1837f37794eSStanislav Mekhanoshin { "ctz" , {1}, {E_ANY}}, 1847f37794eSStanislav Mekhanoshin { "degrees" , {1}, {E_ANY}}, 1857f37794eSStanislav Mekhanoshin { "distance" , {1}, {E_ANY,E_COPY}}, 1867f37794eSStanislav Mekhanoshin { "divide" , {1}, {E_ANY,E_COPY}}, 1877f37794eSStanislav Mekhanoshin { "dot" , {1}, {E_ANY,E_COPY}}, 1887f37794eSStanislav Mekhanoshin { "erf" , {1}, {E_ANY}}, 1897f37794eSStanislav Mekhanoshin { "erfc" , {1}, {E_ANY}}, 1907f37794eSStanislav Mekhanoshin { "exp" , {1}, {E_ANY}}, 1917f37794eSStanislav Mekhanoshin { "exp10" , {1}, {E_ANY}}, 1927f37794eSStanislav Mekhanoshin { "exp2" , {1}, {E_ANY}}, 1937f37794eSStanislav Mekhanoshin { "expm1" , {1}, {E_ANY}}, 1947f37794eSStanislav Mekhanoshin { "fabs" , {1}, {E_ANY}}, 1957f37794eSStanislav Mekhanoshin { "fast_distance" , {1}, {E_ANY,E_COPY}}, 1967f37794eSStanislav Mekhanoshin { "fast_length" , {1}, {E_ANY}}, 1977f37794eSStanislav Mekhanoshin { "fast_normalize" , {1}, {E_ANY}}, 1987f37794eSStanislav Mekhanoshin { "fdim" , {1}, {E_ANY,E_COPY}}, 1997f37794eSStanislav Mekhanoshin { "floor" , {1}, {E_ANY}}, 2007f37794eSStanislav Mekhanoshin { "fma" , {1}, {E_ANY,E_COPY,E_COPY}}, 2017f37794eSStanislav Mekhanoshin { "fmax" , {1}, {E_ANY,E_COPY}}, 2027f37794eSStanislav Mekhanoshin { "fmin" , {1}, {E_ANY,E_COPY}}, 2037f37794eSStanislav Mekhanoshin { "fmod" , {1}, {E_ANY,E_COPY}}, 2047f37794eSStanislav Mekhanoshin { "fract" , {2}, {E_POINTEE,E_ANY}}, 2057f37794eSStanislav Mekhanoshin { "frexp" , {1,2}, {E_ANY,E_ANY}}, 2067f37794eSStanislav Mekhanoshin { "get_image_array_size" , {1}, {E_ANY}}, 2077f37794eSStanislav Mekhanoshin { "get_image_channel_data_type" , {1}, {E_ANY}}, 2087f37794eSStanislav Mekhanoshin { "get_image_channel_order" , {1}, {E_ANY}}, 2097f37794eSStanislav Mekhanoshin { "get_image_dim" , {1}, {E_ANY}}, 2107f37794eSStanislav Mekhanoshin { "get_image_height" , {1}, {E_ANY}}, 2117f37794eSStanislav Mekhanoshin { "get_image_width" , {1}, {E_ANY}}, 2127f37794eSStanislav Mekhanoshin { "get_pipe_max_packets" , {1}, {E_ANY}}, 2137f37794eSStanislav Mekhanoshin { "get_pipe_num_packets" , {1}, {E_ANY}}, 2147f37794eSStanislav Mekhanoshin { "hadd" , {1}, {E_ANY,E_COPY}}, 2157f37794eSStanislav Mekhanoshin { "hypot" , {1}, {E_ANY,E_COPY}}, 2167f37794eSStanislav Mekhanoshin { "ilogb" , {1}, {E_ANY}}, 2177f37794eSStanislav Mekhanoshin { "isequal" , {1}, {E_ANY,E_COPY}}, 2187f37794eSStanislav Mekhanoshin { "isfinite" , {1}, {E_ANY}}, 2197f37794eSStanislav Mekhanoshin { "isgreater" , {1}, {E_ANY,E_COPY}}, 2207f37794eSStanislav Mekhanoshin { "isgreaterequal" , {1}, {E_ANY,E_COPY}}, 2217f37794eSStanislav Mekhanoshin { "isinf" , {1}, {E_ANY}}, 2227f37794eSStanislav Mekhanoshin { "isless" , {1}, {E_ANY,E_COPY}}, 2237f37794eSStanislav Mekhanoshin { "islessequal" , {1}, {E_ANY,E_COPY}}, 2247f37794eSStanislav Mekhanoshin { "islessgreater" , {1}, {E_ANY,E_COPY}}, 2257f37794eSStanislav Mekhanoshin { "isnan" , {1}, {E_ANY}}, 2267f37794eSStanislav Mekhanoshin { "isnormal" , {1}, {E_ANY}}, 2277f37794eSStanislav Mekhanoshin { "isnotequal" , {1}, {E_ANY,E_COPY}}, 2287f37794eSStanislav Mekhanoshin { "isordered" , {1}, {E_ANY,E_COPY}}, 2297f37794eSStanislav Mekhanoshin { "isunordered" , {1}, {E_ANY,E_COPY}}, 2307f37794eSStanislav Mekhanoshin { "ldexp" , {1}, {E_ANY,E_SETBASE_I32}}, 2317f37794eSStanislav Mekhanoshin { "length" , {1}, {E_ANY}}, 2327f37794eSStanislav Mekhanoshin { "lgamma" , {1}, {E_ANY}}, 2337f37794eSStanislav Mekhanoshin { "lgamma_r" , {1,2}, {E_ANY,E_ANY}}, 2347f37794eSStanislav Mekhanoshin { "log" , {1}, {E_ANY}}, 2357f37794eSStanislav Mekhanoshin { "log10" , {1}, {E_ANY}}, 2367f37794eSStanislav Mekhanoshin { "log1p" , {1}, {E_ANY}}, 2377f37794eSStanislav Mekhanoshin { "log2" , {1}, {E_ANY}}, 2387f37794eSStanislav Mekhanoshin { "logb" , {1}, {E_ANY}}, 2397f37794eSStanislav Mekhanoshin { "mad" , {1}, {E_ANY,E_COPY,E_COPY}}, 2407f37794eSStanislav Mekhanoshin { "mad24" , {1}, {E_ANY,E_COPY,E_COPY}}, 2417f37794eSStanislav Mekhanoshin { "mad_hi" , {1}, {E_ANY,E_COPY,E_COPY}}, 2427f37794eSStanislav Mekhanoshin { "mad_sat" , {1}, {E_ANY,E_COPY,E_COPY}}, 2437f37794eSStanislav Mekhanoshin { "max" , {1}, {E_ANY,E_COPY}}, 2447f37794eSStanislav Mekhanoshin { "maxmag" , {1}, {E_ANY,E_COPY}}, 2457f37794eSStanislav Mekhanoshin { "min" , {1}, {E_ANY,E_COPY}}, 2467f37794eSStanislav Mekhanoshin { "minmag" , {1}, {E_ANY,E_COPY}}, 2477f37794eSStanislav Mekhanoshin { "mix" , {1}, {E_ANY,E_COPY,E_COPY}}, 2487f37794eSStanislav Mekhanoshin { "modf" , {2}, {E_POINTEE,E_ANY}}, 2497f37794eSStanislav Mekhanoshin { "mul24" , {1}, {E_ANY,E_COPY}}, 2507f37794eSStanislav Mekhanoshin { "mul_hi" , {1}, {E_ANY,E_COPY}}, 2517f37794eSStanislav Mekhanoshin { "nan" , {1}, {E_ANY}}, 2527f37794eSStanislav Mekhanoshin { "nextafter" , {1}, {E_ANY,E_COPY}}, 2537f37794eSStanislav Mekhanoshin { "normalize" , {1}, {E_ANY}}, 2547f37794eSStanislav Mekhanoshin { "popcount" , {1}, {E_ANY}}, 2557f37794eSStanislav Mekhanoshin { "pow" , {1}, {E_ANY,E_COPY}}, 2567f37794eSStanislav Mekhanoshin { "pown" , {1}, {E_ANY,E_SETBASE_I32}}, 2577f37794eSStanislav Mekhanoshin { "powr" , {1}, {E_ANY,E_COPY}}, 2587f37794eSStanislav Mekhanoshin { "prefetch" , {1}, {E_CONSTPTR_ANY,EX_SIZET}}, 2597f37794eSStanislav Mekhanoshin { "radians" , {1}, {E_ANY}}, 2607f37794eSStanislav Mekhanoshin { "recip" , {1}, {E_ANY}}, 2617f37794eSStanislav Mekhanoshin { "remainder" , {1}, {E_ANY,E_COPY}}, 2627f37794eSStanislav Mekhanoshin { "remquo" , {1,3}, {E_ANY,E_COPY,E_ANY}}, 2637f37794eSStanislav Mekhanoshin { "reserve_read_pipe" , {1}, {E_ANY,EX_UINT}}, 2647f37794eSStanislav Mekhanoshin { "reserve_write_pipe" , {1}, {E_ANY,EX_UINT}}, 2657f37794eSStanislav Mekhanoshin { "rhadd" , {1}, {E_ANY,E_COPY}}, 2667f37794eSStanislav Mekhanoshin { "rint" , {1}, {E_ANY}}, 2677f37794eSStanislav Mekhanoshin { "rootn" , {1}, {E_ANY,E_SETBASE_I32}}, 2687f37794eSStanislav Mekhanoshin { "rotate" , {1}, {E_ANY,E_COPY}}, 2697f37794eSStanislav Mekhanoshin { "round" , {1}, {E_ANY}}, 2707f37794eSStanislav Mekhanoshin { "rsqrt" , {1}, {E_ANY}}, 2717f37794eSStanislav Mekhanoshin { "select" , {1,3}, {E_ANY,E_COPY,E_ANY}}, 2727f37794eSStanislav Mekhanoshin { "shuffle" , {1,2}, {E_ANY,E_ANY}}, 2737f37794eSStanislav Mekhanoshin { "shuffle2" , {1,3}, {E_ANY,E_COPY,E_ANY}}, 2747f37794eSStanislav Mekhanoshin { "sign" , {1}, {E_ANY}}, 2757f37794eSStanislav Mekhanoshin { "signbit" , {1}, {E_ANY}}, 2767f37794eSStanislav Mekhanoshin { "sin" , {1}, {E_ANY}}, 2777f37794eSStanislav Mekhanoshin { "sincos" , {2}, {E_POINTEE,E_ANY}}, 2787f37794eSStanislav Mekhanoshin { "sinh" , {1}, {E_ANY}}, 2797f37794eSStanislav Mekhanoshin { "sinpi" , {1}, {E_ANY}}, 2807f37794eSStanislav Mekhanoshin { "smoothstep" , {1}, {E_ANY,E_COPY,E_COPY}}, 2817f37794eSStanislav Mekhanoshin { "sqrt" , {1}, {E_ANY}}, 2827f37794eSStanislav Mekhanoshin { "step" , {1}, {E_ANY,E_COPY}}, 2837f37794eSStanislav Mekhanoshin { "sub_group_broadcast" , {1}, {E_ANY,EX_UINT}}, 2847f37794eSStanislav Mekhanoshin { "sub_group_commit_read_pipe" , {1}, {E_ANY,EX_RESERVEDID}}, 2857f37794eSStanislav Mekhanoshin { "sub_group_commit_write_pipe" , {1}, {E_ANY,EX_RESERVEDID}}, 2867f37794eSStanislav Mekhanoshin { "sub_group_reduce_add" , {1}, {E_ANY}}, 2877f37794eSStanislav Mekhanoshin { "sub_group_reduce_max" , {1}, {E_ANY}}, 2887f37794eSStanislav Mekhanoshin { "sub_group_reduce_min" , {1}, {E_ANY}}, 2897f37794eSStanislav Mekhanoshin { "sub_group_reserve_read_pipe" , {1}, {E_ANY,EX_UINT}}, 2907f37794eSStanislav Mekhanoshin { "sub_group_reserve_write_pipe" , {1}, {E_ANY,EX_UINT}}, 2917f37794eSStanislav Mekhanoshin { "sub_group_scan_exclusive_add" , {1}, {E_ANY}}, 2927f37794eSStanislav Mekhanoshin { "sub_group_scan_exclusive_max" , {1}, {E_ANY}}, 2937f37794eSStanislav Mekhanoshin { "sub_group_scan_exclusive_min" , {1}, {E_ANY}}, 2947f37794eSStanislav Mekhanoshin { "sub_group_scan_inclusive_add" , {1}, {E_ANY}}, 2957f37794eSStanislav Mekhanoshin { "sub_group_scan_inclusive_max" , {1}, {E_ANY}}, 2967f37794eSStanislav Mekhanoshin { "sub_group_scan_inclusive_min" , {1}, {E_ANY}}, 2977f37794eSStanislav Mekhanoshin { "sub_sat" , {1}, {E_ANY,E_COPY}}, 2987f37794eSStanislav Mekhanoshin { "tan" , {1}, {E_ANY}}, 2997f37794eSStanislav Mekhanoshin { "tanh" , {1}, {E_ANY}}, 3007f37794eSStanislav Mekhanoshin { "tanpi" , {1}, {E_ANY}}, 3017f37794eSStanislav Mekhanoshin { "tgamma" , {1}, {E_ANY}}, 3027f37794eSStanislav Mekhanoshin { "trunc" , {1}, {E_ANY}}, 3037f37794eSStanislav Mekhanoshin { "upsample" , {1}, {E_ANY,E_MAKEBASE_UNS}}, 3047f37794eSStanislav Mekhanoshin { "vec_step" , {1}, {E_ANY}}, 3057f37794eSStanislav Mekhanoshin { "vstore" , {3}, {E_POINTEE,EX_SIZET,E_ANY}}, 3067f37794eSStanislav Mekhanoshin { "vstore16" , {3}, {E_V16_OF_POINTEE,EX_SIZET,E_ANY}}, 3077f37794eSStanislav Mekhanoshin { "vstore2" , {3}, {E_V2_OF_POINTEE,EX_SIZET,E_ANY}}, 3087f37794eSStanislav Mekhanoshin { "vstore3" , {3}, {E_V3_OF_POINTEE,EX_SIZET,E_ANY}}, 3097f37794eSStanislav Mekhanoshin { "vstore4" , {3}, {E_V4_OF_POINTEE,EX_SIZET,E_ANY}}, 3107f37794eSStanislav Mekhanoshin { "vstore8" , {3}, {E_V8_OF_POINTEE,EX_SIZET,E_ANY}}, 3117f37794eSStanislav Mekhanoshin { "work_group_commit_read_pipe" , {1}, {E_ANY,EX_RESERVEDID}}, 3127f37794eSStanislav Mekhanoshin { "work_group_commit_write_pipe" , {1}, {E_ANY,EX_RESERVEDID}}, 3137f37794eSStanislav Mekhanoshin { "work_group_reduce_add" , {1}, {E_ANY}}, 3147f37794eSStanislav Mekhanoshin { "work_group_reduce_max" , {1}, {E_ANY}}, 3157f37794eSStanislav Mekhanoshin { "work_group_reduce_min" , {1}, {E_ANY}}, 3167f37794eSStanislav Mekhanoshin { "work_group_reserve_read_pipe" , {1}, {E_ANY,EX_UINT}}, 3177f37794eSStanislav Mekhanoshin { "work_group_reserve_write_pipe" , {1}, {E_ANY,EX_UINT}}, 3187f37794eSStanislav Mekhanoshin { "work_group_scan_exclusive_add" , {1}, {E_ANY}}, 3197f37794eSStanislav Mekhanoshin { "work_group_scan_exclusive_max" , {1}, {E_ANY}}, 3207f37794eSStanislav Mekhanoshin { "work_group_scan_exclusive_min" , {1}, {E_ANY}}, 3217f37794eSStanislav Mekhanoshin { "work_group_scan_inclusive_add" , {1}, {E_ANY}}, 3227f37794eSStanislav Mekhanoshin { "work_group_scan_inclusive_max" , {1}, {E_ANY}}, 3237f37794eSStanislav Mekhanoshin { "work_group_scan_inclusive_min" , {1}, {E_ANY}}, 3247f37794eSStanislav Mekhanoshin { "write_imagef" , {1}, {E_ANY,E_IMAGECOORDS,EX_FLOAT4}}, 3257f37794eSStanislav Mekhanoshin { "write_imagei" , {1}, {E_ANY,E_IMAGECOORDS,EX_INTV4}}, 3267f37794eSStanislav Mekhanoshin { "write_imageui" , {1}, {E_ANY,E_IMAGECOORDS,EX_UINTV4}}, 3277f37794eSStanislav Mekhanoshin { "ncos" , {1}, {E_ANY} }, 3287f37794eSStanislav Mekhanoshin { "nexp2" , {1}, {E_ANY} }, 3297f37794eSStanislav Mekhanoshin { "nfma" , {1}, {E_ANY, E_COPY, E_COPY} }, 3307f37794eSStanislav Mekhanoshin { "nlog2" , {1}, {E_ANY} }, 3317f37794eSStanislav Mekhanoshin { "nrcp" , {1}, {E_ANY} }, 3327f37794eSStanislav Mekhanoshin { "nrsqrt" , {1}, {E_ANY} }, 3337f37794eSStanislav Mekhanoshin { "nsin" , {1}, {E_ANY} }, 3347f37794eSStanislav Mekhanoshin { "nsqrt" , {1}, {E_ANY} }, 3357f37794eSStanislav Mekhanoshin { "ftz" , {1}, {E_ANY} }, 3367f37794eSStanislav Mekhanoshin { "fldexp" , {1}, {E_ANY, EX_UINT} }, 3377f37794eSStanislav Mekhanoshin { "class" , {1}, {E_ANY, EX_UINT} }, 3387f37794eSStanislav Mekhanoshin { "rcbrt" , {1}, {E_ANY} }, 3397f37794eSStanislav Mekhanoshin }; 3407f37794eSStanislav Mekhanoshin 341fc5121a7SYaxun Liu // Library functions with unmangled name. 342fc5121a7SYaxun Liu const UnmangledFuncInfo UnmangledFuncInfo::Table[] = { 343fc5121a7SYaxun Liu {"__read_pipe_2", 4}, 344fc5121a7SYaxun Liu {"__read_pipe_4", 6}, 345fc5121a7SYaxun Liu {"__write_pipe_2", 4}, 346fc5121a7SYaxun Liu {"__write_pipe_4", 6}, 347fc5121a7SYaxun Liu }; 348fc5121a7SYaxun Liu 349fc5121a7SYaxun Liu const unsigned UnmangledFuncInfo::TableSize = 35085e2cdacSReid Kleckner array_lengthof(UnmangledFuncInfo::Table); 3517f37794eSStanislav Mekhanoshin 3527f37794eSStanislav Mekhanoshin static AMDGPULibFunc::Param getRetType(AMDGPULibFunc::EFuncId id, 3537f37794eSStanislav Mekhanoshin const AMDGPULibFunc::Param (&Leads)[2]) { 3547f37794eSStanislav Mekhanoshin AMDGPULibFunc::Param Res = Leads[0]; 355*dc6e8dfdSJacob Lambert // TBD - This switch may require to be extended for other intrinsics 3567f37794eSStanislav Mekhanoshin switch (id) { 3577f37794eSStanislav Mekhanoshin case AMDGPULibFunc::EI_SINCOS: 3587f37794eSStanislav Mekhanoshin Res.PtrKind = AMDGPULibFunc::BYVALUE; 3597f37794eSStanislav Mekhanoshin break; 3607f37794eSStanislav Mekhanoshin default: 3617f37794eSStanislav Mekhanoshin break; 3627f37794eSStanislav Mekhanoshin } 3637f37794eSStanislav Mekhanoshin return Res; 3647f37794eSStanislav Mekhanoshin } 3657f37794eSStanislav Mekhanoshin 3667f37794eSStanislav Mekhanoshin class ParamIterator { 3677f37794eSStanislav Mekhanoshin const AMDGPULibFunc::Param (&Leads)[2]; 3687f37794eSStanislav Mekhanoshin const ManglingRule& Rule; 3697f37794eSStanislav Mekhanoshin int Index; 3707f37794eSStanislav Mekhanoshin public: 3717f37794eSStanislav Mekhanoshin ParamIterator(const AMDGPULibFunc::Param (&leads)[2], 3727f37794eSStanislav Mekhanoshin const ManglingRule& rule) 3737f37794eSStanislav Mekhanoshin : Leads(leads), Rule(rule), Index(0) {} 3747f37794eSStanislav Mekhanoshin 3757f37794eSStanislav Mekhanoshin AMDGPULibFunc::Param getNextParam(); 3767f37794eSStanislav Mekhanoshin }; 3777f37794eSStanislav Mekhanoshin 3787f37794eSStanislav Mekhanoshin AMDGPULibFunc::Param ParamIterator::getNextParam() { 3797f37794eSStanislav Mekhanoshin AMDGPULibFunc::Param P; 3807f37794eSStanislav Mekhanoshin if (Index >= int(sizeof Rule.Param/sizeof Rule.Param[0])) return P; 3817f37794eSStanislav Mekhanoshin 3827f37794eSStanislav Mekhanoshin const char R = Rule.Param[Index]; 3837f37794eSStanislav Mekhanoshin switch (R) { 3847f37794eSStanislav Mekhanoshin case E_NONE: break; 3857f37794eSStanislav Mekhanoshin case EX_UINT: 3867f37794eSStanislav Mekhanoshin P.ArgType = AMDGPULibFunc::U32; break; 3877f37794eSStanislav Mekhanoshin case EX_INTV4: 3887f37794eSStanislav Mekhanoshin P.ArgType = AMDGPULibFunc::I32; P.VectorSize = 4; break; 3897f37794eSStanislav Mekhanoshin case EX_UINTV4: 3907f37794eSStanislav Mekhanoshin P.ArgType = AMDGPULibFunc::U32; P.VectorSize = 4; break; 3917f37794eSStanislav Mekhanoshin case EX_FLOAT4: 3927f37794eSStanislav Mekhanoshin P.ArgType = AMDGPULibFunc::F32; P.VectorSize = 4; break; 3937f37794eSStanislav Mekhanoshin case EX_SIZET: 3947f37794eSStanislav Mekhanoshin P.ArgType = AMDGPULibFunc::U64; break; 3957f37794eSStanislav Mekhanoshin case EX_EVENT: 3967f37794eSStanislav Mekhanoshin P.ArgType = AMDGPULibFunc::EVENT; break; 3977f37794eSStanislav Mekhanoshin case EX_SAMPLER: 3987f37794eSStanislav Mekhanoshin P.ArgType = AMDGPULibFunc::SAMPLER; break; 3997f37794eSStanislav Mekhanoshin case EX_RESERVEDID: break; // TBD 4007f37794eSStanislav Mekhanoshin default: 4017f37794eSStanislav Mekhanoshin if (Index == (Rule.Lead[1] - 1)) P = Leads[1]; 4027f37794eSStanislav Mekhanoshin else P = Leads[0]; 4037f37794eSStanislav Mekhanoshin 4047f37794eSStanislav Mekhanoshin switch (R) { 4057f37794eSStanislav Mekhanoshin case E_ANY: 4067f37794eSStanislav Mekhanoshin case E_COPY: break; 4077f37794eSStanislav Mekhanoshin 4087f37794eSStanislav Mekhanoshin case E_POINTEE: 4097f37794eSStanislav Mekhanoshin P.PtrKind = AMDGPULibFunc::BYVALUE; break; 4107f37794eSStanislav Mekhanoshin case E_V2_OF_POINTEE: 4117f37794eSStanislav Mekhanoshin P.VectorSize = 2; P.PtrKind = AMDGPULibFunc::BYVALUE; break; 4127f37794eSStanislav Mekhanoshin case E_V3_OF_POINTEE: 4137f37794eSStanislav Mekhanoshin P.VectorSize = 3; P.PtrKind = AMDGPULibFunc::BYVALUE; break; 4147f37794eSStanislav Mekhanoshin case E_V4_OF_POINTEE: 4157f37794eSStanislav Mekhanoshin P.VectorSize = 4; P.PtrKind = AMDGPULibFunc::BYVALUE; break; 4167f37794eSStanislav Mekhanoshin case E_V8_OF_POINTEE: 4177f37794eSStanislav Mekhanoshin P.VectorSize = 8; P.PtrKind = AMDGPULibFunc::BYVALUE; break; 4187f37794eSStanislav Mekhanoshin case E_V16_OF_POINTEE: 4197f37794eSStanislav Mekhanoshin P.VectorSize = 16; P.PtrKind = AMDGPULibFunc::BYVALUE; break; 4207f37794eSStanislav Mekhanoshin case E_CONSTPTR_ANY: 4217f37794eSStanislav Mekhanoshin P.PtrKind |= AMDGPULibFunc::CONST; break; 4227f37794eSStanislav Mekhanoshin case E_VLTLPTR_ANY: 4237f37794eSStanislav Mekhanoshin P.PtrKind |= AMDGPULibFunc::VOLATILE; break; 4247f37794eSStanislav Mekhanoshin case E_SETBASE_I32: 4257f37794eSStanislav Mekhanoshin P.ArgType = AMDGPULibFunc::I32; break; 4267f37794eSStanislav Mekhanoshin case E_SETBASE_U32: 4277f37794eSStanislav Mekhanoshin P.ArgType = AMDGPULibFunc::U32; break; 4287f37794eSStanislav Mekhanoshin 4297f37794eSStanislav Mekhanoshin case E_MAKEBASE_UNS: 4307f37794eSStanislav Mekhanoshin P.ArgType &= ~AMDGPULibFunc::BASE_TYPE_MASK; 4317f37794eSStanislav Mekhanoshin P.ArgType |= AMDGPULibFunc::UINT; 4327f37794eSStanislav Mekhanoshin break; 4337f37794eSStanislav Mekhanoshin 4347f37794eSStanislav Mekhanoshin case E_IMAGECOORDS: 4357f37794eSStanislav Mekhanoshin switch (P.ArgType) { 4367f37794eSStanislav Mekhanoshin case AMDGPULibFunc::IMG1DA: P.VectorSize = 2; break; 4377f37794eSStanislav Mekhanoshin case AMDGPULibFunc::IMG1DB: P.VectorSize = 1; break; 4387f37794eSStanislav Mekhanoshin case AMDGPULibFunc::IMG2DA: P.VectorSize = 4; break; 4397f37794eSStanislav Mekhanoshin case AMDGPULibFunc::IMG1D: P.VectorSize = 1; break; 4407f37794eSStanislav Mekhanoshin case AMDGPULibFunc::IMG2D: P.VectorSize = 2; break; 4417f37794eSStanislav Mekhanoshin case AMDGPULibFunc::IMG3D: P.VectorSize = 4; break; 4427f37794eSStanislav Mekhanoshin } 4437f37794eSStanislav Mekhanoshin P.PtrKind = AMDGPULibFunc::BYVALUE; 4447f37794eSStanislav Mekhanoshin P.ArgType = AMDGPULibFunc::I32; 4457f37794eSStanislav Mekhanoshin break; 4467f37794eSStanislav Mekhanoshin 4470d9673cfSYaxun Liu case E_CONSTPTR_SWAPGL: { 4480d9673cfSYaxun Liu unsigned AS = AMDGPULibFunc::getAddrSpaceFromEPtrKind(P.PtrKind); 4490d9673cfSYaxun Liu switch (AS) { 4500d9673cfSYaxun Liu case AMDGPUAS::GLOBAL_ADDRESS: AS = AMDGPUAS::LOCAL_ADDRESS; break; 4510d9673cfSYaxun Liu case AMDGPUAS::LOCAL_ADDRESS: AS = AMDGPUAS::GLOBAL_ADDRESS; break; 4527f37794eSStanislav Mekhanoshin } 4530d9673cfSYaxun Liu P.PtrKind = AMDGPULibFunc::getEPtrKindFromAddrSpace(AS); 4547f37794eSStanislav Mekhanoshin P.PtrKind |= AMDGPULibFunc::CONST; 4557f37794eSStanislav Mekhanoshin break; 4560d9673cfSYaxun Liu } 4577f37794eSStanislav Mekhanoshin 4587f37794eSStanislav Mekhanoshin default: llvm_unreachable("Unhandeled param rule"); 4597f37794eSStanislav Mekhanoshin } 4607f37794eSStanislav Mekhanoshin } 4617f37794eSStanislav Mekhanoshin ++Index; 4627f37794eSStanislav Mekhanoshin return P; 4637f37794eSStanislav Mekhanoshin } 4647f37794eSStanislav Mekhanoshin 4657f37794eSStanislav Mekhanoshin inline static void drop_front(StringRef& str, size_t n = 1) { 4667f37794eSStanislav Mekhanoshin str = str.drop_front(n); 4677f37794eSStanislav Mekhanoshin } 4687f37794eSStanislav Mekhanoshin 4697f37794eSStanislav Mekhanoshin static bool eatTerm(StringRef& mangledName, const char c) { 4707f37794eSStanislav Mekhanoshin if (mangledName.front() == c) { 4717f37794eSStanislav Mekhanoshin drop_front(mangledName); 4727f37794eSStanislav Mekhanoshin return true; 4737f37794eSStanislav Mekhanoshin } 4747f37794eSStanislav Mekhanoshin return false; 4757f37794eSStanislav Mekhanoshin } 4767f37794eSStanislav Mekhanoshin 4777f37794eSStanislav Mekhanoshin template <size_t N> 4787f37794eSStanislav Mekhanoshin static bool eatTerm(StringRef& mangledName, const char (&str)[N]) { 4797f37794eSStanislav Mekhanoshin if (mangledName.startswith(StringRef(str, N-1))) { 4807f37794eSStanislav Mekhanoshin drop_front(mangledName, N-1); 4817f37794eSStanislav Mekhanoshin return true; 4827f37794eSStanislav Mekhanoshin } 4837f37794eSStanislav Mekhanoshin return false; 4847f37794eSStanislav Mekhanoshin } 4857f37794eSStanislav Mekhanoshin 4867f37794eSStanislav Mekhanoshin static int eatNumber(StringRef& s) { 4877f37794eSStanislav Mekhanoshin size_t const savedSize = s.size(); 4887f37794eSStanislav Mekhanoshin int n = 0; 4897f37794eSStanislav Mekhanoshin while (!s.empty() && isDigit(s.front())) { 4907f37794eSStanislav Mekhanoshin n = n*10 + s.front() - '0'; 4917f37794eSStanislav Mekhanoshin drop_front(s); 4927f37794eSStanislav Mekhanoshin } 4937f37794eSStanislav Mekhanoshin return s.size() < savedSize ? n : -1; 4947f37794eSStanislav Mekhanoshin } 4957f37794eSStanislav Mekhanoshin 4967f37794eSStanislav Mekhanoshin static StringRef eatLengthPrefixedName(StringRef& mangledName) { 4977f37794eSStanislav Mekhanoshin int const Len = eatNumber(mangledName); 4987f37794eSStanislav Mekhanoshin if (Len <= 0 || static_cast<size_t>(Len) > mangledName.size()) 4997f37794eSStanislav Mekhanoshin return StringRef(); 5007f37794eSStanislav Mekhanoshin StringRef Res = mangledName.substr(0, Len); 5017f37794eSStanislav Mekhanoshin drop_front(mangledName, Len); 5027f37794eSStanislav Mekhanoshin return Res; 5037f37794eSStanislav Mekhanoshin } 5047f37794eSStanislav Mekhanoshin 5057f37794eSStanislav Mekhanoshin } // end anonymous namespace 5067f37794eSStanislav Mekhanoshin 507fc5121a7SYaxun Liu AMDGPUMangledLibFunc::AMDGPUMangledLibFunc() { 5087f37794eSStanislav Mekhanoshin FuncId = EI_NONE; 5097f37794eSStanislav Mekhanoshin FKind = NOPFX; 5107f37794eSStanislav Mekhanoshin Leads[0].reset(); 5117f37794eSStanislav Mekhanoshin Leads[1].reset(); 5127f37794eSStanislav Mekhanoshin Name.clear(); 5137f37794eSStanislav Mekhanoshin } 5147f37794eSStanislav Mekhanoshin 515fc5121a7SYaxun Liu AMDGPUUnmangledLibFunc::AMDGPUUnmangledLibFunc() { 516fc5121a7SYaxun Liu FuncId = EI_NONE; 517fc5121a7SYaxun Liu FuncTy = nullptr; 518fc5121a7SYaxun Liu } 519fc5121a7SYaxun Liu 520fc5121a7SYaxun Liu AMDGPUMangledLibFunc::AMDGPUMangledLibFunc( 521fc5121a7SYaxun Liu EFuncId id, const AMDGPUMangledLibFunc ©From) { 522fc5121a7SYaxun Liu FuncId = id; 523fc5121a7SYaxun Liu FKind = copyFrom.FKind; 524fc5121a7SYaxun Liu Leads[0] = copyFrom.Leads[0]; 525fc5121a7SYaxun Liu Leads[1] = copyFrom.Leads[1]; 526fc5121a7SYaxun Liu } 527fc5121a7SYaxun Liu 5287f37794eSStanislav Mekhanoshin /////////////////////////////////////////////////////////////////////////////// 5297f37794eSStanislav Mekhanoshin // Demangling 5307f37794eSStanislav Mekhanoshin 5317f37794eSStanislav Mekhanoshin static int parseVecSize(StringRef& mangledName) { 5327f37794eSStanislav Mekhanoshin size_t const Len = eatNumber(mangledName); 5337f37794eSStanislav Mekhanoshin switch (Len) { 5347f37794eSStanislav Mekhanoshin case 2: case 3: case 4: case 8: case 16: 5357f37794eSStanislav Mekhanoshin return Len; 5367f37794eSStanislav Mekhanoshin default: 5377f37794eSStanislav Mekhanoshin break; 5387f37794eSStanislav Mekhanoshin } 5397f37794eSStanislav Mekhanoshin return 1; 5407f37794eSStanislav Mekhanoshin } 5417f37794eSStanislav Mekhanoshin 5427f37794eSStanislav Mekhanoshin static AMDGPULibFunc::ENamePrefix parseNamePrefix(StringRef& mangledName) { 5437f37794eSStanislav Mekhanoshin std::pair<StringRef, StringRef> const P = mangledName.split('_'); 5447f37794eSStanislav Mekhanoshin AMDGPULibFunc::ENamePrefix Pfx = 5457f37794eSStanislav Mekhanoshin StringSwitch<AMDGPULibFunc::ENamePrefix>(P.first) 5467f37794eSStanislav Mekhanoshin .Case("native", AMDGPULibFunc::NATIVE) 5477f37794eSStanislav Mekhanoshin .Case("half" , AMDGPULibFunc::HALF) 5487f37794eSStanislav Mekhanoshin .Default(AMDGPULibFunc::NOPFX); 5497f37794eSStanislav Mekhanoshin 5507f37794eSStanislav Mekhanoshin if (Pfx != AMDGPULibFunc::NOPFX) 5517f37794eSStanislav Mekhanoshin mangledName = P.second; 5527f37794eSStanislav Mekhanoshin 5537f37794eSStanislav Mekhanoshin return Pfx; 5547f37794eSStanislav Mekhanoshin } 5557f37794eSStanislav Mekhanoshin 55685e2cdacSReid Kleckner StringMap<int> ManglingRule::buildManglingRulesMap() { 55785e2cdacSReid Kleckner StringMap<int> Map(array_lengthof(manglingRules)); 55885e2cdacSReid Kleckner int Id = 0; 55985e2cdacSReid Kleckner for (auto Rule : manglingRules) 56085e2cdacSReid Kleckner Map.insert({Rule.Name, Id++}); 56185e2cdacSReid Kleckner return Map; 56285e2cdacSReid Kleckner } 56385e2cdacSReid Kleckner 564fc5121a7SYaxun Liu bool AMDGPUMangledLibFunc::parseUnmangledName(StringRef FullName) { 56585e2cdacSReid Kleckner static const StringMap<int> manglingRulesMap = 56685e2cdacSReid Kleckner ManglingRule::buildManglingRulesMap(); 567fc5121a7SYaxun Liu FuncId = static_cast<EFuncId>(manglingRulesMap.lookup(FullName)); 5687f37794eSStanislav Mekhanoshin return FuncId != EI_NONE; 5697f37794eSStanislav Mekhanoshin } 5707f37794eSStanislav Mekhanoshin 5717f37794eSStanislav Mekhanoshin /////////////////////////////////////////////////////////////////////////////// 5727f37794eSStanislav Mekhanoshin // Itanium Demangling 5737f37794eSStanislav Mekhanoshin 57449a49fe8SBenjamin Kramer namespace { 5757f37794eSStanislav Mekhanoshin struct ItaniumParamParser { 5767f37794eSStanislav Mekhanoshin AMDGPULibFunc::Param Prev; 5777f37794eSStanislav Mekhanoshin bool parseItaniumParam(StringRef& param, AMDGPULibFunc::Param &res); 5787f37794eSStanislav Mekhanoshin }; 57949a49fe8SBenjamin Kramer } // namespace 5807f37794eSStanislav Mekhanoshin 5817f37794eSStanislav Mekhanoshin bool ItaniumParamParser::parseItaniumParam(StringRef& param, 5827f37794eSStanislav Mekhanoshin AMDGPULibFunc::Param &res) { 5837f37794eSStanislav Mekhanoshin res.reset(); 5847f37794eSStanislav Mekhanoshin if (param.empty()) return false; 5857f37794eSStanislav Mekhanoshin 5867f37794eSStanislav Mekhanoshin // parse pointer prefix 5877f37794eSStanislav Mekhanoshin if (eatTerm(param, 'P')) { 5887f37794eSStanislav Mekhanoshin if (eatTerm(param, 'K')) res.PtrKind |= AMDGPULibFunc::CONST; 5897f37794eSStanislav Mekhanoshin if (eatTerm(param, 'V')) res.PtrKind |= AMDGPULibFunc::VOLATILE; 5900d9673cfSYaxun Liu unsigned AS; 5917f37794eSStanislav Mekhanoshin if (!eatTerm(param, "U3AS")) { 5920d9673cfSYaxun Liu AS = 0; 5937f37794eSStanislav Mekhanoshin } else { 5940d9673cfSYaxun Liu AS = param.front() - '0'; 5957f37794eSStanislav Mekhanoshin drop_front(param, 1); 5967f37794eSStanislav Mekhanoshin } 5970d9673cfSYaxun Liu res.PtrKind |= AMDGPULibFuncBase::getEPtrKindFromAddrSpace(AS); 5987f37794eSStanislav Mekhanoshin } else { 5997f37794eSStanislav Mekhanoshin res.PtrKind = AMDGPULibFunc::BYVALUE; 6007f37794eSStanislav Mekhanoshin } 6017f37794eSStanislav Mekhanoshin 6027f37794eSStanislav Mekhanoshin // parse vector size 6037f37794eSStanislav Mekhanoshin if (eatTerm(param,"Dv")) { 6047f37794eSStanislav Mekhanoshin res.VectorSize = parseVecSize(param); 6057f37794eSStanislav Mekhanoshin if (res.VectorSize==1 || !eatTerm(param, '_')) return false; 6067f37794eSStanislav Mekhanoshin } 6077f37794eSStanislav Mekhanoshin 6087f37794eSStanislav Mekhanoshin // parse type 6097f37794eSStanislav Mekhanoshin char const TC = param.front(); 6108105935dSSander de Smalen if (isDigit(TC)) { 6117f37794eSStanislav Mekhanoshin res.ArgType = StringSwitch<AMDGPULibFunc::EType> 6127f37794eSStanislav Mekhanoshin (eatLengthPrefixedName(param)) 6137f37794eSStanislav Mekhanoshin .Case("ocl_image1darray" , AMDGPULibFunc::IMG1DA) 6147f37794eSStanislav Mekhanoshin .Case("ocl_image1dbuffer", AMDGPULibFunc::IMG1DB) 6157f37794eSStanislav Mekhanoshin .Case("ocl_image2darray" , AMDGPULibFunc::IMG2DA) 6167f37794eSStanislav Mekhanoshin .Case("ocl_image1d" , AMDGPULibFunc::IMG1D) 6177f37794eSStanislav Mekhanoshin .Case("ocl_image2d" , AMDGPULibFunc::IMG2D) 6187f37794eSStanislav Mekhanoshin .Case("ocl_image3d" , AMDGPULibFunc::IMG3D) 6197f37794eSStanislav Mekhanoshin .Case("ocl_event" , AMDGPULibFunc::DUMMY) 6207f37794eSStanislav Mekhanoshin .Case("ocl_sampler" , AMDGPULibFunc::DUMMY) 6217f37794eSStanislav Mekhanoshin .Default(AMDGPULibFunc::DUMMY); 6227f37794eSStanislav Mekhanoshin } else { 6237f37794eSStanislav Mekhanoshin drop_front(param); 6247f37794eSStanislav Mekhanoshin switch (TC) { 6257f37794eSStanislav Mekhanoshin case 'h': res.ArgType = AMDGPULibFunc::U8; break; 6267f37794eSStanislav Mekhanoshin case 't': res.ArgType = AMDGPULibFunc::U16; break; 6277f37794eSStanislav Mekhanoshin case 'j': res.ArgType = AMDGPULibFunc::U32; break; 6287f37794eSStanislav Mekhanoshin case 'm': res.ArgType = AMDGPULibFunc::U64; break; 6297f37794eSStanislav Mekhanoshin case 'c': res.ArgType = AMDGPULibFunc::I8; break; 6307f37794eSStanislav Mekhanoshin case 's': res.ArgType = AMDGPULibFunc::I16; break; 6317f37794eSStanislav Mekhanoshin case 'i': res.ArgType = AMDGPULibFunc::I32; break; 6327f37794eSStanislav Mekhanoshin case 'l': res.ArgType = AMDGPULibFunc::I64; break; 6337f37794eSStanislav Mekhanoshin case 'f': res.ArgType = AMDGPULibFunc::F32; break; 6347f37794eSStanislav Mekhanoshin case 'd': res.ArgType = AMDGPULibFunc::F64; break; 6357f37794eSStanislav Mekhanoshin case 'D': if (!eatTerm(param, 'h')) return false; 6367f37794eSStanislav Mekhanoshin res.ArgType = AMDGPULibFunc::F16; break; 6377f37794eSStanislav Mekhanoshin case 'S': 6387f37794eSStanislav Mekhanoshin if (!eatTerm(param, '_')) { 6397f37794eSStanislav Mekhanoshin eatNumber(param); 6407f37794eSStanislav Mekhanoshin if (!eatTerm(param, '_')) return false; 6417f37794eSStanislav Mekhanoshin } 6427f37794eSStanislav Mekhanoshin res.VectorSize = Prev.VectorSize; 6437f37794eSStanislav Mekhanoshin res.ArgType = Prev.ArgType; 6447f37794eSStanislav Mekhanoshin break; 6457f37794eSStanislav Mekhanoshin default:; 6467f37794eSStanislav Mekhanoshin } 6477f37794eSStanislav Mekhanoshin } 6487f37794eSStanislav Mekhanoshin if (res.ArgType == 0) return false; 6497f37794eSStanislav Mekhanoshin Prev.VectorSize = res.VectorSize; 6507f37794eSStanislav Mekhanoshin Prev.ArgType = res.ArgType; 6517f37794eSStanislav Mekhanoshin return true; 6527f37794eSStanislav Mekhanoshin } 6537f37794eSStanislav Mekhanoshin 654fc5121a7SYaxun Liu bool AMDGPUMangledLibFunc::parseFuncName(StringRef &mangledName) { 6557f37794eSStanislav Mekhanoshin StringRef Name = eatLengthPrefixedName(mangledName); 6567f37794eSStanislav Mekhanoshin FKind = parseNamePrefix(Name); 657fc5121a7SYaxun Liu if (!parseUnmangledName(Name)) 658fc5121a7SYaxun Liu return false; 6597f37794eSStanislav Mekhanoshin 6607f37794eSStanislav Mekhanoshin const ManglingRule& Rule = manglingRules[FuncId]; 6617f37794eSStanislav Mekhanoshin ItaniumParamParser Parser; 6627f37794eSStanislav Mekhanoshin for (int I=0; I < Rule.maxLeadIndex(); ++I) { 6637f37794eSStanislav Mekhanoshin Param P; 6647f37794eSStanislav Mekhanoshin if (!Parser.parseItaniumParam(mangledName, P)) 6657f37794eSStanislav Mekhanoshin return false; 6667f37794eSStanislav Mekhanoshin 6677f37794eSStanislav Mekhanoshin if ((I + 1) == Rule.Lead[0]) Leads[0] = P; 6687f37794eSStanislav Mekhanoshin if ((I + 1) == Rule.Lead[1]) Leads[1] = P; 6697f37794eSStanislav Mekhanoshin } 6707f37794eSStanislav Mekhanoshin return true; 6717f37794eSStanislav Mekhanoshin } 6727f37794eSStanislav Mekhanoshin 673fc5121a7SYaxun Liu bool AMDGPUUnmangledLibFunc::parseFuncName(StringRef &Name) { 674fc5121a7SYaxun Liu if (!UnmangledFuncInfo::lookup(Name, FuncId)) 6757f37794eSStanislav Mekhanoshin return false; 676fc5121a7SYaxun Liu setName(Name); 677fc5121a7SYaxun Liu return true; 6787f37794eSStanislav Mekhanoshin } 679fc5121a7SYaxun Liu 680fc5121a7SYaxun Liu bool AMDGPULibFunc::parse(StringRef FuncName, AMDGPULibFunc &F) { 681fc5121a7SYaxun Liu if (FuncName.empty()) { 682fc5121a7SYaxun Liu F.Impl = std::unique_ptr<AMDGPULibFuncImpl>(); 6837f37794eSStanislav Mekhanoshin return false; 6847f37794eSStanislav Mekhanoshin } 6857f37794eSStanislav Mekhanoshin 686fc5121a7SYaxun Liu if (eatTerm(FuncName, "_Z")) 6870eaee545SJonas Devlieghere F.Impl = std::make_unique<AMDGPUMangledLibFunc>(); 688fc5121a7SYaxun Liu else 6890eaee545SJonas Devlieghere F.Impl = std::make_unique<AMDGPUUnmangledLibFunc>(); 690fc5121a7SYaxun Liu if (F.Impl->parseFuncName(FuncName)) 691fc5121a7SYaxun Liu return true; 692fc5121a7SYaxun Liu 693fc5121a7SYaxun Liu F.Impl = std::unique_ptr<AMDGPULibFuncImpl>(); 694fc5121a7SYaxun Liu return false; 695fc5121a7SYaxun Liu } 696fc5121a7SYaxun Liu 697fc5121a7SYaxun Liu StringRef AMDGPUMangledLibFunc::getUnmangledName(StringRef mangledName) { 6987f37794eSStanislav Mekhanoshin StringRef S = mangledName; 6997f37794eSStanislav Mekhanoshin if (eatTerm(S, "_Z")) 7007f37794eSStanislav Mekhanoshin return eatLengthPrefixedName(S); 7017f37794eSStanislav Mekhanoshin return StringRef(); 7027f37794eSStanislav Mekhanoshin } 7037f37794eSStanislav Mekhanoshin 7047f37794eSStanislav Mekhanoshin /////////////////////////////////////////////////////////////////////////////// 7057f37794eSStanislav Mekhanoshin // Mangling 7067f37794eSStanislav Mekhanoshin 7077f37794eSStanislav Mekhanoshin template <typename Stream> 708fc5121a7SYaxun Liu void AMDGPUMangledLibFunc::writeName(Stream &OS) const { 7097f37794eSStanislav Mekhanoshin const char *Pfx = ""; 7107f37794eSStanislav Mekhanoshin switch (FKind) { 7117f37794eSStanislav Mekhanoshin case NATIVE: Pfx = "native_"; break; 7127f37794eSStanislav Mekhanoshin case HALF: Pfx = "half_"; break; 7137f37794eSStanislav Mekhanoshin default: break; 7147f37794eSStanislav Mekhanoshin } 7157f37794eSStanislav Mekhanoshin if (!Name.empty()) { 7167f37794eSStanislav Mekhanoshin OS << Pfx << Name; 7177f37794eSStanislav Mekhanoshin } else if (FuncId != EI_NONE) { 7187f37794eSStanislav Mekhanoshin OS << Pfx; 7197f37794eSStanislav Mekhanoshin const StringRef& S = manglingRules[FuncId].Name; 7207f37794eSStanislav Mekhanoshin OS.write(S.data(), S.size()); 7217f37794eSStanislav Mekhanoshin } 7227f37794eSStanislav Mekhanoshin } 7237f37794eSStanislav Mekhanoshin 724fc5121a7SYaxun Liu std::string AMDGPUMangledLibFunc::mangle() const { return mangleNameItanium(); } 7257f37794eSStanislav Mekhanoshin 7267f37794eSStanislav Mekhanoshin /////////////////////////////////////////////////////////////////////////////// 7277f37794eSStanislav Mekhanoshin // Itanium Mangling 7287f37794eSStanislav Mekhanoshin 7297f37794eSStanislav Mekhanoshin static const char *getItaniumTypeName(AMDGPULibFunc::EType T) { 7307f37794eSStanislav Mekhanoshin switch (T) { 7317f37794eSStanislav Mekhanoshin case AMDGPULibFunc::U8: return "h"; 7327f37794eSStanislav Mekhanoshin case AMDGPULibFunc::U16: return "t"; 7337f37794eSStanislav Mekhanoshin case AMDGPULibFunc::U32: return "j"; 7347f37794eSStanislav Mekhanoshin case AMDGPULibFunc::U64: return "m"; 7357f37794eSStanislav Mekhanoshin case AMDGPULibFunc::I8: return "c"; 7367f37794eSStanislav Mekhanoshin case AMDGPULibFunc::I16: return "s"; 7377f37794eSStanislav Mekhanoshin case AMDGPULibFunc::I32: return "i"; 7387f37794eSStanislav Mekhanoshin case AMDGPULibFunc::I64: return "l"; 7397f37794eSStanislav Mekhanoshin case AMDGPULibFunc::F16: return "Dh"; 7407f37794eSStanislav Mekhanoshin case AMDGPULibFunc::F32: return "f"; 7417f37794eSStanislav Mekhanoshin case AMDGPULibFunc::F64: return "d"; 7427f37794eSStanislav Mekhanoshin case AMDGPULibFunc::IMG1DA: return "16ocl_image1darray"; 7437f37794eSStanislav Mekhanoshin case AMDGPULibFunc::IMG1DB: return "17ocl_image1dbuffer"; 7447f37794eSStanislav Mekhanoshin case AMDGPULibFunc::IMG2DA: return "16ocl_image2darray"; 7457f37794eSStanislav Mekhanoshin case AMDGPULibFunc::IMG1D: return "11ocl_image1d"; 7467f37794eSStanislav Mekhanoshin case AMDGPULibFunc::IMG2D: return "11ocl_image2d"; 7477f37794eSStanislav Mekhanoshin case AMDGPULibFunc::IMG3D: return "11ocl_image3d"; 7487f37794eSStanislav Mekhanoshin case AMDGPULibFunc::SAMPLER: return "11ocl_sampler"; 7497f37794eSStanislav Mekhanoshin case AMDGPULibFunc::EVENT: return "9ocl_event"; 7507f37794eSStanislav Mekhanoshin default: llvm_unreachable("Unhandeled param type"); 7517f37794eSStanislav Mekhanoshin } 7527f37794eSStanislav Mekhanoshin return nullptr; 7537f37794eSStanislav Mekhanoshin } 7547f37794eSStanislav Mekhanoshin 75549a49fe8SBenjamin Kramer namespace { 7567f37794eSStanislav Mekhanoshin // Itanium mangling ABI says: 7577f37794eSStanislav Mekhanoshin // "5.1.8. Compression 7587f37794eSStanislav Mekhanoshin // ... Each non-terminal in the grammar for which <substitution> appears on the 7597f37794eSStanislav Mekhanoshin // right-hand side is both a source of future substitutions and a candidate 7607f37794eSStanislav Mekhanoshin // for being substituted. There are two exceptions that appear to be 7617f37794eSStanislav Mekhanoshin // substitution candidates from the grammar, but are explicitly excluded: 7627f37794eSStanislav Mekhanoshin // 1. <builtin-type> other than vendor extended types ..." 7637f37794eSStanislav Mekhanoshin 7647f37794eSStanislav Mekhanoshin // For the purpose of functions the following productions make sence for the 7657f37794eSStanislav Mekhanoshin // substitution: 7667f37794eSStanislav Mekhanoshin // <type> ::= <builtin-type> 7677f37794eSStanislav Mekhanoshin // ::= <class-enum-type> 7687f37794eSStanislav Mekhanoshin // ::= <array-type> 7697f37794eSStanislav Mekhanoshin // ::=<CV-qualifiers> <type> 7707f37794eSStanislav Mekhanoshin // ::= P <type> # pointer-to 7717f37794eSStanislav Mekhanoshin // ::= <substitution> 7727f37794eSStanislav Mekhanoshin // 7737f37794eSStanislav Mekhanoshin // Note that while types like images, samplers and events are by the ABI encoded 7747f37794eSStanislav Mekhanoshin // using <class-enum-type> production rule they're not used for substitution 7757f37794eSStanislav Mekhanoshin // because clang consider them as builtin types. 7767f37794eSStanislav Mekhanoshin // 7777f37794eSStanislav Mekhanoshin // DvNN_ type is GCC extension for vectors and is a subject for the substitution. 7787f37794eSStanislav Mekhanoshin 7797f37794eSStanislav Mekhanoshin 7807f37794eSStanislav Mekhanoshin class ItaniumMangler { 781*dc6e8dfdSJacob Lambert SmallVector<AMDGPULibFunc::Param, 10> Str; // list of accumulated substitutions 7827f37794eSStanislav Mekhanoshin bool UseAddrSpace; 7837f37794eSStanislav Mekhanoshin 7847f37794eSStanislav Mekhanoshin int findSubst(const AMDGPULibFunc::Param& P) const { 7857f37794eSStanislav Mekhanoshin for(unsigned I = 0; I < Str.size(); ++I) { 7867f37794eSStanislav Mekhanoshin const AMDGPULibFunc::Param& T = Str[I]; 7877f37794eSStanislav Mekhanoshin if (P.PtrKind == T.PtrKind && 7887f37794eSStanislav Mekhanoshin P.VectorSize == T.VectorSize && 7897f37794eSStanislav Mekhanoshin P.ArgType == T.ArgType) { 7907f37794eSStanislav Mekhanoshin return I; 7917f37794eSStanislav Mekhanoshin } 7927f37794eSStanislav Mekhanoshin } 7937f37794eSStanislav Mekhanoshin return -1; 7947f37794eSStanislav Mekhanoshin } 7957f37794eSStanislav Mekhanoshin 7967f37794eSStanislav Mekhanoshin template <typename Stream> 7977f37794eSStanislav Mekhanoshin bool trySubst(Stream& os, const AMDGPULibFunc::Param& p) { 7987f37794eSStanislav Mekhanoshin int const subst = findSubst(p); 7997f37794eSStanislav Mekhanoshin if (subst < 0) return false; 8007f37794eSStanislav Mekhanoshin // Substitutions are mangled as S(XX)?_ where XX is a hexadecimal number 8017f37794eSStanislav Mekhanoshin // 0 1 2 8027f37794eSStanislav Mekhanoshin // S_ S0_ S1_ 8037f37794eSStanislav Mekhanoshin if (subst == 0) os << "S_"; 8047f37794eSStanislav Mekhanoshin else os << 'S' << (subst-1) << '_'; 8057f37794eSStanislav Mekhanoshin return true; 8067f37794eSStanislav Mekhanoshin } 8077f37794eSStanislav Mekhanoshin 8087f37794eSStanislav Mekhanoshin public: 8097f37794eSStanislav Mekhanoshin ItaniumMangler(bool useAddrSpace) 8107f37794eSStanislav Mekhanoshin : UseAddrSpace(useAddrSpace) {} 8117f37794eSStanislav Mekhanoshin 8127f37794eSStanislav Mekhanoshin template <typename Stream> 8137f37794eSStanislav Mekhanoshin void operator()(Stream& os, AMDGPULibFunc::Param p) { 8147f37794eSStanislav Mekhanoshin 8157f37794eSStanislav Mekhanoshin // Itanium mangling ABI 5.1.8. Compression: 8167f37794eSStanislav Mekhanoshin // Logically, the substitutable components of a mangled name are considered 8177f37794eSStanislav Mekhanoshin // left-to-right, components before the composite structure of which they 8187f37794eSStanislav Mekhanoshin // are a part. If a component has been encountered before, it is substituted 8197f37794eSStanislav Mekhanoshin // as described below. This decision is independent of whether its components 8207f37794eSStanislav Mekhanoshin // have been substituted, so an implementation may optimize by considering 8217f37794eSStanislav Mekhanoshin // large structures for substitution before their components. If a component 8227f37794eSStanislav Mekhanoshin // has not been encountered before, its mangling is identified, and it is 8237f37794eSStanislav Mekhanoshin // added to a dictionary of substitution candidates. No entity is added to 8247f37794eSStanislav Mekhanoshin // the dictionary twice. 8257f37794eSStanislav Mekhanoshin AMDGPULibFunc::Param Ptr; 8267f37794eSStanislav Mekhanoshin 8277f37794eSStanislav Mekhanoshin if (p.PtrKind) { 8287f37794eSStanislav Mekhanoshin if (trySubst(os, p)) return; 8297f37794eSStanislav Mekhanoshin os << 'P'; 8307f37794eSStanislav Mekhanoshin if (p.PtrKind & AMDGPULibFunc::CONST) os << 'K'; 8317f37794eSStanislav Mekhanoshin if (p.PtrKind & AMDGPULibFunc::VOLATILE) os << 'V'; 8320d9673cfSYaxun Liu unsigned AS = UseAddrSpace 8330d9673cfSYaxun Liu ? AMDGPULibFuncBase::getAddrSpaceFromEPtrKind(p.PtrKind) 8340d9673cfSYaxun Liu : 0; 83527332968SMichael Liao if (EnableOCLManglingMismatchWA || AS != 0) 83627332968SMichael Liao os << "U3AS" << AS; 8377f37794eSStanislav Mekhanoshin Ptr = p; 8387f37794eSStanislav Mekhanoshin p.PtrKind = 0; 8397f37794eSStanislav Mekhanoshin } 8407f37794eSStanislav Mekhanoshin 8417f37794eSStanislav Mekhanoshin if (p.VectorSize > 1) { 8427f37794eSStanislav Mekhanoshin if (trySubst(os, p)) goto exit; 8437f37794eSStanislav Mekhanoshin Str.push_back(p); 8447f37794eSStanislav Mekhanoshin os << "Dv" << static_cast<unsigned>(p.VectorSize) << '_'; 8457f37794eSStanislav Mekhanoshin } 8467f37794eSStanislav Mekhanoshin 8477f37794eSStanislav Mekhanoshin os << getItaniumTypeName((AMDGPULibFunc::EType)p.ArgType); 8487f37794eSStanislav Mekhanoshin 8497f37794eSStanislav Mekhanoshin exit: 8507f37794eSStanislav Mekhanoshin if (Ptr.ArgType) Str.push_back(Ptr); 8517f37794eSStanislav Mekhanoshin } 8527f37794eSStanislav Mekhanoshin }; 85349a49fe8SBenjamin Kramer } // namespace 8547f37794eSStanislav Mekhanoshin 855fc5121a7SYaxun Liu std::string AMDGPUMangledLibFunc::mangleNameItanium() const { 8567f37794eSStanislav Mekhanoshin SmallString<128> Buf; 8577f37794eSStanislav Mekhanoshin raw_svector_ostream S(Buf); 8587f37794eSStanislav Mekhanoshin SmallString<128> NameBuf; 8597f37794eSStanislav Mekhanoshin raw_svector_ostream Name(NameBuf); 8607f37794eSStanislav Mekhanoshin writeName(Name); 8617f37794eSStanislav Mekhanoshin const StringRef& NameStr = Name.str(); 8627f37794eSStanislav Mekhanoshin S << "_Z" << static_cast<int>(NameStr.size()) << NameStr; 8637f37794eSStanislav Mekhanoshin 8647f37794eSStanislav Mekhanoshin ItaniumMangler Mangler(true); 8657f37794eSStanislav Mekhanoshin ParamIterator I(Leads, manglingRules[FuncId]); 8667f37794eSStanislav Mekhanoshin Param P; 8677f37794eSStanislav Mekhanoshin while ((P = I.getNextParam()).ArgType != 0) 8687f37794eSStanislav Mekhanoshin Mangler(S, P); 869adcd0268SBenjamin Kramer return std::string(S.str()); 8707f37794eSStanislav Mekhanoshin } 8717f37794eSStanislav Mekhanoshin 8727f37794eSStanislav Mekhanoshin /////////////////////////////////////////////////////////////////////////////// 8737f37794eSStanislav Mekhanoshin // Misc 8747f37794eSStanislav Mekhanoshin 8757f37794eSStanislav Mekhanoshin static Type* getIntrinsicParamType( 8767f37794eSStanislav Mekhanoshin LLVMContext& C, 8777f37794eSStanislav Mekhanoshin const AMDGPULibFunc::Param& P, 8787f37794eSStanislav Mekhanoshin bool useAddrSpace) { 8797f37794eSStanislav Mekhanoshin Type* T = nullptr; 8807f37794eSStanislav Mekhanoshin switch (P.ArgType) { 8817f37794eSStanislav Mekhanoshin case AMDGPULibFunc::U8: 8827f37794eSStanislav Mekhanoshin case AMDGPULibFunc::I8: T = Type::getInt8Ty(C); break; 8837f37794eSStanislav Mekhanoshin case AMDGPULibFunc::U16: 8847f37794eSStanislav Mekhanoshin case AMDGPULibFunc::I16: T = Type::getInt16Ty(C); break; 8857f37794eSStanislav Mekhanoshin case AMDGPULibFunc::U32: 8867f37794eSStanislav Mekhanoshin case AMDGPULibFunc::I32: T = Type::getInt32Ty(C); break; 8877f37794eSStanislav Mekhanoshin case AMDGPULibFunc::U64: 8887f37794eSStanislav Mekhanoshin case AMDGPULibFunc::I64: T = Type::getInt64Ty(C); break; 8897f37794eSStanislav Mekhanoshin case AMDGPULibFunc::F16: T = Type::getHalfTy(C); break; 8907f37794eSStanislav Mekhanoshin case AMDGPULibFunc::F32: T = Type::getFloatTy(C); break; 8917f37794eSStanislav Mekhanoshin case AMDGPULibFunc::F64: T = Type::getDoubleTy(C); break; 8927f37794eSStanislav Mekhanoshin 8937f37794eSStanislav Mekhanoshin case AMDGPULibFunc::IMG1DA: 8947f37794eSStanislav Mekhanoshin case AMDGPULibFunc::IMG1DB: 8957f37794eSStanislav Mekhanoshin case AMDGPULibFunc::IMG2DA: 8967f37794eSStanislav Mekhanoshin case AMDGPULibFunc::IMG1D: 8977f37794eSStanislav Mekhanoshin case AMDGPULibFunc::IMG2D: 8987f37794eSStanislav Mekhanoshin case AMDGPULibFunc::IMG3D: 8997f37794eSStanislav Mekhanoshin T = StructType::create(C,"ocl_image")->getPointerTo(); break; 9007f37794eSStanislav Mekhanoshin case AMDGPULibFunc::SAMPLER: 9017f37794eSStanislav Mekhanoshin T = StructType::create(C,"ocl_sampler")->getPointerTo(); break; 9027f37794eSStanislav Mekhanoshin case AMDGPULibFunc::EVENT: 9037f37794eSStanislav Mekhanoshin T = StructType::create(C,"ocl_event")->getPointerTo(); break; 9047f37794eSStanislav Mekhanoshin default: 9057f37794eSStanislav Mekhanoshin llvm_unreachable("Unhandeled param type"); 9067f37794eSStanislav Mekhanoshin return nullptr; 9077f37794eSStanislav Mekhanoshin } 9087f37794eSStanislav Mekhanoshin if (P.VectorSize > 1) 909aad93654SChristopher Tetreault T = FixedVectorType::get(T, P.VectorSize); 9107f37794eSStanislav Mekhanoshin if (P.PtrKind != AMDGPULibFunc::BYVALUE) 9117f37794eSStanislav Mekhanoshin T = useAddrSpace ? T->getPointerTo((P.PtrKind & AMDGPULibFunc::ADDR_SPACE) 9127f37794eSStanislav Mekhanoshin - 1) 9137f37794eSStanislav Mekhanoshin : T->getPointerTo(); 9147f37794eSStanislav Mekhanoshin return T; 9157f37794eSStanislav Mekhanoshin } 9167f37794eSStanislav Mekhanoshin 917fc5121a7SYaxun Liu FunctionType *AMDGPUMangledLibFunc::getFunctionType(Module &M) const { 9187f37794eSStanislav Mekhanoshin LLVMContext& C = M.getContext(); 9197f37794eSStanislav Mekhanoshin std::vector<Type*> Args; 9207f37794eSStanislav Mekhanoshin ParamIterator I(Leads, manglingRules[FuncId]); 9217f37794eSStanislav Mekhanoshin Param P; 9227f37794eSStanislav Mekhanoshin while ((P=I.getNextParam()).ArgType != 0) 9237f37794eSStanislav Mekhanoshin Args.push_back(getIntrinsicParamType(C, P, true)); 9247f37794eSStanislav Mekhanoshin 9257f37794eSStanislav Mekhanoshin return FunctionType::get( 9267f37794eSStanislav Mekhanoshin getIntrinsicParamType(C, getRetType(FuncId, Leads), true), 9277f37794eSStanislav Mekhanoshin Args, false); 9287f37794eSStanislav Mekhanoshin } 9297f37794eSStanislav Mekhanoshin 930fc5121a7SYaxun Liu unsigned AMDGPUMangledLibFunc::getNumArgs() const { 9317f37794eSStanislav Mekhanoshin return manglingRules[FuncId].getNumArgs(); 9327f37794eSStanislav Mekhanoshin } 9337f37794eSStanislav Mekhanoshin 934fc5121a7SYaxun Liu unsigned AMDGPUUnmangledLibFunc::getNumArgs() const { 935fc5121a7SYaxun Liu return UnmangledFuncInfo::getNumArgs(FuncId); 936fc5121a7SYaxun Liu } 937fc5121a7SYaxun Liu 938fc5121a7SYaxun Liu std::string AMDGPUMangledLibFunc::getName() const { 9397f37794eSStanislav Mekhanoshin SmallString<128> Buf; 9407f37794eSStanislav Mekhanoshin raw_svector_ostream OS(Buf); 9417f37794eSStanislav Mekhanoshin writeName(OS); 942adcd0268SBenjamin Kramer return std::string(OS.str()); 9437f37794eSStanislav Mekhanoshin } 9447f37794eSStanislav Mekhanoshin 9457f37794eSStanislav Mekhanoshin Function *AMDGPULibFunc::getFunction(Module *M, const AMDGPULibFunc &fInfo) { 9467f37794eSStanislav Mekhanoshin std::string FuncName = fInfo.mangle(); 9477f37794eSStanislav Mekhanoshin Function *F = dyn_cast_or_null<Function>( 9487f37794eSStanislav Mekhanoshin M->getValueSymbolTable().lookup(FuncName)); 9497f37794eSStanislav Mekhanoshin 9507f37794eSStanislav Mekhanoshin // check formal with actual types conformance 9517f37794eSStanislav Mekhanoshin if (F && !F->isDeclaration() 9527f37794eSStanislav Mekhanoshin && !F->isVarArg() 9537f37794eSStanislav Mekhanoshin && F->arg_size() == fInfo.getNumArgs()) { 9547f37794eSStanislav Mekhanoshin return F; 9557f37794eSStanislav Mekhanoshin } 9567f37794eSStanislav Mekhanoshin return nullptr; 9577f37794eSStanislav Mekhanoshin } 9587f37794eSStanislav Mekhanoshin 95913680223SJames Y Knight FunctionCallee AMDGPULibFunc::getOrInsertFunction(Module *M, 9607f37794eSStanislav Mekhanoshin const AMDGPULibFunc &fInfo) { 9617f37794eSStanislav Mekhanoshin std::string const FuncName = fInfo.mangle(); 9627f37794eSStanislav Mekhanoshin Function *F = dyn_cast_or_null<Function>( 9637f37794eSStanislav Mekhanoshin M->getValueSymbolTable().lookup(FuncName)); 9647f37794eSStanislav Mekhanoshin 9657f37794eSStanislav Mekhanoshin // check formal with actual types conformance 9667f37794eSStanislav Mekhanoshin if (F && !F->isDeclaration() 9677f37794eSStanislav Mekhanoshin && !F->isVarArg() 9687f37794eSStanislav Mekhanoshin && F->arg_size() == fInfo.getNumArgs()) { 9697f37794eSStanislav Mekhanoshin return F; 9707f37794eSStanislav Mekhanoshin } 9717f37794eSStanislav Mekhanoshin 9727f37794eSStanislav Mekhanoshin FunctionType *FuncTy = fInfo.getFunctionType(*M); 9737f37794eSStanislav Mekhanoshin 9747f37794eSStanislav Mekhanoshin bool hasPtr = false; 9757f37794eSStanislav Mekhanoshin for (FunctionType::param_iterator 9767f37794eSStanislav Mekhanoshin PI = FuncTy->param_begin(), 9777f37794eSStanislav Mekhanoshin PE = FuncTy->param_end(); 9787f37794eSStanislav Mekhanoshin PI != PE; ++PI) { 9797f37794eSStanislav Mekhanoshin const Type* argTy = static_cast<const Type*>(*PI); 9807f37794eSStanislav Mekhanoshin if (argTy->isPointerTy()) { 9817f37794eSStanislav Mekhanoshin hasPtr = true; 9827f37794eSStanislav Mekhanoshin break; 9837f37794eSStanislav Mekhanoshin } 9847f37794eSStanislav Mekhanoshin } 9857f37794eSStanislav Mekhanoshin 98613680223SJames Y Knight FunctionCallee C; 9877f37794eSStanislav Mekhanoshin if (hasPtr) { 9887f37794eSStanislav Mekhanoshin // Do not set extra attributes for functions with pointer arguments. 9897f37794eSStanislav Mekhanoshin C = M->getOrInsertFunction(FuncName, FuncTy); 9907f37794eSStanislav Mekhanoshin } else { 9917f37794eSStanislav Mekhanoshin AttributeList Attr; 9927f37794eSStanislav Mekhanoshin LLVMContext &Ctx = M->getContext(); 993de0ae9e8SArthur Eubanks Attr = Attr.addFnAttribute(Ctx, Attribute::ReadOnly); 994de0ae9e8SArthur Eubanks Attr = Attr.addFnAttribute(Ctx, Attribute::NoUnwind); 9957f37794eSStanislav Mekhanoshin C = M->getOrInsertFunction(FuncName, FuncTy, Attr); 9967f37794eSStanislav Mekhanoshin } 9977f37794eSStanislav Mekhanoshin 99813680223SJames Y Knight return C; 9997f37794eSStanislav Mekhanoshin } 1000fc5121a7SYaxun Liu 100185e2cdacSReid Kleckner StringMap<unsigned> UnmangledFuncInfo::buildNameMap() { 100285e2cdacSReid Kleckner StringMap<unsigned> Map; 100385e2cdacSReid Kleckner for (unsigned I = 0; I != TableSize; ++I) 100485e2cdacSReid Kleckner Map[Table[I].Name] = I; 100585e2cdacSReid Kleckner return Map; 100685e2cdacSReid Kleckner } 100785e2cdacSReid Kleckner 1008fc5121a7SYaxun Liu bool UnmangledFuncInfo::lookup(StringRef Name, ID &Id) { 100985e2cdacSReid Kleckner static const StringMap<unsigned> Map = buildNameMap(); 1010fc5121a7SYaxun Liu auto Loc = Map.find(Name); 1011fc5121a7SYaxun Liu if (Loc != Map.end()) { 1012fc5121a7SYaxun Liu Id = toFuncId(Loc->second); 1013fc5121a7SYaxun Liu return true; 1014fc5121a7SYaxun Liu } 1015fc5121a7SYaxun Liu Id = AMDGPULibFunc::EI_NONE; 1016fc5121a7SYaxun Liu return false; 1017fc5121a7SYaxun Liu } 1018fc5121a7SYaxun Liu 1019fc5121a7SYaxun Liu AMDGPULibFunc::AMDGPULibFunc(const AMDGPULibFunc &F) { 1020fc5121a7SYaxun Liu if (auto *MF = dyn_cast<AMDGPUMangledLibFunc>(F.Impl.get())) 1021fc5121a7SYaxun Liu Impl.reset(new AMDGPUMangledLibFunc(*MF)); 1022fc5121a7SYaxun Liu else if (auto *UMF = dyn_cast<AMDGPUUnmangledLibFunc>(F.Impl.get())) 1023fc5121a7SYaxun Liu Impl.reset(new AMDGPUUnmangledLibFunc(*UMF)); 1024fc5121a7SYaxun Liu else 1025fc5121a7SYaxun Liu Impl = std::unique_ptr<AMDGPULibFuncImpl>(); 1026fc5121a7SYaxun Liu } 1027fc5121a7SYaxun Liu 1028fc5121a7SYaxun Liu AMDGPULibFunc &AMDGPULibFunc::operator=(const AMDGPULibFunc &F) { 1029fc5121a7SYaxun Liu if (this == &F) 1030fc5121a7SYaxun Liu return *this; 1031fc5121a7SYaxun Liu new (this) AMDGPULibFunc(F); 1032fc5121a7SYaxun Liu return *this; 1033fc5121a7SYaxun Liu } 1034fc5121a7SYaxun Liu 1035fc5121a7SYaxun Liu AMDGPULibFunc::AMDGPULibFunc(EFuncId Id, const AMDGPULibFunc &CopyFrom) { 1036fc5121a7SYaxun Liu assert(AMDGPULibFuncBase::isMangled(Id) && CopyFrom.isMangled() && 1037fc5121a7SYaxun Liu "not supported"); 1038fc5121a7SYaxun Liu Impl.reset(new AMDGPUMangledLibFunc( 1039fc5121a7SYaxun Liu Id, *cast<AMDGPUMangledLibFunc>(CopyFrom.Impl.get()))); 1040fc5121a7SYaxun Liu } 1041fc5121a7SYaxun Liu 1042fc5121a7SYaxun Liu AMDGPULibFunc::AMDGPULibFunc(StringRef Name, FunctionType *FT) { 1043fc5121a7SYaxun Liu Impl.reset(new AMDGPUUnmangledLibFunc(Name, FT)); 1044fc5121a7SYaxun Liu } 1045fc5121a7SYaxun Liu 1046fc5121a7SYaxun Liu void AMDGPULibFunc::initMangled() { Impl.reset(new AMDGPUMangledLibFunc()); } 1047fc5121a7SYaxun Liu 1048fc5121a7SYaxun Liu AMDGPULibFunc::Param *AMDGPULibFunc::getLeads() { 1049fc5121a7SYaxun Liu if (!Impl) 1050fc5121a7SYaxun Liu initMangled(); 1051fc5121a7SYaxun Liu return cast<AMDGPUMangledLibFunc>(Impl.get())->Leads; 1052fc5121a7SYaxun Liu } 1053fc5121a7SYaxun Liu 1054fc5121a7SYaxun Liu const AMDGPULibFunc::Param *AMDGPULibFunc::getLeads() const { 1055fc5121a7SYaxun Liu return cast<const AMDGPUMangledLibFunc>(Impl.get())->Leads; 1056fc5121a7SYaxun Liu } 1057