diff options
| author | 2020-08-03 15:06:44 +0000 | |
|---|---|---|
| committer | 2020-08-03 15:06:44 +0000 | |
| commit | b64793999546ed8adebaeebd9d8345d18db8927d (patch) | |
| tree | 4357c27b561d73b0e089727c6ed659f2ceff5f47 /gnu/llvm/lib/Target/AMDGPU/AMDGPULibFunc.cpp | |
| parent | Add support for UTF-8 DISPLAY-HINTs with octet length. For now only (diff) | |
| download | wireguard-openbsd-b64793999546ed8adebaeebd9d8345d18db8927d.tar.xz wireguard-openbsd-b64793999546ed8adebaeebd9d8345d18db8927d.zip | |
Remove LLVM 8.0.1 files.
Diffstat (limited to 'gnu/llvm/lib/Target/AMDGPU/AMDGPULibFunc.cpp')
| -rw-r--r-- | gnu/llvm/lib/Target/AMDGPU/AMDGPULibFunc.cpp | 1055 |
1 files changed, 0 insertions, 1055 deletions
diff --git a/gnu/llvm/lib/Target/AMDGPU/AMDGPULibFunc.cpp b/gnu/llvm/lib/Target/AMDGPU/AMDGPULibFunc.cpp deleted file mode 100644 index 4fc3fe0f105..00000000000 --- a/gnu/llvm/lib/Target/AMDGPU/AMDGPULibFunc.cpp +++ /dev/null @@ -1,1055 +0,0 @@ -//===-- AMDGPULibFunc.cpp -------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains utility functions to work with Itanium mangled names -// -//===----------------------------------------------------------------------===// - -#include "AMDGPU.h" -#include "AMDGPULibFunc.h" -#include <llvm/ADT/SmallString.h> -#include <llvm/ADT/SmallVector.h> -#include <llvm/ADT/StringSwitch.h> -#include "llvm/IR/Attributes.h" -#include "llvm/IR/DerivedTypes.h" -#include "llvm/IR/Function.h" -#include "llvm/IR/Module.h" -#include "llvm/IR/ValueSymbolTable.h" -#include <llvm/Support/raw_ostream.h> -#include <string> - -using namespace llvm; - -namespace { - -enum EManglingParam { - E_NONE, - EX_EVENT, - EX_FLOAT4, - EX_INTV4, - EX_RESERVEDID, - EX_SAMPLER, - EX_SIZET, - EX_UINT, - EX_UINTV4, - E_ANY, - E_CONSTPTR_ANY, - E_CONSTPTR_SWAPGL, - E_COPY, - E_IMAGECOORDS, - E_POINTEE, - E_SETBASE_I32, - E_SETBASE_U32, - E_MAKEBASE_UNS, - E_V16_OF_POINTEE, - E_V2_OF_POINTEE, - E_V3_OF_POINTEE, - E_V4_OF_POINTEE, - E_V8_OF_POINTEE, - E_VLTLPTR_ANY, -}; - -struct ManglingRule { - StringRef const Name; - unsigned char Lead[2]; - unsigned char Param[5]; - - int maxLeadIndex() const { return (std::max)(Lead[0], Lead[1]); } - int getNumLeads() const { return (Lead[0] ? 1 : 0) + (Lead[1] ? 1 : 0); } - - unsigned getNumArgs() const; -}; - -// Information about library functions with unmangled names. -class UnmangledFuncInfo { - StringRef const Name; - unsigned NumArgs; - - // Table for all lib functions with unmangled names. - static const UnmangledFuncInfo Table[]; - - // Number of entries in Table. - static const unsigned TableSize; - - // Map function name to index. - class NameMap : public StringMap<unsigned> { - public: - NameMap() { - for (unsigned I = 0; I != TableSize; ++I) - (*this)[Table[I].Name] = I; - } - }; - friend class NameMap; - static NameMap Map; - -public: - using ID = AMDGPULibFunc::EFuncId; - UnmangledFuncInfo(StringRef _Name, unsigned _NumArgs) - : Name(_Name), NumArgs(_NumArgs) {} - // Get index to Table by function name. - static bool lookup(StringRef Name, ID &Id); - static unsigned toIndex(ID Id) { - assert(static_cast<unsigned>(Id) > - static_cast<unsigned>(AMDGPULibFunc::EI_LAST_MANGLED) && - "Invalid unmangled library function"); - return static_cast<unsigned>(Id) - 1 - - static_cast<unsigned>(AMDGPULibFunc::EI_LAST_MANGLED); - } - static ID toFuncId(unsigned Index) { - assert(Index < TableSize && "Invalid unmangled library function"); - return static_cast<ID>( - Index + 1 + static_cast<unsigned>(AMDGPULibFunc::EI_LAST_MANGLED)); - } - static unsigned getNumArgs(ID Id) { return Table[toIndex(Id)].NumArgs; } - static StringRef getName(ID Id) { return Table[toIndex(Id)].Name; } -}; - -unsigned ManglingRule::getNumArgs() const { - unsigned I=0; - while (I < (sizeof Param/sizeof Param[0]) && Param[I]) ++I; - return I; -} - -// This table describes function formal argument type rules. The order of rules -// corresponds to the EFuncId enum at AMDGPULibFunc.h -// -// "<func name>", { <leads> }, { <param rules> } -// where: -// <leads> - list of integers that are one-based indexes of formal argument -// used to mangle a function name. Other argument types are derived from types -// of these 'leads'. The order of integers in this list correspond to the -// order in which these arguments are mangled in the EDG mangling scheme. The -// same order should be preserved for arguments in the AMDGPULibFunc structure -// when it is used for mangling. For example: -// { "vstorea_half", {3,1}, {E_ANY,EX_SIZET,E_ANY}}, -// will be mangled in EDG scheme as vstorea_half_<3dparam>_<1stparam> -// When mangling from code use: -// AMDGPULibFunc insc; -// insc.param[0] = ... // describe 3rd parameter -// insc.param[1] = ... // describe 1rd parameter -// -// <param rules> - list of rules used to derive all of the function formal -// argument types. EX_ prefixed are simple types, other derived from the -// latest 'lead' argument type in the order of encoding from first to last. -// E_ANY - use prev lead type, E_CONSTPTR_ANY - make const pointer out of -// prev lead type, etc. see ParamIterator::getNextParam() for details. - -static const ManglingRule manglingRules[] = { -{ StringRef(), {0}, {0} }, -{ "abs" , {1}, {E_ANY}}, -{ "abs_diff" , {1}, {E_ANY,E_COPY}}, -{ "acos" , {1}, {E_ANY}}, -{ "acosh" , {1}, {E_ANY}}, -{ "acospi" , {1}, {E_ANY}}, -{ "add_sat" , {1}, {E_ANY,E_COPY}}, -{ "all" , {1}, {E_ANY}}, -{ "any" , {1}, {E_ANY}}, -{ "asin" , {1}, {E_ANY}}, -{ "asinh" , {1}, {E_ANY}}, -{ "asinpi" , {1}, {E_ANY}}, -{ "async_work_group_copy" , {1}, {E_ANY,E_CONSTPTR_SWAPGL,EX_SIZET,EX_EVENT}}, -{ "async_work_group_strided_copy" , {1}, {E_ANY,E_CONSTPTR_SWAPGL,EX_SIZET,EX_SIZET,EX_EVENT}}, -{ "atan" , {1}, {E_ANY}}, -{ "atan2" , {1}, {E_ANY,E_COPY}}, -{ "atan2pi" , {1}, {E_ANY,E_COPY}}, -{ "atanh" , {1}, {E_ANY}}, -{ "atanpi" , {1}, {E_ANY}}, -{ "atomic_add" , {1}, {E_VLTLPTR_ANY,E_POINTEE}}, -{ "atomic_and" , {1}, {E_VLTLPTR_ANY,E_POINTEE}}, -{ "atomic_cmpxchg" , {1}, {E_VLTLPTR_ANY,E_POINTEE,E_POINTEE}}, -{ "atomic_dec" , {1}, {E_VLTLPTR_ANY}}, -{ "atomic_inc" , {1}, {E_VLTLPTR_ANY}}, -{ "atomic_max" , {1}, {E_VLTLPTR_ANY,E_POINTEE}}, -{ "atomic_min" , {1}, {E_VLTLPTR_ANY,E_POINTEE}}, -{ "atomic_or" , {1}, {E_VLTLPTR_ANY,E_POINTEE}}, -{ "atomic_sub" , {1}, {E_VLTLPTR_ANY,E_POINTEE}}, -{ "atomic_xchg" , {1}, {E_VLTLPTR_ANY,E_POINTEE}}, -{ "atomic_xor" , {1}, {E_VLTLPTR_ANY,E_POINTEE}}, -{ "bitselect" , {1}, {E_ANY,E_COPY,E_COPY}}, -{ "cbrt" , {1}, {E_ANY}}, -{ "ceil" , {1}, {E_ANY}}, -{ "clamp" , {1}, {E_ANY,E_COPY,E_COPY}}, -{ "clz" , {1}, {E_ANY}}, -{ "commit_read_pipe" , {1}, {E_ANY,EX_RESERVEDID}}, -{ "commit_write_pipe" , {1}, {E_ANY,EX_RESERVEDID}}, -{ "copysign" , {1}, {E_ANY,E_COPY}}, -{ "cos" , {1}, {E_ANY}}, -{ "cosh" , {1}, {E_ANY}}, -{ "cospi" , {1}, {E_ANY}}, -{ "cross" , {1}, {E_ANY,E_COPY}}, -{ "ctz" , {1}, {E_ANY}}, -{ "degrees" , {1}, {E_ANY}}, -{ "distance" , {1}, {E_ANY,E_COPY}}, -{ "divide" , {1}, {E_ANY,E_COPY}}, -{ "dot" , {1}, {E_ANY,E_COPY}}, -{ "erf" , {1}, {E_ANY}}, -{ "erfc" , {1}, {E_ANY}}, -{ "exp" , {1}, {E_ANY}}, -{ "exp10" , {1}, {E_ANY}}, -{ "exp2" , {1}, {E_ANY}}, -{ "expm1" , {1}, {E_ANY}}, -{ "fabs" , {1}, {E_ANY}}, -{ "fast_distance" , {1}, {E_ANY,E_COPY}}, -{ "fast_length" , {1}, {E_ANY}}, -{ "fast_normalize" , {1}, {E_ANY}}, -{ "fdim" , {1}, {E_ANY,E_COPY}}, -{ "floor" , {1}, {E_ANY}}, -{ "fma" , {1}, {E_ANY,E_COPY,E_COPY}}, -{ "fmax" , {1}, {E_ANY,E_COPY}}, -{ "fmin" , {1}, {E_ANY,E_COPY}}, -{ "fmod" , {1}, {E_ANY,E_COPY}}, -{ "fract" , {2}, {E_POINTEE,E_ANY}}, -{ "frexp" , {1,2}, {E_ANY,E_ANY}}, -{ "get_image_array_size" , {1}, {E_ANY}}, -{ "get_image_channel_data_type" , {1}, {E_ANY}}, -{ "get_image_channel_order" , {1}, {E_ANY}}, -{ "get_image_dim" , {1}, {E_ANY}}, -{ "get_image_height" , {1}, {E_ANY}}, -{ "get_image_width" , {1}, {E_ANY}}, -{ "get_pipe_max_packets" , {1}, {E_ANY}}, -{ "get_pipe_num_packets" , {1}, {E_ANY}}, -{ "hadd" , {1}, {E_ANY,E_COPY}}, -{ "hypot" , {1}, {E_ANY,E_COPY}}, -{ "ilogb" , {1}, {E_ANY}}, -{ "isequal" , {1}, {E_ANY,E_COPY}}, -{ "isfinite" , {1}, {E_ANY}}, -{ "isgreater" , {1}, {E_ANY,E_COPY}}, -{ "isgreaterequal" , {1}, {E_ANY,E_COPY}}, -{ "isinf" , {1}, {E_ANY}}, -{ "isless" , {1}, {E_ANY,E_COPY}}, -{ "islessequal" , {1}, {E_ANY,E_COPY}}, -{ "islessgreater" , {1}, {E_ANY,E_COPY}}, -{ "isnan" , {1}, {E_ANY}}, -{ "isnormal" , {1}, {E_ANY}}, -{ "isnotequal" , {1}, {E_ANY,E_COPY}}, -{ "isordered" , {1}, {E_ANY,E_COPY}}, -{ "isunordered" , {1}, {E_ANY,E_COPY}}, -{ "ldexp" , {1}, {E_ANY,E_SETBASE_I32}}, -{ "length" , {1}, {E_ANY}}, -{ "lgamma" , {1}, {E_ANY}}, -{ "lgamma_r" , {1,2}, {E_ANY,E_ANY}}, -{ "log" , {1}, {E_ANY}}, -{ "log10" , {1}, {E_ANY}}, -{ "log1p" , {1}, {E_ANY}}, -{ "log2" , {1}, {E_ANY}}, -{ "logb" , {1}, {E_ANY}}, -{ "mad" , {1}, {E_ANY,E_COPY,E_COPY}}, -{ "mad24" , {1}, {E_ANY,E_COPY,E_COPY}}, -{ "mad_hi" , {1}, {E_ANY,E_COPY,E_COPY}}, -{ "mad_sat" , {1}, {E_ANY,E_COPY,E_COPY}}, -{ "max" , {1}, {E_ANY,E_COPY}}, -{ "maxmag" , {1}, {E_ANY,E_COPY}}, -{ "min" , {1}, {E_ANY,E_COPY}}, -{ "minmag" , {1}, {E_ANY,E_COPY}}, -{ "mix" , {1}, {E_ANY,E_COPY,E_COPY}}, -{ "modf" , {2}, {E_POINTEE,E_ANY}}, -{ "mul24" , {1}, {E_ANY,E_COPY}}, -{ "mul_hi" , {1}, {E_ANY,E_COPY}}, -{ "nan" , {1}, {E_ANY}}, -{ "nextafter" , {1}, {E_ANY,E_COPY}}, -{ "normalize" , {1}, {E_ANY}}, -{ "popcount" , {1}, {E_ANY}}, -{ "pow" , {1}, {E_ANY,E_COPY}}, -{ "pown" , {1}, {E_ANY,E_SETBASE_I32}}, -{ "powr" , {1}, {E_ANY,E_COPY}}, -{ "prefetch" , {1}, {E_CONSTPTR_ANY,EX_SIZET}}, -{ "radians" , {1}, {E_ANY}}, -{ "recip" , {1}, {E_ANY}}, -{ "remainder" , {1}, {E_ANY,E_COPY}}, -{ "remquo" , {1,3}, {E_ANY,E_COPY,E_ANY}}, -{ "reserve_read_pipe" , {1}, {E_ANY,EX_UINT}}, -{ "reserve_write_pipe" , {1}, {E_ANY,EX_UINT}}, -{ "rhadd" , {1}, {E_ANY,E_COPY}}, -{ "rint" , {1}, {E_ANY}}, -{ "rootn" , {1}, {E_ANY,E_SETBASE_I32}}, -{ "rotate" , {1}, {E_ANY,E_COPY}}, -{ "round" , {1}, {E_ANY}}, -{ "rsqrt" , {1}, {E_ANY}}, -{ "select" , {1,3}, {E_ANY,E_COPY,E_ANY}}, -{ "shuffle" , {1,2}, {E_ANY,E_ANY}}, -{ "shuffle2" , {1,3}, {E_ANY,E_COPY,E_ANY}}, -{ "sign" , {1}, {E_ANY}}, -{ "signbit" , {1}, {E_ANY}}, -{ "sin" , {1}, {E_ANY}}, -{ "sincos" , {2}, {E_POINTEE,E_ANY}}, -{ "sinh" , {1}, {E_ANY}}, -{ "sinpi" , {1}, {E_ANY}}, -{ "smoothstep" , {1}, {E_ANY,E_COPY,E_COPY}}, -{ "sqrt" , {1}, {E_ANY}}, -{ "step" , {1}, {E_ANY,E_COPY}}, -{ "sub_group_broadcast" , {1}, {E_ANY,EX_UINT}}, -{ "sub_group_commit_read_pipe" , {1}, {E_ANY,EX_RESERVEDID}}, -{ "sub_group_commit_write_pipe" , {1}, {E_ANY,EX_RESERVEDID}}, -{ "sub_group_reduce_add" , {1}, {E_ANY}}, -{ "sub_group_reduce_max" , {1}, {E_ANY}}, -{ "sub_group_reduce_min" , {1}, {E_ANY}}, -{ "sub_group_reserve_read_pipe" , {1}, {E_ANY,EX_UINT}}, -{ "sub_group_reserve_write_pipe" , {1}, {E_ANY,EX_UINT}}, -{ "sub_group_scan_exclusive_add" , {1}, {E_ANY}}, -{ "sub_group_scan_exclusive_max" , {1}, {E_ANY}}, -{ "sub_group_scan_exclusive_min" , {1}, {E_ANY}}, -{ "sub_group_scan_inclusive_add" , {1}, {E_ANY}}, -{ "sub_group_scan_inclusive_max" , {1}, {E_ANY}}, -{ "sub_group_scan_inclusive_min" , {1}, {E_ANY}}, -{ "sub_sat" , {1}, {E_ANY,E_COPY}}, -{ "tan" , {1}, {E_ANY}}, -{ "tanh" , {1}, {E_ANY}}, -{ "tanpi" , {1}, {E_ANY}}, -{ "tgamma" , {1}, {E_ANY}}, -{ "trunc" , {1}, {E_ANY}}, -{ "upsample" , {1}, {E_ANY,E_MAKEBASE_UNS}}, -{ "vec_step" , {1}, {E_ANY}}, -{ "vstore" , {3}, {E_POINTEE,EX_SIZET,E_ANY}}, -{ "vstore16" , {3}, {E_V16_OF_POINTEE,EX_SIZET,E_ANY}}, -{ "vstore2" , {3}, {E_V2_OF_POINTEE,EX_SIZET,E_ANY}}, -{ "vstore3" , {3}, {E_V3_OF_POINTEE,EX_SIZET,E_ANY}}, -{ "vstore4" , {3}, {E_V4_OF_POINTEE,EX_SIZET,E_ANY}}, -{ "vstore8" , {3}, {E_V8_OF_POINTEE,EX_SIZET,E_ANY}}, -{ "work_group_commit_read_pipe" , {1}, {E_ANY,EX_RESERVEDID}}, -{ "work_group_commit_write_pipe" , {1}, {E_ANY,EX_RESERVEDID}}, -{ "work_group_reduce_add" , {1}, {E_ANY}}, -{ "work_group_reduce_max" , {1}, {E_ANY}}, -{ "work_group_reduce_min" , {1}, {E_ANY}}, -{ "work_group_reserve_read_pipe" , {1}, {E_ANY,EX_UINT}}, -{ "work_group_reserve_write_pipe" , {1}, {E_ANY,EX_UINT}}, -{ "work_group_scan_exclusive_add" , {1}, {E_ANY}}, -{ "work_group_scan_exclusive_max" , {1}, {E_ANY}}, -{ "work_group_scan_exclusive_min" , {1}, {E_ANY}}, -{ "work_group_scan_inclusive_add" , {1}, {E_ANY}}, -{ "work_group_scan_inclusive_max" , {1}, {E_ANY}}, -{ "work_group_scan_inclusive_min" , {1}, {E_ANY}}, -{ "write_imagef" , {1}, {E_ANY,E_IMAGECOORDS,EX_FLOAT4}}, -{ "write_imagei" , {1}, {E_ANY,E_IMAGECOORDS,EX_INTV4}}, -{ "write_imageui" , {1}, {E_ANY,E_IMAGECOORDS,EX_UINTV4}}, -{ "ncos" , {1}, {E_ANY} }, -{ "nexp2" , {1}, {E_ANY} }, -{ "nfma" , {1}, {E_ANY, E_COPY, E_COPY} }, -{ "nlog2" , {1}, {E_ANY} }, -{ "nrcp" , {1}, {E_ANY} }, -{ "nrsqrt" , {1}, {E_ANY} }, -{ "nsin" , {1}, {E_ANY} }, -{ "nsqrt" , {1}, {E_ANY} }, -{ "ftz" , {1}, {E_ANY} }, -{ "fldexp" , {1}, {E_ANY, EX_UINT} }, -{ "class" , {1}, {E_ANY, EX_UINT} }, -{ "rcbrt" , {1}, {E_ANY} }, -}; - -// Library functions with unmangled name. -const UnmangledFuncInfo UnmangledFuncInfo::Table[] = { - {"__read_pipe_2", 4}, - {"__read_pipe_4", 6}, - {"__write_pipe_2", 4}, - {"__write_pipe_4", 6}, -}; - -const unsigned UnmangledFuncInfo::TableSize = - sizeof(UnmangledFuncInfo::Table) / sizeof(UnmangledFuncInfo::Table[0]); - -UnmangledFuncInfo::NameMap UnmangledFuncInfo::Map; - -static const struct ManglingRulesMap : public StringMap<int> { - ManglingRulesMap() - : StringMap<int>(sizeof(manglingRules)/sizeof(manglingRules[0])) { - int Id = 0; - for (auto Rule : manglingRules) - insert({ Rule.Name, Id++ }); - } -} manglingRulesMap; - -static AMDGPULibFunc::Param getRetType(AMDGPULibFunc::EFuncId id, - const AMDGPULibFunc::Param (&Leads)[2]) { - AMDGPULibFunc::Param Res = Leads[0]; - // TBD - This switch may require to be extended for other intriniscs - switch (id) { - case AMDGPULibFunc::EI_SINCOS: - Res.PtrKind = AMDGPULibFunc::BYVALUE; - break; - default: - break; - } - return Res; -} - -class ParamIterator { - const AMDGPULibFunc::Param (&Leads)[2]; - const ManglingRule& Rule; - int Index; -public: - ParamIterator(const AMDGPULibFunc::Param (&leads)[2], - const ManglingRule& rule) - : Leads(leads), Rule(rule), Index(0) {} - - AMDGPULibFunc::Param getNextParam(); -}; - -AMDGPULibFunc::Param ParamIterator::getNextParam() { - AMDGPULibFunc::Param P; - if (Index >= int(sizeof Rule.Param/sizeof Rule.Param[0])) return P; - - const char R = Rule.Param[Index]; - switch (R) { - case E_NONE: break; - case EX_UINT: - P.ArgType = AMDGPULibFunc::U32; break; - case EX_INTV4: - P.ArgType = AMDGPULibFunc::I32; P.VectorSize = 4; break; - case EX_UINTV4: - P.ArgType = AMDGPULibFunc::U32; P.VectorSize = 4; break; - case EX_FLOAT4: - P.ArgType = AMDGPULibFunc::F32; P.VectorSize = 4; break; - case EX_SIZET: - P.ArgType = AMDGPULibFunc::U64; break; - case EX_EVENT: - P.ArgType = AMDGPULibFunc::EVENT; break; - case EX_SAMPLER: - P.ArgType = AMDGPULibFunc::SAMPLER; break; - case EX_RESERVEDID: break; // TBD - default: - if (Index == (Rule.Lead[1] - 1)) P = Leads[1]; - else P = Leads[0]; - - switch (R) { - case E_ANY: - case E_COPY: break; - - case E_POINTEE: - P.PtrKind = AMDGPULibFunc::BYVALUE; break; - case E_V2_OF_POINTEE: - P.VectorSize = 2; P.PtrKind = AMDGPULibFunc::BYVALUE; break; - case E_V3_OF_POINTEE: - P.VectorSize = 3; P.PtrKind = AMDGPULibFunc::BYVALUE; break; - case E_V4_OF_POINTEE: - P.VectorSize = 4; P.PtrKind = AMDGPULibFunc::BYVALUE; break; - case E_V8_OF_POINTEE: - P.VectorSize = 8; P.PtrKind = AMDGPULibFunc::BYVALUE; break; - case E_V16_OF_POINTEE: - P.VectorSize = 16; P.PtrKind = AMDGPULibFunc::BYVALUE; break; - case E_CONSTPTR_ANY: - P.PtrKind |= AMDGPULibFunc::CONST; break; - case E_VLTLPTR_ANY: - P.PtrKind |= AMDGPULibFunc::VOLATILE; break; - case E_SETBASE_I32: - P.ArgType = AMDGPULibFunc::I32; break; - case E_SETBASE_U32: - P.ArgType = AMDGPULibFunc::U32; break; - - case E_MAKEBASE_UNS: - P.ArgType &= ~AMDGPULibFunc::BASE_TYPE_MASK; - P.ArgType |= AMDGPULibFunc::UINT; - break; - - case E_IMAGECOORDS: - switch (P.ArgType) { - case AMDGPULibFunc::IMG1DA: P.VectorSize = 2; break; - case AMDGPULibFunc::IMG1DB: P.VectorSize = 1; break; - case AMDGPULibFunc::IMG2DA: P.VectorSize = 4; break; - case AMDGPULibFunc::IMG1D: P.VectorSize = 1; break; - case AMDGPULibFunc::IMG2D: P.VectorSize = 2; break; - case AMDGPULibFunc::IMG3D: P.VectorSize = 4; break; - } - P.PtrKind = AMDGPULibFunc::BYVALUE; - P.ArgType = AMDGPULibFunc::I32; - break; - - case E_CONSTPTR_SWAPGL: { - unsigned AS = AMDGPULibFunc::getAddrSpaceFromEPtrKind(P.PtrKind); - switch (AS) { - case AMDGPUAS::GLOBAL_ADDRESS: AS = AMDGPUAS::LOCAL_ADDRESS; break; - case AMDGPUAS::LOCAL_ADDRESS: AS = AMDGPUAS::GLOBAL_ADDRESS; break; - } - P.PtrKind = AMDGPULibFunc::getEPtrKindFromAddrSpace(AS); - P.PtrKind |= AMDGPULibFunc::CONST; - break; - } - - default: llvm_unreachable("Unhandeled param rule"); - } - } - ++Index; - return P; -} - -inline static void drop_front(StringRef& str, size_t n = 1) { - str = str.drop_front(n); -} - -static bool eatTerm(StringRef& mangledName, const char c) { - if (mangledName.front() == c) { - drop_front(mangledName); - return true; - } - return false; -} - -template <size_t N> -static bool eatTerm(StringRef& mangledName, const char (&str)[N]) { - if (mangledName.startswith(StringRef(str, N-1))) { - drop_front(mangledName, N-1); - return true; - } - return false; -} - -static inline bool isDigit(char c) { return c >= '0' && c <= '9'; } - -static int eatNumber(StringRef& s) { - size_t const savedSize = s.size(); - int n = 0; - while (!s.empty() && isDigit(s.front())) { - n = n*10 + s.front() - '0'; - drop_front(s); - } - return s.size() < savedSize ? n : -1; -} - -static StringRef eatLengthPrefixedName(StringRef& mangledName) { - int const Len = eatNumber(mangledName); - if (Len <= 0 || static_cast<size_t>(Len) > mangledName.size()) - return StringRef(); - StringRef Res = mangledName.substr(0, Len); - drop_front(mangledName, Len); - return Res; -} - -} // end anonymous namespace - -AMDGPUMangledLibFunc::AMDGPUMangledLibFunc() { - FuncId = EI_NONE; - FKind = NOPFX; - Leads[0].reset(); - Leads[1].reset(); - Name.clear(); -} - -AMDGPUUnmangledLibFunc::AMDGPUUnmangledLibFunc() { - FuncId = EI_NONE; - FuncTy = nullptr; -} - -AMDGPUMangledLibFunc::AMDGPUMangledLibFunc( - EFuncId id, const AMDGPUMangledLibFunc ©From) { - FuncId = id; - FKind = copyFrom.FKind; - Leads[0] = copyFrom.Leads[0]; - Leads[1] = copyFrom.Leads[1]; -} - -/////////////////////////////////////////////////////////////////////////////// -// Demangling - -static int parseVecSize(StringRef& mangledName) { - size_t const Len = eatNumber(mangledName); - switch (Len) { - case 2: case 3: case 4: case 8: case 16: - return Len; - default: - break; - } - return 1; -} - -static AMDGPULibFunc::ENamePrefix parseNamePrefix(StringRef& mangledName) { - std::pair<StringRef, StringRef> const P = mangledName.split('_'); - AMDGPULibFunc::ENamePrefix Pfx = - StringSwitch<AMDGPULibFunc::ENamePrefix>(P.first) - .Case("native", AMDGPULibFunc::NATIVE) - .Case("half" , AMDGPULibFunc::HALF) - .Default(AMDGPULibFunc::NOPFX); - - if (Pfx != AMDGPULibFunc::NOPFX) - mangledName = P.second; - - return Pfx; -} - -bool AMDGPUMangledLibFunc::parseUnmangledName(StringRef FullName) { - FuncId = static_cast<EFuncId>(manglingRulesMap.lookup(FullName)); - return FuncId != EI_NONE; -} - -/////////////////////////////////////////////////////////////////////////////// -// Itanium Demangling - -namespace { -struct ItaniumParamParser { - AMDGPULibFunc::Param Prev; - bool parseItaniumParam(StringRef& param, AMDGPULibFunc::Param &res); -}; -} // namespace - -bool ItaniumParamParser::parseItaniumParam(StringRef& param, - AMDGPULibFunc::Param &res) { - res.reset(); - if (param.empty()) return false; - - // parse pointer prefix - if (eatTerm(param, 'P')) { - if (eatTerm(param, 'K')) res.PtrKind |= AMDGPULibFunc::CONST; - if (eatTerm(param, 'V')) res.PtrKind |= AMDGPULibFunc::VOLATILE; - unsigned AS; - if (!eatTerm(param, "U3AS")) { - AS = 0; - } else { - AS = param.front() - '0'; - drop_front(param, 1); - } - res.PtrKind |= AMDGPULibFuncBase::getEPtrKindFromAddrSpace(AS); - } else { - res.PtrKind = AMDGPULibFunc::BYVALUE; - } - - // parse vector size - if (eatTerm(param,"Dv")) { - res.VectorSize = parseVecSize(param); - if (res.VectorSize==1 || !eatTerm(param, '_')) return false; - } - - // parse type - char const TC = param.front(); - if (::isDigit(TC)) { - res.ArgType = StringSwitch<AMDGPULibFunc::EType> - (eatLengthPrefixedName(param)) - .Case("ocl_image1darray" , AMDGPULibFunc::IMG1DA) - .Case("ocl_image1dbuffer", AMDGPULibFunc::IMG1DB) - .Case("ocl_image2darray" , AMDGPULibFunc::IMG2DA) - .Case("ocl_image1d" , AMDGPULibFunc::IMG1D) - .Case("ocl_image2d" , AMDGPULibFunc::IMG2D) - .Case("ocl_image3d" , AMDGPULibFunc::IMG3D) - .Case("ocl_event" , AMDGPULibFunc::DUMMY) - .Case("ocl_sampler" , AMDGPULibFunc::DUMMY) - .Default(AMDGPULibFunc::DUMMY); - } else { - drop_front(param); - switch (TC) { - case 'h': res.ArgType = AMDGPULibFunc::U8; break; - case 't': res.ArgType = AMDGPULibFunc::U16; break; - case 'j': res.ArgType = AMDGPULibFunc::U32; break; - case 'm': res.ArgType = AMDGPULibFunc::U64; break; - case 'c': res.ArgType = AMDGPULibFunc::I8; break; - case 's': res.ArgType = AMDGPULibFunc::I16; break; - case 'i': res.ArgType = AMDGPULibFunc::I32; break; - case 'l': res.ArgType = AMDGPULibFunc::I64; break; - case 'f': res.ArgType = AMDGPULibFunc::F32; break; - case 'd': res.ArgType = AMDGPULibFunc::F64; break; - case 'D': if (!eatTerm(param, 'h')) return false; - res.ArgType = AMDGPULibFunc::F16; break; - case 'S': - if (!eatTerm(param, '_')) { - eatNumber(param); - if (!eatTerm(param, '_')) return false; - } - res.VectorSize = Prev.VectorSize; - res.ArgType = Prev.ArgType; - break; - default:; - } - } - if (res.ArgType == 0) return false; - Prev.VectorSize = res.VectorSize; - Prev.ArgType = res.ArgType; - return true; -} - -bool AMDGPUMangledLibFunc::parseFuncName(StringRef &mangledName) { - StringRef Name = eatLengthPrefixedName(mangledName); - FKind = parseNamePrefix(Name); - if (!parseUnmangledName(Name)) - return false; - - const ManglingRule& Rule = manglingRules[FuncId]; - ItaniumParamParser Parser; - for (int I=0; I < Rule.maxLeadIndex(); ++I) { - Param P; - if (!Parser.parseItaniumParam(mangledName, P)) - return false; - - if ((I + 1) == Rule.Lead[0]) Leads[0] = P; - if ((I + 1) == Rule.Lead[1]) Leads[1] = P; - } - return true; -} - -bool AMDGPUUnmangledLibFunc::parseFuncName(StringRef &Name) { - if (!UnmangledFuncInfo::lookup(Name, FuncId)) - return false; - setName(Name); - return true; -} - -bool AMDGPULibFunc::parse(StringRef FuncName, AMDGPULibFunc &F) { - if (FuncName.empty()) { - F.Impl = std::unique_ptr<AMDGPULibFuncImpl>(); - return false; - } - - if (eatTerm(FuncName, "_Z")) - F.Impl = make_unique<AMDGPUMangledLibFunc>(); - else - F.Impl = make_unique<AMDGPUUnmangledLibFunc>(); - if (F.Impl->parseFuncName(FuncName)) - return true; - - F.Impl = std::unique_ptr<AMDGPULibFuncImpl>(); - return false; -} - -StringRef AMDGPUMangledLibFunc::getUnmangledName(StringRef mangledName) { - StringRef S = mangledName; - if (eatTerm(S, "_Z")) - return eatLengthPrefixedName(S); - return StringRef(); -} - -/////////////////////////////////////////////////////////////////////////////// -// Mangling - -template <typename Stream> -void AMDGPUMangledLibFunc::writeName(Stream &OS) const { - const char *Pfx = ""; - switch (FKind) { - case NATIVE: Pfx = "native_"; break; - case HALF: Pfx = "half_"; break; - default: break; - } - if (!Name.empty()) { - OS << Pfx << Name; - } else if (FuncId != EI_NONE) { - OS << Pfx; - const StringRef& S = manglingRules[FuncId].Name; - OS.write(S.data(), S.size()); - } -} - -std::string AMDGPUMangledLibFunc::mangle() const { return mangleNameItanium(); } - -/////////////////////////////////////////////////////////////////////////////// -// Itanium Mangling - -static const char *getItaniumTypeName(AMDGPULibFunc::EType T) { - switch (T) { - case AMDGPULibFunc::U8: return "h"; - case AMDGPULibFunc::U16: return "t"; - case AMDGPULibFunc::U32: return "j"; - case AMDGPULibFunc::U64: return "m"; - case AMDGPULibFunc::I8: return "c"; - case AMDGPULibFunc::I16: return "s"; - case AMDGPULibFunc::I32: return "i"; - case AMDGPULibFunc::I64: return "l"; - case AMDGPULibFunc::F16: return "Dh"; - case AMDGPULibFunc::F32: return "f"; - case AMDGPULibFunc::F64: return "d"; - case AMDGPULibFunc::IMG1DA: return "16ocl_image1darray"; - case AMDGPULibFunc::IMG1DB: return "17ocl_image1dbuffer"; - case AMDGPULibFunc::IMG2DA: return "16ocl_image2darray"; - case AMDGPULibFunc::IMG1D: return "11ocl_image1d"; - case AMDGPULibFunc::IMG2D: return "11ocl_image2d"; - case AMDGPULibFunc::IMG3D: return "11ocl_image3d"; - case AMDGPULibFunc::SAMPLER: return "11ocl_sampler"; - case AMDGPULibFunc::EVENT: return "9ocl_event"; - default: llvm_unreachable("Unhandeled param type"); - } - return nullptr; -} - -namespace { -// Itanium mangling ABI says: -// "5.1.8. Compression -// ... Each non-terminal in the grammar for which <substitution> appears on the -// right-hand side is both a source of future substitutions and a candidate -// for being substituted. There are two exceptions that appear to be -// substitution candidates from the grammar, but are explicitly excluded: -// 1. <builtin-type> other than vendor extended types ..." - -// For the purpose of functions the following productions make sence for the -// substitution: -// <type> ::= <builtin-type> -// ::= <class-enum-type> -// ::= <array-type> -// ::=<CV-qualifiers> <type> -// ::= P <type> # pointer-to -// ::= <substitution> -// -// Note that while types like images, samplers and events are by the ABI encoded -// using <class-enum-type> production rule they're not used for substitution -// because clang consider them as builtin types. -// -// DvNN_ type is GCC extension for vectors and is a subject for the substitution. - - -class ItaniumMangler { - SmallVector<AMDGPULibFunc::Param, 10> Str; // list of accumulated substituions - bool UseAddrSpace; - - int findSubst(const AMDGPULibFunc::Param& P) const { - for(unsigned I = 0; I < Str.size(); ++I) { - const AMDGPULibFunc::Param& T = Str[I]; - if (P.PtrKind == T.PtrKind && - P.VectorSize == T.VectorSize && - P.ArgType == T.ArgType) { - return I; - } - } - return -1; - } - - template <typename Stream> - bool trySubst(Stream& os, const AMDGPULibFunc::Param& p) { - int const subst = findSubst(p); - if (subst < 0) return false; - // Substitutions are mangled as S(XX)?_ where XX is a hexadecimal number - // 0 1 2 - // S_ S0_ S1_ - if (subst == 0) os << "S_"; - else os << 'S' << (subst-1) << '_'; - return true; - } - -public: - ItaniumMangler(bool useAddrSpace) - : UseAddrSpace(useAddrSpace) {} - - template <typename Stream> - void operator()(Stream& os, AMDGPULibFunc::Param p) { - - // Itanium mangling ABI 5.1.8. Compression: - // Logically, the substitutable components of a mangled name are considered - // left-to-right, components before the composite structure of which they - // are a part. If a component has been encountered before, it is substituted - // as described below. This decision is independent of whether its components - // have been substituted, so an implementation may optimize by considering - // large structures for substitution before their components. If a component - // has not been encountered before, its mangling is identified, and it is - // added to a dictionary of substitution candidates. No entity is added to - // the dictionary twice. - AMDGPULibFunc::Param Ptr; - - if (p.PtrKind) { - if (trySubst(os, p)) return; - os << 'P'; - if (p.PtrKind & AMDGPULibFunc::CONST) os << 'K'; - if (p.PtrKind & AMDGPULibFunc::VOLATILE) os << 'V'; - unsigned AS = UseAddrSpace - ? AMDGPULibFuncBase::getAddrSpaceFromEPtrKind(p.PtrKind) - : 0; - if (AS != 0) os << "U3AS" << AS; - Ptr = p; - p.PtrKind = 0; - } - - if (p.VectorSize > 1) { - if (trySubst(os, p)) goto exit; - Str.push_back(p); - os << "Dv" << static_cast<unsigned>(p.VectorSize) << '_'; - } - - os << getItaniumTypeName((AMDGPULibFunc::EType)p.ArgType); - - exit: - if (Ptr.ArgType) Str.push_back(Ptr); - } -}; -} // namespace - -std::string AMDGPUMangledLibFunc::mangleNameItanium() const { - SmallString<128> Buf; - raw_svector_ostream S(Buf); - SmallString<128> NameBuf; - raw_svector_ostream Name(NameBuf); - writeName(Name); - const StringRef& NameStr = Name.str(); - S << "_Z" << static_cast<int>(NameStr.size()) << NameStr; - - ItaniumMangler Mangler(true); - ParamIterator I(Leads, manglingRules[FuncId]); - Param P; - while ((P = I.getNextParam()).ArgType != 0) - Mangler(S, P); - return S.str(); -} - -/////////////////////////////////////////////////////////////////////////////// -// Misc - -static Type* getIntrinsicParamType( - LLVMContext& C, - const AMDGPULibFunc::Param& P, - bool useAddrSpace) { - Type* T = nullptr; - switch (P.ArgType) { - case AMDGPULibFunc::U8: - case AMDGPULibFunc::I8: T = Type::getInt8Ty(C); break; - case AMDGPULibFunc::U16: - case AMDGPULibFunc::I16: T = Type::getInt16Ty(C); break; - case AMDGPULibFunc::U32: - case AMDGPULibFunc::I32: T = Type::getInt32Ty(C); break; - case AMDGPULibFunc::U64: - case AMDGPULibFunc::I64: T = Type::getInt64Ty(C); break; - case AMDGPULibFunc::F16: T = Type::getHalfTy(C); break; - case AMDGPULibFunc::F32: T = Type::getFloatTy(C); break; - case AMDGPULibFunc::F64: T = Type::getDoubleTy(C); break; - - case AMDGPULibFunc::IMG1DA: - case AMDGPULibFunc::IMG1DB: - case AMDGPULibFunc::IMG2DA: - case AMDGPULibFunc::IMG1D: - case AMDGPULibFunc::IMG2D: - case AMDGPULibFunc::IMG3D: - T = StructType::create(C,"ocl_image")->getPointerTo(); break; - case AMDGPULibFunc::SAMPLER: - T = StructType::create(C,"ocl_sampler")->getPointerTo(); break; - case AMDGPULibFunc::EVENT: - T = StructType::create(C,"ocl_event")->getPointerTo(); break; - default: - llvm_unreachable("Unhandeled param type"); - return nullptr; - } - if (P.VectorSize > 1) - T = VectorType::get(T, P.VectorSize); - if (P.PtrKind != AMDGPULibFunc::BYVALUE) - T = useAddrSpace ? T->getPointerTo((P.PtrKind & AMDGPULibFunc::ADDR_SPACE) - - 1) - : T->getPointerTo(); - return T; -} - -FunctionType *AMDGPUMangledLibFunc::getFunctionType(Module &M) const { - LLVMContext& C = M.getContext(); - std::vector<Type*> Args; - ParamIterator I(Leads, manglingRules[FuncId]); - Param P; - while ((P=I.getNextParam()).ArgType != 0) - Args.push_back(getIntrinsicParamType(C, P, true)); - - return FunctionType::get( - getIntrinsicParamType(C, getRetType(FuncId, Leads), true), - Args, false); -} - -unsigned AMDGPUMangledLibFunc::getNumArgs() const { - return manglingRules[FuncId].getNumArgs(); -} - -unsigned AMDGPUUnmangledLibFunc::getNumArgs() const { - return UnmangledFuncInfo::getNumArgs(FuncId); -} - -std::string AMDGPUMangledLibFunc::getName() const { - SmallString<128> Buf; - raw_svector_ostream OS(Buf); - writeName(OS); - return OS.str(); -} - -Function *AMDGPULibFunc::getFunction(Module *M, const AMDGPULibFunc &fInfo) { - std::string FuncName = fInfo.mangle(); - Function *F = dyn_cast_or_null<Function>( - M->getValueSymbolTable().lookup(FuncName)); - - // check formal with actual types conformance - if (F && !F->isDeclaration() - && !F->isVarArg() - && F->arg_size() == fInfo.getNumArgs()) { - return F; - } - return nullptr; -} - -Function *AMDGPULibFunc::getOrInsertFunction(Module *M, - const AMDGPULibFunc &fInfo) { - std::string const FuncName = fInfo.mangle(); - Function *F = dyn_cast_or_null<Function>( - M->getValueSymbolTable().lookup(FuncName)); - - // check formal with actual types conformance - if (F && !F->isDeclaration() - && !F->isVarArg() - && F->arg_size() == fInfo.getNumArgs()) { - return F; - } - - FunctionType *FuncTy = fInfo.getFunctionType(*M); - - bool hasPtr = false; - for (FunctionType::param_iterator - PI = FuncTy->param_begin(), - PE = FuncTy->param_end(); - PI != PE; ++PI) { - const Type* argTy = static_cast<const Type*>(*PI); - if (argTy->isPointerTy()) { - hasPtr = true; - break; - } - } - - Constant *C = nullptr; - if (hasPtr) { - // Do not set extra attributes for functions with pointer arguments. - C = M->getOrInsertFunction(FuncName, FuncTy); - } else { - AttributeList Attr; - LLVMContext &Ctx = M->getContext(); - Attr = Attr.addAttribute(Ctx, AttributeList::FunctionIndex, - Attribute::ReadOnly); - Attr = Attr.addAttribute(Ctx, AttributeList::FunctionIndex, - Attribute::NoUnwind); - C = M->getOrInsertFunction(FuncName, FuncTy, Attr); - } - - return cast<Function>(C); -} - -bool UnmangledFuncInfo::lookup(StringRef Name, ID &Id) { - auto Loc = Map.find(Name); - if (Loc != Map.end()) { - Id = toFuncId(Loc->second); - return true; - } - Id = AMDGPULibFunc::EI_NONE; - return false; -} - -AMDGPULibFunc::AMDGPULibFunc(const AMDGPULibFunc &F) { - if (auto *MF = dyn_cast<AMDGPUMangledLibFunc>(F.Impl.get())) - Impl.reset(new AMDGPUMangledLibFunc(*MF)); - else if (auto *UMF = dyn_cast<AMDGPUUnmangledLibFunc>(F.Impl.get())) - Impl.reset(new AMDGPUUnmangledLibFunc(*UMF)); - else - Impl = std::unique_ptr<AMDGPULibFuncImpl>(); -} - -AMDGPULibFunc &AMDGPULibFunc::operator=(const AMDGPULibFunc &F) { - if (this == &F) - return *this; - new (this) AMDGPULibFunc(F); - return *this; -} - -AMDGPULibFunc::AMDGPULibFunc(EFuncId Id, const AMDGPULibFunc &CopyFrom) { - assert(AMDGPULibFuncBase::isMangled(Id) && CopyFrom.isMangled() && - "not supported"); - Impl.reset(new AMDGPUMangledLibFunc( - Id, *cast<AMDGPUMangledLibFunc>(CopyFrom.Impl.get()))); -} - -AMDGPULibFunc::AMDGPULibFunc(StringRef Name, FunctionType *FT) { - Impl.reset(new AMDGPUUnmangledLibFunc(Name, FT)); -} - -void AMDGPULibFunc::initMangled() { Impl.reset(new AMDGPUMangledLibFunc()); } - -AMDGPULibFunc::Param *AMDGPULibFunc::getLeads() { - if (!Impl) - initMangled(); - return cast<AMDGPUMangledLibFunc>(Impl.get())->Leads; -} - -const AMDGPULibFunc::Param *AMDGPULibFunc::getLeads() const { - return cast<const AMDGPUMangledLibFunc>(Impl.get())->Leads; -} |
