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;
76class UnmangledFuncInfo {
81 static const UnmangledFuncInfo Table[];
84 static const unsigned TableSize;
90 constexpr UnmangledFuncInfo(
const char *_Name,
unsigned _NumArgs)
91 :
Name(_Name), NumArgs(_NumArgs) {}
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) {
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; }
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);
358 case AMDGPULibFunc::EI_SINCOS:
359 Res.
PtrKind = AMDGPULibFunc::BYVALUE;
369 const ManglingRule& Rule;
373 const ManglingRule& rule)
374 : Leads(leads), Rule(rule) {}
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;
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);
489 size_t const savedSize = s.
size();
492 n = n*10 + s.
front() -
'0';
495 return s.
size() < savedSize ? n : -1;
499 int const Len = eatNumber(mangledName);
500 if (Len <= 0 ||
static_cast<size_t>(Len) > mangledName.
size())
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;
571 for (
auto Rule : manglingRules)
572 Map.insert({Rule.Name,
Id++});
576bool AMDGPUMangledLibFunc::parseUnmangledName(
StringRef FullName) {
578 ManglingRule::buildManglingRulesMap();
587struct ItaniumParamParser {
593bool ItaniumParamParser::parseItaniumParam(
StringRef& param,
596 if (param.
empty())
return false;
599 if (eatTerm(param,
'P')) {
603 if (!eatTerm(param,
"U3AS")) {
606 AS = param.
front() -
'0';
607 drop_front(param, 1);
615 if (eatTerm(param,
"Dv")) {
617 if (res.
VectorSize==1 || !eatTerm(param,
'_'))
return false;
621 char const TC = param.
front();
624 (eatLengthPrefixedName(param))
647 case 'D':
if (!eatTerm(param,
'h'))
return false;
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;
793class ItaniumMangler {
798 for(
unsigned I = 0;
I < Str.size(); ++
I) {
800 if (
P.PtrKind ==
T.PtrKind &&
801 P.VectorSize ==
T.VectorSize &&
802 P.ArgType ==
T.ArgType) {
809 template <
typename Stream>
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>
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 {
875 S <<
"_Z" <<
static_cast<int>(NameStr.
size()) << NameStr;
880 while ((
P =
I.getNextParam()).ArgType != 0)
882 return std::string(S.str());
892 P.VectorSize = VT->getNumElements();
893 Ty = VT->getElementType();
965 if (
P.VectorSize > 1)
976 std::vector<Type*> Args;
977 ParamIterator
I(Leads, manglingRules[
FuncId]);
979 while ((
P=
I.getNextParam()).ArgType != 0)
988 return manglingRules[
FuncId].getNumArgs();
992 return UnmangledFuncInfo::getNumArgs(
FuncId);
999 return std::string(
OS.str());
1008 std::string FuncName = fInfo.
mangle();
1009 Function *
F = dyn_cast_or_null<Function>(
1010 M->getValueSymbolTable().lookup(FuncName));
1011 if (!
F ||
F->isDeclaration())
1014 if (
F->hasFnAttribute(Attribute::NoBuiltin))
1025 std::string
const FuncName = fInfo.
mangle();
1026 Function *
F = dyn_cast_or_null<Function>(
1027 M->getValueSymbolTable().lookup(FuncName));
1030 if (
F->hasFnAttribute(Attribute::NoBuiltin))
1032 if (!
F->isDeclaration() &&
1039 bool hasPtr =
false;
1044 const Type* argTy =
static_cast<const Type*
>(*PI);
1054 C = M->getOrInsertFunction(FuncName, FuncTy);
1061 C = M->getOrInsertFunction(FuncName, FuncTy, Attr);
1069 for (
unsigned I = 0;
I != TableSize; ++
I)
1076 auto Loc = Map.find(
Name);
1077 if (Loc != Map.end()) {
1078 Id = toFuncId(Loc->second);
1086 if (
auto *MF = dyn_cast<AMDGPUMangledLibFunc>(
F.Impl.get()))
1087 Impl = std::make_unique<AMDGPUMangledLibFunc>(*MF);
1088 else if (
auto *UMF = dyn_cast<AMDGPUUnmangledLibFunc>(
F.Impl.get()))
1089 Impl = std::make_unique<AMDGPUUnmangledLibFunc>(*UMF);
1091 Impl = std::unique_ptr<AMDGPULibFuncImpl>();
1104 Impl = std::make_unique<AMDGPUMangledLibFunc>(
1105 Id, *cast<AMDGPUMangledLibFunc>(CopyFrom.Impl.get()));
1109 Impl = std::make_unique<AMDGPUMangledLibFunc>(Id, FT, SignedInts);
1113 Impl = std::make_unique<AMDGPUUnmangledLibFunc>(
Name, FT);
1116void AMDGPULibFunc::initMangled() {
1117 Impl = std::make_unique<AMDGPUMangledLibFunc>();
1123 return cast<AMDGPUMangledLibFunc>(Impl.get())->Leads;
1127 return cast<const AMDGPUMangledLibFunc>(Impl.get())->Leads;
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 Type * getIntrinsicParamType(LLVMContext &C, const AMDGPULibFunc::Param &P, bool useAddrSpace)
static AMDGPULibFunc::ENamePrefix parseNamePrefix(StringRef &mangledName)
static const char * getItaniumTypeName(AMDGPULibFunc::EType T)
static int parseVecSize(StringRef &mangledName)
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.
Module.h This file contains the declarations for the Module class.
static StringRef getName(Value *V)
static bool isDigit(const char C)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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)
Wrapper class for AMDGPULIbFuncImpl.
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(Module &M) const
bool isCompatibleSignature(const FunctionType *FuncTy) const
std::string mangle() const
AMDGPULibFunc & operator=(const AMDGPULibFunc &F)
Param * getLeads()
Get leading parameters for mangled lib functions.
static StringRef getUnmangledName(StringRef MangledName)
unsigned getNumArgs() const override
FunctionType * getFunctionType(Module &M) 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.
std::string mangle() const override
unsigned getNumArgs() const override
bool parseFuncName(StringRef &Name) override
AttributeList addFnAttribute(LLVMContext &C, Attribute::AttrKind Kind) const
Add a function attribute to the list.
static Attribute getWithMemoryEffects(LLVMContext &Context, MemoryEffects ME)
Class to represent fixed width SIMD vectors.
static 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.
param_iterator param_begin() const
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.
param_iterator param_end() const
static 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()
Create MemoryEffectsBase that can read any memory.
A Module instance is used to store all the information related to an LLVM module.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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)
static StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
The instances of the Type class are immutable: once they are created, they are never changed.
static Type * getHalfTy(LLVMContext &C)
static Type * getDoubleTy(LLVMContext &C)
PointerType * getPointerTo(unsigned AddrSpace=0) const
Return a pointer to the current type.
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 IntegerType * getInt16Ty(LLVMContext &C)
static IntegerType * getInt8Ty(LLVMContext &C)
static IntegerType * getInt32Ty(LLVMContext &C)
static IntegerType * getInt64Ty(LLVMContext &C)
static Type * getFloatTy(LLVMContext &C)
TypeID getTypeID() const
Return the type id for the type.
raw_ostream & write(unsigned char C)
A raw_ostream that writes to an SmallVector or SmallString.
#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).
@ 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.
static Param getFromTy(Type *Ty, bool Signed)