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