LLVM  10.0.0svn
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 "AMDGPU.h"
14 #include "AMDGPULibFunc.h"
15 #include <llvm/ADT/SmallString.h>
16 #include <llvm/ADT/SmallVector.h>
17 #include <llvm/ADT/StringSwitch.h>
18 #include "llvm/IR/Attributes.h"
19 #include "llvm/IR/DerivedTypes.h"
20 #include "llvm/IR/Function.h"
21 #include "llvm/IR/Module.h"
24 #include <string>
25 
26 using namespace llvm;
27 
28 namespace {
29 
31  E_NONE,
32  EX_EVENT,
33  EX_FLOAT4,
34  EX_INTV4,
35  EX_RESERVEDID,
36  EX_SAMPLER,
37  EX_SIZET,
38  EX_UINT,
39  EX_UINTV4,
40  E_ANY,
41  E_CONSTPTR_ANY,
42  E_CONSTPTR_SWAPGL,
43  E_COPY,
44  E_IMAGECOORDS,
45  E_POINTEE,
46  E_SETBASE_I32,
47  E_SETBASE_U32,
48  E_MAKEBASE_UNS,
49  E_V16_OF_POINTEE,
50  E_V2_OF_POINTEE,
51  E_V3_OF_POINTEE,
52  E_V4_OF_POINTEE,
53  E_V8_OF_POINTEE,
54  E_VLTLPTR_ANY,
55 };
56 
57 struct ManglingRule {
58  StringRef const Name;
59  unsigned char Lead[2];
60  unsigned char Param[5];
61 
62  int maxLeadIndex() const { return (std::max)(Lead[0], Lead[1]); }
63  int getNumLeads() const { return (Lead[0] ? 1 : 0) + (Lead[1] ? 1 : 0); }
64 
65  unsigned getNumArgs() const;
66 
67  static StringMap<int> buildManglingRulesMap();
68 };
69 
70 // Information about library functions with unmangled names.
71 class UnmangledFuncInfo {
72  StringRef const Name;
73  unsigned NumArgs;
74 
75  // Table for all lib functions with unmangled names.
76  static const UnmangledFuncInfo Table[];
77 
78  // Number of entries in Table.
79  static const unsigned TableSize;
80 
81  static StringMap<unsigned> buildNameMap();
82 
83 public:
84  using ID = AMDGPULibFunc::EFuncId;
85  UnmangledFuncInfo(StringRef _Name, unsigned _NumArgs)
86  : Name(_Name), NumArgs(_NumArgs) {}
87  // Get index to Table by function name.
88  static bool lookup(StringRef Name, ID &Id);
89  static unsigned toIndex(ID Id) {
90  assert(static_cast<unsigned>(Id) >
91  static_cast<unsigned>(AMDGPULibFunc::EI_LAST_MANGLED) &&
92  "Invalid unmangled library function");
93  return static_cast<unsigned>(Id) - 1 -
94  static_cast<unsigned>(AMDGPULibFunc::EI_LAST_MANGLED);
95  }
96  static ID toFuncId(unsigned Index) {
97  assert(Index < TableSize &&
98  "Invalid unmangled library function");
99  return static_cast<ID>(
100  Index + 1 + static_cast<unsigned>(AMDGPULibFunc::EI_LAST_MANGLED));
101  }
102  static unsigned getNumArgs(ID Id) { return Table[toIndex(Id)].NumArgs; }
103  static StringRef getName(ID Id) { return Table[toIndex(Id)].Name; }
104 };
105 
106 unsigned ManglingRule::getNumArgs() const {
107  unsigned I=0;
108  while (I < (sizeof Param/sizeof Param[0]) && Param[I]) ++I;
109  return I;
110 }
111 
112 // This table describes function formal argument type rules. The order of rules
113 // corresponds to the EFuncId enum at AMDGPULibFunc.h
114 //
115 // "<func name>", { <leads> }, { <param rules> }
116 // where:
117 // <leads> - list of integers that are one-based indexes of formal argument
118 // used to mangle a function name. Other argument types are derived from types
119 // of these 'leads'. The order of integers in this list correspond to the
120 // order in which these arguments are mangled in the EDG mangling scheme. The
121 // same order should be preserved for arguments in the AMDGPULibFunc structure
122 // when it is used for mangling. For example:
123 // { "vstorea_half", {3,1}, {E_ANY,EX_SIZET,E_ANY}},
124 // will be mangled in EDG scheme as vstorea_half_<3dparam>_<1stparam>
125 // When mangling from code use:
126 // AMDGPULibFunc insc;
127 // insc.param[0] = ... // describe 3rd parameter
128 // insc.param[1] = ... // describe 1rd parameter
129 //
130 // <param rules> - list of rules used to derive all of the function formal
131 // argument types. EX_ prefixed are simple types, other derived from the
132 // latest 'lead' argument type in the order of encoding from first to last.
133 // E_ANY - use prev lead type, E_CONSTPTR_ANY - make const pointer out of
134 // prev lead type, etc. see ParamIterator::getNextParam() for details.
135 
136 static const ManglingRule manglingRules[] = {
137 { StringRef(), {0}, {0} },
138 { "abs" , {1}, {E_ANY}},
139 { "abs_diff" , {1}, {E_ANY,E_COPY}},
140 { "acos" , {1}, {E_ANY}},
141 { "acosh" , {1}, {E_ANY}},
142 { "acospi" , {1}, {E_ANY}},
143 { "add_sat" , {1}, {E_ANY,E_COPY}},
144 { "all" , {1}, {E_ANY}},
145 { "any" , {1}, {E_ANY}},
146 { "asin" , {1}, {E_ANY}},
147 { "asinh" , {1}, {E_ANY}},
148 { "asinpi" , {1}, {E_ANY}},
149 { "async_work_group_copy" , {1}, {E_ANY,E_CONSTPTR_SWAPGL,EX_SIZET,EX_EVENT}},
150 { "async_work_group_strided_copy" , {1}, {E_ANY,E_CONSTPTR_SWAPGL,EX_SIZET,EX_SIZET,EX_EVENT}},
151 { "atan" , {1}, {E_ANY}},
152 { "atan2" , {1}, {E_ANY,E_COPY}},
153 { "atan2pi" , {1}, {E_ANY,E_COPY}},
154 { "atanh" , {1}, {E_ANY}},
155 { "atanpi" , {1}, {E_ANY}},
156 { "atomic_add" , {1}, {E_VLTLPTR_ANY,E_POINTEE}},
157 { "atomic_and" , {1}, {E_VLTLPTR_ANY,E_POINTEE}},
158 { "atomic_cmpxchg" , {1}, {E_VLTLPTR_ANY,E_POINTEE,E_POINTEE}},
159 { "atomic_dec" , {1}, {E_VLTLPTR_ANY}},
160 { "atomic_inc" , {1}, {E_VLTLPTR_ANY}},
161 { "atomic_max" , {1}, {E_VLTLPTR_ANY,E_POINTEE}},
162 { "atomic_min" , {1}, {E_VLTLPTR_ANY,E_POINTEE}},
163 { "atomic_or" , {1}, {E_VLTLPTR_ANY,E_POINTEE}},
164 { "atomic_sub" , {1}, {E_VLTLPTR_ANY,E_POINTEE}},
165 { "atomic_xchg" , {1}, {E_VLTLPTR_ANY,E_POINTEE}},
166 { "atomic_xor" , {1}, {E_VLTLPTR_ANY,E_POINTEE}},
167 { "bitselect" , {1}, {E_ANY,E_COPY,E_COPY}},
168 { "cbrt" , {1}, {E_ANY}},
169 { "ceil" , {1}, {E_ANY}},
170 { "clamp" , {1}, {E_ANY,E_COPY,E_COPY}},
171 { "clz" , {1}, {E_ANY}},
172 { "commit_read_pipe" , {1}, {E_ANY,EX_RESERVEDID}},
173 { "commit_write_pipe" , {1}, {E_ANY,EX_RESERVEDID}},
174 { "copysign" , {1}, {E_ANY,E_COPY}},
175 { "cos" , {1}, {E_ANY}},
176 { "cosh" , {1}, {E_ANY}},
177 { "cospi" , {1}, {E_ANY}},
178 { "cross" , {1}, {E_ANY,E_COPY}},
179 { "ctz" , {1}, {E_ANY}},
180 { "degrees" , {1}, {E_ANY}},
181 { "distance" , {1}, {E_ANY,E_COPY}},
182 { "divide" , {1}, {E_ANY,E_COPY}},
183 { "dot" , {1}, {E_ANY,E_COPY}},
184 { "erf" , {1}, {E_ANY}},
185 { "erfc" , {1}, {E_ANY}},
186 { "exp" , {1}, {E_ANY}},
187 { "exp10" , {1}, {E_ANY}},
188 { "exp2" , {1}, {E_ANY}},
189 { "expm1" , {1}, {E_ANY}},
190 { "fabs" , {1}, {E_ANY}},
191 { "fast_distance" , {1}, {E_ANY,E_COPY}},
192 { "fast_length" , {1}, {E_ANY}},
193 { "fast_normalize" , {1}, {E_ANY}},
194 { "fdim" , {1}, {E_ANY,E_COPY}},
195 { "floor" , {1}, {E_ANY}},
196 { "fma" , {1}, {E_ANY,E_COPY,E_COPY}},
197 { "fmax" , {1}, {E_ANY,E_COPY}},
198 { "fmin" , {1}, {E_ANY,E_COPY}},
199 { "fmod" , {1}, {E_ANY,E_COPY}},
200 { "fract" , {2}, {E_POINTEE,E_ANY}},
201 { "frexp" , {1,2}, {E_ANY,E_ANY}},
202 { "get_image_array_size" , {1}, {E_ANY}},
203 { "get_image_channel_data_type" , {1}, {E_ANY}},
204 { "get_image_channel_order" , {1}, {E_ANY}},
205 { "get_image_dim" , {1}, {E_ANY}},
206 { "get_image_height" , {1}, {E_ANY}},
207 { "get_image_width" , {1}, {E_ANY}},
208 { "get_pipe_max_packets" , {1}, {E_ANY}},
209 { "get_pipe_num_packets" , {1}, {E_ANY}},
210 { "hadd" , {1}, {E_ANY,E_COPY}},
211 { "hypot" , {1}, {E_ANY,E_COPY}},
212 { "ilogb" , {1}, {E_ANY}},
213 { "isequal" , {1}, {E_ANY,E_COPY}},
214 { "isfinite" , {1}, {E_ANY}},
215 { "isgreater" , {1}, {E_ANY,E_COPY}},
216 { "isgreaterequal" , {1}, {E_ANY,E_COPY}},
217 { "isinf" , {1}, {E_ANY}},
218 { "isless" , {1}, {E_ANY,E_COPY}},
219 { "islessequal" , {1}, {E_ANY,E_COPY}},
220 { "islessgreater" , {1}, {E_ANY,E_COPY}},
221 { "isnan" , {1}, {E_ANY}},
222 { "isnormal" , {1}, {E_ANY}},
223 { "isnotequal" , {1}, {E_ANY,E_COPY}},
224 { "isordered" , {1}, {E_ANY,E_COPY}},
225 { "isunordered" , {1}, {E_ANY,E_COPY}},
226 { "ldexp" , {1}, {E_ANY,E_SETBASE_I32}},
227 { "length" , {1}, {E_ANY}},
228 { "lgamma" , {1}, {E_ANY}},
229 { "lgamma_r" , {1,2}, {E_ANY,E_ANY}},
230 { "log" , {1}, {E_ANY}},
231 { "log10" , {1}, {E_ANY}},
232 { "log1p" , {1}, {E_ANY}},
233 { "log2" , {1}, {E_ANY}},
234 { "logb" , {1}, {E_ANY}},
235 { "mad" , {1}, {E_ANY,E_COPY,E_COPY}},
236 { "mad24" , {1}, {E_ANY,E_COPY,E_COPY}},
237 { "mad_hi" , {1}, {E_ANY,E_COPY,E_COPY}},
238 { "mad_sat" , {1}, {E_ANY,E_COPY,E_COPY}},
239 { "max" , {1}, {E_ANY,E_COPY}},
240 { "maxmag" , {1}, {E_ANY,E_COPY}},
241 { "min" , {1}, {E_ANY,E_COPY}},
242 { "minmag" , {1}, {E_ANY,E_COPY}},
243 { "mix" , {1}, {E_ANY,E_COPY,E_COPY}},
244 { "modf" , {2}, {E_POINTEE,E_ANY}},
245 { "mul24" , {1}, {E_ANY,E_COPY}},
246 { "mul_hi" , {1}, {E_ANY,E_COPY}},
247 { "nan" , {1}, {E_ANY}},
248 { "nextafter" , {1}, {E_ANY,E_COPY}},
249 { "normalize" , {1}, {E_ANY}},
250 { "popcount" , {1}, {E_ANY}},
251 { "pow" , {1}, {E_ANY,E_COPY}},
252 { "pown" , {1}, {E_ANY,E_SETBASE_I32}},
253 { "powr" , {1}, {E_ANY,E_COPY}},
254 { "prefetch" , {1}, {E_CONSTPTR_ANY,EX_SIZET}},
255 { "radians" , {1}, {E_ANY}},
256 { "recip" , {1}, {E_ANY}},
257 { "remainder" , {1}, {E_ANY,E_COPY}},
258 { "remquo" , {1,3}, {E_ANY,E_COPY,E_ANY}},
259 { "reserve_read_pipe" , {1}, {E_ANY,EX_UINT}},
260 { "reserve_write_pipe" , {1}, {E_ANY,EX_UINT}},
261 { "rhadd" , {1}, {E_ANY,E_COPY}},
262 { "rint" , {1}, {E_ANY}},
263 { "rootn" , {1}, {E_ANY,E_SETBASE_I32}},
264 { "rotate" , {1}, {E_ANY,E_COPY}},
265 { "round" , {1}, {E_ANY}},
266 { "rsqrt" , {1}, {E_ANY}},
267 { "select" , {1,3}, {E_ANY,E_COPY,E_ANY}},
268 { "shuffle" , {1,2}, {E_ANY,E_ANY}},
269 { "shuffle2" , {1,3}, {E_ANY,E_COPY,E_ANY}},
270 { "sign" , {1}, {E_ANY}},
271 { "signbit" , {1}, {E_ANY}},
272 { "sin" , {1}, {E_ANY}},
273 { "sincos" , {2}, {E_POINTEE,E_ANY}},
274 { "sinh" , {1}, {E_ANY}},
275 { "sinpi" , {1}, {E_ANY}},
276 { "smoothstep" , {1}, {E_ANY,E_COPY,E_COPY}},
277 { "sqrt" , {1}, {E_ANY}},
278 { "step" , {1}, {E_ANY,E_COPY}},
279 { "sub_group_broadcast" , {1}, {E_ANY,EX_UINT}},
280 { "sub_group_commit_read_pipe" , {1}, {E_ANY,EX_RESERVEDID}},
281 { "sub_group_commit_write_pipe" , {1}, {E_ANY,EX_RESERVEDID}},
282 { "sub_group_reduce_add" , {1}, {E_ANY}},
283 { "sub_group_reduce_max" , {1}, {E_ANY}},
284 { "sub_group_reduce_min" , {1}, {E_ANY}},
285 { "sub_group_reserve_read_pipe" , {1}, {E_ANY,EX_UINT}},
286 { "sub_group_reserve_write_pipe" , {1}, {E_ANY,EX_UINT}},
287 { "sub_group_scan_exclusive_add" , {1}, {E_ANY}},
288 { "sub_group_scan_exclusive_max" , {1}, {E_ANY}},
289 { "sub_group_scan_exclusive_min" , {1}, {E_ANY}},
290 { "sub_group_scan_inclusive_add" , {1}, {E_ANY}},
291 { "sub_group_scan_inclusive_max" , {1}, {E_ANY}},
292 { "sub_group_scan_inclusive_min" , {1}, {E_ANY}},
293 { "sub_sat" , {1}, {E_ANY,E_COPY}},
294 { "tan" , {1}, {E_ANY}},
295 { "tanh" , {1}, {E_ANY}},
296 { "tanpi" , {1}, {E_ANY}},
297 { "tgamma" , {1}, {E_ANY}},
298 { "trunc" , {1}, {E_ANY}},
299 { "upsample" , {1}, {E_ANY,E_MAKEBASE_UNS}},
300 { "vec_step" , {1}, {E_ANY}},
301 { "vstore" , {3}, {E_POINTEE,EX_SIZET,E_ANY}},
302 { "vstore16" , {3}, {E_V16_OF_POINTEE,EX_SIZET,E_ANY}},
303 { "vstore2" , {3}, {E_V2_OF_POINTEE,EX_SIZET,E_ANY}},
304 { "vstore3" , {3}, {E_V3_OF_POINTEE,EX_SIZET,E_ANY}},
305 { "vstore4" , {3}, {E_V4_OF_POINTEE,EX_SIZET,E_ANY}},
306 { "vstore8" , {3}, {E_V8_OF_POINTEE,EX_SIZET,E_ANY}},
307 { "work_group_commit_read_pipe" , {1}, {E_ANY,EX_RESERVEDID}},
308 { "work_group_commit_write_pipe" , {1}, {E_ANY,EX_RESERVEDID}},
309 { "work_group_reduce_add" , {1}, {E_ANY}},
310 { "work_group_reduce_max" , {1}, {E_ANY}},
311 { "work_group_reduce_min" , {1}, {E_ANY}},
312 { "work_group_reserve_read_pipe" , {1}, {E_ANY,EX_UINT}},
313 { "work_group_reserve_write_pipe" , {1}, {E_ANY,EX_UINT}},
314 { "work_group_scan_exclusive_add" , {1}, {E_ANY}},
315 { "work_group_scan_exclusive_max" , {1}, {E_ANY}},
316 { "work_group_scan_exclusive_min" , {1}, {E_ANY}},
317 { "work_group_scan_inclusive_add" , {1}, {E_ANY}},
318 { "work_group_scan_inclusive_max" , {1}, {E_ANY}},
319 { "work_group_scan_inclusive_min" , {1}, {E_ANY}},
320 { "write_imagef" , {1}, {E_ANY,E_IMAGECOORDS,EX_FLOAT4}},
321 { "write_imagei" , {1}, {E_ANY,E_IMAGECOORDS,EX_INTV4}},
322 { "write_imageui" , {1}, {E_ANY,E_IMAGECOORDS,EX_UINTV4}},
323 { "ncos" , {1}, {E_ANY} },
324 { "nexp2" , {1}, {E_ANY} },
325 { "nfma" , {1}, {E_ANY, E_COPY, E_COPY} },
326 { "nlog2" , {1}, {E_ANY} },
327 { "nrcp" , {1}, {E_ANY} },
328 { "nrsqrt" , {1}, {E_ANY} },
329 { "nsin" , {1}, {E_ANY} },
330 { "nsqrt" , {1}, {E_ANY} },
331 { "ftz" , {1}, {E_ANY} },
332 { "fldexp" , {1}, {E_ANY, EX_UINT} },
333 { "class" , {1}, {E_ANY, EX_UINT} },
334 { "rcbrt" , {1}, {E_ANY} },
335 };
336 
337 // Library functions with unmangled name.
338 const UnmangledFuncInfo UnmangledFuncInfo::Table[] = {
339  {"__read_pipe_2", 4},
340  {"__read_pipe_4", 6},
341  {"__write_pipe_2", 4},
342  {"__write_pipe_4", 6},
343 };
344 
345 const unsigned UnmangledFuncInfo::TableSize =
346  array_lengthof(UnmangledFuncInfo::Table);
347 
348 static AMDGPULibFunc::Param getRetType(AMDGPULibFunc::EFuncId id,
349  const AMDGPULibFunc::Param (&Leads)[2]) {
350  AMDGPULibFunc::Param Res = Leads[0];
351  // TBD - This switch may require to be extended for other intriniscs
352  switch (id) {
354  Res.PtrKind = AMDGPULibFunc::BYVALUE;
355  break;
356  default:
357  break;
358  }
359  return Res;
360 }
361 
362 class ParamIterator {
363  const AMDGPULibFunc::Param (&Leads)[2];
364  const ManglingRule& Rule;
365  int Index;
366 public:
367  ParamIterator(const AMDGPULibFunc::Param (&leads)[2],
368  const ManglingRule& rule)
369  : Leads(leads), Rule(rule), Index(0) {}
370 
371  AMDGPULibFunc::Param getNextParam();
372 };
373 
374 AMDGPULibFunc::Param ParamIterator::getNextParam() {
375  AMDGPULibFunc::Param P;
376  if (Index >= int(sizeof Rule.Param/sizeof Rule.Param[0])) return P;
377 
378  const char R = Rule.Param[Index];
379  switch (R) {
380  case E_NONE: break;
381  case EX_UINT:
382  P.ArgType = AMDGPULibFunc::U32; break;
383  case EX_INTV4:
384  P.ArgType = AMDGPULibFunc::I32; P.VectorSize = 4; break;
385  case EX_UINTV4:
386  P.ArgType = AMDGPULibFunc::U32; P.VectorSize = 4; break;
387  case EX_FLOAT4:
388  P.ArgType = AMDGPULibFunc::F32; P.VectorSize = 4; break;
389  case EX_SIZET:
390  P.ArgType = AMDGPULibFunc::U64; break;
391  case EX_EVENT:
392  P.ArgType = AMDGPULibFunc::EVENT; break;
393  case EX_SAMPLER:
394  P.ArgType = AMDGPULibFunc::SAMPLER; break;
395  case EX_RESERVEDID: break; // TBD
396  default:
397  if (Index == (Rule.Lead[1] - 1)) P = Leads[1];
398  else P = Leads[0];
399 
400  switch (R) {
401  case E_ANY:
402  case E_COPY: break;
403 
404  case E_POINTEE:
405  P.PtrKind = AMDGPULibFunc::BYVALUE; break;
406  case E_V2_OF_POINTEE:
407  P.VectorSize = 2; P.PtrKind = AMDGPULibFunc::BYVALUE; break;
408  case E_V3_OF_POINTEE:
409  P.VectorSize = 3; P.PtrKind = AMDGPULibFunc::BYVALUE; break;
410  case E_V4_OF_POINTEE:
411  P.VectorSize = 4; P.PtrKind = AMDGPULibFunc::BYVALUE; break;
412  case E_V8_OF_POINTEE:
413  P.VectorSize = 8; P.PtrKind = AMDGPULibFunc::BYVALUE; break;
414  case E_V16_OF_POINTEE:
415  P.VectorSize = 16; P.PtrKind = AMDGPULibFunc::BYVALUE; break;
416  case E_CONSTPTR_ANY:
417  P.PtrKind |= AMDGPULibFunc::CONST; break;
418  case E_VLTLPTR_ANY:
419  P.PtrKind |= AMDGPULibFunc::VOLATILE; break;
420  case E_SETBASE_I32:
421  P.ArgType = AMDGPULibFunc::I32; break;
422  case E_SETBASE_U32:
423  P.ArgType = AMDGPULibFunc::U32; break;
424 
425  case E_MAKEBASE_UNS:
426  P.ArgType &= ~AMDGPULibFunc::BASE_TYPE_MASK;
427  P.ArgType |= AMDGPULibFunc::UINT;
428  break;
429 
430  case E_IMAGECOORDS:
431  switch (P.ArgType) {
432  case AMDGPULibFunc::IMG1DA: P.VectorSize = 2; break;
433  case AMDGPULibFunc::IMG1DB: P.VectorSize = 1; break;
434  case AMDGPULibFunc::IMG2DA: P.VectorSize = 4; break;
435  case AMDGPULibFunc::IMG1D: P.VectorSize = 1; break;
436  case AMDGPULibFunc::IMG2D: P.VectorSize = 2; break;
437  case AMDGPULibFunc::IMG3D: P.VectorSize = 4; break;
438  }
439  P.PtrKind = AMDGPULibFunc::BYVALUE;
440  P.ArgType = AMDGPULibFunc::I32;
441  break;
442 
443  case E_CONSTPTR_SWAPGL: {
444  unsigned AS = AMDGPULibFunc::getAddrSpaceFromEPtrKind(P.PtrKind);
445  switch (AS) {
448  }
450  P.PtrKind |= AMDGPULibFunc::CONST;
451  break;
452  }
453 
454  default: llvm_unreachable("Unhandeled param rule");
455  }
456  }
457  ++Index;
458  return P;
459 }
460 
461 inline static void drop_front(StringRef& str, size_t n = 1) {
462  str = str.drop_front(n);
463 }
464 
465 static bool eatTerm(StringRef& mangledName, const char c) {
466  if (mangledName.front() == c) {
467  drop_front(mangledName);
468  return true;
469  }
470  return false;
471 }
472 
473 template <size_t N>
474 static bool eatTerm(StringRef& mangledName, const char (&str)[N]) {
475  if (mangledName.startswith(StringRef(str, N-1))) {
476  drop_front(mangledName, N-1);
477  return true;
478  }
479  return false;
480 }
481 
482 static inline bool isDigit(char c) { return c >= '0' && c <= '9'; }
483 
484 static int eatNumber(StringRef& s) {
485  size_t const savedSize = s.size();
486  int n = 0;
487  while (!s.empty() && isDigit(s.front())) {
488  n = n*10 + s.front() - '0';
489  drop_front(s);
490  }
491  return s.size() < savedSize ? n : -1;
492 }
493 
494 static StringRef eatLengthPrefixedName(StringRef& mangledName) {
495  int const Len = eatNumber(mangledName);
496  if (Len <= 0 || static_cast<size_t>(Len) > mangledName.size())
497  return StringRef();
498  StringRef Res = mangledName.substr(0, Len);
499  drop_front(mangledName, Len);
500  return Res;
501 }
502 
503 } // end anonymous namespace
504 
506  FuncId = EI_NONE;
507  FKind = NOPFX;
508  Leads[0].reset();
509  Leads[1].reset();
510  Name.clear();
511 }
512 
514  FuncId = EI_NONE;
515  FuncTy = nullptr;
516 }
517 
519  EFuncId id, const AMDGPUMangledLibFunc &copyFrom) {
520  FuncId = id;
521  FKind = copyFrom.FKind;
522  Leads[0] = copyFrom.Leads[0];
523  Leads[1] = copyFrom.Leads[1];
524 }
525 
526 ///////////////////////////////////////////////////////////////////////////////
527 // Demangling
528 
529 static int parseVecSize(StringRef& mangledName) {
530  size_t const Len = eatNumber(mangledName);
531  switch (Len) {
532  case 2: case 3: case 4: case 8: case 16:
533  return Len;
534  default:
535  break;
536  }
537  return 1;
538 }
539 
541  std::pair<StringRef, StringRef> const P = mangledName.split('_');
544  .Case("native", AMDGPULibFunc::NATIVE)
545  .Case("half" , AMDGPULibFunc::HALF)
547 
548  if (Pfx != AMDGPULibFunc::NOPFX)
549  mangledName = P.second;
550 
551  return Pfx;
552 }
553 
554 StringMap<int> ManglingRule::buildManglingRulesMap() {
555  StringMap<int> Map(array_lengthof(manglingRules));
556  int Id = 0;
557  for (auto Rule : manglingRules)
558  Map.insert({Rule.Name, Id++});
559  return Map;
560 }
561 
562 bool AMDGPUMangledLibFunc::parseUnmangledName(StringRef FullName) {
563  static const StringMap<int> manglingRulesMap =
564  ManglingRule::buildManglingRulesMap();
565  FuncId = static_cast<EFuncId>(manglingRulesMap.lookup(FullName));
566  return FuncId != EI_NONE;
567 }
568 
569 ///////////////////////////////////////////////////////////////////////////////
570 // Itanium Demangling
571 
572 namespace {
573 struct ItaniumParamParser {
574  AMDGPULibFunc::Param Prev;
575  bool parseItaniumParam(StringRef& param, AMDGPULibFunc::Param &res);
576 };
577 } // namespace
578 
579 bool ItaniumParamParser::parseItaniumParam(StringRef& param,
580  AMDGPULibFunc::Param &res) {
581  res.reset();
582  if (param.empty()) return false;
583 
584  // parse pointer prefix
585  if (eatTerm(param, 'P')) {
586  if (eatTerm(param, 'K')) res.PtrKind |= AMDGPULibFunc::CONST;
587  if (eatTerm(param, 'V')) res.PtrKind |= AMDGPULibFunc::VOLATILE;
588  unsigned AS;
589  if (!eatTerm(param, "U3AS")) {
590  AS = 0;
591  } else {
592  AS = param.front() - '0';
593  drop_front(param, 1);
594  }
596  } else {
597  res.PtrKind = AMDGPULibFunc::BYVALUE;
598  }
599 
600  // parse vector size
601  if (eatTerm(param,"Dv")) {
602  res.VectorSize = parseVecSize(param);
603  if (res.VectorSize==1 || !eatTerm(param, '_')) return false;
604  }
605 
606  // parse type
607  char const TC = param.front();
608  if (::isDigit(TC)) {
610  (eatLengthPrefixedName(param))
611  .Case("ocl_image1darray" , AMDGPULibFunc::IMG1DA)
612  .Case("ocl_image1dbuffer", AMDGPULibFunc::IMG1DB)
613  .Case("ocl_image2darray" , AMDGPULibFunc::IMG2DA)
614  .Case("ocl_image1d" , AMDGPULibFunc::IMG1D)
615  .Case("ocl_image2d" , AMDGPULibFunc::IMG2D)
616  .Case("ocl_image3d" , AMDGPULibFunc::IMG3D)
617  .Case("ocl_event" , AMDGPULibFunc::DUMMY)
618  .Case("ocl_sampler" , AMDGPULibFunc::DUMMY)
620  } else {
621  drop_front(param);
622  switch (TC) {
623  case 'h': res.ArgType = AMDGPULibFunc::U8; break;
624  case 't': res.ArgType = AMDGPULibFunc::U16; break;
625  case 'j': res.ArgType = AMDGPULibFunc::U32; break;
626  case 'm': res.ArgType = AMDGPULibFunc::U64; break;
627  case 'c': res.ArgType = AMDGPULibFunc::I8; break;
628  case 's': res.ArgType = AMDGPULibFunc::I16; break;
629  case 'i': res.ArgType = AMDGPULibFunc::I32; break;
630  case 'l': res.ArgType = AMDGPULibFunc::I64; break;
631  case 'f': res.ArgType = AMDGPULibFunc::F32; break;
632  case 'd': res.ArgType = AMDGPULibFunc::F64; break;
633  case 'D': if (!eatTerm(param, 'h')) return false;
634  res.ArgType = AMDGPULibFunc::F16; break;
635  case 'S':
636  if (!eatTerm(param, '_')) {
637  eatNumber(param);
638  if (!eatTerm(param, '_')) return false;
639  }
640  res.VectorSize = Prev.VectorSize;
641  res.ArgType = Prev.ArgType;
642  break;
643  default:;
644  }
645  }
646  if (res.ArgType == 0) return false;
647  Prev.VectorSize = res.VectorSize;
648  Prev.ArgType = res.ArgType;
649  return true;
650 }
651 
653  StringRef Name = eatLengthPrefixedName(mangledName);
654  FKind = parseNamePrefix(Name);
655  if (!parseUnmangledName(Name))
656  return false;
657 
658  const ManglingRule& Rule = manglingRules[FuncId];
659  ItaniumParamParser Parser;
660  for (int I=0; I < Rule.maxLeadIndex(); ++I) {
661  Param P;
662  if (!Parser.parseItaniumParam(mangledName, P))
663  return false;
664 
665  if ((I + 1) == Rule.Lead[0]) Leads[0] = P;
666  if ((I + 1) == Rule.Lead[1]) Leads[1] = P;
667  }
668  return true;
669 }
670 
672  if (!UnmangledFuncInfo::lookup(Name, FuncId))
673  return false;
674  setName(Name);
675  return true;
676 }
677 
679  if (FuncName.empty()) {
680  F.Impl = std::unique_ptr<AMDGPULibFuncImpl>();
681  return false;
682  }
683 
684  if (eatTerm(FuncName, "_Z"))
685  F.Impl = std::make_unique<AMDGPUMangledLibFunc>();
686  else
687  F.Impl = std::make_unique<AMDGPUUnmangledLibFunc>();
688  if (F.Impl->parseFuncName(FuncName))
689  return true;
690 
691  F.Impl = std::unique_ptr<AMDGPULibFuncImpl>();
692  return false;
693 }
694 
696  StringRef S = mangledName;
697  if (eatTerm(S, "_Z"))
698  return eatLengthPrefixedName(S);
699  return StringRef();
700 }
701 
702 ///////////////////////////////////////////////////////////////////////////////
703 // Mangling
704 
705 template <typename Stream>
706 void AMDGPUMangledLibFunc::writeName(Stream &OS) const {
707  const char *Pfx = "";
708  switch (FKind) {
709  case NATIVE: Pfx = "native_"; break;
710  case HALF: Pfx = "half_"; break;
711  default: break;
712  }
713  if (!Name.empty()) {
714  OS << Pfx << Name;
715  } else if (FuncId != EI_NONE) {
716  OS << Pfx;
717  const StringRef& S = manglingRules[FuncId].Name;
718  OS.write(S.data(), S.size());
719  }
720 }
721 
722 std::string AMDGPUMangledLibFunc::mangle() const { return mangleNameItanium(); }
723 
724 ///////////////////////////////////////////////////////////////////////////////
725 // Itanium Mangling
726 
728  switch (T) {
729  case AMDGPULibFunc::U8: return "h";
730  case AMDGPULibFunc::U16: return "t";
731  case AMDGPULibFunc::U32: return "j";
732  case AMDGPULibFunc::U64: return "m";
733  case AMDGPULibFunc::I8: return "c";
734  case AMDGPULibFunc::I16: return "s";
735  case AMDGPULibFunc::I32: return "i";
736  case AMDGPULibFunc::I64: return "l";
737  case AMDGPULibFunc::F16: return "Dh";
738  case AMDGPULibFunc::F32: return "f";
739  case AMDGPULibFunc::F64: return "d";
740  case AMDGPULibFunc::IMG1DA: return "16ocl_image1darray";
741  case AMDGPULibFunc::IMG1DB: return "17ocl_image1dbuffer";
742  case AMDGPULibFunc::IMG2DA: return "16ocl_image2darray";
743  case AMDGPULibFunc::IMG1D: return "11ocl_image1d";
744  case AMDGPULibFunc::IMG2D: return "11ocl_image2d";
745  case AMDGPULibFunc::IMG3D: return "11ocl_image3d";
746  case AMDGPULibFunc::SAMPLER: return "11ocl_sampler";
747  case AMDGPULibFunc::EVENT: return "9ocl_event";
748  default: llvm_unreachable("Unhandeled param type");
749  }
750  return nullptr;
751 }
752 
753 namespace {
754 // Itanium mangling ABI says:
755 // "5.1.8. Compression
756 // ... Each non-terminal in the grammar for which <substitution> appears on the
757 // right-hand side is both a source of future substitutions and a candidate
758 // for being substituted. There are two exceptions that appear to be
759 // substitution candidates from the grammar, but are explicitly excluded:
760 // 1. <builtin-type> other than vendor extended types ..."
761 
762 // For the purpose of functions the following productions make sence for the
763 // substitution:
764 // <type> ::= <builtin-type>
765 // ::= <class-enum-type>
766 // ::= <array-type>
767 // ::=<CV-qualifiers> <type>
768 // ::= P <type> # pointer-to
769 // ::= <substitution>
770 //
771 // Note that while types like images, samplers and events are by the ABI encoded
772 // using <class-enum-type> production rule they're not used for substitution
773 // because clang consider them as builtin types.
774 //
775 // DvNN_ type is GCC extension for vectors and is a subject for the substitution.
776 
777 
778 class ItaniumMangler {
779  SmallVector<AMDGPULibFunc::Param, 10> Str; // list of accumulated substituions
780  bool UseAddrSpace;
781 
782  int findSubst(const AMDGPULibFunc::Param& P) const {
783  for(unsigned I = 0; I < Str.size(); ++I) {
784  const AMDGPULibFunc::Param& T = Str[I];
785  if (P.PtrKind == T.PtrKind &&
786  P.VectorSize == T.VectorSize &&
787  P.ArgType == T.ArgType) {
788  return I;
789  }
790  }
791  return -1;
792  }
793 
794  template <typename Stream>
795  bool trySubst(Stream& os, const AMDGPULibFunc::Param& p) {
796  int const subst = findSubst(p);
797  if (subst < 0) return false;
798  // Substitutions are mangled as S(XX)?_ where XX is a hexadecimal number
799  // 0 1 2
800  // S_ S0_ S1_
801  if (subst == 0) os << "S_";
802  else os << 'S' << (subst-1) << '_';
803  return true;
804  }
805 
806 public:
807  ItaniumMangler(bool useAddrSpace)
808  : UseAddrSpace(useAddrSpace) {}
809 
810  template <typename Stream>
811  void operator()(Stream& os, AMDGPULibFunc::Param p) {
812 
813  // Itanium mangling ABI 5.1.8. Compression:
814  // Logically, the substitutable components of a mangled name are considered
815  // left-to-right, components before the composite structure of which they
816  // are a part. If a component has been encountered before, it is substituted
817  // as described below. This decision is independent of whether its components
818  // have been substituted, so an implementation may optimize by considering
819  // large structures for substitution before their components. If a component
820  // has not been encountered before, its mangling is identified, and it is
821  // added to a dictionary of substitution candidates. No entity is added to
822  // the dictionary twice.
823  AMDGPULibFunc::Param Ptr;
824 
825  if (p.PtrKind) {
826  if (trySubst(os, p)) return;
827  os << 'P';
828  if (p.PtrKind & AMDGPULibFunc::CONST) os << 'K';
829  if (p.PtrKind & AMDGPULibFunc::VOLATILE) os << 'V';
830  unsigned AS = UseAddrSpace
832  : 0;
833  if (AS != 0) os << "U3AS" << AS;
834  Ptr = p;
835  p.PtrKind = 0;
836  }
837 
838  if (p.VectorSize > 1) {
839  if (trySubst(os, p)) goto exit;
840  Str.push_back(p);
841  os << "Dv" << static_cast<unsigned>(p.VectorSize) << '_';
842  }
843 
844  os << getItaniumTypeName((AMDGPULibFunc::EType)p.ArgType);
845 
846  exit:
847  if (Ptr.ArgType) Str.push_back(Ptr);
848  }
849 };
850 } // namespace
851 
852 std::string AMDGPUMangledLibFunc::mangleNameItanium() const {
853  SmallString<128> Buf;
854  raw_svector_ostream S(Buf);
855  SmallString<128> NameBuf;
856  raw_svector_ostream Name(NameBuf);
857  writeName(Name);
858  const StringRef& NameStr = Name.str();
859  S << "_Z" << static_cast<int>(NameStr.size()) << NameStr;
860 
861  ItaniumMangler Mangler(true);
862  ParamIterator I(Leads, manglingRules[FuncId]);
863  Param P;
864  while ((P = I.getNextParam()).ArgType != 0)
865  Mangler(S, P);
866  return S.str();
867 }
868 
869 ///////////////////////////////////////////////////////////////////////////////
870 // Misc
871 
873  LLVMContext& C,
874  const AMDGPULibFunc::Param& P,
875  bool useAddrSpace) {
876  Type* T = nullptr;
877  switch (P.ArgType) {
878  case AMDGPULibFunc::U8:
879  case AMDGPULibFunc::I8: T = Type::getInt8Ty(C); break;
880  case AMDGPULibFunc::U16:
881  case AMDGPULibFunc::I16: T = Type::getInt16Ty(C); break;
882  case AMDGPULibFunc::U32:
883  case AMDGPULibFunc::I32: T = Type::getInt32Ty(C); break;
884  case AMDGPULibFunc::U64:
885  case AMDGPULibFunc::I64: T = Type::getInt64Ty(C); break;
886  case AMDGPULibFunc::F16: T = Type::getHalfTy(C); break;
887  case AMDGPULibFunc::F32: T = Type::getFloatTy(C); break;
888  case AMDGPULibFunc::F64: T = Type::getDoubleTy(C); break;
889 
896  T = StructType::create(C,"ocl_image")->getPointerTo(); break;
898  T = StructType::create(C,"ocl_sampler")->getPointerTo(); break;
900  T = StructType::create(C,"ocl_event")->getPointerTo(); break;
901  default:
902  llvm_unreachable("Unhandeled param type");
903  return nullptr;
904  }
905  if (P.VectorSize > 1)
906  T = VectorType::get(T, P.VectorSize);
907  if (P.PtrKind != AMDGPULibFunc::BYVALUE)
908  T = useAddrSpace ? T->getPointerTo((P.PtrKind & AMDGPULibFunc::ADDR_SPACE)
909  - 1)
910  : T->getPointerTo();
911  return T;
912 }
913 
915  LLVMContext& C = M.getContext();
916  std::vector<Type*> Args;
917  ParamIterator I(Leads, manglingRules[FuncId]);
918  Param P;
919  while ((P=I.getNextParam()).ArgType != 0)
920  Args.push_back(getIntrinsicParamType(C, P, true));
921 
922  return FunctionType::get(
923  getIntrinsicParamType(C, getRetType(FuncId, Leads), true),
924  Args, false);
925 }
926 
928  return manglingRules[FuncId].getNumArgs();
929 }
930 
932  return UnmangledFuncInfo::getNumArgs(FuncId);
933 }
934 
935 std::string AMDGPUMangledLibFunc::getName() const {
936  SmallString<128> Buf;
937  raw_svector_ostream OS(Buf);
938  writeName(OS);
939  return OS.str();
940 }
941 
943  std::string FuncName = fInfo.mangle();
944  Function *F = dyn_cast_or_null<Function>(
945  M->getValueSymbolTable().lookup(FuncName));
946 
947  // check formal with actual types conformance
948  if (F && !F->isDeclaration()
949  && !F->isVarArg()
950  && F->arg_size() == fInfo.getNumArgs()) {
951  return F;
952  }
953  return nullptr;
954 }
955 
957  const AMDGPULibFunc &fInfo) {
958  std::string const FuncName = fInfo.mangle();
959  Function *F = dyn_cast_or_null<Function>(
960  M->getValueSymbolTable().lookup(FuncName));
961 
962  // check formal with actual types conformance
963  if (F && !F->isDeclaration()
964  && !F->isVarArg()
965  && F->arg_size() == fInfo.getNumArgs()) {
966  return F;
967  }
968 
969  FunctionType *FuncTy = fInfo.getFunctionType(*M);
970 
971  bool hasPtr = false;
973  PI = FuncTy->param_begin(),
974  PE = FuncTy->param_end();
975  PI != PE; ++PI) {
976  const Type* argTy = static_cast<const Type*>(*PI);
977  if (argTy->isPointerTy()) {
978  hasPtr = true;
979  break;
980  }
981  }
982 
984  if (hasPtr) {
985  // Do not set extra attributes for functions with pointer arguments.
986  C = M->getOrInsertFunction(FuncName, FuncTy);
987  } else {
988  AttributeList Attr;
989  LLVMContext &Ctx = M->getContext();
991  Attribute::ReadOnly);
993  Attribute::NoUnwind);
994  C = M->getOrInsertFunction(FuncName, FuncTy, Attr);
995  }
996 
997  return C;
998 }
999 
1000 StringMap<unsigned> UnmangledFuncInfo::buildNameMap() {
1001  StringMap<unsigned> Map;
1002  for (unsigned I = 0; I != TableSize; ++I)
1003  Map[Table[I].Name] = I;
1004  return Map;
1005 }
1006 
1008  static const StringMap<unsigned> Map = buildNameMap();
1009  auto Loc = Map.find(Name);
1010  if (Loc != Map.end()) {
1011  Id = toFuncId(Loc->second);
1012  return true;
1013  }
1015  return false;
1016 }
1017 
1019  if (auto *MF = dyn_cast<AMDGPUMangledLibFunc>(F.Impl.get()))
1020  Impl.reset(new AMDGPUMangledLibFunc(*MF));
1021  else if (auto *UMF = dyn_cast<AMDGPUUnmangledLibFunc>(F.Impl.get()))
1022  Impl.reset(new AMDGPUUnmangledLibFunc(*UMF));
1023  else
1024  Impl = std::unique_ptr<AMDGPULibFuncImpl>();
1025 }
1026 
1028  if (this == &F)
1029  return *this;
1030  new (this) AMDGPULibFunc(F);
1031  return *this;
1032 }
1033 
1035  assert(AMDGPULibFuncBase::isMangled(Id) && CopyFrom.isMangled() &&
1036  "not supported");
1037  Impl.reset(new AMDGPUMangledLibFunc(
1038  Id, *cast<AMDGPUMangledLibFunc>(CopyFrom.Impl.get())));
1039 }
1040 
1042  Impl.reset(new AMDGPUUnmangledLibFunc(Name, FT));
1043 }
1044 
1045 void AMDGPULibFunc::initMangled() { Impl.reset(new AMDGPUMangledLibFunc()); }
1046 
1048  if (!Impl)
1049  initMangled();
1050  return cast<AMDGPUMangledLibFunc>(Impl.get())->Leads;
1051 }
1052 
1054  return cast<const AMDGPUMangledLibFunc>(Impl.get())->Leads;
1055 }
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition: Function.h:176
uint64_t CallInst * C
Profile::FuncID FuncId
Definition: Profile.cpp:321
static Type * getDoubleTy(LLVMContext &C)
Definition: Type.cpp:164
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
This class represents lattice values for constants.
Definition: AllocatorList.h:23
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:65
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
Address space for local memory.
Definition: AMDGPU.h:274
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Definition: DerivedTypes.h:165
LLVM_NODISCARD bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:256
static bool parse(StringRef MangledName, AMDGPULibFunc &Ptr)
const ValueSymbolTable & getValueSymbolTable() const
Get the symbol table of global variable and function identifiers.
Definition: Module.h:568
iterator find(StringRef Key)
Definition: StringMap.h:332
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:530
F(f)
param_iterator param_end() const
Definition: DerivedTypes.h:129
static IntegerType * getInt64Ty(LLVMContext &C)
Definition: Type.cpp:176
static IntegerType * getInt16Ty(LLVMContext &C)
Definition: Type.cpp:174
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:67
bool parseFuncName(StringRef &Name) override
static FunctionCallee getOrInsertFunction(llvm::Module *M, const AMDGPULibFunc &fInfo)
static StringRef getUnmangledName(StringRef MangledName)
unsigned getNumArgs() const override
static bool isMangled(EFuncId Id)
static Type * getFloatTy(LLVMContext &C)
Definition: Type.cpp:163
LLVM_NODISCARD StringRef drop_front(size_t N=1) const
Return a StringRef equal to &#39;this&#39; but with the first N elements dropped.
Definition: StringRef.h:620
LLVMContext & getContext() const
Get the global data context.
Definition: Module.h:244
Address space for global memory (RAT0, VTX0).
Definition: AMDGPU.h:270
PointerType * getPointerTo(unsigned AddrSpace=0) const
Return a pointer to the current type.
Definition: Type.cpp:654
LLVM_NODISCARD R Default(T Value)
Definition: StringSwitch.h:181
Param * getLeads()
Get leading parameters for mangled lib functions.
static StringRef getName(Value *V)
This file contains the simple types necessary to represent the attributes associated with functions a...
LLVM_NODISCARD StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:578
static const uint16_t * lookup(unsigned opcode, unsigned domain, ArrayRef< uint16_t[3]> Table)
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:126
unsigned getNumArgs() const
Class to represent function types.
Definition: DerivedTypes.h:103
unsigned getNumArgs() const override
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:130
std::string mangle() const override
#define P(N)
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:42
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
static Function * getFunction(llvm::Module *M, const AMDGPULibFunc &fInfo)
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:64
bool isPointerTy() const
True if this is an instance of PointerType.
Definition: Type.h:223
static AMDGPULibFunc::ENamePrefix parseNamePrefix(StringRef &mangledName)
param_iterator param_begin() const
Definition: DerivedTypes.h:128
bool isMangled() const
FunctionType * getFunctionType(Module &M) const override
static FunctionType * get(Type *Result, ArrayRef< Type *> Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
Definition: Type.cpp:296
size_t arg_size() const
Definition: Function.h:728
Wrapper class for AMDGPULIbFuncImpl.
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:346
bool parseFuncName(StringRef &mangledName) override
static unsigned getEPtrKindFromAddrSpace(unsigned AS)
size_t size() const
Definition: SmallVector.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static Type * getHalfTy(LLVMContext &C)
Definition: Type.cpp:162
static const char * getItaniumTypeName(AMDGPULibFunc::EType T)
static unsigned getAddrSpaceFromEPtrKind(unsigned Kind)
AMDGPULibFunc & operator=(const AMDGPULibFunc &F)
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:837
Module.h This file contains the declarations for the Module class.
LLVM_NODISCARD std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:696
Type::subtype_iterator param_iterator
Definition: DerivedTypes.h:126
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
Definition: STLExtras.h:1035
static int parseVecSize(StringRef &mangledName)
StringRef str()
Return a StringRef for the vector contents.
Definition: raw_ostream.h:555
FunctionCallee getOrInsertFunction(StringRef Name, FunctionType *T, AttributeList AttributeList)
Look up the specified function in the module symbol table.
Definition: Module.cpp:143
std::string getName() const override
Get unmangled name for mangled library function and name for unmangled library function.
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
Definition: StringMap.h:370
LLVM_NODISCARD AttributeList addAttribute(LLVMContext &C, unsigned Index, Attribute::AttrKind Kind) const
Add an attribute to the attribute set at the given index.
bool isDigit(char C)
Checks if character C is one of the 10 decimal digits.
Definition: StringExtras.h:76
static IntegerType * getInt32Ty(LLVMContext &C)
Definition: Type.cpp:175
static VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
Definition: Type.cpp:609
#define I(x, y, z)
Definition: MD5.cpp:58
#define N
Value * lookup(StringRef Name) const
This method finds the value with the given Name in the the symbol table.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition: Globals.cpp:231
LLVM_NODISCARD const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:122
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM_NODISCARD char front() const
front - Get the first character in the string.
Definition: StringRef.h:134
static StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
Definition: Type.cpp:436
static Type * getIntrinsicParamType(LLVMContext &C, const AMDGPULibFunc::Param &P, bool useAddrSpace)
EManglingParam
std::string mangle() const
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
static IntegerType * getInt8Ty(LLVMContext &C)
Definition: Type.cpp:173
iterator end()
Definition: StringMap.h:317
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
FunctionType * getFunctionType(Module &M) const