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)) {
624 (eatLengthPrefixedName(param))
625 .Case("ocl_image1darray" , AMDGPULibFunc::IMG1DA)
626 .Case("ocl_image1dbuffer", AMDGPULibFunc::IMG1DB)
627 .Case("ocl_image2darray" , AMDGPULibFunc::IMG2DA)
628 .Case("ocl_image1d" , AMDGPULibFunc::IMG1D)
629 .Case("ocl_image2d" , AMDGPULibFunc::IMG2D)
630 .Case("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
956 T = StructType::create(C,"ocl_image")->getPointerTo(); break;
958 T = StructType::create(C,"ocl_sampler")->getPointerTo(); break;
960 T = StructType::create(C,"ocl_event")->getPointerTo(); break;
961 default:
962 llvm_unreachable("Unhandled param type");
963 return nullptr;
964 }
965 if (P.VectorSize > 1)
966 T = FixedVectorType::get(T, P.VectorSize);
967 if (P.PtrKind != AMDGPULibFunc::BYVALUE)
968 T = useAddrSpace ? T->getPointerTo((P.PtrKind & AMDGPULibFunc::ADDR_SPACE)
969 - 1)
970 : T->getPointerTo();
971 return T;
972}
973
975 LLVMContext& C = M.getContext();
976 std::vector<Type*> Args;
977 ParamIterator I(Leads, manglingRules[FuncId]);
978 Param P;
979 while ((P=I.getNextParam()).ArgType != 0)
980 Args.push_back(getIntrinsicParamType(C, P, true));
981
982 return FunctionType::get(
983 getIntrinsicParamType(C, getRetType(FuncId, Leads), true),
984 Args, false);
985}
986
988 return manglingRules[FuncId].getNumArgs();
989}
990
992 return UnmangledFuncInfo::getNumArgs(FuncId);
993}
994
995std::string AMDGPUMangledLibFunc::getName() const {
998 writeName(OS);
999 return std::string(OS.str());
1000}
1001
1003 // TODO: Validate types make sense
1004 return !FuncTy->isVarArg() && FuncTy->getNumParams() == getNumArgs();
1005}
1006
1008 std::string FuncName = fInfo.mangle();
1009 Function *F = dyn_cast_or_null<Function>(
1010 M->getValueSymbolTable().lookup(FuncName));
1011 if (!F || F->isDeclaration())
1012 return nullptr;
1013
1014 if (F->hasFnAttribute(Attribute::NoBuiltin))
1015 return nullptr;
1016
1017 if (!fInfo.isCompatibleSignature(F->getFunctionType()))
1018 return nullptr;
1019
1020 return F;
1021}
1022
1024 const AMDGPULibFunc &fInfo) {
1025 std::string const FuncName = fInfo.mangle();
1026 Function *F = dyn_cast_or_null<Function>(
1027 M->getValueSymbolTable().lookup(FuncName));
1028
1029 if (F) {
1030 if (F->hasFnAttribute(Attribute::NoBuiltin))
1031 return nullptr;
1032 if (!F->isDeclaration() &&
1033 fInfo.isCompatibleSignature(F->getFunctionType()))
1034 return F;
1035 }
1036
1037 FunctionType *FuncTy = fInfo.getFunctionType(*M);
1038
1039 bool hasPtr = false;
1041 PI = FuncTy->param_begin(),
1042 PE = FuncTy->param_end();
1043 PI != PE; ++PI) {
1044 const Type* argTy = static_cast<const Type*>(*PI);
1045 if (argTy->isPointerTy()) {
1046 hasPtr = true;
1047 break;
1048 }
1049 }
1050
1052 if (hasPtr) {
1053 // Do not set extra attributes for functions with pointer arguments.
1054 C = M->getOrInsertFunction(FuncName, FuncTy);
1055 } else {
1056 AttributeList Attr;
1057 LLVMContext &Ctx = M->getContext();
1058 Attr = Attr.addFnAttribute(
1060 Attr = Attr.addFnAttribute(Ctx, Attribute::NoUnwind);
1061 C = M->getOrInsertFunction(FuncName, FuncTy, Attr);
1062 }
1063
1064 return C;
1065}
1066
1067StringMap<unsigned> UnmangledFuncInfo::buildNameMap() {
1069 for (unsigned I = 0; I != TableSize; ++I)
1070 Map[Table[I].Name] = I;
1071 return Map;
1072}
1073
1074bool UnmangledFuncInfo::lookup(StringRef Name, ID &Id) {
1075 static const StringMap<unsigned> Map = buildNameMap();
1076 auto Loc = Map.find(Name);
1077 if (Loc != Map.end()) {
1078 Id = toFuncId(Loc->second);
1079 return true;
1080 }
1082 return false;
1083}
1084
1086 if (auto *MF = dyn_cast<AMDGPUMangledLibFunc>(F.Impl.get()))
1087 Impl = std::make_unique<AMDGPUMangledLibFunc>(*MF);
1088 else if (auto *UMF = dyn_cast<AMDGPUUnmangledLibFunc>(F.Impl.get()))
1089 Impl = std::make_unique<AMDGPUUnmangledLibFunc>(*UMF);
1090 else
1091 Impl = std::unique_ptr<AMDGPULibFuncImpl>();
1092}
1093
1095 if (this == &F)
1096 return *this;
1097 new (this) AMDGPULibFunc(F);
1098 return *this;
1099}
1100
1102 assert(AMDGPULibFuncBase::isMangled(Id) && CopyFrom.isMangled() &&
1103 "not supported");
1104 Impl = std::make_unique<AMDGPUMangledLibFunc>(
1105 Id, *cast<AMDGPUMangledLibFunc>(CopyFrom.Impl.get()));
1106}
1107
1109 Impl = std::make_unique<AMDGPUMangledLibFunc>(Id, FT, SignedInts);
1110}
1111
1113 Impl = std::make_unique<AMDGPUUnmangledLibFunc>(Name, FT);
1114}
1115
1116void AMDGPULibFunc::initMangled() {
1117 Impl = std::make_unique<AMDGPUMangledLibFunc>();
1118}
1119
1121 if (!Impl)
1122 initMangled();
1123 return cast<AMDGPUMangledLibFunc>(Impl.get())->Leads;
1124}
1125
1127 return cast<const AMDGPUMangledLibFunc>(Impl.get())->Leads;
1128}
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
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:109
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
Module.h This file contains the declarations for the Module class.
#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(Module &M) const
bool isCompatibleSignature(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
FunctionType * getFunctionType(Module &M) const override
bool parseFuncName(StringRef &mangledName) override
std::string getName() const override
Get unmangled name for mangled library function and name for unmangled library function.
std::string mangle() const override
unsigned getNumArgs() const override
bool parseFuncName(StringRef &Name) override
AttributeList addFnAttribute(LLVMContext &C, Attribute::AttrKind Kind) const
Add a function attribute to the list.
Definition: Attributes.h:555
static Attribute getWithMemoryEffects(LLVMContext &Context, MemoryEffects ME)
Definition: Attributes.cpp:280
Class to represent fixed width SIMD vectors.
Definition: DerivedTypes.h:539
static FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition: Type.cpp:680
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Definition: DerivedTypes.h:168
Class to represent function types.
Definition: DerivedTypes.h:103
param_iterator param_begin() const
Definition: DerivedTypes.h:128
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
Definition: DerivedTypes.h:142
Type::subtype_iterator param_iterator
Definition: DerivedTypes.h:126
Type * getParamType(unsigned i) const
Parameter type accessors.
Definition: DerivedTypes.h:135
bool isVarArg() const
Definition: DerivedTypes.h:123
param_iterator param_end() const
Definition: DerivedTypes.h:129
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
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:1209
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:50
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:685
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:556
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:250
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
Definition: StringRef.h:594
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
char front() const
front - Get the first character in the string.
Definition: StringRef.h:140
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:131
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
static StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
Definition: Type.cpp:501
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)
PointerType * getPointerTo(unsigned AddrSpace=0) const
Return a pointer to the current type.
bool isPointerTy() const
True if this is an instance of PointerType.
Definition: Type.h:251
@ 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)