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 const AMDGPULibFunc::Param &P,
934 bool UseAddrSpace) {
935 Type *T = nullptr;
936 switch (P.ArgType) {
937 default:
938 return nullptr;
942 break;
946 break;
950 break;
954 break;
957 break;
960 break;
963 break;
964
974 break;
984 return nullptr;
985 }
986 if (P.VectorSize > 1)
987 T = FixedVectorType::get(T, P.VectorSize);
988 if (P.PtrKind != AMDGPULibFunc::BYVALUE)
990 C, UseAddrSpace ? ((P.PtrKind & AMDGPULibFunc::ADDR_SPACE) - 1) : 0);
991 return T;
992}
993
995 LLVMContext& C = M.getContext();
996 std::vector<Type*> Args;
997 ParamIterator I(Leads, manglingRules[FuncId]);
998 Param P;
999 while ((P = I.getNextParam()).ArgType != 0) {
1000 Type *ParamTy = getIntrinsicParamType(C, P, true);
1001 if (!ParamTy)
1002 return nullptr;
1003
1004 Args.push_back(ParamTy);
1005 }
1006
1007 Type *RetTy = getIntrinsicParamType(C, getRetType(FuncId, Leads), true);
1008 if (!RetTy)
1009 return nullptr;
1010
1011 return FunctionType::get(RetTy, Args, false);
1012}
1013
1015 return manglingRules[FuncId].getNumArgs();
1016}
1017
1019 return UnmangledFuncInfo::getNumArgs(FuncId);
1020}
1021
1023 SmallString<128> Buf;
1025 writeName(OS);
1026 return std::string(OS.str());
1027}
1028
1030 const FunctionType *CallTy) const {
1031 const FunctionType *FuncTy = getFunctionType(M);
1032
1033 if (!FuncTy) {
1034 // Give up on mangled functions with unexpected types.
1035 if (AMDGPULibFuncBase::isMangled(getId()))
1036 return false;
1037
1038 // FIXME: UnmangledFuncInfo does not have any type information other than
1039 // the number of arguments.
1040 return getNumArgs() == CallTy->getNumParams();
1041 }
1042
1043 // Normally the types should exactly match.
1044 if (FuncTy == CallTy)
1045 return true;
1046
1047 const unsigned NumParams = FuncTy->getNumParams();
1048 if (NumParams != CallTy->getNumParams())
1049 return false;
1050
1051 for (unsigned I = 0; I != NumParams; ++I) {
1052 Type *FuncArgTy = FuncTy->getParamType(I);
1053 Type *CallArgTy = CallTy->getParamType(I);
1054 if (FuncArgTy == CallArgTy)
1055 continue;
1056
1057 // Some cases permit implicit splatting a scalar value to a vector argument.
1058 auto *FuncVecTy = dyn_cast<VectorType>(FuncArgTy);
1059 if (FuncVecTy && FuncVecTy->getElementType() == CallArgTy &&
1060 allowsImplicitVectorSplat(I))
1061 continue;
1062
1063 return false;
1064 }
1065
1066 return true;
1067}
1068
1070 std::string FuncName = fInfo.mangle();
1071 Function *F = dyn_cast_or_null<Function>(
1072 M->getValueSymbolTable().lookup(FuncName));
1073 if (!F || F->isDeclaration())
1074 return nullptr;
1075
1076 if (F->hasFnAttribute(Attribute::NoBuiltin))
1077 return nullptr;
1078
1079 if (!fInfo.isCompatibleSignature(*M, F->getFunctionType()))
1080 return nullptr;
1081
1082 return F;
1083}
1084
1086 const AMDGPULibFunc &fInfo) {
1087 std::string const FuncName = fInfo.mangle();
1088 Function *F = dyn_cast_or_null<Function>(
1089 M->getValueSymbolTable().lookup(FuncName));
1090
1091 if (F) {
1092 if (F->hasFnAttribute(Attribute::NoBuiltin))
1093 return nullptr;
1094 if (!F->isDeclaration() &&
1095 fInfo.isCompatibleSignature(*M, F->getFunctionType()))
1096 return F;
1097 }
1098
1099 FunctionType *FuncTy = fInfo.getFunctionType(*M);
1100 assert(FuncTy);
1101
1102 bool hasPtr = false;
1104 PI = FuncTy->param_begin(),
1105 PE = FuncTy->param_end();
1106 PI != PE; ++PI) {
1107 const Type* argTy = static_cast<const Type*>(*PI);
1108 if (argTy->isPointerTy()) {
1109 hasPtr = true;
1110 break;
1111 }
1112 }
1113
1115 if (hasPtr) {
1116 // Do not set extra attributes for functions with pointer arguments.
1117 C = M->getOrInsertFunction(FuncName, FuncTy);
1118 } else {
1119 AttributeList Attr;
1120 LLVMContext &Ctx = M->getContext();
1121 Attr = Attr.addFnAttribute(
1123 Attr = Attr.addFnAttribute(Ctx, Attribute::NoUnwind);
1124 C = M->getOrInsertFunction(FuncName, FuncTy, Attr);
1125 }
1126
1127 return C;
1128}
1129
1130StringMap<unsigned> UnmangledFuncInfo::buildNameMap() {
1132 for (unsigned I = 0; I != TableSize; ++I)
1133 Map[Table[I].Name] = I;
1134 return Map;
1135}
1136
1137bool UnmangledFuncInfo::lookup(StringRef Name, ID &Id) {
1138 static const StringMap<unsigned> Map = buildNameMap();
1139 auto Loc = Map.find(Name);
1140 if (Loc != Map.end()) {
1141 Id = toFuncId(Loc->second);
1142 return true;
1143 }
1145 return false;
1146}
1147
1149 if (auto *MF = dyn_cast<AMDGPUMangledLibFunc>(F.Impl.get()))
1150 Impl = std::make_unique<AMDGPUMangledLibFunc>(*MF);
1151 else if (auto *UMF = dyn_cast<AMDGPUUnmangledLibFunc>(F.Impl.get()))
1152 Impl = std::make_unique<AMDGPUUnmangledLibFunc>(*UMF);
1153 else
1154 Impl = std::unique_ptr<AMDGPULibFuncImpl>();
1155}
1156
1158 if (this == &F)
1159 return *this;
1160 new (this) AMDGPULibFunc(F);
1161 return *this;
1162}
1163
1165 assert(AMDGPULibFuncBase::isMangled(Id) && CopyFrom.isMangled() &&
1166 "not supported");
1167 Impl = std::make_unique<AMDGPUMangledLibFunc>(
1168 Id, *cast<AMDGPUMangledLibFunc>(CopyFrom.Impl.get()));
1169}
1170
1172 Impl = std::make_unique<AMDGPUMangledLibFunc>(Id, FT, SignedInts);
1173}
1174
1176 Impl = std::make_unique<AMDGPUUnmangledLibFunc>(Name, FT);
1177}
1178
1179void AMDGPULibFunc::initMangled() {
1180 Impl = std::make_unique<AMDGPUMangledLibFunc>();
1181}
1182
1184 if (!Impl)
1185 initMangled();
1186 return cast<AMDGPUMangledLibFunc>(Impl.get())->Leads;
1187}
1188
1190 return cast<const AMDGPUMangledLibFunc>(Impl.get())->Leads;
1191}
This file defines the StringMap class.
static cl::opt< bool > EnableOCLManglingMismatchWA("amdgpu-enable-ocl-mangling-mismatch-workaround", cl::init(true), cl::ReallyHidden, cl::desc("Enable the workaround for OCL name mangling mismatch."))
static AMDGPULibFunc::ENamePrefix parseNamePrefix(StringRef &mangledName)
static const char * getItaniumTypeName(AMDGPULibFunc::EType T)
static int parseVecSize(StringRef &mangledName)
static Type * getIntrinsicParamType(LLVMContext &C, const AMDGPULibFunc::Param &P, bool UseAddrSpace)
return RetTy
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:577
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)