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