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)