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) {
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; }
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();
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();
971 if (
P.VectorSize > 1)
981 std::vector<Type*> Args;
982 ParamIterator
I(Leads, manglingRules[
FuncId]);
984 while ((
P =
I.getNextParam()).ArgType != 0) {
989 Args.push_back(ParamTy);
998 return manglingRules[
FuncId].getNumArgs();
1002 return UnmangledFuncInfo::getNumArgs(
FuncId);
1009 return std::string(
OS.str());
1027 if (FuncTy == CallTy)
1034 for (
unsigned I = 0;
I != NumParams; ++
I) {
1037 if (FuncArgTy == CallArgTy)
1041 auto *FuncVecTy = dyn_cast<VectorType>(FuncArgTy);
1042 if (FuncVecTy && FuncVecTy->getElementType() == CallArgTy &&
1043 allowsImplicitVectorSplat(
I))
1053 std::string FuncName = fInfo.
mangle();
1054 Function *
F = dyn_cast_or_null<Function>(
1055 M->getValueSymbolTable().lookup(FuncName));
1056 if (!
F ||
F->isDeclaration())
1059 if (
F->hasFnAttribute(Attribute::NoBuiltin))
1070 std::string
const FuncName = fInfo.
mangle();
1071 Function *
F = dyn_cast_or_null<Function>(
1072 M->getValueSymbolTable().lookup(FuncName));
1075 if (
F->hasFnAttribute(Attribute::NoBuiltin))
1077 if (!
F->isDeclaration() &&
1084 bool hasPtr =
false;
1089 const Type* argTy =
static_cast<const Type*
>(*PI);
1099 C = M->getOrInsertFunction(FuncName, FuncTy);
1106 C = M->getOrInsertFunction(FuncName, FuncTy, Attr);
1114 for (
unsigned I = 0;
I != TableSize; ++
I)
1121 auto Loc = Map.find(
Name);
1122 if (Loc != Map.end()) {
1123 Id = toFuncId(Loc->second);
1131 if (
auto *MF = dyn_cast<AMDGPUMangledLibFunc>(
F.Impl.get()))
1132 Impl = std::make_unique<AMDGPUMangledLibFunc>(*MF);
1133 else if (
auto *UMF = dyn_cast<AMDGPUUnmangledLibFunc>(
F.Impl.get()))
1134 Impl = std::make_unique<AMDGPUUnmangledLibFunc>(*UMF);
1136 Impl = std::unique_ptr<AMDGPULibFuncImpl>();
1149 Impl = std::make_unique<AMDGPUMangledLibFunc>(
1150 Id, *cast<AMDGPUMangledLibFunc>(CopyFrom.Impl.get()));
1154 Impl = std::make_unique<AMDGPUMangledLibFunc>(Id, FT, SignedInts);
1158 Impl = std::make_unique<AMDGPUUnmangledLibFunc>(
Name, FT);
1161void AMDGPULibFunc::initMangled() {
1162 Impl = std::make_unique<AMDGPUMangledLibFunc>();
1168 return cast<AMDGPUMangledLibFunc>(Impl.get())->Leads;
1172 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)
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)
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(const Module &M) const
bool isCompatibleSignature(const Module &M, 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
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
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.
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
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)
StringSwitch & StartsWith(StringLiteral S, T Value)
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)
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)