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