LLVM 20.0.0git
AMDGPULibFunc.cpp
Go to the documentation of this file.
1//===-- AMDGPULibFunc.cpp -------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains utility functions to work with Itanium mangled names
10//
11//===----------------------------------------------------------------------===//
12
13#include "AMDGPULibFunc.h"
14#include "AMDGPU.h"
16#include "llvm/ADT/StringMap.h"
19#include "llvm/IR/Function.h"
20#include "llvm/IR/Module.h"
23#include "llvm/Support/ModRef.h"
25
26using namespace llvm;
27
29 "amdgpu-enable-ocl-mangling-mismatch-workaround", cl::init(true),
31 cl::desc("Enable the workaround for OCL name mangling mismatch."));
32
33namespace {
34
35enum EManglingParam {
36 E_NONE,
37 EX_EVENT,
38 EX_FLOAT4,
39 EX_INTV4,
40 EX_RESERVEDID,
41 EX_SAMPLER,
42 EX_SIZET,
43 EX_UINT,
44 EX_UINTV4,
45 E_ANY,
46 E_CONSTPTR_ANY,
47 E_CONSTPTR_SWAPGL,
48 E_COPY,
49 E_IMAGECOORDS,
50 E_POINTEE,
51 E_SETBASE_I32,
52 E_SETBASE_U32,
53 E_MAKEBASE_UNS,
54 E_V16_OF_POINTEE,
55 E_V2_OF_POINTEE,
56 E_V3_OF_POINTEE,
57 E_V4_OF_POINTEE,
58 E_V8_OF_POINTEE,
59 E_VLTLPTR_ANY,
60};
61
62struct ManglingRule {
63 const char *Name;
64 unsigned char Lead[2];
65 unsigned char Param[5];
66
67 int maxLeadIndex() const { return (std::max)(Lead[0], Lead[1]); }
68 int getNumLeads() const { return (Lead[0] ? 1 : 0) + (Lead[1] ? 1 : 0); }
69
70 unsigned getNumArgs() const;
71
72 static StringMap<int> buildManglingRulesMap();
73};
74
75// Information about library functions with unmangled names.
76class UnmangledFuncInfo {
77 const char *Name;
78 unsigned NumArgs;
79
80 // Table for all lib functions with unmangled names.
81 static const UnmangledFuncInfo Table[];
82
83 // Number of entries in Table.
84 static const unsigned TableSize;
85
86 static StringMap<unsigned> buildNameMap();
87
88public:
90 constexpr UnmangledFuncInfo(const char *_Name, unsigned _NumArgs)
91 : Name(_Name), NumArgs(_NumArgs) {}
92 // Get index to Table by function name.
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);
100 }
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));
106 }
107 static unsigned getNumArgs(ID Id) { return Table[toIndex(Id)].NumArgs; }
108 static StringRef getName(ID Id) { return Table[toIndex(Id)].Name; }
109};
110
111unsigned ManglingRule::getNumArgs() const {
112 unsigned I=0;
113 while (I < (sizeof Param/sizeof Param[0]) && Param[I]) ++I;
114 return I;
115}
116
117// This table describes function formal argument type rules. The order of rules
118// corresponds to the EFuncId enum at AMDGPULibFunc.h
119//
120// "<func name>", { <leads> }, { <param rules> }
121// where:
122// <leads> - list of integers that are one-based indexes of formal argument
123// used to mangle a function name. Other argument types are derived from types
124// of these 'leads'. The order of integers in this list correspond to the
125// order in which these arguments are mangled in the EDG mangling scheme. The
126// same order should be preserved for arguments in the AMDGPULibFunc structure
127// when it is used for mangling. For example:
128// { "vstorea_half", {3,1}, {E_ANY,EX_SIZET,E_ANY}},
129// will be mangled in EDG scheme as vstorea_half_<3dparam>_<1stparam>
130// When mangling from code use:
131// AMDGPULibFunc insc;
132// insc.param[0] = ... // describe 3rd parameter
133// insc.param[1] = ... // describe 1rd parameter
134//
135// <param rules> - list of rules used to derive all of the function formal
136// argument types. EX_ prefixed are simple types, other derived from the
137// latest 'lead' argument type in the order of encoding from first to last.
138// E_ANY - use prev lead type, E_CONSTPTR_ANY - make const pointer out of
139// prev lead type, etc. see ParamIterator::getNextParam() for details.
140
141static constexpr ManglingRule manglingRules[] = {
142{ "", {0}, {0} },
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} },
340};
341
342// Library functions with unmangled name.
343const UnmangledFuncInfo UnmangledFuncInfo::Table[] = {
344 {"__read_pipe_2", 4},
345 {"__read_pipe_4", 6},
346 {"__write_pipe_2", 4},
347 {"__write_pipe_4", 6},
348};
349
350const unsigned UnmangledFuncInfo::TableSize =
351 std::size(UnmangledFuncInfo::Table);
352
354 const AMDGPULibFunc::Param (&Leads)[2]) {
355 AMDGPULibFunc::Param Res = Leads[0];
356 // TBD - This switch may require to be extended for other intrinsics
357 switch (id) {
358 case AMDGPULibFunc::EI_SINCOS:
359 Res.PtrKind = AMDGPULibFunc::BYVALUE;
360 break;
361 default:
362 break;
363 }
364 return Res;
365}
366
367class ParamIterator {
368 const AMDGPULibFunc::Param (&Leads)[2];
369 const ManglingRule& Rule;
370 int Index = 0;
371public:
372 ParamIterator(const AMDGPULibFunc::Param (&leads)[2],
373 const ManglingRule& rule)
374 : Leads(leads), Rule(rule) {}
375
376 AMDGPULibFunc::Param getNextParam();
377};
378
379AMDGPULibFunc::Param ParamIterator::getNextParam() {
381 if (Index >= int(sizeof Rule.Param/sizeof Rule.Param[0])) return P;
382
383 const char R = Rule.Param[Index];
384 switch (R) {
385 case E_NONE: break;
386 case EX_UINT:
387 P.ArgType = AMDGPULibFunc::U32; break;
388 case EX_INTV4:
389 P.ArgType = AMDGPULibFunc::I32; P.VectorSize = 4; break;
390 case EX_UINTV4:
391 P.ArgType = AMDGPULibFunc::U32; P.VectorSize = 4; break;
392 case EX_FLOAT4:
393 P.ArgType = AMDGPULibFunc::F32; P.VectorSize = 4; break;
394 case EX_SIZET:
395 P.ArgType = AMDGPULibFunc::U64; break;
396 case EX_EVENT:
397 P.ArgType = AMDGPULibFunc::EVENT; break;
398 case EX_SAMPLER:
399 P.ArgType = AMDGPULibFunc::SAMPLER; break;
400 case EX_RESERVEDID: break; // TBD
401 default:
402 if (Index == (Rule.Lead[1] - 1)) P = Leads[1];
403 else P = Leads[0];
404
405 switch (R) {
406 case E_ANY:
407 case E_COPY: break;
408
409 case E_POINTEE:
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;
421 case E_CONSTPTR_ANY:
422 P.PtrKind |= AMDGPULibFunc::CONST; break;
423 case E_VLTLPTR_ANY:
424 P.PtrKind |= AMDGPULibFunc::VOLATILE; break;
425 case E_SETBASE_I32:
426 P.ArgType = AMDGPULibFunc::I32; break;
427 case E_SETBASE_U32:
428 P.ArgType = AMDGPULibFunc::U32; break;
429
430 case E_MAKEBASE_UNS:
431 P.ArgType &= ~AMDGPULibFunc::BASE_TYPE_MASK;
432 P.ArgType |= AMDGPULibFunc::UINT;
433 break;
434
435 case E_IMAGECOORDS:
436 switch (P.ArgType) {
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;
443 }
444 P.PtrKind = AMDGPULibFunc::BYVALUE;
445 P.ArgType = AMDGPULibFunc::I32;
446 break;
447
448 case E_CONSTPTR_SWAPGL: {
449 unsigned AS = AMDGPULibFunc::getAddrSpaceFromEPtrKind(P.PtrKind);
450 switch (AS) {
453 }
454 P.PtrKind = AMDGPULibFunc::getEPtrKindFromAddrSpace(AS);
455 P.PtrKind |= AMDGPULibFunc::CONST;
456 break;
457 }
458
459 default:
460 llvm_unreachable("Unhandled param rule");
461 }
462 }
463 ++Index;
464 return P;
465}
466
467inline static void drop_front(StringRef& str, size_t n = 1) {
468 str = str.drop_front(n);
469}
470
471static bool eatTerm(StringRef& mangledName, const char c) {
472 if (mangledName.front() == c) {
473 drop_front(mangledName);
474 return true;
475 }
476 return false;
477}
478
479template <size_t N>
480static bool eatTerm(StringRef& mangledName, const char (&str)[N]) {
481 if (mangledName.starts_with(StringRef(str, N - 1))) {
482 drop_front(mangledName, N-1);
483 return true;
484 }
485 return false;
486}
487
488static int eatNumber(StringRef& s) {
489 size_t const savedSize = s.size();
490 int n = 0;
491 while (!s.empty() && isDigit(s.front())) {
492 n = n*10 + s.front() - '0';
493 drop_front(s);
494 }
495 return s.size() < savedSize ? n : -1;
496}
497
498static StringRef eatLengthPrefixedName(StringRef& mangledName) {
499 int const Len = eatNumber(mangledName);
500 if (Len <= 0 || static_cast<size_t>(Len) > mangledName.size())
501 return StringRef();
502 StringRef Res = mangledName.substr(0, Len);
503 drop_front(mangledName, Len);
504 return Res;
505}
506
507} // end anonymous namespace
508
510 FuncId = EI_NONE;
511 FKind = NOPFX;
512 Leads[0].reset();
513 Leads[1].reset();
514 Name.clear();
515}
516
518 FuncId = EI_NONE;
519 FuncTy = nullptr;
520}
521
523 EFuncId id, const AMDGPUMangledLibFunc &copyFrom) {
524 FuncId = id;
525 FKind = copyFrom.FKind;
526 Leads[0] = copyFrom.Leads[0];
527 Leads[1] = copyFrom.Leads[1];
528}
529
531 bool SignedInts) {
532 FuncId = id;
533 unsigned NumArgs = FT->getNumParams();
534 if (NumArgs >= 1)
535 Leads[0] = Param::getFromTy(FT->getParamType(0), SignedInts);
536 if (NumArgs >= 2)
537 Leads[1] = Param::getFromTy(FT->getParamType(1), SignedInts);
538}
539
540///////////////////////////////////////////////////////////////////////////////
541// Demangling
542
543static int parseVecSize(StringRef& mangledName) {
544 size_t const Len = eatNumber(mangledName);
545 switch (Len) {
546 case 2: case 3: case 4: case 8: case 16:
547 return Len;
548 default:
549 break;
550 }
551 return 1;
552}
553
555 std::pair<StringRef, StringRef> const P = mangledName.split('_');
558 .Case("native", AMDGPULibFunc::NATIVE)
559 .Case("half" , AMDGPULibFunc::HALF)
561
562 if (Pfx != AMDGPULibFunc::NOPFX)
563 mangledName = P.second;
564
565 return Pfx;
566}
567
568StringMap<int> ManglingRule::buildManglingRulesMap() {
569 StringMap<int> Map(std::size(manglingRules));
570 int Id = 0;
571 for (auto Rule : manglingRules)
572 Map.insert({Rule.Name, Id++});
573 return Map;
574}
575
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;
581}
582
583///////////////////////////////////////////////////////////////////////////////
584// Itanium Demangling
585
586namespace {
587struct ItaniumParamParser {
589 bool parseItaniumParam(StringRef& param, AMDGPULibFunc::Param &res);
590};
591} // namespace
592
593bool ItaniumParamParser::parseItaniumParam(StringRef& param,
595 res.reset();
596 if (param.empty()) return false;
597
598 // parse pointer prefix
599 if (eatTerm(param, 'P')) {
600 if (eatTerm(param, 'K')) res.PtrKind |= AMDGPULibFunc::CONST;
601 if (eatTerm(param, 'V')) res.PtrKind |= AMDGPULibFunc::VOLATILE;
602 unsigned AS;
603 if (!eatTerm(param, "U3AS")) {
604 AS = 0;
605 } else {
606 AS = param.front() - '0';
607 drop_front(param, 1);
608 }
610 } else {
612 }
613
614 // parse vector size
615 if (eatTerm(param,"Dv")) {
616 res.VectorSize = parseVecSize(param);
617 if (res.VectorSize==1 || !eatTerm(param, '_')) return false;
618 }
619
620 // parse type
621 char const TC = param.front();
622 if (isDigit(TC)) {
623 res.ArgType =
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)
634 } else {
635 drop_front(param);
636 switch (TC) {
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;
649 case 'S':
650 if (!eatTerm(param, '_')) {
651 eatNumber(param);
652 if (!eatTerm(param, '_')) return false;
653 }
654 res.VectorSize = Prev.VectorSize;
655 res.ArgType = Prev.ArgType;
656 break;
657 default:;
658 }
659 }
660 if (res.ArgType == 0) return false;
661 Prev.VectorSize = res.VectorSize;
662 Prev.ArgType = res.ArgType;
663 return true;
664}
665
667 StringRef Name = eatLengthPrefixedName(mangledName);
669 if (!parseUnmangledName(Name))
670 return false;
671
672 const ManglingRule& Rule = manglingRules[FuncId];
673 ItaniumParamParser Parser;
674 for (int I=0; I < Rule.maxLeadIndex(); ++I) {
675 Param P;
676 if (!Parser.parseItaniumParam(mangledName, P))
677 return false;
678
679 if ((I + 1) == Rule.Lead[0]) Leads[0] = P;
680 if ((I + 1) == Rule.Lead[1]) Leads[1] = P;
681 }
682 return true;
683}
684
686 if (!UnmangledFuncInfo::lookup(Name, FuncId))
687 return false;
688 setName(Name);
689 return true;
690}
691
693 if (FuncName.empty()) {
694 F.Impl = std::unique_ptr<AMDGPULibFuncImpl>();
695 return false;
696 }
697
698 if (eatTerm(FuncName, "_Z"))
699 F.Impl = std::make_unique<AMDGPUMangledLibFunc>();
700 else
701 F.Impl = std::make_unique<AMDGPUUnmangledLibFunc>();
702 if (F.Impl->parseFuncName(FuncName))
703 return true;
704
705 F.Impl = std::unique_ptr<AMDGPULibFuncImpl>();
706 return false;
707}
708
710 StringRef S = mangledName;
711 if (eatTerm(S, "_Z"))
712 return eatLengthPrefixedName(S);
713 return StringRef();
714}
715
716///////////////////////////////////////////////////////////////////////////////
717// Mangling
718
719template <typename Stream>
720void AMDGPUMangledLibFunc::writeName(Stream &OS) const {
721 const char *Pfx = "";
722 switch (FKind) {
723 case NATIVE: Pfx = "native_"; break;
724 case HALF: Pfx = "half_"; break;
725 default: break;
726 }
727 if (!Name.empty()) {
728 OS << Pfx << Name;
729 } else if (FuncId != EI_NONE) {
730 OS << Pfx;
731 const StringRef& S = manglingRules[FuncId].Name;
732 OS.write(S.data(), S.size());
733 }
734}
735
736std::string AMDGPUMangledLibFunc::mangle() const { return mangleNameItanium(); }
737
738///////////////////////////////////////////////////////////////////////////////
739// Itanium Mangling
740
742 switch (T) {
743 case AMDGPULibFunc::U8: return "h";
744 case AMDGPULibFunc::U16: return "t";
745 case AMDGPULibFunc::U32: return "j";
746 case AMDGPULibFunc::U64: return "m";
747 case AMDGPULibFunc::I8: return "c";
748 case AMDGPULibFunc::I16: return "s";
749 case AMDGPULibFunc::I32: return "i";
750 case AMDGPULibFunc::I64: return "l";
751 case AMDGPULibFunc::F16: return "Dh";
752 case AMDGPULibFunc::F32: return "f";
753 case AMDGPULibFunc::F64: return "d";
754 case AMDGPULibFunc::IMG1DA: return "16ocl_image1darray";
755 case AMDGPULibFunc::IMG1DB: return "17ocl_image1dbuffer";
756 case AMDGPULibFunc::IMG2DA: return "16ocl_image2darray";
757 case AMDGPULibFunc::IMG1D: return "11ocl_image1d";
758 case AMDGPULibFunc::IMG2D: return "11ocl_image2d";
759 case AMDGPULibFunc::IMG3D: return "11ocl_image3d";
760 case AMDGPULibFunc::SAMPLER: return "11ocl_sampler";
761 case AMDGPULibFunc::EVENT: return "9ocl_event";
762 default:
763 llvm_unreachable("Unhandled param type");
764 }
765 return nullptr;
766}
767
768namespace {
769// Itanium mangling ABI says:
770// "5.1.8. Compression
771// ... Each non-terminal in the grammar for which <substitution> appears on the
772// right-hand side is both a source of future substitutions and a candidate
773// for being substituted. There are two exceptions that appear to be
774// substitution candidates from the grammar, but are explicitly excluded:
775// 1. <builtin-type> other than vendor extended types ..."
776
777// For the purpose of functions the following productions make sense for the
778// substitution:
779// <type> ::= <builtin-type>
780// ::= <class-enum-type>
781// ::= <array-type>
782// ::=<CV-qualifiers> <type>
783// ::= P <type> # pointer-to
784// ::= <substitution>
785//
786// Note that while types like images, samplers and events are by the ABI encoded
787// using <class-enum-type> production rule they're not used for substitution
788// because clang consider them as builtin types.
789//
790// DvNN_ type is GCC extension for vectors and is a subject for the
791// substitution.
792
793class ItaniumMangler {
794 SmallVector<AMDGPULibFunc::Param, 10> Str; // list of accumulated substitutions
795 bool UseAddrSpace;
796
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) {
803 return I;
804 }
805 }
806 return -1;
807 }
808
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;
813 // Substitutions are mangled as S(XX)?_ where XX is a hexadecimal number
814 // 0 1 2
815 // S_ S0_ S1_
816 if (subst == 0) os << "S_";
817 else os << 'S' << (subst-1) << '_';
818 return true;
819 }
820
821public:
822 ItaniumMangler(bool useAddrSpace)
823 : UseAddrSpace(useAddrSpace) {}
824
825 template <typename Stream>
826 void operator()(Stream& os, AMDGPULibFunc::Param p) {
827
828 // Itanium mangling ABI 5.1.8. Compression:
829 // Logically, the substitutable components of a mangled name are considered
830 // left-to-right, components before the composite structure of which they
831 // are a part. If a component has been encountered before, it is substituted
832 // as described below. This decision is independent of whether its components
833 // have been substituted, so an implementation may optimize by considering
834 // large structures for substitution before their components. If a component
835 // has not been encountered before, its mangling is identified, and it is
836 // added to a dictionary of substitution candidates. No entity is added to
837 // the dictionary twice.
839
840 if (p.PtrKind) {
841 if (trySubst(os, p)) return;
842 os << 'P';
843 if (p.PtrKind & AMDGPULibFunc::CONST) os << 'K';
844 if (p.PtrKind & AMDGPULibFunc::VOLATILE) os << 'V';
845 unsigned AS = UseAddrSpace
847 : 0;
848 if (EnableOCLManglingMismatchWA || AS != 0)
849 os << "U3AS" << AS;
850 Ptr = p;
851 p.PtrKind = 0;
852 }
853
854 if (p.VectorSize > 1) {
855 if (trySubst(os, p)) goto exit;
856 Str.push_back(p);
857 os << "Dv" << static_cast<unsigned>(p.VectorSize) << '_';
858 }
859
861
862 exit:
863 if (Ptr.ArgType) Str.push_back(Ptr);
864 }
865};
866} // namespace
867
868std::string AMDGPUMangledLibFunc::mangleNameItanium() const {
870 raw_svector_ostream S(Buf);
871 SmallString<128> NameBuf;
872 raw_svector_ostream Name(NameBuf);
873 writeName(Name);
874 const StringRef& NameStr = Name.str();
875 S << "_Z" << static_cast<int>(NameStr.size()) << NameStr;
876
877 ItaniumMangler Mangler(true);
878 ParamIterator I(Leads, manglingRules[FuncId]);
879 Param P;
880 while ((P = I.getNextParam()).ArgType != 0)
881 Mangler(S, P);
882 return std::string(S.str());
883}
884
885///////////////////////////////////////////////////////////////////////////////
886// Misc
887
889 bool Signed) {
890 Param P;
891 if (FixedVectorType *VT = dyn_cast<FixedVectorType>(Ty)) {
892 P.VectorSize = VT->getNumElements();
893 Ty = VT->getElementType();
894 }
895
896 switch (Ty->getTypeID()) {
897 case Type::FloatTyID:
898 P.ArgType = AMDGPULibFunc::F32;
899 break;
900 case Type::DoubleTyID:
901 P.ArgType = AMDGPULibFunc::F64;
902 break;
903 case Type::HalfTyID:
904 P.ArgType = AMDGPULibFunc::F16;
905 break;
907 switch (cast<IntegerType>(Ty)->getBitWidth()) {
908 case 8:
910 break;
911 case 16:
913 break;
914 case 32:
916 break;
917 case 64:
919 break;
920 default:
921 llvm_unreachable("unhandled libcall argument type");
922 }
923
924 break;
925 default:
926 llvm_unreachable("unhandled libcall argument type");
927 }
928
929 return P;
930}
931
933 LLVMContext& C,
934 const AMDGPULibFunc::Param& P,
935 bool useAddrSpace) {
936 Type* T = nullptr;
937 switch (P.ArgType) {
939 case AMDGPULibFunc::I8: T = Type::getInt8Ty(C); break;
941 case AMDGPULibFunc::I16: T = Type::getInt16Ty(C); break;
943 case AMDGPULibFunc::I32: T = Type::getInt32Ty(C); break;
945 case AMDGPULibFunc::I64: T = Type::getInt64Ty(C); break;
946 case AMDGPULibFunc::F16: T = Type::getHalfTy(C); break;
947 case AMDGPULibFunc::F32: T = Type::getFloatTy(C); break;
948 case AMDGPULibFunc::F64: T = Type::getDoubleTy(C); break;
949
959 break;
969 return nullptr;
970 }
971 if (P.VectorSize > 1)
972 T = FixedVectorType::get(T, P.VectorSize);
973 if (P.PtrKind != AMDGPULibFunc::BYVALUE)
975 C, useAddrSpace ? ((P.PtrKind & AMDGPULibFunc::ADDR_SPACE) - 1) : 0);
976 return T;
977}
978
980 LLVMContext& C = M.getContext();
981 std::vector<Type*> Args;
982 ParamIterator I(Leads, manglingRules[FuncId]);
983 Param P;
984 while ((P = I.getNextParam()).ArgType != 0) {
985 Type *ParamTy = getIntrinsicParamType(C, P, true);
986 if (!ParamTy)
987 return nullptr;
988
989 Args.push_back(ParamTy);
990 }
991
992 return FunctionType::get(
993 getIntrinsicParamType(C, getRetType(FuncId, Leads), true),
994 Args, false);
995}
996
998 return manglingRules[FuncId].getNumArgs();
999}
1000
1002 return UnmangledFuncInfo::getNumArgs(FuncId);
1003}
1004
1006 SmallString<128> Buf;
1008 writeName(OS);
1009 return std::string(OS.str());
1010}
1011
1013 const FunctionType *CallTy) const {
1014 const FunctionType *FuncTy = getFunctionType(M);
1015
1016 if (!FuncTy) {
1017 // Give up on mangled functions with unexpected types.
1018 if (AMDGPULibFuncBase::isMangled(getId()))
1019 return false;
1020
1021 // FIXME: UnmangledFuncInfo does not have any type information other than
1022 // the number of arguments.
1023 return getNumArgs() == CallTy->getNumParams();
1024 }
1025
1026 // Normally the types should exactly match.
1027 if (FuncTy == CallTy)
1028 return true;
1029
1030 const unsigned NumParams = FuncTy->getNumParams();
1031 if (NumParams != CallTy->getNumParams())
1032 return false;
1033
1034 for (unsigned I = 0; I != NumParams; ++I) {
1035 Type *FuncArgTy = FuncTy->getParamType(I);
1036 Type *CallArgTy = CallTy->getParamType(I);
1037 if (FuncArgTy == CallArgTy)
1038 continue;
1039
1040 // Some cases permit implicit splatting a scalar value to a vector argument.
1041 auto *FuncVecTy = dyn_cast<VectorType>(FuncArgTy);
1042 if (FuncVecTy && FuncVecTy->getElementType() == CallArgTy &&
1043 allowsImplicitVectorSplat(I))
1044 continue;
1045
1046 return false;
1047 }
1048
1049 return true;
1050}
1051
1053 std::string FuncName = fInfo.mangle();
1054 Function *F = dyn_cast_or_null<Function>(
1055 M->getValueSymbolTable().lookup(FuncName));
1056 if (!F || F->isDeclaration())
1057 return nullptr;
1058
1059 if (F->hasFnAttribute(Attribute::NoBuiltin))
1060 return nullptr;
1061
1062 if (!fInfo.isCompatibleSignature(*M, F->getFunctionType()))
1063 return nullptr;
1064
1065 return F;
1066}
1067
1069 const AMDGPULibFunc &fInfo) {
1070 std::string const FuncName = fInfo.mangle();
1071 Function *F = dyn_cast_or_null<Function>(
1072 M->getValueSymbolTable().lookup(FuncName));
1073
1074 if (F) {
1075 if (F->hasFnAttribute(Attribute::NoBuiltin))
1076 return nullptr;
1077 if (!F->isDeclaration() &&
1078 fInfo.isCompatibleSignature(*M, F->getFunctionType()))
1079 return F;
1080 }
1081
1082 FunctionType *FuncTy = fInfo.getFunctionType(*M);
1083
1084 bool hasPtr = false;
1086 PI = FuncTy->param_begin(),
1087 PE = FuncTy->param_end();
1088 PI != PE; ++PI) {
1089 const Type* argTy = static_cast<const Type*>(*PI);
1090 if (argTy->isPointerTy()) {
1091 hasPtr = true;
1092 break;
1093 }
1094 }
1095
1097 if (hasPtr) {
1098 // Do not set extra attributes for functions with pointer arguments.
1099 C = M->getOrInsertFunction(FuncName, FuncTy);
1100 } else {
1101 AttributeList Attr;
1102 LLVMContext &Ctx = M->getContext();
1103 Attr = Attr.addFnAttribute(
1105 Attr = Attr.addFnAttribute(Ctx, Attribute::NoUnwind);
1106 C = M->getOrInsertFunction(FuncName, FuncTy, Attr);
1107 }
1108
1109 return C;
1110}
1111
1112StringMap<unsigned> UnmangledFuncInfo::buildNameMap() {
1114 for (unsigned I = 0; I != TableSize; ++I)
1115 Map[Table[I].Name] = I;
1116 return Map;
1117}
1118
1119bool UnmangledFuncInfo::lookup(StringRef Name, ID &Id) {
1120 static const StringMap<unsigned> Map = buildNameMap();
1121 auto Loc = Map.find(Name);
1122 if (Loc != Map.end()) {
1123 Id = toFuncId(Loc->second);
1124 return true;
1125 }
1127 return false;
1128}
1129
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);
1135 else
1136 Impl = std::unique_ptr<AMDGPULibFuncImpl>();
1137}
1138
1140 if (this == &F)
1141 return *this;
1142 new (this) AMDGPULibFunc(F);
1143 return *this;
1144}
1145
1147 assert(AMDGPULibFuncBase::isMangled(Id) && CopyFrom.isMangled() &&
1148 "not supported");
1149 Impl = std::make_unique<AMDGPUMangledLibFunc>(
1150 Id, *cast<AMDGPUMangledLibFunc>(CopyFrom.Impl.get()));
1151}
1152
1154 Impl = std::make_unique<AMDGPUMangledLibFunc>(Id, FT, SignedInts);
1155}
1156
1158 Impl = std::make_unique<AMDGPUUnmangledLibFunc>(Name, FT);
1159}
1160
1161void AMDGPULibFunc::initMangled() {
1162 Impl = std::make_unique<AMDGPUMangledLibFunc>();
1163}
1164
1166 if (!Impl)
1167 initMangled();
1168 return cast<AMDGPUMangledLibFunc>(Impl.get())->Leads;
1169}
1170
1172 return cast<const AMDGPUMangledLibFunc>(Impl.get())->Leads;
1173}
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)
std::string Name
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.
Definition: InlineInfo.cpp:108
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
#define P(N)
Profile::FuncID FuncId
Definition: Profile.cpp:321
static StringRef getName(Value *V)
static bool isDigit(const char C)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This file contains some functions that are useful when dealing with strings.
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
bool isMangled() 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.
Definition: Attributes.h:573
static Attribute getWithMemoryEffects(LLVMContext &Context, MemoryEffects ME)
Definition: Attributes.cpp:281
Class to represent fixed width SIMD vectors.
Definition: DerivedTypes.h:563
static FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition: Type.cpp:791
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Definition: DerivedTypes.h:170
Class to represent function types.
Definition: DerivedTypes.h:105
param_iterator param_begin() const
Definition: DerivedTypes.h:130
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
Definition: DerivedTypes.h:144
Type::subtype_iterator param_iterator
Definition: DerivedTypes.h:128
Type * getParamType(unsigned i) const
Parameter type accessors.
Definition: DerivedTypes.h:137
param_iterator param_end() const
Definition: DerivedTypes.h:131
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.
Definition: LLVMContext.h:67
static MemoryEffectsBase readOnly()
Create MemoryEffectsBase that can read any memory.
Definition: ModRef.h:122
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
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...
Definition: DerivedTypes.h:686
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:128
ValueTy lookup(StringRef Key) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Definition: StringMap.h:253
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:700
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:571
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:265
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:147
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
Definition: StringRef.h:609
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:150
char front() const
front - Get the first character in the string.
Definition: StringRef.h:153
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:144
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:69
R Default(T Value)
Definition: StringSwitch.h:182
StringSwitch & StartsWith(StringLiteral S, T Value)
Definition: StringSwitch.h:83
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
static Type * getHalfTy(LLVMContext &C)
static Type * getDoubleTy(LLVMContext &C)
bool isPointerTy() const
True if this is an instance of PointerType.
Definition: Type.h:264
@ HalfTyID
16-bit floating point type
Definition: Type.h:56
@ FloatTyID
32-bit floating point type
Definition: Type.h:58
@ IntegerTyID
Arbitrary bit width integers.
Definition: Type.h:70
@ DoubleTyID
64-bit floating point type
Definition: Type.h:59
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.
Definition: Type.h:136
raw_ostream & write(unsigned char C)
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:691
#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.
Definition: CallingConv.h:34
@ ReallyHidden
Definition: CommandLine.h:138
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
#define N
static Param getFromTy(Type *Ty, bool Signed)