brintos

brintos / llvm-project-archived public Read only

0
0
Text · 41.2 KiB · 82233c0 Raw
1192 lines · cpp
1//===-- AMDGPULibFunc.cpp -------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9//  This file contains utility functions to work with Itanium mangled names10//11//===----------------------------------------------------------------------===//12 13#include "AMDGPULibFunc.h"14#include "AMDGPU.h"15#include "llvm/ADT/StringExtras.h"16#include "llvm/ADT/StringMap.h"17#include "llvm/ADT/StringSwitch.h"18#include "llvm/IR/DerivedTypes.h"19#include "llvm/IR/Function.h"20#include "llvm/IR/Module.h"21#include "llvm/IR/ValueSymbolTable.h"22#include "llvm/Support/CommandLine.h"23#include "llvm/Support/ModRef.h"24#include "llvm/Support/raw_ostream.h"25 26using namespace llvm;27 28static cl::opt<bool> EnableOCLManglingMismatchWA(29    "amdgpu-enable-ocl-mangling-mismatch-workaround", cl::init(true),30    cl::ReallyHidden,31    cl::desc("Enable the workaround for OCL name mangling mismatch."));32 33namespace {34 35enum EManglingParam {36    E_NONE,37    EX_EVENT,38    EX_FLOAT4,39    EX_INTV4,40    EX_RESERVEDID,41    EX_SAMPLER,42    EX_SIZET,43    EX_UINT,44    EX_UINTV4,45    E_ANY,46    E_CONSTPTR_ANY,47    E_CONSTPTR_SWAPGL,48    E_COPY,49    E_IMAGECOORDS,50    E_POINTEE,51    E_SETBASE_I32,52    E_SETBASE_U32,53    E_MAKEBASE_UNS,54    E_V16_OF_POINTEE,55    E_V2_OF_POINTEE,56    E_V3_OF_POINTEE,57    E_V4_OF_POINTEE,58    E_V8_OF_POINTEE,59    E_VLTLPTR_ANY,60};61 62struct ManglingRule {63   const char *Name;64   unsigned char Lead[2];65   unsigned char Param[5];66 67   int maxLeadIndex() const { return (std::max)(Lead[0], Lead[1]); }68   int getNumLeads() const { return (Lead[0] ? 1 : 0) + (Lead[1] ? 1 : 0); }69 70   unsigned getNumArgs() const;71 72   static StringMap<int> buildManglingRulesMap();73};74 75// Information about library functions with unmangled names.76class UnmangledFuncInfo {77  const char *Name;78  unsigned NumArgs;79 80  // Table for all lib functions with unmangled names.81  static const UnmangledFuncInfo Table[];82 83  // Number of entries in Table.84  static const unsigned TableSize;85 86  static StringMap<unsigned> buildNameMap();87 88public:89  using ID = AMDGPULibFunc::EFuncId;90  constexpr UnmangledFuncInfo(const char *_Name, unsigned _NumArgs)91      : Name(_Name), NumArgs(_NumArgs) {}92  // Get index to Table by function name.93  static bool lookup(StringRef Name, ID &Id);94  static unsigned toIndex(ID Id) {95    assert(static_cast<unsigned>(Id) >96               static_cast<unsigned>(AMDGPULibFunc::EI_LAST_MANGLED) &&97           "Invalid unmangled library function");98    return static_cast<unsigned>(Id) - 1 -99           static_cast<unsigned>(AMDGPULibFunc::EI_LAST_MANGLED);100  }101  static ID toFuncId(unsigned Index) {102    assert(Index < TableSize &&103           "Invalid unmangled library function");104    return static_cast<ID>(105        Index + 1 + static_cast<unsigned>(AMDGPULibFunc::EI_LAST_MANGLED));106  }107  static unsigned getNumArgs(ID Id) { return Table[toIndex(Id)].NumArgs; }108  static StringRef getName(ID Id) { return Table[toIndex(Id)].Name; }109};110 111unsigned ManglingRule::getNumArgs() const {112   unsigned I=0;113   while (I < (sizeof Param/sizeof Param[0]) && Param[I]) ++I;114   return I;115}116 117// This table describes function formal argument type rules. The order of rules118// corresponds to the EFuncId enum at AMDGPULibFunc.h119//120// "<func name>", { <leads> }, { <param rules> }121// where:122//  <leads> - list of integers that are one-based indexes of formal argument123//    used to mangle a function name. Other argument types are derived from types124//    of these 'leads'. The order of integers in this list correspond to the125//    order in which these arguments are mangled in the EDG mangling scheme. The126//    same order should be preserved for arguments in the AMDGPULibFunc structure127//    when it is used for mangling. For example:128//    { "vstorea_half", {3,1}, {E_ANY,EX_SIZET,E_ANY}},129//    will be mangled in EDG scheme as  vstorea_half_<3dparam>_<1stparam>130//    When mangling from code use:131//    AMDGPULibFunc insc;132//    insc.param[0] = ... // describe 3rd parameter133//    insc.param[1] = ... // describe 1rd parameter134//135// <param rules> - list of rules used to derive all of the function formal136//    argument types. EX_ prefixed are simple types, other derived from the137//    latest 'lead' argument type in the order of encoding from first to last.138//    E_ANY - use prev lead type, E_CONSTPTR_ANY - make const pointer out of139//    prev lead type, etc. see ParamIterator::getNextParam() for details.140 141static constexpr ManglingRule manglingRules[] = {142{ "", {0}, {0} },143{ "abs"                             , {1},   {E_ANY}},144{ "abs_diff"                        , {1},   {E_ANY,E_COPY}},145{ "acos"                            , {1},   {E_ANY}},146{ "acosh"                           , {1},   {E_ANY}},147{ "acospi"                          , {1},   {E_ANY}},148{ "add_sat"                         , {1},   {E_ANY,E_COPY}},149{ "all"                             , {1},   {E_ANY}},150{ "any"                             , {1},   {E_ANY}},151{ "asin"                            , {1},   {E_ANY}},152{ "asinh"                           , {1},   {E_ANY}},153{ "asinpi"                          , {1},   {E_ANY}},154{ "async_work_group_copy"           , {1},   {E_ANY,E_CONSTPTR_SWAPGL,EX_SIZET,EX_EVENT}},155{ "async_work_group_strided_copy"   , {1},   {E_ANY,E_CONSTPTR_SWAPGL,EX_SIZET,EX_SIZET,EX_EVENT}},156{ "atan"                            , {1},   {E_ANY}},157{ "atan2"                           , {1},   {E_ANY,E_COPY}},158{ "atan2pi"                         , {1},   {E_ANY,E_COPY}},159{ "atanh"                           , {1},   {E_ANY}},160{ "atanpi"                          , {1},   {E_ANY}},161{ "atomic_add"                      , {1},   {E_VLTLPTR_ANY,E_POINTEE}},162{ "atomic_and"                      , {1},   {E_VLTLPTR_ANY,E_POINTEE}},163{ "atomic_cmpxchg"                  , {1},   {E_VLTLPTR_ANY,E_POINTEE,E_POINTEE}},164{ "atomic_dec"                      , {1},   {E_VLTLPTR_ANY}},165{ "atomic_inc"                      , {1},   {E_VLTLPTR_ANY}},166{ "atomic_max"                      , {1},   {E_VLTLPTR_ANY,E_POINTEE}},167{ "atomic_min"                      , {1},   {E_VLTLPTR_ANY,E_POINTEE}},168{ "atomic_or"                       , {1},   {E_VLTLPTR_ANY,E_POINTEE}},169{ "atomic_sub"                      , {1},   {E_VLTLPTR_ANY,E_POINTEE}},170{ "atomic_xchg"                     , {1},   {E_VLTLPTR_ANY,E_POINTEE}},171{ "atomic_xor"                      , {1},   {E_VLTLPTR_ANY,E_POINTEE}},172{ "bitselect"                       , {1},   {E_ANY,E_COPY,E_COPY}},173{ "cbrt"                            , {1},   {E_ANY}},174{ "ceil"                            , {1},   {E_ANY}},175{ "clamp"                           , {1},   {E_ANY,E_COPY,E_COPY}},176{ "clz"                             , {1},   {E_ANY}},177{ "commit_read_pipe"                , {1},   {E_ANY,EX_RESERVEDID}},178{ "commit_write_pipe"               , {1},   {E_ANY,EX_RESERVEDID}},179{ "copysign"                        , {1},   {E_ANY,E_COPY}},180{ "cos"                             , {1},   {E_ANY}},181{ "cosh"                            , {1},   {E_ANY}},182{ "cospi"                           , {1},   {E_ANY}},183{ "cross"                           , {1},   {E_ANY,E_COPY}},184{ "ctz"                             , {1},   {E_ANY}},185{ "degrees"                         , {1},   {E_ANY}},186{ "distance"                        , {1},   {E_ANY,E_COPY}},187{ "divide"                          , {1},   {E_ANY,E_COPY}},188{ "dot"                             , {1},   {E_ANY,E_COPY}},189{ "erf"                             , {1},   {E_ANY}},190{ "erfc"                            , {1},   {E_ANY}},191{ "exp"                             , {1},   {E_ANY}},192{ "exp10"                           , {1},   {E_ANY}},193{ "exp2"                            , {1},   {E_ANY}},194{ "expm1"                           , {1},   {E_ANY}},195{ "fabs"                            , {1},   {E_ANY}},196{ "fast_distance"                   , {1},   {E_ANY,E_COPY}},197{ "fast_length"                     , {1},   {E_ANY}},198{ "fast_normalize"                  , {1},   {E_ANY}},199{ "fdim"                            , {1},   {E_ANY,E_COPY}},200{ "floor"                           , {1},   {E_ANY}},201{ "fma"                             , {1},   {E_ANY,E_COPY,E_COPY}},202{ "fmax"                            , {1},   {E_ANY,E_COPY}},203{ "fmin"                            , {1},   {E_ANY,E_COPY}},204{ "fmod"                            , {1},   {E_ANY,E_COPY}},205{ "fract"                           , {2},   {E_POINTEE,E_ANY}},206{ "frexp"                           , {1,2}, {E_ANY,E_ANY}},207{ "get_image_array_size"            , {1},   {E_ANY}},208{ "get_image_channel_data_type"     , {1},   {E_ANY}},209{ "get_image_channel_order"         , {1},   {E_ANY}},210{ "get_image_dim"                   , {1},   {E_ANY}},211{ "get_image_height"                , {1},   {E_ANY}},212{ "get_image_width"                 , {1},   {E_ANY}},213{ "get_pipe_max_packets"            , {1},   {E_ANY}},214{ "get_pipe_num_packets"            , {1},   {E_ANY}},215{ "hadd"                            , {1},   {E_ANY,E_COPY}},216{ "hypot"                           , {1},   {E_ANY,E_COPY}},217{ "ilogb"                           , {1},   {E_ANY}},218{ "isequal"                         , {1},   {E_ANY,E_COPY}},219{ "isfinite"                        , {1},   {E_ANY}},220{ "isgreater"                       , {1},   {E_ANY,E_COPY}},221{ "isgreaterequal"                  , {1},   {E_ANY,E_COPY}},222{ "isinf"                           , {1},   {E_ANY}},223{ "isless"                          , {1},   {E_ANY,E_COPY}},224{ "islessequal"                     , {1},   {E_ANY,E_COPY}},225{ "islessgreater"                   , {1},   {E_ANY,E_COPY}},226{ "isnan"                           , {1},   {E_ANY}},227{ "isnormal"                        , {1},   {E_ANY}},228{ "isnotequal"                      , {1},   {E_ANY,E_COPY}},229{ "isordered"                       , {1},   {E_ANY,E_COPY}},230{ "isunordered"                     , {1},   {E_ANY,E_COPY}},231{ "ldexp"                           , {1},   {E_ANY,E_SETBASE_I32}},232{ "length"                          , {1},   {E_ANY}},233{ "lgamma"                          , {1},   {E_ANY}},234{ "lgamma_r"                        , {1,2}, {E_ANY,E_ANY}},235{ "log"                             , {1},   {E_ANY}},236{ "log10"                           , {1},   {E_ANY}},237{ "log1p"                           , {1},   {E_ANY}},238{ "log2"                            , {1},   {E_ANY}},239{ "logb"                            , {1},   {E_ANY}},240{ "mad"                             , {1},   {E_ANY,E_COPY,E_COPY}},241{ "mad24"                           , {1},   {E_ANY,E_COPY,E_COPY}},242{ "mad_hi"                          , {1},   {E_ANY,E_COPY,E_COPY}},243{ "mad_sat"                         , {1},   {E_ANY,E_COPY,E_COPY}},244{ "max"                             , {1},   {E_ANY,E_COPY}},245{ "maxmag"                          , {1},   {E_ANY,E_COPY}},246{ "min"                             , {1},   {E_ANY,E_COPY}},247{ "minmag"                          , {1},   {E_ANY,E_COPY}},248{ "mix"                             , {1},   {E_ANY,E_COPY,E_COPY}},249{ "modf"                            , {2},   {E_POINTEE,E_ANY}},250{ "mul24"                           , {1},   {E_ANY,E_COPY}},251{ "mul_hi"                          , {1},   {E_ANY,E_COPY}},252{ "nan"                             , {1},   {E_ANY}},253{ "nextafter"                       , {1},   {E_ANY,E_COPY}},254{ "normalize"                       , {1},   {E_ANY}},255{ "popcount"                        , {1},   {E_ANY}},256{ "pow"                             , {1},   {E_ANY,E_COPY}},257{ "pown"                            , {1},   {E_ANY,E_SETBASE_I32}},258{ "powr"                            , {1},   {E_ANY,E_COPY}},259{ "prefetch"                        , {1},   {E_CONSTPTR_ANY,EX_SIZET}},260{ "radians"                         , {1},   {E_ANY}},261{ "recip"                           , {1},   {E_ANY}},262{ "remainder"                       , {1},   {E_ANY,E_COPY}},263{ "remquo"                          , {1,3}, {E_ANY,E_COPY,E_ANY}},264{ "reserve_read_pipe"               , {1},   {E_ANY,EX_UINT}},265{ "reserve_write_pipe"              , {1},   {E_ANY,EX_UINT}},266{ "rhadd"                           , {1},   {E_ANY,E_COPY}},267{ "rint"                            , {1},   {E_ANY}},268{ "rootn"                           , {1},   {E_ANY,E_SETBASE_I32}},269{ "rotate"                          , {1},   {E_ANY,E_COPY}},270{ "round"                           , {1},   {E_ANY}},271{ "rsqrt"                           , {1},   {E_ANY}},272{ "select"                          , {1,3}, {E_ANY,E_COPY,E_ANY}},273{ "shuffle"                         , {1,2}, {E_ANY,E_ANY}},274{ "shuffle2"                        , {1,3}, {E_ANY,E_COPY,E_ANY}},275{ "sign"                            , {1},   {E_ANY}},276{ "signbit"                         , {1},   {E_ANY}},277{ "sin"                             , {1},   {E_ANY}},278{ "sincos"                          , {2},   {E_POINTEE,E_ANY}},279{ "sinh"                            , {1},   {E_ANY}},280{ "sinpi"                           , {1},   {E_ANY}},281{ "smoothstep"                      , {1},   {E_ANY,E_COPY,E_COPY}},282{ "sqrt"                            , {1},   {E_ANY}},283{ "step"                            , {1},   {E_ANY,E_COPY}},284{ "sub_group_broadcast"             , {1},   {E_ANY,EX_UINT}},285{ "sub_group_commit_read_pipe"      , {1},   {E_ANY,EX_RESERVEDID}},286{ "sub_group_commit_write_pipe"     , {1},   {E_ANY,EX_RESERVEDID}},287{ "sub_group_reduce_add"            , {1},   {E_ANY}},288{ "sub_group_reduce_max"            , {1},   {E_ANY}},289{ "sub_group_reduce_min"            , {1},   {E_ANY}},290{ "sub_group_reserve_read_pipe"     , {1},   {E_ANY,EX_UINT}},291{ "sub_group_reserve_write_pipe"    , {1},   {E_ANY,EX_UINT}},292{ "sub_group_scan_exclusive_add"    , {1},   {E_ANY}},293{ "sub_group_scan_exclusive_max"    , {1},   {E_ANY}},294{ "sub_group_scan_exclusive_min"    , {1},   {E_ANY}},295{ "sub_group_scan_inclusive_add"    , {1},   {E_ANY}},296{ "sub_group_scan_inclusive_max"    , {1},   {E_ANY}},297{ "sub_group_scan_inclusive_min"    , {1},   {E_ANY}},298{ "sub_sat"                         , {1},   {E_ANY,E_COPY}},299{ "tan"                             , {1},   {E_ANY}},300{ "tanh"                            , {1},   {E_ANY}},301{ "tanpi"                           , {1},   {E_ANY}},302{ "tgamma"                          , {1},   {E_ANY}},303{ "trunc"                           , {1},   {E_ANY}},304{ "upsample"                        , {1},   {E_ANY,E_MAKEBASE_UNS}},305{ "vec_step"                        , {1},   {E_ANY}},306{ "vstore"                          , {3},   {E_POINTEE,EX_SIZET,E_ANY}},307{ "vstore16"                        , {3},   {E_V16_OF_POINTEE,EX_SIZET,E_ANY}},308{ "vstore2"                         , {3},   {E_V2_OF_POINTEE,EX_SIZET,E_ANY}},309{ "vstore3"                         , {3},   {E_V3_OF_POINTEE,EX_SIZET,E_ANY}},310{ "vstore4"                         , {3},   {E_V4_OF_POINTEE,EX_SIZET,E_ANY}},311{ "vstore8"                         , {3},   {E_V8_OF_POINTEE,EX_SIZET,E_ANY}},312{ "work_group_commit_read_pipe"     , {1},   {E_ANY,EX_RESERVEDID}},313{ "work_group_commit_write_pipe"    , {1},   {E_ANY,EX_RESERVEDID}},314{ "work_group_reduce_add"           , {1},   {E_ANY}},315{ "work_group_reduce_max"           , {1},   {E_ANY}},316{ "work_group_reduce_min"           , {1},   {E_ANY}},317{ "work_group_reserve_read_pipe"    , {1},   {E_ANY,EX_UINT}},318{ "work_group_reserve_write_pipe"   , {1},   {E_ANY,EX_UINT}},319{ "work_group_scan_exclusive_add"   , {1},   {E_ANY}},320{ "work_group_scan_exclusive_max"   , {1},   {E_ANY}},321{ "work_group_scan_exclusive_min"   , {1},   {E_ANY}},322{ "work_group_scan_inclusive_add"   , {1},   {E_ANY}},323{ "work_group_scan_inclusive_max"   , {1},   {E_ANY}},324{ "work_group_scan_inclusive_min"   , {1},   {E_ANY}},325{ "write_imagef"                    , {1},   {E_ANY,E_IMAGECOORDS,EX_FLOAT4}},326{ "write_imagei"                    , {1},   {E_ANY,E_IMAGECOORDS,EX_INTV4}},327{ "write_imageui"                   , {1},   {E_ANY,E_IMAGECOORDS,EX_UINTV4}},328{ "ncos"                            , {1},   {E_ANY} },329{ "nexp2"                           , {1},   {E_ANY} },330{ "nfma"                            , {1},   {E_ANY, E_COPY, E_COPY} },331{ "nlog2"                           , {1},   {E_ANY} },332{ "nrcp"                            , {1},   {E_ANY} },333{ "nrsqrt"                          , {1},   {E_ANY} },334{ "nsin"                            , {1},   {E_ANY} },335{ "nsqrt"                           , {1},   {E_ANY} },336{ "ftz"                             , {1},   {E_ANY} },337{ "fldexp"                          , {1},   {E_ANY, EX_UINT} },338{ "class"                           , {1},   {E_ANY, EX_UINT} },339{ "rcbrt"                           , {1},   {E_ANY} },340};341 342// Library functions with unmangled name.343const UnmangledFuncInfo UnmangledFuncInfo::Table[] = {344    {"__read_pipe_2", 4},345    {"__read_pipe_4", 6},346    {"__write_pipe_2", 4},347    {"__write_pipe_4", 6},348};349 350const unsigned UnmangledFuncInfo::TableSize =351    std::size(UnmangledFuncInfo::Table);352 353static AMDGPULibFunc::Param getRetType(AMDGPULibFunc::EFuncId id,354                                       const AMDGPULibFunc::Param (&Leads)[2]) {355  AMDGPULibFunc::Param Res = Leads[0];356  // TBD - This switch may require to be extended for other intrinsics357  switch (id) {358  case AMDGPULibFunc::EI_SINCOS:359    Res.PtrKind = AMDGPULibFunc::BYVALUE;360    break;361  default:362    break;363  }364  return Res;365}366 367class ParamIterator {368  const AMDGPULibFunc::Param (&Leads)[2];369  const ManglingRule& Rule;370  int Index = 0;371public:372  ParamIterator(const AMDGPULibFunc::Param (&leads)[2],373                const ManglingRule& rule)374    : Leads(leads), Rule(rule) {}375 376  AMDGPULibFunc::Param getNextParam();377};378 379AMDGPULibFunc::Param ParamIterator::getNextParam() {380  AMDGPULibFunc::Param P;381  if (Index >= int(sizeof Rule.Param/sizeof Rule.Param[0])) return P;382 383  const char R = Rule.Param[Index];384  switch (R) {385  case E_NONE:     break;386  case EX_UINT:387    P.ArgType = AMDGPULibFunc::U32; break;388  case EX_INTV4:389    P.ArgType = AMDGPULibFunc::I32; P.VectorSize = 4; break;390  case EX_UINTV4:391    P.ArgType = AMDGPULibFunc::U32; P.VectorSize = 4; break;392  case EX_FLOAT4:393    P.ArgType = AMDGPULibFunc::F32; P.VectorSize = 4; break;394  case EX_SIZET:395    P.ArgType = AMDGPULibFunc::U64; break;396  case EX_EVENT:397    P.ArgType = AMDGPULibFunc::EVENT;   break;398  case EX_SAMPLER:399    P.ArgType = AMDGPULibFunc::SAMPLER; break;400  case EX_RESERVEDID: break; // TBD401  default:402    if (Index == (Rule.Lead[1] - 1)) P = Leads[1];403    else P = Leads[0];404 405    switch (R) {406    case E_ANY:407    case E_COPY: break;408 409    case E_POINTEE:410      P.PtrKind = AMDGPULibFunc::BYVALUE; break;411    case E_V2_OF_POINTEE:412      P.VectorSize = 2; P.PtrKind = AMDGPULibFunc::BYVALUE; break;413    case E_V3_OF_POINTEE:414      P.VectorSize = 3; P.PtrKind = AMDGPULibFunc::BYVALUE; break;415    case E_V4_OF_POINTEE:416      P.VectorSize = 4; P.PtrKind = AMDGPULibFunc::BYVALUE; break;417    case E_V8_OF_POINTEE:418      P.VectorSize = 8; P.PtrKind = AMDGPULibFunc::BYVALUE; break;419    case E_V16_OF_POINTEE:420      P.VectorSize = 16; P.PtrKind = AMDGPULibFunc::BYVALUE; break;421    case E_CONSTPTR_ANY:422      P.PtrKind |= AMDGPULibFunc::CONST; break;423    case E_VLTLPTR_ANY:424      P.PtrKind |= AMDGPULibFunc::VOLATILE; break;425    case E_SETBASE_I32:426      P.ArgType = AMDGPULibFunc::I32; break;427    case E_SETBASE_U32:428      P.ArgType = AMDGPULibFunc::U32; break;429 430    case E_MAKEBASE_UNS:431      P.ArgType &= ~AMDGPULibFunc::BASE_TYPE_MASK;432      P.ArgType |= AMDGPULibFunc::UINT;433      break;434 435    case E_IMAGECOORDS:436      switch (P.ArgType) {437      case AMDGPULibFunc::IMG1DA: P.VectorSize = 2; break;438      case AMDGPULibFunc::IMG1DB: P.VectorSize = 1; break;439      case AMDGPULibFunc::IMG2DA: P.VectorSize = 4; break;440      case AMDGPULibFunc::IMG1D:  P.VectorSize = 1; break;441      case AMDGPULibFunc::IMG2D:  P.VectorSize = 2; break;442      case AMDGPULibFunc::IMG3D:  P.VectorSize = 4; break;443      }444      P.PtrKind = AMDGPULibFunc::BYVALUE;445      P.ArgType = AMDGPULibFunc::I32;446      break;447 448    case E_CONSTPTR_SWAPGL: {449      unsigned AS = AMDGPULibFunc::getAddrSpaceFromEPtrKind(P.PtrKind);450      switch (AS) {451      case AMDGPUAS::GLOBAL_ADDRESS: AS = AMDGPUAS::LOCAL_ADDRESS; break;452      case AMDGPUAS::LOCAL_ADDRESS:  AS = AMDGPUAS::GLOBAL_ADDRESS; break;453      }454      P.PtrKind = AMDGPULibFunc::getEPtrKindFromAddrSpace(AS);455      P.PtrKind |= AMDGPULibFunc::CONST;456      break;457    }458 459    default:460      llvm_unreachable("Unhandled param rule");461    }462  }463  ++Index;464  return P;465}466 467inline static void drop_front(StringRef& str, size_t n = 1) {468  str = str.drop_front(n);469}470 471static bool eatTerm(StringRef& mangledName, const char c) {472  if (mangledName.front() == c) {473    drop_front(mangledName);474    return true;475  }476  return false;477}478 479template <size_t N>480static bool eatTerm(StringRef& mangledName, const char (&str)[N]) {481  if (mangledName.starts_with(StringRef(str, N - 1))) {482    drop_front(mangledName, N-1);483    return true;484  }485  return false;486}487 488static int eatNumber(StringRef& s) {489  size_t const savedSize = s.size();490  int n = 0;491  while (!s.empty() && isDigit(s.front())) {492    n = n*10 + s.front() - '0';493    drop_front(s);494  }495  return s.size() < savedSize ? n : -1;496}497 498static StringRef eatLengthPrefixedName(StringRef& mangledName) {499  int const Len = eatNumber(mangledName);500  if (Len <= 0 || static_cast<size_t>(Len) > mangledName.size())501    return StringRef();502  StringRef Res = mangledName.substr(0, Len);503  drop_front(mangledName, Len);504  return Res;505}506 507} // end anonymous namespace508 509AMDGPUMangledLibFunc::AMDGPUMangledLibFunc() {510  FuncId = EI_NONE;511  FKind = NOPFX;512  Leads[0].reset();513  Leads[1].reset();514  Name.clear();515}516 517AMDGPUUnmangledLibFunc::AMDGPUUnmangledLibFunc() {518  FuncId = EI_NONE;519  FuncTy = nullptr;520}521 522AMDGPUMangledLibFunc::AMDGPUMangledLibFunc(523    EFuncId id, const AMDGPUMangledLibFunc &copyFrom) {524  FuncId = id;525  FKind = copyFrom.FKind;526  Leads[0] = copyFrom.Leads[0];527  Leads[1] = copyFrom.Leads[1];528}529 530AMDGPUMangledLibFunc::AMDGPUMangledLibFunc(EFuncId id, FunctionType *FT,531                                           bool SignedInts) {532  FuncId = id;533  unsigned NumArgs = FT->getNumParams();534  if (NumArgs >= 1)535    Leads[0] = Param::getFromTy(FT->getParamType(0), SignedInts);536  if (NumArgs >= 2)537    Leads[1] = Param::getFromTy(FT->getParamType(1), SignedInts);538}539 540///////////////////////////////////////////////////////////////////////////////541// Demangling542 543static int parseVecSize(StringRef& mangledName) {544  size_t const Len = eatNumber(mangledName);545  switch (Len) {546  case 2: case 3: case 4: case 8: case 16:547    return Len;548  default:549    break;550  }551  return 1;552}553 554static AMDGPULibFunc::ENamePrefix parseNamePrefix(StringRef& mangledName) {555  std::pair<StringRef, StringRef> const P = mangledName.split('_');556  AMDGPULibFunc::ENamePrefix Pfx =557    StringSwitch<AMDGPULibFunc::ENamePrefix>(P.first)558    .Case("native", AMDGPULibFunc::NATIVE)559    .Case("half"  , AMDGPULibFunc::HALF)560    .Default(AMDGPULibFunc::NOPFX);561 562  if (Pfx != AMDGPULibFunc::NOPFX)563    mangledName = P.second;564 565  return Pfx;566}567 568StringMap<int> ManglingRule::buildManglingRulesMap() {569  StringMap<int> Map(std::size(manglingRules));570  int Id = 0;571  for (auto Rule : manglingRules)572    Map.insert({Rule.Name, Id++});573  return Map;574}575 576bool AMDGPUMangledLibFunc::parseUnmangledName(StringRef FullName) {577  static const StringMap<int> manglingRulesMap =578      ManglingRule::buildManglingRulesMap();579  FuncId = static_cast<EFuncId>(manglingRulesMap.lookup(FullName));580  return FuncId != EI_NONE;581}582 583///////////////////////////////////////////////////////////////////////////////584// Itanium Demangling585 586namespace {587struct ItaniumParamParser {588  AMDGPULibFunc::Param Prev;589  bool parseItaniumParam(StringRef& param, AMDGPULibFunc::Param &res);590};591} // namespace592 593bool ItaniumParamParser::parseItaniumParam(StringRef& param,594                                           AMDGPULibFunc::Param &res) {595  res.reset();596  if (param.empty()) return false;597 598  // parse pointer prefix599  if (eatTerm(param, 'P')) {600    if (eatTerm(param, 'K')) res.PtrKind |= AMDGPULibFunc::CONST;601    if (eatTerm(param, 'V')) res.PtrKind |= AMDGPULibFunc::VOLATILE;602    unsigned AS;603    if (!eatTerm(param, "U3AS")) {604      AS = 0;605    } else {606      AS = param.front() - '0';607      drop_front(param, 1);608    }609    res.PtrKind |= AMDGPULibFuncBase::getEPtrKindFromAddrSpace(AS);610  } else {611    res.PtrKind = AMDGPULibFunc::BYVALUE;612  }613 614  // parse vector size615  if (eatTerm(param,"Dv")) {616    res.VectorSize = parseVecSize(param);617    if (res.VectorSize==1 || !eatTerm(param, '_')) return false;618  }619 620  // parse type621  char const TC = param.front();622  if (isDigit(TC)) {623    res.ArgType =624        StringSwitch<AMDGPULibFunc::EType>(eatLengthPrefixedName(param))625            .StartsWith("ocl_image1d_array", AMDGPULibFunc::IMG1DA)626            .StartsWith("ocl_image1d_buffer", AMDGPULibFunc::IMG1DB)627            .StartsWith("ocl_image2d_array", AMDGPULibFunc::IMG2DA)628            .StartsWith("ocl_image1d", AMDGPULibFunc::IMG1D)629            .StartsWith("ocl_image2d", AMDGPULibFunc::IMG2D)630            .StartsWith("ocl_image3d", AMDGPULibFunc::IMG3D)631            .Case("ocl_event", AMDGPULibFunc::DUMMY)632            .Case("ocl_sampler", AMDGPULibFunc::DUMMY)633            .Default(AMDGPULibFunc::DUMMY);634  } else {635    drop_front(param);636    switch (TC) {637    case 'h': res.ArgType =  AMDGPULibFunc::U8; break;638    case 't': res.ArgType = AMDGPULibFunc::U16; break;639    case 'j': res.ArgType = AMDGPULibFunc::U32; break;640    case 'm': res.ArgType = AMDGPULibFunc::U64; break;641    case 'c': res.ArgType =  AMDGPULibFunc::I8; break;642    case 's': res.ArgType = AMDGPULibFunc::I16; break;643    case 'i': res.ArgType = AMDGPULibFunc::I32; break;644    case 'l': res.ArgType = AMDGPULibFunc::I64; break;645    case 'f': res.ArgType = AMDGPULibFunc::F32; break;646    case 'd': res.ArgType = AMDGPULibFunc::F64; break;647    case 'D': if (!eatTerm(param, 'h')) return false;648              res.ArgType = AMDGPULibFunc::F16; break;649    case 'S':650      if (!eatTerm(param, '_')) {651        eatNumber(param);652        if (!eatTerm(param, '_')) return false;653      }654      res.VectorSize = Prev.VectorSize;655      res.ArgType    = Prev.ArgType;656      break;657    default:;658    }659  }660  if (res.ArgType == 0) return false;661  Prev.VectorSize = res.VectorSize;662  Prev.ArgType    = res.ArgType;663  return true;664}665 666bool AMDGPUMangledLibFunc::parseFuncName(StringRef &mangledName) {667  StringRef Name = eatLengthPrefixedName(mangledName);668  FKind = parseNamePrefix(Name);669  if (!parseUnmangledName(Name))670    return false;671 672  const ManglingRule& Rule = manglingRules[FuncId];673  ItaniumParamParser Parser;674  for (int I=0; I < Rule.maxLeadIndex(); ++I) {675    Param P;676    if (!Parser.parseItaniumParam(mangledName, P))677      return false;678 679    if ((I + 1) == Rule.Lead[0]) Leads[0] = P;680    if ((I + 1) == Rule.Lead[1]) Leads[1] = P;681  }682  return true;683}684 685bool AMDGPUUnmangledLibFunc::parseFuncName(StringRef &Name) {686  if (!UnmangledFuncInfo::lookup(Name, FuncId))687    return false;688  setName(Name);689  return true;690}691 692bool AMDGPULibFunc::parse(StringRef FuncName, AMDGPULibFunc &F) {693  if (FuncName.empty()) {694    F.Impl = std::unique_ptr<AMDGPULibFuncImpl>();695    return false;696  }697 698  if (eatTerm(FuncName, "_Z"))699    F.Impl = std::make_unique<AMDGPUMangledLibFunc>();700  else701    F.Impl = std::make_unique<AMDGPUUnmangledLibFunc>();702  if (F.Impl->parseFuncName(FuncName))703    return true;704 705  F.Impl = std::unique_ptr<AMDGPULibFuncImpl>();706  return false;707}708 709StringRef AMDGPUMangledLibFunc::getUnmangledName(StringRef mangledName) {710  StringRef S = mangledName;711  if (eatTerm(S, "_Z"))712    return eatLengthPrefixedName(S);713  return StringRef();714}715 716///////////////////////////////////////////////////////////////////////////////717// Mangling718 719template <typename Stream>720void AMDGPUMangledLibFunc::writeName(Stream &OS) const {721  const char *Pfx = "";722  switch (FKind) {723  case NATIVE: Pfx = "native_"; break;724  case HALF:   Pfx = "half_";   break;725  default: break;726  }727  if (!Name.empty()) {728    OS << Pfx << Name;729  } else if (FuncId != EI_NONE) {730    OS << Pfx;731    const StringRef& S = manglingRules[FuncId].Name;732    OS.write(S.data(), S.size());733  }734}735 736std::string AMDGPUMangledLibFunc::mangle() const { return mangleNameItanium(); }737 738///////////////////////////////////////////////////////////////////////////////739// Itanium Mangling740 741static const char *getItaniumTypeName(AMDGPULibFunc::EType T) {742  switch (T) {743  case AMDGPULibFunc::U8:      return "h";744  case AMDGPULibFunc::U16:     return "t";745  case AMDGPULibFunc::U32:     return "j";746  case AMDGPULibFunc::U64:     return "m";747  case AMDGPULibFunc::I8:      return "c";748  case AMDGPULibFunc::I16:     return "s";749  case AMDGPULibFunc::I32:     return "i";750  case AMDGPULibFunc::I64:     return "l";751  case AMDGPULibFunc::F16:     return "Dh";752  case AMDGPULibFunc::F32:     return "f";753  case AMDGPULibFunc::F64:     return "d";754  case AMDGPULibFunc::IMG1DA:  return "16ocl_image1darray";755  case AMDGPULibFunc::IMG1DB:  return "17ocl_image1dbuffer";756  case AMDGPULibFunc::IMG2DA:  return "16ocl_image2darray";757  case AMDGPULibFunc::IMG1D:   return "11ocl_image1d";758  case AMDGPULibFunc::IMG2D:   return "11ocl_image2d";759  case AMDGPULibFunc::IMG3D:   return "11ocl_image3d";760  case AMDGPULibFunc::SAMPLER: return "11ocl_sampler";761  case AMDGPULibFunc::EVENT:   return "9ocl_event";762  default:763    llvm_unreachable("Unhandled param type");764  }765  return nullptr;766}767 768namespace {769// Itanium mangling ABI says:770// "5.1.8. Compression771// ... Each non-terminal in the grammar for which <substitution> appears on the772// right-hand side is both a source of future substitutions and a candidate773// for being substituted. There are two exceptions that appear to be774// substitution candidates from the grammar, but are explicitly excluded:775// 1. <builtin-type> other than vendor extended types ..."776 777// For the purpose of functions the following productions make sense for the778// substitution:779//  <type> ::= <builtin-type>780//    ::= <class-enum-type>781//    ::= <array-type>782//    ::=<CV-qualifiers> <type>783//    ::= P <type>                # pointer-to784//    ::= <substitution>785//786// Note that while types like images, samplers and events are by the ABI encoded787// using <class-enum-type> production rule they're not used for substitution788// because clang consider them as builtin types.789//790// DvNN_ type is GCC extension for vectors and is a subject for the791// substitution.792 793class ItaniumMangler {794  SmallVector<AMDGPULibFunc::Param, 10> Str; // list of accumulated substitutions795  bool  UseAddrSpace;796 797  int findSubst(const AMDGPULibFunc::Param& P) const {798    for(unsigned I = 0; I < Str.size(); ++I) {799      const AMDGPULibFunc::Param& T = Str[I];800      if (P.PtrKind    == T.PtrKind &&801          P.VectorSize == T.VectorSize &&802          P.ArgType    == T.ArgType) {803        return I;804      }805    }806    return -1;807  }808 809  template <typename Stream>810  bool trySubst(Stream& os, const AMDGPULibFunc::Param& p) {811    int const subst = findSubst(p);812    if (subst < 0) return false;813    // Substitutions are mangled as S(XX)?_ where XX is a hexadecimal number814    // 0   1    2815    // S_  S0_  S1_816    if (subst == 0) os << "S_";817    else os << 'S' << (subst-1) << '_';818    return true;819  }820 821public:822  ItaniumMangler(bool useAddrSpace)823    : UseAddrSpace(useAddrSpace) {}824 825  template <typename Stream>826  void operator()(Stream& os, AMDGPULibFunc::Param p) {827 828    // Itanium mangling ABI 5.1.8. Compression:829    // Logically, the substitutable components of a mangled name are considered830    // left-to-right, components before the composite structure of which they831    // are a part. If a component has been encountered before, it is substituted832    // as described below. This decision is independent of whether its components833    // have been substituted, so an implementation may optimize by considering834    // large structures for substitution before their components. If a component835    // has not been encountered before, its mangling is identified, and it is836    // added to a dictionary of substitution candidates. No entity is added to837    // the dictionary twice.838    AMDGPULibFunc::Param Ptr;839 840    if (p.PtrKind) {841      if (trySubst(os, p)) return;842      os << 'P';843      if (p.PtrKind & AMDGPULibFunc::CONST) os << 'K';844      if (p.PtrKind & AMDGPULibFunc::VOLATILE) os << 'V';845      unsigned AS = UseAddrSpace846                        ? AMDGPULibFuncBase::getAddrSpaceFromEPtrKind(p.PtrKind)847                        : 0;848      if (EnableOCLManglingMismatchWA || AS != 0)849        os << "U3AS" << AS;850      Ptr = p;851      p.PtrKind = 0;852    }853 854    if (p.VectorSize > 1) {855      if (trySubst(os, p)) goto exit;856      Str.push_back(p);857      os << "Dv" << static_cast<unsigned>(p.VectorSize) << '_';858    }859 860    os << getItaniumTypeName((AMDGPULibFunc::EType)p.ArgType);861 862  exit:863    if (Ptr.ArgType) Str.push_back(Ptr);864  }865};866} // namespace867 868std::string AMDGPUMangledLibFunc::mangleNameItanium() const {869  SmallString<128> Buf;870  raw_svector_ostream S(Buf);871  SmallString<128> NameBuf;872  raw_svector_ostream Name(NameBuf);873  writeName(Name);874  const StringRef& NameStr = Name.str();875  S << "_Z" << static_cast<int>(NameStr.size()) << NameStr;876 877  ItaniumMangler Mangler(true);878  ParamIterator I(Leads, manglingRules[FuncId]);879  Param P;880  while ((P = I.getNextParam()).ArgType != 0)881    Mangler(S, P);882  return std::string(S.str());883}884 885///////////////////////////////////////////////////////////////////////////////886// Misc887 888AMDGPULibFuncBase::Param AMDGPULibFuncBase::Param::getFromTy(Type *Ty,889                                                             bool Signed) {890  Param P;891  if (FixedVectorType *VT = dyn_cast<FixedVectorType>(Ty)) {892    P.VectorSize = VT->getNumElements();893    Ty = VT->getElementType();894  }895 896  switch (Ty->getTypeID()) {897  case Type::FloatTyID:898    P.ArgType = AMDGPULibFunc::F32;899    break;900  case Type::DoubleTyID:901    P.ArgType = AMDGPULibFunc::F64;902    break;903  case Type::HalfTyID:904    P.ArgType = AMDGPULibFunc::F16;905    break;906  case Type::IntegerTyID:907    switch (cast<IntegerType>(Ty)->getBitWidth()) {908    case 8:909      P.ArgType = Signed ? AMDGPULibFunc::I8 : AMDGPULibFunc::U8;910      break;911    case 16:912      P.ArgType = Signed ? AMDGPULibFunc::I16 : AMDGPULibFunc::U16;913      break;914    case 32:915      P.ArgType = Signed ? AMDGPULibFunc::I32 : AMDGPULibFunc::U32;916      break;917    case 64:918      P.ArgType = Signed ? AMDGPULibFunc::I64 : AMDGPULibFunc::U64;919      break;920    default:921      llvm_unreachable("unhandled libcall argument type");922    }923 924    break;925  default:926    llvm_unreachable("unhandled libcall argument type");927  }928 929  return P;930}931 932static Type *getIntrinsicParamType(LLVMContext &C,933                                   const AMDGPULibFunc::Param &P,934                                   bool UseAddrSpace) {935  Type *T = nullptr;936  switch (P.ArgType) {937  default:938    return nullptr;939  case AMDGPULibFunc::U8:940  case AMDGPULibFunc::I8:941    T = Type::getInt8Ty(C);942    break;943  case AMDGPULibFunc::U16:944  case AMDGPULibFunc::I16:945    T = Type::getInt16Ty(C);946    break;947  case AMDGPULibFunc::U32:948  case AMDGPULibFunc::I32:949    T = Type::getInt32Ty(C);950    break;951  case AMDGPULibFunc::U64:952  case AMDGPULibFunc::I64:953    T = Type::getInt64Ty(C);954    break;955  case AMDGPULibFunc::F16:956    T = Type::getHalfTy(C);957    break;958  case AMDGPULibFunc::F32:959    T = Type::getFloatTy(C);960    break;961  case AMDGPULibFunc::F64:962    T = Type::getDoubleTy(C);963    break;964 965  case AMDGPULibFunc::IMG1DA:966  case AMDGPULibFunc::IMG1DB:967  case AMDGPULibFunc::IMG2DA:968  case AMDGPULibFunc::IMG1D:969  case AMDGPULibFunc::IMG2D:970  case AMDGPULibFunc::IMG3D:971  case AMDGPULibFunc::SAMPLER:972  case AMDGPULibFunc::EVENT:973    T = PointerType::getUnqual(C);974    break;975  case AMDGPULibFunc::B8:976  case AMDGPULibFunc::B16:977  case AMDGPULibFunc::B32:978  case AMDGPULibFunc::B64:979  case AMDGPULibFunc::SIZE_MASK:980  case AMDGPULibFunc::FLOAT:981  case AMDGPULibFunc::INT:982  case AMDGPULibFunc::UINT:983  case AMDGPULibFunc::DUMMY:984    return nullptr;985  }986  if (P.VectorSize > 1)987    T = FixedVectorType::get(T, P.VectorSize);988  if (P.PtrKind != AMDGPULibFunc::BYVALUE)989    T = PointerType::get(990        C, UseAddrSpace ? ((P.PtrKind & AMDGPULibFunc::ADDR_SPACE) - 1) : 0);991  return T;992}993 994FunctionType *AMDGPUMangledLibFunc::getFunctionType(const Module &M) const {995  LLVMContext& C = M.getContext();996  std::vector<Type*> Args;997  ParamIterator I(Leads, manglingRules[FuncId]);998  Param P;999  while ((P = I.getNextParam()).ArgType != 0) {1000    Type *ParamTy = getIntrinsicParamType(C, P, true);1001    if (!ParamTy)1002      return nullptr;1003 1004    Args.push_back(ParamTy);1005  }1006 1007  Type *RetTy = getIntrinsicParamType(C, getRetType(FuncId, Leads), true);1008  if (!RetTy)1009    return nullptr;1010 1011  return FunctionType::get(RetTy, Args, false);1012}1013 1014unsigned AMDGPUMangledLibFunc::getNumArgs() const {1015  return manglingRules[FuncId].getNumArgs();1016}1017 1018unsigned AMDGPUUnmangledLibFunc::getNumArgs() const {1019  return UnmangledFuncInfo::getNumArgs(FuncId);1020}1021 1022std::string AMDGPUMangledLibFunc::getName() const {1023  SmallString<128> Buf;1024  raw_svector_ostream OS(Buf);1025  writeName(OS);1026  return std::string(OS.str());1027}1028 1029bool AMDGPULibFunc::isCompatibleSignature(const Module &M,1030                                          const FunctionType *CallTy) const {1031  const FunctionType *FuncTy = getFunctionType(M);1032 1033  if (!FuncTy) {1034    // Give up on mangled functions with unexpected types.1035    if (AMDGPULibFuncBase::isMangled(getId()))1036      return false;1037 1038    // FIXME: UnmangledFuncInfo does not have any type information other than1039    // the number of arguments.1040    return getNumArgs() == CallTy->getNumParams();1041  }1042 1043  // Normally the types should exactly match.1044  if (FuncTy == CallTy)1045    return true;1046 1047  const unsigned NumParams = FuncTy->getNumParams();1048  if (NumParams != CallTy->getNumParams())1049    return false;1050 1051  for (unsigned I = 0; I != NumParams; ++I) {1052    Type *FuncArgTy = FuncTy->getParamType(I);1053    Type *CallArgTy = CallTy->getParamType(I);1054    if (FuncArgTy == CallArgTy)1055      continue;1056 1057    // Some cases permit implicit splatting a scalar value to a vector argument.1058    auto *FuncVecTy = dyn_cast<VectorType>(FuncArgTy);1059    if (FuncVecTy && FuncVecTy->getElementType() == CallArgTy &&1060        allowsImplicitVectorSplat(I))1061      continue;1062 1063    return false;1064  }1065 1066  return true;1067}1068 1069Function *AMDGPULibFunc::getFunction(Module *M, const AMDGPULibFunc &fInfo) {1070  std::string FuncName = fInfo.mangle();1071  Function *F = dyn_cast_or_null<Function>(1072    M->getValueSymbolTable().lookup(FuncName));1073  if (!F || F->isDeclaration())1074    return nullptr;1075 1076  if (F->hasFnAttribute(Attribute::NoBuiltin))1077    return nullptr;1078 1079  if (!fInfo.isCompatibleSignature(*M, F->getFunctionType()))1080    return nullptr;1081 1082  return F;1083}1084 1085FunctionCallee AMDGPULibFunc::getOrInsertFunction(Module *M,1086                                                  const AMDGPULibFunc &fInfo) {1087  std::string const FuncName = fInfo.mangle();1088  Function *F = dyn_cast_or_null<Function>(1089    M->getValueSymbolTable().lookup(FuncName));1090 1091  if (F) {1092    if (F->hasFnAttribute(Attribute::NoBuiltin))1093      return nullptr;1094    if (!F->isDeclaration() &&1095        fInfo.isCompatibleSignature(*M, F->getFunctionType()))1096      return F;1097  }1098 1099  FunctionType *FuncTy = fInfo.getFunctionType(*M);1100  assert(FuncTy);1101 1102  bool hasPtr = false;1103  for (FunctionType::param_iterator1104         PI = FuncTy->param_begin(),1105         PE = FuncTy->param_end();1106       PI != PE; ++PI) {1107    const Type* argTy = static_cast<const Type*>(*PI);1108    if (argTy->isPointerTy()) {1109      hasPtr = true;1110      break;1111    }1112  }1113 1114  FunctionCallee C;1115  if (hasPtr) {1116    // Do not set extra attributes for functions with pointer arguments.1117    C = M->getOrInsertFunction(FuncName, FuncTy);1118  } else {1119    AttributeList Attr;1120    LLVMContext &Ctx = M->getContext();1121    Attr = Attr.addFnAttribute(1122        Ctx, Attribute::getWithMemoryEffects(Ctx, MemoryEffects::readOnly()));1123    Attr = Attr.addFnAttribute(Ctx, Attribute::NoUnwind);1124    C = M->getOrInsertFunction(FuncName, FuncTy, Attr);1125  }1126 1127  return C;1128}1129 1130StringMap<unsigned> UnmangledFuncInfo::buildNameMap() {1131  StringMap<unsigned> Map;1132  for (unsigned I = 0; I != TableSize; ++I)1133    Map[Table[I].Name] = I;1134  return Map;1135}1136 1137bool UnmangledFuncInfo::lookup(StringRef Name, ID &Id) {1138  static const StringMap<unsigned> Map = buildNameMap();1139  auto Loc = Map.find(Name);1140  if (Loc != Map.end()) {1141    Id = toFuncId(Loc->second);1142    return true;1143  }1144  Id = AMDGPULibFunc::EI_NONE;1145  return false;1146}1147 1148AMDGPULibFunc::AMDGPULibFunc(const AMDGPULibFunc &F) {1149  if (auto *MF = dyn_cast<AMDGPUMangledLibFunc>(F.Impl.get()))1150    Impl = std::make_unique<AMDGPUMangledLibFunc>(*MF);1151  else if (auto *UMF = dyn_cast<AMDGPUUnmangledLibFunc>(F.Impl.get()))1152    Impl = std::make_unique<AMDGPUUnmangledLibFunc>(*UMF);1153  else1154    Impl = std::unique_ptr<AMDGPULibFuncImpl>();1155}1156 1157AMDGPULibFunc &AMDGPULibFunc::operator=(const AMDGPULibFunc &F) {1158  if (this == &F)1159    return *this;1160  new (this) AMDGPULibFunc(F);1161  return *this;1162}1163 1164AMDGPULibFunc::AMDGPULibFunc(EFuncId Id, const AMDGPULibFunc &CopyFrom) {1165  assert(AMDGPULibFuncBase::isMangled(Id) && CopyFrom.isMangled() &&1166         "not supported");1167  Impl = std::make_unique<AMDGPUMangledLibFunc>(1168      Id, *cast<AMDGPUMangledLibFunc>(CopyFrom.Impl.get()));1169}1170 1171AMDGPULibFunc::AMDGPULibFunc(EFuncId Id, FunctionType *FT, bool SignedInts) {1172  Impl = std::make_unique<AMDGPUMangledLibFunc>(Id, FT, SignedInts);1173}1174 1175AMDGPULibFunc::AMDGPULibFunc(StringRef Name, FunctionType *FT) {1176  Impl = std::make_unique<AMDGPUUnmangledLibFunc>(Name, FT);1177}1178 1179void AMDGPULibFunc::initMangled() {1180  Impl = std::make_unique<AMDGPUMangledLibFunc>();1181}1182 1183AMDGPULibFunc::Param *AMDGPULibFunc::getLeads() {1184  if (!Impl)1185    initMangled();1186  return cast<AMDGPUMangledLibFunc>(Impl.get())->Leads;1187}1188 1189const AMDGPULibFunc::Param *AMDGPULibFunc::getLeads() const {1190  return cast<const AMDGPUMangledLibFunc>(Impl.get())->Leads;1191}1192