59 unsigned char Lead[2];
60 unsigned char Param[5];
62 int maxLeadIndex()
const {
return (std::max)(Lead[0], Lead[1]); }
64 unsigned getNumArgs()
const;
66 static StringMap<int> buildManglingRulesMap();
70class UnmangledFuncInfo {
75 static const UnmangledFuncInfo Table[];
78 static const unsigned TableSize;
80 static StringMap<unsigned> buildNameMap();
83 using ID = AMDGPULibFunc::EFuncId;
84 constexpr UnmangledFuncInfo(
const char *_Name,
unsigned _NumArgs)
85 : Name(_Name), NumArgs(_NumArgs) {}
87 static bool lookup(StringRef Name, ID &Id);
88 static unsigned toIndex(ID Id) {
89 assert(
static_cast<unsigned>(Id) >
90 static_cast<unsigned>(AMDGPULibFunc::EI_LAST_MANGLED) &&
91 "Invalid unmangled library function");
92 return static_cast<unsigned>(
Id) - 1 -
93 static_cast<unsigned>(AMDGPULibFunc::EI_LAST_MANGLED);
95 static ID toFuncId(
unsigned Index) {
96 assert(Index < TableSize &&
97 "Invalid unmangled library function");
98 return static_cast<ID
>(
99 Index + 1 +
static_cast<unsigned>(AMDGPULibFunc::EI_LAST_MANGLED));
101 static unsigned getNumArgs(ID Id) {
return Table[toIndex(Id)].NumArgs; }
104unsigned ManglingRule::getNumArgs()
const {
106 while (
I < (
sizeof Param/
sizeof Param[0]) && Param[
I]) ++
I;
134static constexpr ManglingRule manglingRules[] = {
136{
"abs" , {1}, {E_ANY}},
137{
"abs_diff" , {1}, {E_ANY,E_COPY}},
138{
"acos" , {1}, {E_ANY}},
139{
"acosh" , {1}, {E_ANY}},
140{
"acospi" , {1}, {E_ANY}},
141{
"add_sat" , {1}, {E_ANY,E_COPY}},
142{
"all" , {1}, {E_ANY}},
143{
"any" , {1}, {E_ANY}},
144{
"asin" , {1}, {E_ANY}},
145{
"asinh" , {1}, {E_ANY}},
146{
"asinpi" , {1}, {E_ANY}},
147{
"async_work_group_copy" , {1}, {E_ANY,E_CONSTPTR_SWAPGL,EX_SIZET,EX_EVENT}},
148{
"async_work_group_strided_copy" , {1}, {E_ANY,E_CONSTPTR_SWAPGL,EX_SIZET,EX_SIZET,EX_EVENT}},
149{
"atan" , {1}, {E_ANY}},
150{
"atan2" , {1}, {E_ANY,E_COPY}},
151{
"atan2pi" , {1}, {E_ANY,E_COPY}},
152{
"atanh" , {1}, {E_ANY}},
153{
"atanpi" , {1}, {E_ANY}},
154{
"atomic_add" , {1}, {E_VLTLPTR_ANY,E_POINTEE}},
155{
"atomic_and" , {1}, {E_VLTLPTR_ANY,E_POINTEE}},
156{
"atomic_cmpxchg" , {1}, {E_VLTLPTR_ANY,E_POINTEE,E_POINTEE}},
157{
"atomic_dec" , {1}, {E_VLTLPTR_ANY}},
158{
"atomic_inc" , {1}, {E_VLTLPTR_ANY}},
159{
"atomic_max" , {1}, {E_VLTLPTR_ANY,E_POINTEE}},
160{
"atomic_min" , {1}, {E_VLTLPTR_ANY,E_POINTEE}},
161{
"atomic_or" , {1}, {E_VLTLPTR_ANY,E_POINTEE}},
162{
"atomic_sub" , {1}, {E_VLTLPTR_ANY,E_POINTEE}},
163{
"atomic_xchg" , {1}, {E_VLTLPTR_ANY,E_POINTEE}},
164{
"atomic_xor" , {1}, {E_VLTLPTR_ANY,E_POINTEE}},
165{
"bitselect" , {1}, {E_ANY,E_COPY,E_COPY}},
166{
"cbrt" , {1}, {E_ANY}},
167{
"ceil" , {1}, {E_ANY}},
168{
"clamp" , {1}, {E_ANY,E_COPY,E_COPY}},
169{
"clz" , {1}, {E_ANY}},
170{
"commit_read_pipe" , {1}, {E_ANY,EX_RESERVEDID}},
171{
"commit_write_pipe" , {1}, {E_ANY,EX_RESERVEDID}},
172{
"copysign" , {1}, {E_ANY,E_COPY}},
173{
"cos" , {1}, {E_ANY}},
174{
"cosh" , {1}, {E_ANY}},
175{
"cospi" , {1}, {E_ANY}},
176{
"cross" , {1}, {E_ANY,E_COPY}},
177{
"ctz" , {1}, {E_ANY}},
178{
"degrees" , {1}, {E_ANY}},
179{
"distance" , {1}, {E_ANY,E_COPY}},
180{
"divide" , {1}, {E_ANY,E_COPY}},
181{
"dot" , {1}, {E_ANY,E_COPY}},
182{
"erf" , {1}, {E_ANY}},
183{
"erfc" , {1}, {E_ANY}},
184{
"exp" , {1}, {E_ANY}},
185{
"exp10" , {1}, {E_ANY}},
186{
"exp2" , {1}, {E_ANY}},
187{
"expm1" , {1}, {E_ANY}},
188{
"fabs" , {1}, {E_ANY}},
189{
"fast_distance" , {1}, {E_ANY,E_COPY}},
190{
"fast_length" , {1}, {E_ANY}},
191{
"fast_normalize" , {1}, {E_ANY}},
192{
"fdim" , {1}, {E_ANY,E_COPY}},
193{
"floor" , {1}, {E_ANY}},
194{
"fma" , {1}, {E_ANY,E_COPY,E_COPY}},
195{
"fmax" , {1}, {E_ANY,E_COPY}},
196{
"fmin" , {1}, {E_ANY,E_COPY}},
197{
"fmod" , {1}, {E_ANY,E_COPY}},
198{
"fract" , {2}, {E_POINTEE,E_ANY}},
199{
"frexp" , {1,2}, {E_ANY,E_ANY}},
200{
"get_image_array_size" , {1}, {E_ANY}},
201{
"get_image_channel_data_type" , {1}, {E_ANY}},
202{
"get_image_channel_order" , {1}, {E_ANY}},
203{
"get_image_dim" , {1}, {E_ANY}},
204{
"get_image_height" , {1}, {E_ANY}},
205{
"get_image_width" , {1}, {E_ANY}},
206{
"get_pipe_max_packets" , {1}, {E_ANY}},
207{
"get_pipe_num_packets" , {1}, {E_ANY}},
208{
"hadd" , {1}, {E_ANY,E_COPY}},
209{
"hypot" , {1}, {E_ANY,E_COPY}},
210{
"ilogb" , {1}, {E_ANY}},
211{
"isequal" , {1}, {E_ANY,E_COPY}},
212{
"isfinite" , {1}, {E_ANY}},
213{
"isgreater" , {1}, {E_ANY,E_COPY}},
214{
"isgreaterequal" , {1}, {E_ANY,E_COPY}},
215{
"isinf" , {1}, {E_ANY}},
216{
"isless" , {1}, {E_ANY,E_COPY}},
217{
"islessequal" , {1}, {E_ANY,E_COPY}},
218{
"islessgreater" , {1}, {E_ANY,E_COPY}},
219{
"isnan" , {1}, {E_ANY}},
220{
"isnormal" , {1}, {E_ANY}},
221{
"isnotequal" , {1}, {E_ANY,E_COPY}},
222{
"isordered" , {1}, {E_ANY,E_COPY}},
223{
"isunordered" , {1}, {E_ANY,E_COPY}},
224{
"ldexp" , {1}, {E_ANY,E_SETBASE_I32}},
225{
"length" , {1}, {E_ANY}},
226{
"lgamma" , {1}, {E_ANY}},
227{
"lgamma_r" , {1,2}, {E_ANY,E_ANY}},
228{
"log" , {1}, {E_ANY}},
229{
"log10" , {1}, {E_ANY}},
230{
"log1p" , {1}, {E_ANY}},
231{
"log2" , {1}, {E_ANY}},
232{
"logb" , {1}, {E_ANY}},
233{
"mad" , {1}, {E_ANY,E_COPY,E_COPY}},
234{
"mad24" , {1}, {E_ANY,E_COPY,E_COPY}},
235{
"mad_hi" , {1}, {E_ANY,E_COPY,E_COPY}},
236{
"mad_sat" , {1}, {E_ANY,E_COPY,E_COPY}},
237{
"max" , {1}, {E_ANY,E_COPY}},
238{
"maxmag" , {1}, {E_ANY,E_COPY}},
239{
"min" , {1}, {E_ANY,E_COPY}},
240{
"minmag" , {1}, {E_ANY,E_COPY}},
241{
"mix" , {1}, {E_ANY,E_COPY,E_COPY}},
242{
"modf" , {2}, {E_POINTEE,E_ANY}},
243{
"mul24" , {1}, {E_ANY,E_COPY}},
244{
"mul_hi" , {1}, {E_ANY,E_COPY}},
245{
"nan" , {1}, {E_ANY}},
246{
"nextafter" , {1}, {E_ANY,E_COPY}},
247{
"normalize" , {1}, {E_ANY}},
248{
"popcount" , {1}, {E_ANY}},
249{
"pow" , {1}, {E_ANY,E_COPY}},
250{
"__pow_fast" , {1}, {E_ANY,E_COPY}},
251{
"pown" , {1}, {E_ANY,E_SETBASE_I32}},
252{
"__pown_fast" , {1}, {E_ANY,E_SETBASE_I32}},
253{
"powr" , {1}, {E_ANY,E_COPY}},
254{
"__powr_fast" , {1}, {E_ANY,E_COPY}},
255{
"prefetch" , {1}, {E_CONSTPTR_ANY,EX_SIZET}},
256{
"radians" , {1}, {E_ANY}},
257{
"recip" , {1}, {E_ANY}},
258{
"remainder" , {1}, {E_ANY,E_COPY}},
259{
"remquo" , {1,3}, {E_ANY,E_COPY,E_ANY}},
260{
"reserve_read_pipe" , {1}, {E_ANY,EX_UINT}},
261{
"reserve_write_pipe" , {1}, {E_ANY,EX_UINT}},
262{
"rhadd" , {1}, {E_ANY,E_COPY}},
263{
"rint" , {1}, {E_ANY}},
264{
"rootn" , {1}, {E_ANY,E_SETBASE_I32}},
265{
"__rootn_fast" , {1}, {E_ANY,E_SETBASE_I32}},
266{
"rotate" , {1}, {E_ANY,E_COPY}},
267{
"round" , {1}, {E_ANY}},
268{
"rsqrt" , {1}, {E_ANY}},
269{
"select" , {1,3}, {E_ANY,E_COPY,E_ANY}},
270{
"shuffle" , {1,2}, {E_ANY,E_ANY}},
271{
"shuffle2" , {1,3}, {E_ANY,E_COPY,E_ANY}},
272{
"sign" , {1}, {E_ANY}},
273{
"signbit" , {1}, {E_ANY}},
274{
"sin" , {1}, {E_ANY}},
275{
"sincos" , {2}, {E_POINTEE,E_ANY}},
276{
"sinh" , {1}, {E_ANY}},
277{
"sinpi" , {1}, {E_ANY}},
278{
"smoothstep" , {1}, {E_ANY,E_COPY,E_COPY}},
279{
"sqrt" , {1}, {E_ANY}},
280{
"step" , {1}, {E_ANY,E_COPY}},
281{
"sub_group_broadcast" , {1}, {E_ANY,EX_UINT}},
282{
"sub_group_commit_read_pipe" , {1}, {E_ANY,EX_RESERVEDID}},
283{
"sub_group_commit_write_pipe" , {1}, {E_ANY,EX_RESERVEDID}},
284{
"sub_group_reduce_add" , {1}, {E_ANY}},
285{
"sub_group_reduce_max" , {1}, {E_ANY}},
286{
"sub_group_reduce_min" , {1}, {E_ANY}},
287{
"sub_group_reserve_read_pipe" , {1}, {E_ANY,EX_UINT}},
288{
"sub_group_reserve_write_pipe" , {1}, {E_ANY,EX_UINT}},
289{
"sub_group_scan_exclusive_add" , {1}, {E_ANY}},
290{
"sub_group_scan_exclusive_max" , {1}, {E_ANY}},
291{
"sub_group_scan_exclusive_min" , {1}, {E_ANY}},
292{
"sub_group_scan_inclusive_add" , {1}, {E_ANY}},
293{
"sub_group_scan_inclusive_max" , {1}, {E_ANY}},
294{
"sub_group_scan_inclusive_min" , {1}, {E_ANY}},
295{
"sub_sat" , {1}, {E_ANY,E_COPY}},
296{
"tan" , {1}, {E_ANY}},
297{
"tanh" , {1}, {E_ANY}},
298{
"tanpi" , {1}, {E_ANY}},
299{
"tgamma" , {1}, {E_ANY}},
300{
"trunc" , {1}, {E_ANY}},
301{
"upsample" , {1}, {E_ANY,E_MAKEBASE_UNS}},
302{
"vec_step" , {1}, {E_ANY}},
303{
"vstore" , {3}, {E_POINTEE,EX_SIZET,E_ANY}},
304{
"vstore16" , {3}, {E_V16_OF_POINTEE,EX_SIZET,E_ANY}},
305{
"vstore2" , {3}, {E_V2_OF_POINTEE,EX_SIZET,E_ANY}},
306{
"vstore3" , {3}, {E_V3_OF_POINTEE,EX_SIZET,E_ANY}},
307{
"vstore4" , {3}, {E_V4_OF_POINTEE,EX_SIZET,E_ANY}},
308{
"vstore8" , {3}, {E_V8_OF_POINTEE,EX_SIZET,E_ANY}},
309{
"work_group_commit_read_pipe" , {1}, {E_ANY,EX_RESERVEDID}},
310{
"work_group_commit_write_pipe" , {1}, {E_ANY,EX_RESERVEDID}},
311{
"work_group_reduce_add" , {1}, {E_ANY}},
312{
"work_group_reduce_max" , {1}, {E_ANY}},
313{
"work_group_reduce_min" , {1}, {E_ANY}},
314{
"work_group_reserve_read_pipe" , {1}, {E_ANY,EX_UINT}},
315{
"work_group_reserve_write_pipe" , {1}, {E_ANY,EX_UINT}},
316{
"work_group_scan_exclusive_add" , {1}, {E_ANY}},
317{
"work_group_scan_exclusive_max" , {1}, {E_ANY}},
318{
"work_group_scan_exclusive_min" , {1}, {E_ANY}},
319{
"work_group_scan_inclusive_add" , {1}, {E_ANY}},
320{
"work_group_scan_inclusive_max" , {1}, {E_ANY}},
321{
"work_group_scan_inclusive_min" , {1}, {E_ANY}},
322{
"write_imagef" , {1}, {E_ANY,E_IMAGECOORDS,EX_FLOAT4}},
323{
"write_imagei" , {1}, {E_ANY,E_IMAGECOORDS,EX_INTV4}},
324{
"write_imageui" , {1}, {E_ANY,E_IMAGECOORDS,EX_UINTV4}},
325{
"ncos" , {1}, {E_ANY} },
326{
"nexp2" , {1}, {E_ANY} },
327{
"nfma" , {1}, {E_ANY, E_COPY, E_COPY} },
328{
"nlog2" , {1}, {E_ANY} },
329{
"nrcp" , {1}, {E_ANY} },
330{
"nrsqrt" , {1}, {E_ANY} },
331{
"nsin" , {1}, {E_ANY} },
332{
"nsqrt" , {1}, {E_ANY} },
333{
"ftz" , {1}, {E_ANY} },
334{
"fldexp" , {1}, {E_ANY, EX_UINT} },
335{
"class" , {1}, {E_ANY, EX_UINT} },
336{
"rcbrt" , {1}, {E_ANY} },
340const UnmangledFuncInfo UnmangledFuncInfo::Table[] = {
341 {
"__read_pipe_2", 4},
342 {
"__read_pipe_4", 6},
343 {
"__write_pipe_2", 4},
344 {
"__write_pipe_4", 6},
347const unsigned UnmangledFuncInfo::TableSize =
348 std::size(UnmangledFuncInfo::Table);
350static AMDGPULibFunc::Param getRetType(AMDGPULibFunc::EFuncId
id,
351 const AMDGPULibFunc::Param (&Leads)[2]) {
352 AMDGPULibFunc::Param Res = Leads[0];
355 case AMDGPULibFunc::EI_SINCOS:
356 Res.
PtrKind = AMDGPULibFunc::BYVALUE;
365 const AMDGPULibFunc::Param (&Leads)[2];
366 const ManglingRule& Rule;
369 ParamIterator(
const AMDGPULibFunc::Param (&leads)[2],
370 const ManglingRule& rule)
371 : Leads(leads), Rule(rule) {}
373 AMDGPULibFunc::Param getNextParam();
376AMDGPULibFunc::Param ParamIterator::getNextParam() {
377 AMDGPULibFunc::Param
P;
378 if (Index >=
int(
sizeof Rule.Param/
sizeof Rule.Param[0]))
return P;
380 const char R = Rule.Param[
Index];
384 P.ArgType = AMDGPULibFunc::U32;
break;
386 P.ArgType = AMDGPULibFunc::I32;
P.VectorSize = 4;
break;
388 P.ArgType = AMDGPULibFunc::U32;
P.VectorSize = 4;
break;
390 P.ArgType = AMDGPULibFunc::F32;
P.VectorSize = 4;
break;
392 P.ArgType = AMDGPULibFunc::U64;
break;
394 P.ArgType = AMDGPULibFunc::EVENT;
break;
396 P.ArgType = AMDGPULibFunc::SAMPLER;
break;
397 case EX_RESERVEDID:
break;
399 if (Index == (Rule.Lead[1] - 1))
P = Leads[1];
407 P.PtrKind = AMDGPULibFunc::BYVALUE;
break;
408 case E_V2_OF_POINTEE:
409 P.VectorSize = 2;
P.PtrKind = AMDGPULibFunc::BYVALUE;
break;
410 case E_V3_OF_POINTEE:
411 P.VectorSize = 3;
P.PtrKind = AMDGPULibFunc::BYVALUE;
break;
412 case E_V4_OF_POINTEE:
413 P.VectorSize = 4;
P.PtrKind = AMDGPULibFunc::BYVALUE;
break;
414 case E_V8_OF_POINTEE:
415 P.VectorSize = 8;
P.PtrKind = AMDGPULibFunc::BYVALUE;
break;
416 case E_V16_OF_POINTEE:
417 P.VectorSize = 16;
P.PtrKind = AMDGPULibFunc::BYVALUE;
break;
419 P.PtrKind |= AMDGPULibFunc::CONST;
break;
421 P.PtrKind |= AMDGPULibFunc::VOLATILE;
break;
423 P.ArgType = AMDGPULibFunc::I32;
break;
425 P.ArgType = AMDGPULibFunc::U32;
break;
428 P.ArgType &= ~AMDGPULibFunc::BASE_TYPE_MASK;
429 P.ArgType |= AMDGPULibFunc::UINT;
434 case AMDGPULibFunc::IMG1DA:
P.VectorSize = 2;
break;
435 case AMDGPULibFunc::IMG1DB:
P.VectorSize = 1;
break;
436 case AMDGPULibFunc::IMG2DA:
P.VectorSize = 4;
break;
437 case AMDGPULibFunc::IMG1D:
P.VectorSize = 1;
break;
438 case AMDGPULibFunc::IMG2D:
P.VectorSize = 2;
break;
439 case AMDGPULibFunc::IMG3D:
P.VectorSize = 4;
break;
441 P.PtrKind = AMDGPULibFunc::BYVALUE;
442 P.ArgType = AMDGPULibFunc::I32;
445 case E_CONSTPTR_SWAPGL: {
446 unsigned AS = AMDGPULibFunc::getAddrSpaceFromEPtrKind(
P.PtrKind);
451 P.PtrKind = AMDGPULibFunc::getEPtrKindFromAddrSpace(AS);
452 P.PtrKind |= AMDGPULibFunc::CONST;
464inline static void drop_front(StringRef& str,
size_t n = 1) {
468static bool eatTerm(StringRef& mangledName,
const char c) {
469 if (mangledName.
front() == c) {
470 drop_front(mangledName);
477static bool eatTerm(StringRef& mangledName,
const char (&str)[
N]) {
479 drop_front(mangledName,
N-1);
485static int eatNumber(StringRef& s) {
486 size_t const savedSize = s.
size();
489 n = n*10 + s.
front() -
'0';
492 return s.
size() < savedSize ? n : -1;
495static StringRef eatLengthPrefixedName(StringRef& mangledName) {
496 int const Len = eatNumber(mangledName);
497 if (Len <= 0 ||
static_cast<size_t>(Len) > mangledName.
size())
499 StringRef Res = mangledName.
substr(0, Len);
500 drop_front(mangledName, Len);
541 int const Len = eatNumber(mangledName);
543 case 2:
case 3:
case 4:
case 8:
case 16:
544 return static_cast<unsigned char>(Len);
551 std::pair<StringRef, StringRef>
const P = mangledName.
split(
'_');
559 mangledName =
P.second;
564StringMap<int> ManglingRule::buildManglingRulesMap() {
565 StringMap<int>
Map(std::size(manglingRules));
567 for (
auto Rule : manglingRules)
568 Map.insert({Rule.Name,
Id++});
572bool AMDGPUMangledLibFunc::parseUnmangledName(StringRef FullName) {
573 static const StringMap<int> manglingRulesMap =
574 ManglingRule::buildManglingRulesMap();
575 FuncId =
static_cast<EFuncId
>(manglingRulesMap.
lookup(FullName));
576 return FuncId != EI_NONE;
583struct ItaniumParamParser {
584 AMDGPULibFunc::Param Prev;
585 bool parseItaniumParam(StringRef& param, AMDGPULibFunc::Param &res);
589bool ItaniumParamParser::parseItaniumParam(StringRef& param,
590 AMDGPULibFunc::Param &res) {
592 if (param.
empty())
return false;
595 if (eatTerm(param,
'P')) {
596 if (eatTerm(param,
'K')) res.
PtrKind |= AMDGPULibFunc::CONST;
597 if (eatTerm(param,
'V')) res.
PtrKind |= AMDGPULibFunc::VOLATILE;
599 if (!eatTerm(param,
"U3AS")) {
602 AS = param.
front() -
'0';
603 drop_front(param, 1);
607 res.
PtrKind = AMDGPULibFunc::BYVALUE;
611 if (eatTerm(param,
"Dv")) {
613 if (res.
VectorSize==1 || !eatTerm(param,
'_'))
return false;
617 char const TC = param.
front();
620 StringSwitch<AMDGPULibFunc::EType>(eatLengthPrefixedName(param))
621 .StartsWith(
"ocl_image1d_array", AMDGPULibFunc::IMG1DA)
622 .StartsWith(
"ocl_image1d_buffer", AMDGPULibFunc::IMG1DB)
623 .StartsWith(
"ocl_image2d_array", AMDGPULibFunc::IMG2DA)
624 .StartsWith(
"ocl_image1d", AMDGPULibFunc::IMG1D)
625 .StartsWith(
"ocl_image2d", AMDGPULibFunc::IMG2D)
626 .StartsWith(
"ocl_image3d", AMDGPULibFunc::IMG3D)
627 .Case(
"ocl_event", AMDGPULibFunc::DUMMY)
628 .Case(
"ocl_sampler", AMDGPULibFunc::DUMMY)
629 .Default(AMDGPULibFunc::DUMMY);
633 case 'h': res.
ArgType = AMDGPULibFunc::U8;
break;
634 case 't': res.
ArgType = AMDGPULibFunc::U16;
break;
635 case 'j': res.
ArgType = AMDGPULibFunc::U32;
break;
636 case 'm': res.
ArgType = AMDGPULibFunc::U64;
break;
637 case 'c': res.
ArgType = AMDGPULibFunc::I8;
break;
638 case 's': res.
ArgType = AMDGPULibFunc::I16;
break;
639 case 'i': res.
ArgType = AMDGPULibFunc::I32;
break;
640 case 'l': res.
ArgType = AMDGPULibFunc::I64;
break;
641 case 'f': res.
ArgType = AMDGPULibFunc::F32;
break;
642 case 'd': res.
ArgType = AMDGPULibFunc::F64;
break;
643 case 'D':
if (!eatTerm(param,
'h'))
return false;
644 res.
ArgType = AMDGPULibFunc::F16;
break;
646 if (!eatTerm(param,
'_')) {
648 if (!eatTerm(param,
'_'))
return false;
656 if (res.
ArgType == 0)
return false;
665 if (!parseUnmangledName(
Name))
668 const ManglingRule& Rule = manglingRules[
FuncId];
669 ItaniumParamParser Parser;
670 for (
int I=0;
I < Rule.maxLeadIndex(); ++
I) {
672 if (!Parser.parseItaniumParam(mangledName,
P))
675 if ((
I + 1) == Rule.Lead[0])
Leads[0] =
P;
676 if ((
I + 1) == Rule.Lead[1])
Leads[1] =
P;
689 if (FuncName.
empty()) {
690 F.Impl = std::unique_ptr<AMDGPULibFuncImpl>();
694 if (eatTerm(FuncName,
"_Z"))
695 F.Impl = std::make_unique<AMDGPUMangledLibFunc>();
697 F.Impl = std::make_unique<AMDGPUUnmangledLibFunc>();
698 if (
F.Impl->parseFuncName(FuncName))
701 F.Impl = std::unique_ptr<AMDGPULibFuncImpl>();
708template <
typename Stream>
709void AMDGPUMangledLibFunc::writeName(Stream &OS)
const {
710 const char *Pfx =
"";
712 case NATIVE: Pfx =
"native_";
break;
713 case HALF: Pfx =
"half_";
break;
718 }
else if (FuncId != EI_NONE) {
720 const StringRef& S = manglingRules[FuncId].Name;
726 return mangleNameItanium(CLOpts);
784class ItaniumMangler {
787 bool OCLManglingMismatchWA;
789 int findSubst(
const AMDGPULibFunc::Param&
P)
const {
790 for(
unsigned I = 0;
I < Str.size(); ++
I) {
791 const AMDGPULibFunc::Param&
T = Str[
I];
792 if (
P.PtrKind ==
T.PtrKind &&
793 P.VectorSize ==
T.VectorSize &&
794 P.ArgType ==
T.ArgType) {
801 template <
typename Stream>
802 bool trySubst(Stream& os,
const AMDGPULibFunc::Param& p) {
803 int const subst = findSubst(p);
804 if (subst < 0)
return false;
808 if (subst == 0) os <<
"S_";
809 else os <<
'S' << (subst-1) <<
'_';
814 ItaniumMangler(
bool useAddrSpace,
bool OCLManglingMismatchWA)
815 : UseAddrSpace(useAddrSpace),
816 OCLManglingMismatchWA(OCLManglingMismatchWA) {}
818 template <
typename Stream>
819 void operator()(Stream& os, AMDGPULibFunc::Param p) {
831 AMDGPULibFunc::Param Ptr;
834 if (trySubst(os, p))
return;
836 if (
p.PtrKind & AMDGPULibFunc::CONST) os <<
'K';
837 if (
p.PtrKind & AMDGPULibFunc::VOLATILE) os <<
'V';
838 unsigned AS = UseAddrSpace
841 if (OCLManglingMismatchWA || AS != 0)
847 if (
p.VectorSize > 1) {
848 if (trySubst(os, p))
goto exit;
850 os <<
"Dv" <<
static_cast<unsigned>(
p.VectorSize) <<
'_';
856 if (Ptr.
ArgType) Str.push_back(Ptr);
862AMDGPUMangledLibFunc::mangleNameItanium(
const AMDGPUOptions &CLOpts)
const {
863 SmallString<128> Buf;
864 raw_svector_ostream S(Buf);
865 SmallString<128> NameBuf;
866 raw_svector_ostream
Name(NameBuf);
868 const StringRef& NameStr =
Name.str();
869 S <<
"_Z" <<
static_cast<int>(NameStr.
size()) << NameStr;
871 ItaniumMangler Mangler(
true, CLOpts.enable_ocl_mangling_mismatch_workaround);
872 ParamIterator
I(Leads, manglingRules[FuncId]);
874 while ((
P =
I.getNextParam()).ArgType != 0)
876 return std::string(S.str());
886 P.VectorSize =
static_cast<unsigned char>(VT->getNumElements());
887 Ty = VT->getElementType();
890 switch (Ty->getTypeID()) {
980 if (
P.VectorSize > 1)
990 std::vector<Type*> Args;
993 while ((
P =
I.getNextParam()).ArgType != 0) {
998 Args.push_back(ParamTy);
1009 return manglingRules[
FuncId].getNumArgs();
1013 return UnmangledFuncInfo::getNumArgs(
FuncId);
1020 return std::string(OS.
str());
1038 if (FuncTy == CallTy)
1041 const unsigned NumParams = FuncTy->getNumParams();
1045 for (
unsigned I = 0;
I != NumParams; ++
I) {
1046 Type *FuncArgTy = FuncTy->getParamType(
I);
1048 if (FuncArgTy == CallArgTy)
1053 if (FuncVecTy && FuncVecTy->getElementType() == CallArgTy &&
1064 std::string FuncName =
1065 fInfo.
mangle(M->getContext().getLibraryOptions().get<AMDGPUOptions>());
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 =
1098 fInfo.
mangle(M->getContext().getLibraryOptions().get<AMDGPUOptions>());
1100 M->getValueSymbolTable().lookup(FuncName));
1103 if (
F->hasFnAttribute(Attribute::NoBuiltin))
1105 if (!
F->isDeclaration() &&
1113 bool hasPtr =
false;
1115 PI = FuncTy->param_begin(),
1116 PE = FuncTy->param_end();
1118 const Type* argTy =
static_cast<const Type*
>(*PI);
1128 C = M->getOrInsertFunction(FuncName, FuncTy);
1132 Attr = Attr.addFnAttribute(
1134 Attr = Attr.addFnAttribute(Ctx, Attribute::NoUnwind);
1135 C = M->getOrInsertFunction(FuncName, FuncTy, Attr);
1143 for (
unsigned I = 0;
I != TableSize; ++
I)
1148bool UnmangledFuncInfo::lookup(
StringRef Name, ID &Id) {
1150 auto Loc = Map.find(Name);
1151 if (
Loc != Map.end()) {
1152 Id = toFuncId(
Loc->second);
1155 Id = AMDGPULibFunc::EI_NONE;
1161 Impl = std::make_unique<AMDGPUMangledLibFunc>(*MF);
1163 Impl = std::make_unique<AMDGPUUnmangledLibFunc>(*UMF);
1165 Impl = std::unique_ptr<AMDGPULibFuncImpl>();
1180 Impl = std::make_unique<AMDGPUMangledLibFunc>(
1185 Impl = std::make_unique<AMDGPUMangledLibFunc>(Id, FT, SignedInts);
1189 Impl = std::make_unique<AMDGPUUnmangledLibFunc>(Name, FT);
1192void AMDGPULibFunc::initMangled() {
1193 Impl = std::make_unique<AMDGPUMangledLibFunc>();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the StringMap class.
static unsigned char parseVecSize(StringRef &mangledName)
static AMDGPULibFunc::ENamePrefix parseNamePrefix(StringRef &mangledName)
static const char * getItaniumTypeName(AMDGPULibFunc::EType T)
static Type * getIntrinsicParamType(LLVMContext &C, const AMDGPULibFunc::Param &P, bool UseAddrSpace)
Base class for AMDGPU specific classes of TargetSubtarget.
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 getAddrSpaceFromEPtrKind(unsigned Kind)
static bool isMangled(EFuncId Id)
static unsigned char getEPtrKindFromAddrSpace(unsigned AS)
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)
std::string mangle(const AMDGPUOptions &CLOpts) const
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.
AMDGPULibFunc & operator=(const AMDGPULibFunc &F)
Param * getLeads()
Get leading parameters for mangled lib functions.
unsigned getNumArgs() const
std::string mangle(const AMDGPUOptions &CLOpts) const override
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
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).
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)