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