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