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]); }
69 unsigned getNumArgs()
const;
71 static StringMap<int> buildManglingRulesMap();
75class UnmangledFuncInfo {
80 static const UnmangledFuncInfo Table[];
83 static const unsigned TableSize;
85 static StringMap<unsigned> buildNameMap();
88 using ID = AMDGPULibFunc::EFuncId;
89 constexpr UnmangledFuncInfo(
const char *_Name,
unsigned _NumArgs)
90 : Name(_Name), NumArgs(_NumArgs) {}
92 static bool lookup(StringRef Name, ID &Id);
93 static unsigned toIndex(ID Id) {
94 assert(
static_cast<unsigned>(Id) >
95 static_cast<unsigned>(AMDGPULibFunc::EI_LAST_MANGLED) &&
96 "Invalid unmangled library function");
97 return static_cast<unsigned>(
Id) - 1 -
98 static_cast<unsigned>(AMDGPULibFunc::EI_LAST_MANGLED);
100 static ID toFuncId(
unsigned Index) {
101 assert(Index < TableSize &&
102 "Invalid unmangled library function");
103 return static_cast<ID
>(
104 Index + 1 +
static_cast<unsigned>(AMDGPULibFunc::EI_LAST_MANGLED));
106 static unsigned getNumArgs(ID Id) {
return Table[toIndex(Id)].NumArgs; }
109unsigned ManglingRule::getNumArgs()
const {
111 while (
I < (
sizeof Param/
sizeof Param[0]) && Param[
I]) ++
I;
139static constexpr ManglingRule manglingRules[] = {
141{
"abs" , {1}, {E_ANY}},
142{
"abs_diff" , {1}, {E_ANY,E_COPY}},
143{
"acos" , {1}, {E_ANY}},
144{
"acosh" , {1}, {E_ANY}},
145{
"acospi" , {1}, {E_ANY}},
146{
"add_sat" , {1}, {E_ANY,E_COPY}},
147{
"all" , {1}, {E_ANY}},
148{
"any" , {1}, {E_ANY}},
149{
"asin" , {1}, {E_ANY}},
150{
"asinh" , {1}, {E_ANY}},
151{
"asinpi" , {1}, {E_ANY}},
152{
"async_work_group_copy" , {1}, {E_ANY,E_CONSTPTR_SWAPGL,EX_SIZET,EX_EVENT}},
153{
"async_work_group_strided_copy" , {1}, {E_ANY,E_CONSTPTR_SWAPGL,EX_SIZET,EX_SIZET,EX_EVENT}},
154{
"atan" , {1}, {E_ANY}},
155{
"atan2" , {1}, {E_ANY,E_COPY}},
156{
"atan2pi" , {1}, {E_ANY,E_COPY}},
157{
"atanh" , {1}, {E_ANY}},
158{
"atanpi" , {1}, {E_ANY}},
159{
"atomic_add" , {1}, {E_VLTLPTR_ANY,E_POINTEE}},
160{
"atomic_and" , {1}, {E_VLTLPTR_ANY,E_POINTEE}},
161{
"atomic_cmpxchg" , {1}, {E_VLTLPTR_ANY,E_POINTEE,E_POINTEE}},
162{
"atomic_dec" , {1}, {E_VLTLPTR_ANY}},
163{
"atomic_inc" , {1}, {E_VLTLPTR_ANY}},
164{
"atomic_max" , {1}, {E_VLTLPTR_ANY,E_POINTEE}},
165{
"atomic_min" , {1}, {E_VLTLPTR_ANY,E_POINTEE}},
166{
"atomic_or" , {1}, {E_VLTLPTR_ANY,E_POINTEE}},
167{
"atomic_sub" , {1}, {E_VLTLPTR_ANY,E_POINTEE}},
168{
"atomic_xchg" , {1}, {E_VLTLPTR_ANY,E_POINTEE}},
169{
"atomic_xor" , {1}, {E_VLTLPTR_ANY,E_POINTEE}},
170{
"bitselect" , {1}, {E_ANY,E_COPY,E_COPY}},
171{
"cbrt" , {1}, {E_ANY}},
172{
"ceil" , {1}, {E_ANY}},
173{
"clamp" , {1}, {E_ANY,E_COPY,E_COPY}},
174{
"clz" , {1}, {E_ANY}},
175{
"commit_read_pipe" , {1}, {E_ANY,EX_RESERVEDID}},
176{
"commit_write_pipe" , {1}, {E_ANY,EX_RESERVEDID}},
177{
"copysign" , {1}, {E_ANY,E_COPY}},
178{
"cos" , {1}, {E_ANY}},
179{
"cosh" , {1}, {E_ANY}},
180{
"cospi" , {1}, {E_ANY}},
181{
"cross" , {1}, {E_ANY,E_COPY}},
182{
"ctz" , {1}, {E_ANY}},
183{
"degrees" , {1}, {E_ANY}},
184{
"distance" , {1}, {E_ANY,E_COPY}},
185{
"divide" , {1}, {E_ANY,E_COPY}},
186{
"dot" , {1}, {E_ANY,E_COPY}},
187{
"erf" , {1}, {E_ANY}},
188{
"erfc" , {1}, {E_ANY}},
189{
"exp" , {1}, {E_ANY}},
190{
"exp10" , {1}, {E_ANY}},
191{
"exp2" , {1}, {E_ANY}},
192{
"expm1" , {1}, {E_ANY}},
193{
"fabs" , {1}, {E_ANY}},
194{
"fast_distance" , {1}, {E_ANY,E_COPY}},
195{
"fast_length" , {1}, {E_ANY}},
196{
"fast_normalize" , {1}, {E_ANY}},
197{
"fdim" , {1}, {E_ANY,E_COPY}},
198{
"floor" , {1}, {E_ANY}},
199{
"fma" , {1}, {E_ANY,E_COPY,E_COPY}},
200{
"fmax" , {1}, {E_ANY,E_COPY}},
201{
"fmin" , {1}, {E_ANY,E_COPY}},
202{
"fmod" , {1}, {E_ANY,E_COPY}},
203{
"fract" , {2}, {E_POINTEE,E_ANY}},
204{
"frexp" , {1,2}, {E_ANY,E_ANY}},
205{
"get_image_array_size" , {1}, {E_ANY}},
206{
"get_image_channel_data_type" , {1}, {E_ANY}},
207{
"get_image_channel_order" , {1}, {E_ANY}},
208{
"get_image_dim" , {1}, {E_ANY}},
209{
"get_image_height" , {1}, {E_ANY}},
210{
"get_image_width" , {1}, {E_ANY}},
211{
"get_pipe_max_packets" , {1}, {E_ANY}},
212{
"get_pipe_num_packets" , {1}, {E_ANY}},
213{
"hadd" , {1}, {E_ANY,E_COPY}},
214{
"hypot" , {1}, {E_ANY,E_COPY}},
215{
"ilogb" , {1}, {E_ANY}},
216{
"isequal" , {1}, {E_ANY,E_COPY}},
217{
"isfinite" , {1}, {E_ANY}},
218{
"isgreater" , {1}, {E_ANY,E_COPY}},
219{
"isgreaterequal" , {1}, {E_ANY,E_COPY}},
220{
"isinf" , {1}, {E_ANY}},
221{
"isless" , {1}, {E_ANY,E_COPY}},
222{
"islessequal" , {1}, {E_ANY,E_COPY}},
223{
"islessgreater" , {1}, {E_ANY,E_COPY}},
224{
"isnan" , {1}, {E_ANY}},
225{
"isnormal" , {1}, {E_ANY}},
226{
"isnotequal" , {1}, {E_ANY,E_COPY}},
227{
"isordered" , {1}, {E_ANY,E_COPY}},
228{
"isunordered" , {1}, {E_ANY,E_COPY}},
229{
"ldexp" , {1}, {E_ANY,E_SETBASE_I32}},
230{
"length" , {1}, {E_ANY}},
231{
"lgamma" , {1}, {E_ANY}},
232{
"lgamma_r" , {1,2}, {E_ANY,E_ANY}},
233{
"log" , {1}, {E_ANY}},
234{
"log10" , {1}, {E_ANY}},
235{
"log1p" , {1}, {E_ANY}},
236{
"log2" , {1}, {E_ANY}},
237{
"logb" , {1}, {E_ANY}},
238{
"mad" , {1}, {E_ANY,E_COPY,E_COPY}},
239{
"mad24" , {1}, {E_ANY,E_COPY,E_COPY}},
240{
"mad_hi" , {1}, {E_ANY,E_COPY,E_COPY}},
241{
"mad_sat" , {1}, {E_ANY,E_COPY,E_COPY}},
242{
"max" , {1}, {E_ANY,E_COPY}},
243{
"maxmag" , {1}, {E_ANY,E_COPY}},
244{
"min" , {1}, {E_ANY,E_COPY}},
245{
"minmag" , {1}, {E_ANY,E_COPY}},
246{
"mix" , {1}, {E_ANY,E_COPY,E_COPY}},
247{
"modf" , {2}, {E_POINTEE,E_ANY}},
248{
"mul24" , {1}, {E_ANY,E_COPY}},
249{
"mul_hi" , {1}, {E_ANY,E_COPY}},
250{
"nan" , {1}, {E_ANY}},
251{
"nextafter" , {1}, {E_ANY,E_COPY}},
252{
"normalize" , {1}, {E_ANY}},
253{
"popcount" , {1}, {E_ANY}},
254{
"pow" , {1}, {E_ANY,E_COPY}},
255{
"__pow_fast" , {1}, {E_ANY,E_COPY}},
256{
"pown" , {1}, {E_ANY,E_SETBASE_I32}},
257{
"__pown_fast" , {1}, {E_ANY,E_SETBASE_I32}},
258{
"powr" , {1}, {E_ANY,E_COPY}},
259{
"__powr_fast" , {1}, {E_ANY,E_COPY}},
260{
"prefetch" , {1}, {E_CONSTPTR_ANY,EX_SIZET}},
261{
"radians" , {1}, {E_ANY}},
262{
"recip" , {1}, {E_ANY}},
263{
"remainder" , {1}, {E_ANY,E_COPY}},
264{
"remquo" , {1,3}, {E_ANY,E_COPY,E_ANY}},
265{
"reserve_read_pipe" , {1}, {E_ANY,EX_UINT}},
266{
"reserve_write_pipe" , {1}, {E_ANY,EX_UINT}},
267{
"rhadd" , {1}, {E_ANY,E_COPY}},
268{
"rint" , {1}, {E_ANY}},
269{
"rootn" , {1}, {E_ANY,E_SETBASE_I32}},
270{
"__rootn_fast" , {1}, {E_ANY,E_SETBASE_I32}},
271{
"rotate" , {1}, {E_ANY,E_COPY}},
272{
"round" , {1}, {E_ANY}},
273{
"rsqrt" , {1}, {E_ANY}},
274{
"select" , {1,3}, {E_ANY,E_COPY,E_ANY}},
275{
"shuffle" , {1,2}, {E_ANY,E_ANY}},
276{
"shuffle2" , {1,3}, {E_ANY,E_COPY,E_ANY}},
277{
"sign" , {1}, {E_ANY}},
278{
"signbit" , {1}, {E_ANY}},
279{
"sin" , {1}, {E_ANY}},
280{
"sincos" , {2}, {E_POINTEE,E_ANY}},
281{
"sinh" , {1}, {E_ANY}},
282{
"sinpi" , {1}, {E_ANY}},
283{
"smoothstep" , {1}, {E_ANY,E_COPY,E_COPY}},
284{
"sqrt" , {1}, {E_ANY}},
285{
"step" , {1}, {E_ANY,E_COPY}},
286{
"sub_group_broadcast" , {1}, {E_ANY,EX_UINT}},
287{
"sub_group_commit_read_pipe" , {1}, {E_ANY,EX_RESERVEDID}},
288{
"sub_group_commit_write_pipe" , {1}, {E_ANY,EX_RESERVEDID}},
289{
"sub_group_reduce_add" , {1}, {E_ANY}},
290{
"sub_group_reduce_max" , {1}, {E_ANY}},
291{
"sub_group_reduce_min" , {1}, {E_ANY}},
292{
"sub_group_reserve_read_pipe" , {1}, {E_ANY,EX_UINT}},
293{
"sub_group_reserve_write_pipe" , {1}, {E_ANY,EX_UINT}},
294{
"sub_group_scan_exclusive_add" , {1}, {E_ANY}},
295{
"sub_group_scan_exclusive_max" , {1}, {E_ANY}},
296{
"sub_group_scan_exclusive_min" , {1}, {E_ANY}},
297{
"sub_group_scan_inclusive_add" , {1}, {E_ANY}},
298{
"sub_group_scan_inclusive_max" , {1}, {E_ANY}},
299{
"sub_group_scan_inclusive_min" , {1}, {E_ANY}},
300{
"sub_sat" , {1}, {E_ANY,E_COPY}},
301{
"tan" , {1}, {E_ANY}},
302{
"tanh" , {1}, {E_ANY}},
303{
"tanpi" , {1}, {E_ANY}},
304{
"tgamma" , {1}, {E_ANY}},
305{
"trunc" , {1}, {E_ANY}},
306{
"upsample" , {1}, {E_ANY,E_MAKEBASE_UNS}},
307{
"vec_step" , {1}, {E_ANY}},
308{
"vstore" , {3}, {E_POINTEE,EX_SIZET,E_ANY}},
309{
"vstore16" , {3}, {E_V16_OF_POINTEE,EX_SIZET,E_ANY}},
310{
"vstore2" , {3}, {E_V2_OF_POINTEE,EX_SIZET,E_ANY}},
311{
"vstore3" , {3}, {E_V3_OF_POINTEE,EX_SIZET,E_ANY}},
312{
"vstore4" , {3}, {E_V4_OF_POINTEE,EX_SIZET,E_ANY}},
313{
"vstore8" , {3}, {E_V8_OF_POINTEE,EX_SIZET,E_ANY}},
314{
"work_group_commit_read_pipe" , {1}, {E_ANY,EX_RESERVEDID}},
315{
"work_group_commit_write_pipe" , {1}, {E_ANY,EX_RESERVEDID}},
316{
"work_group_reduce_add" , {1}, {E_ANY}},
317{
"work_group_reduce_max" , {1}, {E_ANY}},
318{
"work_group_reduce_min" , {1}, {E_ANY}},
319{
"work_group_reserve_read_pipe" , {1}, {E_ANY,EX_UINT}},
320{
"work_group_reserve_write_pipe" , {1}, {E_ANY,EX_UINT}},
321{
"work_group_scan_exclusive_add" , {1}, {E_ANY}},
322{
"work_group_scan_exclusive_max" , {1}, {E_ANY}},
323{
"work_group_scan_exclusive_min" , {1}, {E_ANY}},
324{
"work_group_scan_inclusive_add" , {1}, {E_ANY}},
325{
"work_group_scan_inclusive_max" , {1}, {E_ANY}},
326{
"work_group_scan_inclusive_min" , {1}, {E_ANY}},
327{
"write_imagef" , {1}, {E_ANY,E_IMAGECOORDS,EX_FLOAT4}},
328{
"write_imagei" , {1}, {E_ANY,E_IMAGECOORDS,EX_INTV4}},
329{
"write_imageui" , {1}, {E_ANY,E_IMAGECOORDS,EX_UINTV4}},
330{
"ncos" , {1}, {E_ANY} },
331{
"nexp2" , {1}, {E_ANY} },
332{
"nfma" , {1}, {E_ANY, E_COPY, E_COPY} },
333{
"nlog2" , {1}, {E_ANY} },
334{
"nrcp" , {1}, {E_ANY} },
335{
"nrsqrt" , {1}, {E_ANY} },
336{
"nsin" , {1}, {E_ANY} },
337{
"nsqrt" , {1}, {E_ANY} },
338{
"ftz" , {1}, {E_ANY} },
339{
"fldexp" , {1}, {E_ANY, EX_UINT} },
340{
"class" , {1}, {E_ANY, EX_UINT} },
341{
"rcbrt" , {1}, {E_ANY} },
345const UnmangledFuncInfo UnmangledFuncInfo::Table[] = {
346 {
"__read_pipe_2", 4},
347 {
"__read_pipe_4", 6},
348 {
"__write_pipe_2", 4},
349 {
"__write_pipe_4", 6},
352const unsigned UnmangledFuncInfo::TableSize =
353 std::size(UnmangledFuncInfo::Table);
355static AMDGPULibFunc::Param getRetType(AMDGPULibFunc::EFuncId
id,
356 const AMDGPULibFunc::Param (&Leads)[2]) {
357 AMDGPULibFunc::Param Res = Leads[0];
360 case AMDGPULibFunc::EI_SINCOS:
361 Res.
PtrKind = AMDGPULibFunc::BYVALUE;
370 const AMDGPULibFunc::Param (&Leads)[2];
371 const ManglingRule& Rule;
374 ParamIterator(
const AMDGPULibFunc::Param (&leads)[2],
375 const ManglingRule& rule)
376 : Leads(leads), Rule(rule) {}
378 AMDGPULibFunc::Param getNextParam();
381AMDGPULibFunc::Param ParamIterator::getNextParam() {
382 AMDGPULibFunc::Param
P;
383 if (Index >=
int(
sizeof Rule.Param/
sizeof Rule.Param[0]))
return P;
385 const char R = Rule.Param[
Index];
389 P.ArgType = AMDGPULibFunc::U32;
break;
391 P.ArgType = AMDGPULibFunc::I32;
P.VectorSize = 4;
break;
393 P.ArgType = AMDGPULibFunc::U32;
P.VectorSize = 4;
break;
395 P.ArgType = AMDGPULibFunc::F32;
P.VectorSize = 4;
break;
397 P.ArgType = AMDGPULibFunc::U64;
break;
399 P.ArgType = AMDGPULibFunc::EVENT;
break;
401 P.ArgType = AMDGPULibFunc::SAMPLER;
break;
402 case EX_RESERVEDID:
break;
404 if (Index == (Rule.Lead[1] - 1))
P = Leads[1];
412 P.PtrKind = AMDGPULibFunc::BYVALUE;
break;
413 case E_V2_OF_POINTEE:
414 P.VectorSize = 2;
P.PtrKind = AMDGPULibFunc::BYVALUE;
break;
415 case E_V3_OF_POINTEE:
416 P.VectorSize = 3;
P.PtrKind = AMDGPULibFunc::BYVALUE;
break;
417 case E_V4_OF_POINTEE:
418 P.VectorSize = 4;
P.PtrKind = AMDGPULibFunc::BYVALUE;
break;
419 case E_V8_OF_POINTEE:
420 P.VectorSize = 8;
P.PtrKind = AMDGPULibFunc::BYVALUE;
break;
421 case E_V16_OF_POINTEE:
422 P.VectorSize = 16;
P.PtrKind = AMDGPULibFunc::BYVALUE;
break;
424 P.PtrKind |= AMDGPULibFunc::CONST;
break;
426 P.PtrKind |= AMDGPULibFunc::VOLATILE;
break;
428 P.ArgType = AMDGPULibFunc::I32;
break;
430 P.ArgType = AMDGPULibFunc::U32;
break;
433 P.ArgType &= ~AMDGPULibFunc::BASE_TYPE_MASK;
434 P.ArgType |= AMDGPULibFunc::UINT;
439 case AMDGPULibFunc::IMG1DA:
P.VectorSize = 2;
break;
440 case AMDGPULibFunc::IMG1DB:
P.VectorSize = 1;
break;
441 case AMDGPULibFunc::IMG2DA:
P.VectorSize = 4;
break;
442 case AMDGPULibFunc::IMG1D:
P.VectorSize = 1;
break;
443 case AMDGPULibFunc::IMG2D:
P.VectorSize = 2;
break;
444 case AMDGPULibFunc::IMG3D:
P.VectorSize = 4;
break;
446 P.PtrKind = AMDGPULibFunc::BYVALUE;
447 P.ArgType = AMDGPULibFunc::I32;
450 case E_CONSTPTR_SWAPGL: {
451 unsigned AS = AMDGPULibFunc::getAddrSpaceFromEPtrKind(
P.PtrKind);
456 P.PtrKind = AMDGPULibFunc::getEPtrKindFromAddrSpace(AS);
457 P.PtrKind |= AMDGPULibFunc::CONST;
469inline static void drop_front(StringRef& str,
size_t n = 1) {
473static bool eatTerm(StringRef& mangledName,
const char c) {
474 if (mangledName.
front() == c) {
475 drop_front(mangledName);
482static bool eatTerm(StringRef& mangledName,
const char (&str)[
N]) {
484 drop_front(mangledName,
N-1);
490static int eatNumber(StringRef& s) {
491 size_t const savedSize = s.
size();
494 n = n*10 + s.
front() -
'0';
497 return s.
size() < savedSize ? n : -1;
500static StringRef eatLengthPrefixedName(StringRef& mangledName) {
501 int const Len = eatNumber(mangledName);
502 if (Len <= 0 ||
static_cast<size_t>(Len) > mangledName.
size())
504 StringRef Res = mangledName.
substr(0, Len);
505 drop_front(mangledName, Len);
546 size_t const Len = eatNumber(mangledName);
548 case 2:
case 3:
case 4:
case 8:
case 16:
557 std::pair<StringRef, StringRef>
const P = mangledName.
split(
'_');
565 mangledName =
P.second;
570StringMap<int> ManglingRule::buildManglingRulesMap() {
571 StringMap<int>
Map(std::size(manglingRules));
573 for (
auto Rule : manglingRules)
574 Map.insert({Rule.Name,
Id++});
578bool AMDGPUMangledLibFunc::parseUnmangledName(StringRef FullName) {
579 static const StringMap<int> manglingRulesMap =
580 ManglingRule::buildManglingRulesMap();
581 FuncId =
static_cast<EFuncId
>(manglingRulesMap.
lookup(FullName));
582 return FuncId != EI_NONE;
589struct ItaniumParamParser {
590 AMDGPULibFunc::Param Prev;
591 bool parseItaniumParam(StringRef& param, AMDGPULibFunc::Param &res);
595bool ItaniumParamParser::parseItaniumParam(StringRef& param,
596 AMDGPULibFunc::Param &res) {
598 if (param.
empty())
return false;
601 if (eatTerm(param,
'P')) {
602 if (eatTerm(param,
'K')) res.
PtrKind |= AMDGPULibFunc::CONST;
603 if (eatTerm(param,
'V')) res.
PtrKind |= AMDGPULibFunc::VOLATILE;
605 if (!eatTerm(param,
"U3AS")) {
608 AS = param.
front() -
'0';
609 drop_front(param, 1);
613 res.
PtrKind = AMDGPULibFunc::BYVALUE;
617 if (eatTerm(param,
"Dv")) {
619 if (res.
VectorSize==1 || !eatTerm(param,
'_'))
return false;
623 char const TC = param.
front();
626 StringSwitch<AMDGPULibFunc::EType>(eatLengthPrefixedName(param))
627 .StartsWith(
"ocl_image1d_array", AMDGPULibFunc::IMG1DA)
628 .StartsWith(
"ocl_image1d_buffer", AMDGPULibFunc::IMG1DB)
629 .StartsWith(
"ocl_image2d_array", AMDGPULibFunc::IMG2DA)
630 .StartsWith(
"ocl_image1d", AMDGPULibFunc::IMG1D)
631 .StartsWith(
"ocl_image2d", AMDGPULibFunc::IMG2D)
632 .StartsWith(
"ocl_image3d", AMDGPULibFunc::IMG3D)
633 .Case(
"ocl_event", AMDGPULibFunc::DUMMY)
634 .Case(
"ocl_sampler", AMDGPULibFunc::DUMMY)
635 .Default(AMDGPULibFunc::DUMMY);
639 case 'h': res.
ArgType = AMDGPULibFunc::U8;
break;
640 case 't': res.
ArgType = AMDGPULibFunc::U16;
break;
641 case 'j': res.
ArgType = AMDGPULibFunc::U32;
break;
642 case 'm': res.
ArgType = AMDGPULibFunc::U64;
break;
643 case 'c': res.
ArgType = AMDGPULibFunc::I8;
break;
644 case 's': res.
ArgType = AMDGPULibFunc::I16;
break;
645 case 'i': res.
ArgType = AMDGPULibFunc::I32;
break;
646 case 'l': res.
ArgType = AMDGPULibFunc::I64;
break;
647 case 'f': res.
ArgType = AMDGPULibFunc::F32;
break;
648 case 'd': res.
ArgType = AMDGPULibFunc::F64;
break;
649 case 'D':
if (!eatTerm(param,
'h'))
return false;
650 res.
ArgType = AMDGPULibFunc::F16;
break;
652 if (!eatTerm(param,
'_')) {
654 if (!eatTerm(param,
'_'))
return false;
662 if (res.
ArgType == 0)
return false;
671 if (!parseUnmangledName(
Name))
674 const ManglingRule& Rule = manglingRules[
FuncId];
675 ItaniumParamParser Parser;
676 for (
int I=0;
I < Rule.maxLeadIndex(); ++
I) {
678 if (!Parser.parseItaniumParam(mangledName,
P))
681 if ((
I + 1) == Rule.Lead[0])
Leads[0] =
P;
682 if ((
I + 1) == Rule.Lead[1])
Leads[1] =
P;
695 if (FuncName.
empty()) {
696 F.Impl = std::unique_ptr<AMDGPULibFuncImpl>();
700 if (eatTerm(FuncName,
"_Z"))
701 F.Impl = std::make_unique<AMDGPUMangledLibFunc>();
703 F.Impl = std::make_unique<AMDGPUUnmangledLibFunc>();
704 if (
F.Impl->parseFuncName(FuncName))
707 F.Impl = std::unique_ptr<AMDGPULibFuncImpl>();
714template <
typename Stream>
715void AMDGPUMangledLibFunc::writeName(Stream &OS)
const {
716 const char *Pfx =
"";
718 case NATIVE: Pfx =
"native_";
break;
719 case HALF: Pfx =
"half_";
break;
724 }
else if (FuncId != EI_NONE) {
726 const StringRef& S = manglingRules[FuncId].Name;
788class ItaniumMangler {
792 int findSubst(
const AMDGPULibFunc::Param&
P)
const {
793 for(
unsigned I = 0;
I < Str.size(); ++
I) {
794 const AMDGPULibFunc::Param&
T = Str[
I];
795 if (
P.PtrKind ==
T.PtrKind &&
796 P.VectorSize ==
T.VectorSize &&
797 P.ArgType ==
T.ArgType) {
804 template <
typename Stream>
805 bool trySubst(Stream& os,
const AMDGPULibFunc::Param& p) {
806 int const subst = findSubst(p);
807 if (subst < 0)
return false;
811 if (subst == 0) os <<
"S_";
812 else os <<
'S' << (subst-1) <<
'_';
817 ItaniumMangler(
bool useAddrSpace)
818 : UseAddrSpace(useAddrSpace) {}
820 template <
typename Stream>
821 void operator()(Stream& os, AMDGPULibFunc::Param p) {
833 AMDGPULibFunc::Param Ptr;
836 if (trySubst(os, p))
return;
838 if (
p.PtrKind & AMDGPULibFunc::CONST) os <<
'K';
839 if (
p.PtrKind & AMDGPULibFunc::VOLATILE) os <<
'V';
840 unsigned AS = UseAddrSpace
849 if (
p.VectorSize > 1) {
850 if (trySubst(os, p))
goto exit;
852 os <<
"Dv" <<
static_cast<unsigned>(
p.VectorSize) <<
'_';
858 if (Ptr.
ArgType) Str.push_back(Ptr);
863std::string AMDGPUMangledLibFunc::mangleNameItanium()
const {
864 SmallString<128> Buf;
865 raw_svector_ostream S(Buf);
866 SmallString<128> NameBuf;
867 raw_svector_ostream
Name(NameBuf);
869 const StringRef& NameStr =
Name.str();
870 S <<
"_Z" <<
static_cast<int>(NameStr.
size()) << NameStr;
872 ItaniumMangler Mangler(
true);
873 ParamIterator
I(Leads, manglingRules[FuncId]);
875 while ((
P =
I.getNextParam()).ArgType != 0)
877 return std::string(S.str());
887 P.VectorSize = VT->getNumElements();
888 Ty = VT->getElementType();
891 switch (Ty->getTypeID()) {
981 if (
P.VectorSize > 1)
991 std::vector<Type*> Args;
994 while ((
P =
I.getNextParam()).ArgType != 0) {
999 Args.push_back(ParamTy);
1010 return manglingRules[
FuncId].getNumArgs();
1014 return UnmangledFuncInfo::getNumArgs(
FuncId);
1021 return std::string(OS.
str());
1039 if (FuncTy == CallTy)
1042 const unsigned NumParams = FuncTy->getNumParams();
1046 for (
unsigned I = 0;
I != NumParams; ++
I) {
1047 Type *FuncArgTy = FuncTy->getParamType(
I);
1049 if (FuncArgTy == CallArgTy)
1054 if (FuncVecTy && FuncVecTy->getElementType() == CallArgTy &&
1065 std::string FuncName = fInfo.
mangle();
1067 M->getValueSymbolTable().lookup(FuncName));
1068 if (!
F ||
F->isDeclaration())
1071 if (
F->hasFnAttribute(Attribute::NoBuiltin))
1077 switch (fInfo.
getId()) {
1085 if (!M->getModuleFlag(
"amdgpu-libcall-have-fast-pow"))
1097 std::string
const FuncName = fInfo.
mangle();
1099 M->getValueSymbolTable().lookup(FuncName));
1102 if (
F->hasFnAttribute(Attribute::NoBuiltin))
1104 if (!
F->isDeclaration() &&
1112 bool hasPtr =
false;
1114 PI = FuncTy->param_begin(),
1115 PE = FuncTy->param_end();
1117 const Type* argTy =
static_cast<const Type*
>(*PI);
1127 C = M->getOrInsertFunction(FuncName, FuncTy);
1131 Attr = Attr.addFnAttribute(
1133 Attr = Attr.addFnAttribute(Ctx, Attribute::NoUnwind);
1134 C = M->getOrInsertFunction(FuncName, FuncTy, Attr);
1142 for (
unsigned I = 0;
I != TableSize; ++
I)
1147bool UnmangledFuncInfo::lookup(
StringRef Name, ID &Id) {
1149 auto Loc = Map.find(Name);
1150 if (
Loc != Map.end()) {
1151 Id = toFuncId(
Loc->second);
1154 Id = AMDGPULibFunc::EI_NONE;
1160 Impl = std::make_unique<AMDGPUMangledLibFunc>(*MF);
1162 Impl = std::make_unique<AMDGPUUnmangledLibFunc>(*UMF);
1164 Impl = std::unique_ptr<AMDGPULibFuncImpl>();
1179 Impl = std::make_unique<AMDGPUMangledLibFunc>(
1184 Impl = std::make_unique<AMDGPUMangledLibFunc>(Id, FT, SignedInts);
1188 Impl = std::make_unique<AMDGPUUnmangledLibFunc>(Name, FT);
1191void AMDGPULibFunc::initMangled() {
1192 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)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
Module.h This file contains the declarations for the Module class.
static bool lookup(const GsymReader &GR, GsymDataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr, uint64_t Addr, SourceLocations &SrcLocs, llvm::Error &Err)
A Lookup helper functions.
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
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(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
static LLVM_ABI PointerType * get(LLVMContext &C, unsigned AddressSpace)
This constructs an opaque pointer to an object 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...
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
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
Get the string size.
char front() const
Get the first character in the string.
constexpr const char * data() const
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).
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)