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