29    "amdgpu-enable-ocl-mangling-mismatch-workaround", 
cl::init(
true),
 
   31    cl::desc(
"Enable the workaround for OCL name mangling mismatch."));
 
   64   unsigned char Lead[2];
 
   65   unsigned char Param[5];
 
   67   int maxLeadIndex()
 const { 
return (std::max)(Lead[0], Lead[1]); }
 
   68   int getNumLeads()
 const { 
return (Lead[0] ? 1 : 0) + (Lead[1] ? 1 : 0); }
 
   70   unsigned getNumArgs() 
const;
 
   72   static StringMap<int> buildManglingRulesMap();
 
   76class UnmangledFuncInfo {
 
   81  static const UnmangledFuncInfo Table[];
 
   84  static const unsigned TableSize;
 
   86  static StringMap<unsigned> buildNameMap();
 
   89  using ID = AMDGPULibFunc::EFuncId;
 
   90  constexpr UnmangledFuncInfo(
const char *_Name, 
unsigned _NumArgs)
 
   91      : Name(_Name), NumArgs(_NumArgs) {}
 
   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);
 
  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));
 
  107  static unsigned getNumArgs(ID Id) { 
return Table[toIndex(Id)].NumArgs; }
 
  108  static StringRef 
getName(ID Id) { 
return Table[toIndex(Id)].Name; }
 
  111unsigned ManglingRule::getNumArgs()
 const {
 
  113   while (
I < (
sizeof Param/
sizeof Param[0]) && Param[
I]) ++
I;
 
  141static constexpr ManglingRule manglingRules[] = {
 
  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} },
 
  343const UnmangledFuncInfo UnmangledFuncInfo::Table[] = {
 
  344    {
"__read_pipe_2", 4},
 
  345    {
"__read_pipe_4", 6},
 
  346    {
"__write_pipe_2", 4},
 
  347    {
"__write_pipe_4", 6},
 
  350const unsigned UnmangledFuncInfo::TableSize =
 
  351    std::size(UnmangledFuncInfo::Table);
 
  353static AMDGPULibFunc::Param getRetType(AMDGPULibFunc::EFuncId 
id,
 
  354                                       const AMDGPULibFunc::Param (&Leads)[2]) {
 
  355  AMDGPULibFunc::Param Res = Leads[0];
 
  358  case AMDGPULibFunc::EI_SINCOS:
 
  359    Res.
PtrKind = AMDGPULibFunc::BYVALUE;
 
  368  const AMDGPULibFunc::Param (&Leads)[2];
 
  369  const ManglingRule& Rule;
 
  372  ParamIterator(
const AMDGPULibFunc::Param (&leads)[2],
 
  373                const ManglingRule& rule)
 
  374    : Leads(leads), Rule(rule) {}
 
  376  AMDGPULibFunc::Param getNextParam();
 
  379AMDGPULibFunc::Param ParamIterator::getNextParam() {
 
  380  AMDGPULibFunc::Param 
P;
 
  381  if (Index >= 
int(
sizeof Rule.Param/
sizeof Rule.Param[0])) 
return P;
 
  383  const char R = Rule.Param[
Index];
 
  387    P.ArgType = AMDGPULibFunc::U32; 
break;
 
  389    P.ArgType = AMDGPULibFunc::I32; 
P.VectorSize = 4; 
break;
 
  391    P.ArgType = AMDGPULibFunc::U32; 
P.VectorSize = 4; 
break;
 
  393    P.ArgType = AMDGPULibFunc::F32; 
P.VectorSize = 4; 
break;
 
  395    P.ArgType = AMDGPULibFunc::U64; 
break;
 
  397    P.ArgType = AMDGPULibFunc::EVENT;   
break;
 
  399    P.ArgType = AMDGPULibFunc::SAMPLER; 
break;
 
  400  case EX_RESERVEDID: 
break; 
 
  402    if (Index == (Rule.Lead[1] - 1)) 
P = Leads[1];
 
  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;
 
  422      P.PtrKind |= AMDGPULibFunc::CONST; 
break;
 
  424      P.PtrKind |= AMDGPULibFunc::VOLATILE; 
break;
 
  426      P.ArgType = AMDGPULibFunc::I32; 
break;
 
  428      P.ArgType = AMDGPULibFunc::U32; 
break;
 
  431      P.ArgType &= ~AMDGPULibFunc::BASE_TYPE_MASK;
 
  432      P.ArgType |= AMDGPULibFunc::UINT;
 
  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;
 
  444      P.PtrKind = AMDGPULibFunc::BYVALUE;
 
  445      P.ArgType = AMDGPULibFunc::I32;
 
  448    case E_CONSTPTR_SWAPGL: {
 
  449      unsigned AS = AMDGPULibFunc::getAddrSpaceFromEPtrKind(
P.PtrKind);
 
  454      P.PtrKind = AMDGPULibFunc::getEPtrKindFromAddrSpace(AS);
 
  455      P.PtrKind |= AMDGPULibFunc::CONST;
 
  467inline static void drop_front(StringRef& str, 
size_t n = 1) {
 
  471static bool eatTerm(StringRef& mangledName, 
const char c) {
 
  472  if (mangledName.
front() == c) {
 
  473    drop_front(mangledName);
 
  480static bool eatTerm(StringRef& mangledName, 
const char (&str)[
N]) {
 
  482    drop_front(mangledName, 
N-1);
 
  488static int eatNumber(StringRef& s) {
 
  489  size_t const savedSize = s.
size();
 
  492    n = n*10 + s.
front() - 
'0';
 
  495  return s.
size() < savedSize ? n : -1;
 
  498static StringRef eatLengthPrefixedName(StringRef& mangledName) {
 
  499  int const Len = eatNumber(mangledName);
 
  500  if (Len <= 0 || 
static_cast<size_t>(Len) > mangledName.
size())
 
  502  StringRef Res = mangledName.
substr(0, Len);
 
  503  drop_front(mangledName, Len);
 
  544  size_t const Len = eatNumber(mangledName);
 
  546  case 2: 
case 3: 
case 4: 
case 8: 
case 16:
 
 
  555  std::pair<StringRef, StringRef> 
const P = mangledName.
split(
'_');
 
  563    mangledName = 
P.second;
 
 
  568StringMap<int> ManglingRule::buildManglingRulesMap() {
 
  569  StringMap<int> 
Map(std::size(manglingRules));
 
  571  for (
auto Rule : manglingRules)
 
  572    Map.insert({Rule.Name, 
Id++});
 
  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;
 
  587struct ItaniumParamParser {
 
  588  AMDGPULibFunc::Param Prev;
 
  589  bool parseItaniumParam(StringRef& param, AMDGPULibFunc::Param &res);
 
  593bool ItaniumParamParser::parseItaniumParam(StringRef& param,
 
  594                                           AMDGPULibFunc::Param &res) {
 
  596  if (param.
empty()) 
return false;
 
  599  if (eatTerm(param, 
'P')) {
 
  600    if (eatTerm(param, 
'K')) res.
PtrKind |= AMDGPULibFunc::CONST;
 
  601    if (eatTerm(param, 
'V')) res.
PtrKind |= AMDGPULibFunc::VOLATILE;
 
  603    if (!eatTerm(param, 
"U3AS")) {
 
  606      AS = param.
front() - 
'0';
 
  607      drop_front(param, 1);
 
  611    res.
PtrKind = AMDGPULibFunc::BYVALUE;
 
  615  if (eatTerm(param,
"Dv")) {
 
  617    if (res.
VectorSize==1 || !eatTerm(param, 
'_')) 
return false;
 
  621  char const TC = param.
front();
 
  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);
 
  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;
 
  650      if (!eatTerm(param, 
'_')) {
 
  652        if (!eatTerm(param, 
'_')) 
return false;
 
  660  if (res.
ArgType == 0) 
return false;
 
  669  if (!parseUnmangledName(
Name))
 
  672  const ManglingRule& Rule = manglingRules[
FuncId];
 
  673  ItaniumParamParser Parser;
 
  674  for (
int I=0; 
I < Rule.maxLeadIndex(); ++
I) {
 
  676    if (!Parser.parseItaniumParam(mangledName, 
P))
 
  679    if ((
I + 1) == Rule.Lead[0]) 
Leads[0] = 
P;
 
  680    if ((
I + 1) == Rule.Lead[1]) 
Leads[1] = 
P;
 
 
  693  if (FuncName.
empty()) {
 
  694    F.Impl = std::unique_ptr<AMDGPULibFuncImpl>();
 
  698  if (eatTerm(FuncName, 
"_Z"))
 
  699    F.Impl = std::make_unique<AMDGPUMangledLibFunc>();
 
  701    F.Impl = std::make_unique<AMDGPUUnmangledLibFunc>();
 
  702  if (
F.Impl->parseFuncName(FuncName))
 
  705  F.Impl = std::unique_ptr<AMDGPULibFuncImpl>();
 
 
  711  if (eatTerm(S, 
"_Z"))
 
  712    return eatLengthPrefixedName(S);
 
 
  719template <
typename Stream>
 
  720void AMDGPUMangledLibFunc::writeName(Stream &OS)
 const {
 
  721  const char *Pfx = 
"";
 
  723  case NATIVE: Pfx = 
"native_"; 
break;
 
  724  case HALF:   Pfx = 
"half_";   
break;
 
  729  } 
else if (FuncId != EI_NONE) {
 
  731    const StringRef& S = manglingRules[FuncId].Name;
 
  793class ItaniumMangler {
 
  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) {
 
  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;
 
  816    if (subst == 0) os << 
"S_";
 
  817    else os << 
'S' << (subst-1) << 
'_';
 
  822  ItaniumMangler(
bool useAddrSpace)
 
  823    : UseAddrSpace(useAddrSpace) {}
 
  825  template <
typename Stream>
 
  826  void operator()(Stream& os, AMDGPULibFunc::Param p) {
 
  838    AMDGPULibFunc::Param 
Ptr;
 
  841      if (trySubst(os, p)) 
return;
 
  843      if (
p.PtrKind & AMDGPULibFunc::CONST) os << 
'K';
 
  844      if (
p.PtrKind & AMDGPULibFunc::VOLATILE) os << 
'V';
 
  845      unsigned AS = UseAddrSpace
 
  854    if (
p.VectorSize > 1) {
 
  855      if (trySubst(os, p)) 
goto exit;
 
  857      os << 
"Dv" << 
static_cast<unsigned>(
p.VectorSize) << 
'_';
 
  863    if (
Ptr.ArgType) Str.push_back(
Ptr);
 
  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);
 
  874  const StringRef& NameStr = 
Name.str();
 
  875  S << 
"_Z" << 
static_cast<int>(NameStr.
size()) << NameStr;
 
  877  ItaniumMangler Mangler(
true);
 
  878  ParamIterator 
I(Leads, manglingRules[FuncId]);
 
  880  while ((
P = 
I.getNextParam()).ArgType != 0)
 
  882  return std::string(S.str());
 
  892    P.VectorSize = VT->getNumElements();
 
  893    Ty = VT->getElementType();
 
  896  switch (Ty->getTypeID()) {
 
 
  986  if (
P.VectorSize > 1)
 
 
  996  std::vector<Type*> Args;
 
  999  while ((
P = 
I.getNextParam()).ArgType != 0) {
 
 1004    Args.push_back(ParamTy);
 
 
 1015  return manglingRules[
FuncId].getNumArgs();
 
 
 1019  return UnmangledFuncInfo::getNumArgs(
FuncId);
 
 
 1026  return std::string(OS.
str());
 
 
 1044  if (FuncTy == CallTy)
 
 1047  const unsigned NumParams = FuncTy->getNumParams();
 
 1051  for (
unsigned I = 0; 
I != NumParams; ++
I) {
 
 1052    Type *FuncArgTy = FuncTy->getParamType(
I);
 
 1054    if (FuncArgTy == CallArgTy)
 
 1059    if (FuncVecTy && FuncVecTy->getElementType() == CallArgTy &&
 
 
 1070  std::string FuncName = fInfo.
mangle();
 
 1072    M->getValueSymbolTable().lookup(FuncName));
 
 1073  if (!
F || 
F->isDeclaration())
 
 1076  if (
F->hasFnAttribute(Attribute::NoBuiltin))
 
 
 1087  std::string 
const FuncName = fInfo.
mangle();
 
 1089    M->getValueSymbolTable().lookup(FuncName));
 
 1092    if (
F->hasFnAttribute(Attribute::NoBuiltin))
 
 1094    if (!
F->isDeclaration() &&
 
 1102  bool hasPtr = 
false;
 
 1104         PI = FuncTy->param_begin(),
 
 1105         PE = FuncTy->param_end();
 
 1107    const Type* argTy = 
static_cast<const Type*
>(*PI);
 
 1117    C = M->getOrInsertFunction(FuncName, FuncTy);
 
 1121    Attr = Attr.addFnAttribute(
 
 1123    Attr = Attr.addFnAttribute(Ctx, Attribute::NoUnwind);
 
 1124    C = M->getOrInsertFunction(FuncName, FuncTy, Attr);
 
 
 1132  for (
unsigned I = 0; 
I != TableSize; ++
I)
 
 1133    Map[Table[
I].Name] = 
I;
 
 1137bool UnmangledFuncInfo::lookup(
StringRef Name, 
ID &Id) {
 
 1139  auto Loc = Map.find(Name);
 
 1140  if (
Loc != Map.end()) {
 
 1141    Id = toFuncId(
Loc->second);
 
 1144  Id = AMDGPULibFunc::EI_NONE;
 
 1150    Impl = std::make_unique<AMDGPUMangledLibFunc>(*MF);
 
 1152    Impl = std::make_unique<AMDGPUUnmangledLibFunc>(*UMF);
 
 1154    Impl = std::unique_ptr<AMDGPULibFuncImpl>();
 
 
 1167  Impl = std::make_unique<AMDGPUMangledLibFunc>(
 
 
 1172  Impl = std::make_unique<AMDGPUMangledLibFunc>(Id, FT, SignedInts);
 
 
 1176  Impl = std::make_unique<AMDGPUUnmangledLibFunc>(Name, FT);
 
 
 1179void AMDGPULibFunc::initMangled() {
 
 1180  Impl = std::make_unique<AMDGPUMangledLibFunc>();
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the StringMap class.
static cl::opt< bool > EnableOCLManglingMismatchWA("amdgpu-enable-ocl-mangling-mismatch-workaround", cl::init(true), cl::ReallyHidden, cl::desc("Enable the workaround for OCL name mangling mismatch."))
static AMDGPULibFunc::ENamePrefix parseNamePrefix(StringRef &mangledName)
static const char * getItaniumTypeName(AMDGPULibFunc::EType T)
static int parseVecSize(StringRef &mangledName)
static Type * getIntrinsicParamType(LLVMContext &C, const AMDGPULibFunc::Param &P, bool UseAddrSpace)
Module.h This file contains the declarations for the Module class.
static bool lookup(const GsymReader &GR, DataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr, uint64_t Addr, SourceLocations &SrcLocs, llvm::Error &Err)
A Lookup helper functions.
static StringRef getName(Value *V)
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
static unsigned getEPtrKindFromAddrSpace(unsigned AS)
static unsigned getAddrSpaceFromEPtrKind(unsigned Kind)
static bool isMangled(EFuncId Id)
void setName(StringRef N)
static Function * getFunction(llvm::Module *M, const AMDGPULibFunc &fInfo)
static bool parse(StringRef MangledName, AMDGPULibFunc &Ptr)
static FunctionCallee getOrInsertFunction(llvm::Module *M, const AMDGPULibFunc &fInfo)
FunctionType * getFunctionType(const Module &M) const
bool isCompatibleSignature(const Module &M, const FunctionType *FuncTy) const
bool allowsImplicitVectorSplat(int ArgIdx) const
Return true if it's legal to splat a scalar value passed in parameter ArgIdx to a vector argument.
std::string mangle() const
AMDGPULibFunc & operator=(const AMDGPULibFunc &F)
Param * getLeads()
Get leading parameters for mangled lib functions.
unsigned getNumArgs() const
static StringRef getUnmangledName(StringRef MangledName)
unsigned getNumArgs() const override
bool parseFuncName(StringRef &mangledName) override
std::string getName() const override
Get unmangled name for mangled library function and name for unmangled library function.
FunctionType * getFunctionType(const Module &M) const override
std::string mangle() const override
unsigned getNumArgs() const override
bool parseFuncName(StringRef &Name) override
static LLVM_ABI Attribute getWithMemoryEffects(LLVMContext &Context, MemoryEffects ME)
Class to represent fixed width SIMD vectors.
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Class to represent function types.
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
Type::subtype_iterator param_iterator
Type * getParamType(unsigned i) const
Parameter type accessors.
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
This is an important class for using LLVM in a threaded context.
static MemoryEffectsBase readOnly()
A Module instance is used to store all the information related to an LLVM module.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
static LLVM_ABI PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
ValueTy lookup(StringRef Key) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
constexpr size_t size() const
size - Get the string size.
char front() const
front - Get the first character in the string.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
bool isPointerTy() const
True if this is an instance of PointerType.
@ HalfTyID
16-bit floating point type
@ FloatTyID
32-bit floating point type
@ IntegerTyID
Arbitrary bit width integers.
@ DoubleTyID
64-bit floating point type
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getInt16Ty(LLVMContext &C)
static LLVM_ABI Type * getDoubleTy(LLVMContext &C)
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
static LLVM_ABI Type * getHalfTy(LLVMContext &C)
A raw_ostream that writes to an SmallVector or SmallString.
StringRef str() const
Return a StringRef for the vector contents.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ LOCAL_ADDRESS
Address space for local memory.
@ GLOBAL_ADDRESS
Address space for global memory (RAT0, VTX0).
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto dyn_cast_or_null(const Y &Val)
bool isDigit(char C)
Checks if character C is one of the 10 decimal digits.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
static Param getFromTy(Type *Ty, bool Signed)