LLVM  14.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 intriniscs
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: llvm_unreachable("Unhandeled param rule");
459  }
460  }
461  ++Index;
462  return P;
463 }
464 
465 inline static void drop_front(StringRef& str, size_t n = 1) {
466  str = str.drop_front(n);
467 }
468 
469 static bool eatTerm(StringRef& mangledName, const char c) {
470  if (mangledName.front() == c) {
471  drop_front(mangledName);
472  return true;
473  }
474  return false;
475 }
476 
477 template <size_t N>
478 static bool eatTerm(StringRef& mangledName, const char (&str)[N]) {
479  if (mangledName.startswith(StringRef(str, N-1))) {
480  drop_front(mangledName, N-1);
481  return true;
482  }
483  return false;
484 }
485 
486 static int eatNumber(StringRef& s) {
487  size_t const savedSize = s.size();
488  int n = 0;
489  while (!s.empty() && isDigit(s.front())) {
490  n = n*10 + s.front() - '0';
491  drop_front(s);
492  }
493  return s.size() < savedSize ? n : -1;
494 }
495 
496 static StringRef eatLengthPrefixedName(StringRef& mangledName) {
497  int const Len = eatNumber(mangledName);
498  if (Len <= 0 || static_cast<size_t>(Len) > mangledName.size())
499  return StringRef();
500  StringRef Res = mangledName.substr(0, Len);
501  drop_front(mangledName, Len);
502  return Res;
503 }
504 
505 } // end anonymous namespace
506 
508  FuncId = EI_NONE;
509  FKind = NOPFX;
510  Leads[0].reset();
511  Leads[1].reset();
512  Name.clear();
513 }
514 
516  FuncId = EI_NONE;
517  FuncTy = nullptr;
518 }
519 
521  EFuncId id, const AMDGPUMangledLibFunc &copyFrom) {
522  FuncId = id;
523  FKind = copyFrom.FKind;
524  Leads[0] = copyFrom.Leads[0];
525  Leads[1] = copyFrom.Leads[1];
526 }
527 
528 ///////////////////////////////////////////////////////////////////////////////
529 // Demangling
530 
531 static int parseVecSize(StringRef& mangledName) {
532  size_t const Len = eatNumber(mangledName);
533  switch (Len) {
534  case 2: case 3: case 4: case 8: case 16:
535  return Len;
536  default:
537  break;
538  }
539  return 1;
540 }
541 
543  std::pair<StringRef, StringRef> const P = mangledName.split('_');
546  .Case("native", AMDGPULibFunc::NATIVE)
547  .Case("half" , AMDGPULibFunc::HALF)
549 
550  if (Pfx != AMDGPULibFunc::NOPFX)
551  mangledName = P.second;
552 
553  return Pfx;
554 }
555 
556 StringMap<int> ManglingRule::buildManglingRulesMap() {
557  StringMap<int> Map(array_lengthof(manglingRules));
558  int Id = 0;
559  for (auto Rule : manglingRules)
560  Map.insert({Rule.Name, Id++});
561  return Map;
562 }
563 
564 bool AMDGPUMangledLibFunc::parseUnmangledName(StringRef FullName) {
565  static const StringMap<int> manglingRulesMap =
566  ManglingRule::buildManglingRulesMap();
567  FuncId = static_cast<EFuncId>(manglingRulesMap.lookup(FullName));
568  return FuncId != EI_NONE;
569 }
570 
571 ///////////////////////////////////////////////////////////////////////////////
572 // Itanium Demangling
573 
574 namespace {
575 struct ItaniumParamParser {
577  bool parseItaniumParam(StringRef& param, AMDGPULibFunc::Param &res);
578 };
579 } // namespace
580 
581 bool ItaniumParamParser::parseItaniumParam(StringRef& param,
582  AMDGPULibFunc::Param &res) {
583  res.reset();
584  if (param.empty()) return false;
585 
586  // parse pointer prefix
587  if (eatTerm(param, 'P')) {
588  if (eatTerm(param, 'K')) res.PtrKind |= AMDGPULibFunc::CONST;
589  if (eatTerm(param, 'V')) res.PtrKind |= AMDGPULibFunc::VOLATILE;
590  unsigned AS;
591  if (!eatTerm(param, "U3AS")) {
592  AS = 0;
593  } else {
594  AS = param.front() - '0';
595  drop_front(param, 1);
596  }
598  } else {
599  res.PtrKind = AMDGPULibFunc::BYVALUE;
600  }
601 
602  // parse vector size
603  if (eatTerm(param,"Dv")) {
604  res.VectorSize = parseVecSize(param);
605  if (res.VectorSize==1 || !eatTerm(param, '_')) return false;
606  }
607 
608  // parse type
609  char const TC = param.front();
610  if (isDigit(TC)) {
612  (eatLengthPrefixedName(param))
613  .Case("ocl_image1darray" , AMDGPULibFunc::IMG1DA)
614  .Case("ocl_image1dbuffer", AMDGPULibFunc::IMG1DB)
615  .Case("ocl_image2darray" , AMDGPULibFunc::IMG2DA)
616  .Case("ocl_image1d" , AMDGPULibFunc::IMG1D)
617  .Case("ocl_image2d" , AMDGPULibFunc::IMG2D)
618  .Case("ocl_image3d" , AMDGPULibFunc::IMG3D)
619  .Case("ocl_event" , AMDGPULibFunc::DUMMY)
620  .Case("ocl_sampler" , AMDGPULibFunc::DUMMY)
622  } else {
623  drop_front(param);
624  switch (TC) {
625  case 'h': res.ArgType = AMDGPULibFunc::U8; break;
626  case 't': res.ArgType = AMDGPULibFunc::U16; break;
627  case 'j': res.ArgType = AMDGPULibFunc::U32; break;
628  case 'm': res.ArgType = AMDGPULibFunc::U64; break;
629  case 'c': res.ArgType = AMDGPULibFunc::I8; break;
630  case 's': res.ArgType = AMDGPULibFunc::I16; break;
631  case 'i': res.ArgType = AMDGPULibFunc::I32; break;
632  case 'l': res.ArgType = AMDGPULibFunc::I64; break;
633  case 'f': res.ArgType = AMDGPULibFunc::F32; break;
634  case 'd': res.ArgType = AMDGPULibFunc::F64; break;
635  case 'D': if (!eatTerm(param, 'h')) return false;
636  res.ArgType = AMDGPULibFunc::F16; break;
637  case 'S':
638  if (!eatTerm(param, '_')) {
639  eatNumber(param);
640  if (!eatTerm(param, '_')) return false;
641  }
642  res.VectorSize = Prev.VectorSize;
643  res.ArgType = Prev.ArgType;
644  break;
645  default:;
646  }
647  }
648  if (res.ArgType == 0) return false;
649  Prev.VectorSize = res.VectorSize;
650  Prev.ArgType = res.ArgType;
651  return true;
652 }
653 
655  StringRef Name = eatLengthPrefixedName(mangledName);
657  if (!parseUnmangledName(Name))
658  return false;
659 
660  const ManglingRule& Rule = manglingRules[FuncId];
661  ItaniumParamParser Parser;
662  for (int I=0; I < Rule.maxLeadIndex(); ++I) {
663  Param P;
664  if (!Parser.parseItaniumParam(mangledName, P))
665  return false;
666 
667  if ((I + 1) == Rule.Lead[0]) Leads[0] = P;
668  if ((I + 1) == Rule.Lead[1]) Leads[1] = P;
669  }
670  return true;
671 }
672 
675  return false;
676  setName(Name);
677  return true;
678 }
679 
681  if (FuncName.empty()) {
682  F.Impl = std::unique_ptr<AMDGPULibFuncImpl>();
683  return false;
684  }
685 
686  if (eatTerm(FuncName, "_Z"))
687  F.Impl = std::make_unique<AMDGPUMangledLibFunc>();
688  else
689  F.Impl = std::make_unique<AMDGPUUnmangledLibFunc>();
690  if (F.Impl->parseFuncName(FuncName))
691  return true;
692 
693  F.Impl = std::unique_ptr<AMDGPULibFuncImpl>();
694  return false;
695 }
696 
698  StringRef S = mangledName;
699  if (eatTerm(S, "_Z"))
700  return eatLengthPrefixedName(S);
701  return StringRef();
702 }
703 
704 ///////////////////////////////////////////////////////////////////////////////
705 // Mangling
706 
707 template <typename Stream>
708 void AMDGPUMangledLibFunc::writeName(Stream &OS) const {
709  const char *Pfx = "";
710  switch (FKind) {
711  case NATIVE: Pfx = "native_"; break;
712  case HALF: Pfx = "half_"; break;
713  default: break;
714  }
715  if (!Name.empty()) {
716  OS << Pfx << Name;
717  } else if (FuncId != EI_NONE) {
718  OS << Pfx;
719  const StringRef& S = manglingRules[FuncId].Name;
720  OS.write(S.data(), S.size());
721  }
722 }
723 
724 std::string AMDGPUMangledLibFunc::mangle() const { return mangleNameItanium(); }
725 
726 ///////////////////////////////////////////////////////////////////////////////
727 // Itanium Mangling
728 
730  switch (T) {
731  case AMDGPULibFunc::U8: return "h";
732  case AMDGPULibFunc::U16: return "t";
733  case AMDGPULibFunc::U32: return "j";
734  case AMDGPULibFunc::U64: return "m";
735  case AMDGPULibFunc::I8: return "c";
736  case AMDGPULibFunc::I16: return "s";
737  case AMDGPULibFunc::I32: return "i";
738  case AMDGPULibFunc::I64: return "l";
739  case AMDGPULibFunc::F16: return "Dh";
740  case AMDGPULibFunc::F32: return "f";
741  case AMDGPULibFunc::F64: return "d";
742  case AMDGPULibFunc::IMG1DA: return "16ocl_image1darray";
743  case AMDGPULibFunc::IMG1DB: return "17ocl_image1dbuffer";
744  case AMDGPULibFunc::IMG2DA: return "16ocl_image2darray";
745  case AMDGPULibFunc::IMG1D: return "11ocl_image1d";
746  case AMDGPULibFunc::IMG2D: return "11ocl_image2d";
747  case AMDGPULibFunc::IMG3D: return "11ocl_image3d";
748  case AMDGPULibFunc::SAMPLER: return "11ocl_sampler";
749  case AMDGPULibFunc::EVENT: return "9ocl_event";
750  default: llvm_unreachable("Unhandeled param type");
751  }
752  return nullptr;
753 }
754 
755 namespace {
756 // Itanium mangling ABI says:
757 // "5.1.8. Compression
758 // ... Each non-terminal in the grammar for which <substitution> appears on the
759 // right-hand side is both a source of future substitutions and a candidate
760 // for being substituted. There are two exceptions that appear to be
761 // substitution candidates from the grammar, but are explicitly excluded:
762 // 1. <builtin-type> other than vendor extended types ..."
763 
764 // For the purpose of functions the following productions make sence for the
765 // substitution:
766 // <type> ::= <builtin-type>
767 // ::= <class-enum-type>
768 // ::= <array-type>
769 // ::=<CV-qualifiers> <type>
770 // ::= P <type> # pointer-to
771 // ::= <substitution>
772 //
773 // Note that while types like images, samplers and events are by the ABI encoded
774 // using <class-enum-type> production rule they're not used for substitution
775 // because clang consider them as builtin types.
776 //
777 // DvNN_ type is GCC extension for vectors and is a subject for the substitution.
778 
779 
780 class ItaniumMangler {
781  SmallVector<AMDGPULibFunc::Param, 10> Str; // list of accumulated substituions
782  bool UseAddrSpace;
783 
784  int findSubst(const AMDGPULibFunc::Param& P) const {
785  for(unsigned I = 0; I < Str.size(); ++I) {
786  const AMDGPULibFunc::Param& T = Str[I];
787  if (P.PtrKind == T.PtrKind &&
788  P.VectorSize == T.VectorSize &&
789  P.ArgType == T.ArgType) {
790  return I;
791  }
792  }
793  return -1;
794  }
795 
796  template <typename Stream>
797  bool trySubst(Stream& os, const AMDGPULibFunc::Param& p) {
798  int const subst = findSubst(p);
799  if (subst < 0) return false;
800  // Substitutions are mangled as S(XX)?_ where XX is a hexadecimal number
801  // 0 1 2
802  // S_ S0_ S1_
803  if (subst == 0) os << "S_";
804  else os << 'S' << (subst-1) << '_';
805  return true;
806  }
807 
808 public:
809  ItaniumMangler(bool useAddrSpace)
810  : UseAddrSpace(useAddrSpace) {}
811 
812  template <typename Stream>
813  void operator()(Stream& os, AMDGPULibFunc::Param p) {
814 
815  // Itanium mangling ABI 5.1.8. Compression:
816  // Logically, the substitutable components of a mangled name are considered
817  // left-to-right, components before the composite structure of which they
818  // are a part. If a component has been encountered before, it is substituted
819  // as described below. This decision is independent of whether its components
820  // have been substituted, so an implementation may optimize by considering
821  // large structures for substitution before their components. If a component
822  // has not been encountered before, its mangling is identified, and it is
823  // added to a dictionary of substitution candidates. No entity is added to
824  // the dictionary twice.
826 
827  if (p.PtrKind) {
828  if (trySubst(os, p)) return;
829  os << 'P';
830  if (p.PtrKind & AMDGPULibFunc::CONST) os << 'K';
831  if (p.PtrKind & AMDGPULibFunc::VOLATILE) os << 'V';
832  unsigned AS = UseAddrSpace
834  : 0;
835  if (EnableOCLManglingMismatchWA || AS != 0)
836  os << "U3AS" << AS;
837  Ptr = p;
838  p.PtrKind = 0;
839  }
840 
841  if (p.VectorSize > 1) {
842  if (trySubst(os, p)) goto exit;
843  Str.push_back(p);
844  os << "Dv" << static_cast<unsigned>(p.VectorSize) << '_';
845  }
846 
847  os << getItaniumTypeName((AMDGPULibFunc::EType)p.ArgType);
848 
849  exit:
850  if (Ptr.ArgType) Str.push_back(Ptr);
851  }
852 };
853 } // namespace
854 
855 std::string AMDGPUMangledLibFunc::mangleNameItanium() const {
856  SmallString<128> Buf;
857  raw_svector_ostream S(Buf);
858  SmallString<128> NameBuf;
859  raw_svector_ostream Name(NameBuf);
860  writeName(Name);
861  const StringRef& NameStr = Name.str();
862  S << "_Z" << static_cast<int>(NameStr.size()) << NameStr;
863 
864  ItaniumMangler Mangler(true);
865  ParamIterator I(Leads, manglingRules[FuncId]);
866  Param P;
867  while ((P = I.getNextParam()).ArgType != 0)
868  Mangler(S, P);
869  return std::string(S.str());
870 }
871 
872 ///////////////////////////////////////////////////////////////////////////////
873 // Misc
874 
876  LLVMContext& C,
877  const AMDGPULibFunc::Param& P,
878  bool useAddrSpace) {
879  Type* T = nullptr;
880  switch (P.ArgType) {
881  case AMDGPULibFunc::U8:
882  case AMDGPULibFunc::I8: T = Type::getInt8Ty(C); break;
883  case AMDGPULibFunc::U16:
884  case AMDGPULibFunc::I16: T = Type::getInt16Ty(C); break;
885  case AMDGPULibFunc::U32:
886  case AMDGPULibFunc::I32: T = Type::getInt32Ty(C); break;
887  case AMDGPULibFunc::U64:
888  case AMDGPULibFunc::I64: T = Type::getInt64Ty(C); break;
889  case AMDGPULibFunc::F16: T = Type::getHalfTy(C); break;
890  case AMDGPULibFunc::F32: T = Type::getFloatTy(C); break;
891  case AMDGPULibFunc::F64: T = Type::getDoubleTy(C); break;
892 
899  T = StructType::create(C,"ocl_image")->getPointerTo(); break;
901  T = StructType::create(C,"ocl_sampler")->getPointerTo(); break;
903  T = StructType::create(C,"ocl_event")->getPointerTo(); break;
904  default:
905  llvm_unreachable("Unhandeled param type");
906  return nullptr;
907  }
908  if (P.VectorSize > 1)
909  T = FixedVectorType::get(T, P.VectorSize);
910  if (P.PtrKind != AMDGPULibFunc::BYVALUE)
911  T = useAddrSpace ? T->getPointerTo((P.PtrKind & AMDGPULibFunc::ADDR_SPACE)
912  - 1)
913  : T->getPointerTo();
914  return T;
915 }
916 
918  LLVMContext& C = M.getContext();
919  std::vector<Type*> Args;
920  ParamIterator I(Leads, manglingRules[FuncId]);
921  Param P;
922  while ((P=I.getNextParam()).ArgType != 0)
923  Args.push_back(getIntrinsicParamType(C, P, true));
924 
925  return FunctionType::get(
926  getIntrinsicParamType(C, getRetType(FuncId, Leads), true),
927  Args, false);
928 }
929 
931  return manglingRules[FuncId].getNumArgs();
932 }
933 
935  return UnmangledFuncInfo::getNumArgs(FuncId);
936 }
937 
938 std::string AMDGPUMangledLibFunc::getName() const {
939  SmallString<128> Buf;
940  raw_svector_ostream OS(Buf);
941  writeName(OS);
942  return std::string(OS.str());
943 }
944 
946  std::string FuncName = fInfo.mangle();
947  Function *F = dyn_cast_or_null<Function>(
948  M->getValueSymbolTable().lookup(FuncName));
949 
950  // check formal with actual types conformance
951  if (F && !F->isDeclaration()
952  && !F->isVarArg()
953  && F->arg_size() == fInfo.getNumArgs()) {
954  return F;
955  }
956  return nullptr;
957 }
958 
960  const AMDGPULibFunc &fInfo) {
961  std::string const FuncName = fInfo.mangle();
962  Function *F = dyn_cast_or_null<Function>(
963  M->getValueSymbolTable().lookup(FuncName));
964 
965  // check formal with actual types conformance
966  if (F && !F->isDeclaration()
967  && !F->isVarArg()
968  && F->arg_size() == fInfo.getNumArgs()) {
969  return F;
970  }
971 
972  FunctionType *FuncTy = fInfo.getFunctionType(*M);
973 
974  bool hasPtr = false;
976  PI = FuncTy->param_begin(),
977  PE = FuncTy->param_end();
978  PI != PE; ++PI) {
979  const Type* argTy = static_cast<const Type*>(*PI);
980  if (argTy->isPointerTy()) {
981  hasPtr = true;
982  break;
983  }
984  }
985 
987  if (hasPtr) {
988  // Do not set extra attributes for functions with pointer arguments.
989  C = M->getOrInsertFunction(FuncName, FuncTy);
990  } else {
991  AttributeList Attr;
992  LLVMContext &Ctx = M->getContext();
993  Attr = Attr.addFnAttribute(Ctx, Attribute::ReadOnly);
994  Attr = Attr.addFnAttribute(Ctx, Attribute::NoUnwind);
995  C = M->getOrInsertFunction(FuncName, FuncTy, Attr);
996  }
997 
998  return C;
999 }
1000 
1001 StringMap<unsigned> UnmangledFuncInfo::buildNameMap() {
1002  StringMap<unsigned> Map;
1003  for (unsigned I = 0; I != TableSize; ++I)
1004  Map[Table[I].Name] = I;
1005  return Map;
1006 }
1007 
1009  static const StringMap<unsigned> Map = buildNameMap();
1010  auto Loc = Map.find(Name);
1011  if (Loc != Map.end()) {
1012  Id = toFuncId(Loc->second);
1013  return true;
1014  }
1016  return false;
1017 }
1018 
1020  if (auto *MF = dyn_cast<AMDGPUMangledLibFunc>(F.Impl.get()))
1021  Impl.reset(new AMDGPUMangledLibFunc(*MF));
1022  else if (auto *UMF = dyn_cast<AMDGPUUnmangledLibFunc>(F.Impl.get()))
1023  Impl.reset(new AMDGPUUnmangledLibFunc(*UMF));
1024  else
1025  Impl = std::unique_ptr<AMDGPULibFuncImpl>();
1026 }
1027 
1029  if (this == &F)
1030  return *this;
1031  new (this) AMDGPULibFunc(F);
1032  return *this;
1033 }
1034 
1037  "not supported");
1038  Impl.reset(new AMDGPUMangledLibFunc(
1039  Id, *cast<AMDGPUMangledLibFunc>(CopyFrom.Impl.get())));
1040 }
1041 
1043  Impl.reset(new AMDGPUUnmangledLibFunc(Name, FT));
1044 }
1045 
1046 void AMDGPULibFunc::initMangled() { Impl.reset(new AMDGPUMangledLibFunc()); }
1047 
1049  if (!Impl)
1050  initMangled();
1051  return cast<AMDGPUMangledLibFunc>(Impl.get())->Leads;
1052 }
1053 
1055  return cast<const AMDGPUMangledLibFunc>(Impl.get())->Leads;
1056 }
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:286
getName
static StringRef getName(Value *V)
Definition: ProvenanceAnalysisEvaluator.cpp:42
llvm
---------------------— PointerInfo ------------------------------------—
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:153
llvm::AMDGPULibFuncBase::F64
@ F64
Definition: AMDGPULibFunc.h:272
llvm::AttributeList::addFnAttribute
LLVM_NODISCARD AttributeList addFnAttribute(LLVMContext &C, Attribute::AttrKind Kind) const
Add a function attribute to the list.
Definition: Attributes.h:483
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:228
llvm::AMDGPUUnmangledLibFunc::parseFuncName
bool parseFuncName(StringRef &Name) override
Definition: AMDGPULibFunc.cpp:673
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:729
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::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:325
llvm::AMDGPUMangledLibFunc::Leads
Param Leads[2]
Definition: AMDGPULibFunc.h:409
llvm::AMDGPULibFunc::parse
static bool parse(StringRef MangledName, AMDGPULibFunc &Ptr)
Definition: AMDGPULibFunc.cpp:680
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:270
llvm::AMDGPULibFuncBase::Param::reset
void reset()
Definition: AMDGPULibFunc.h:298
llvm::AttributeList
Definition: Attributes.h:398
T
#define T
Definition: Mips16ISelLowering.cpp:341
llvm::AMDGPUUnmangledLibFunc::getNumArgs
unsigned getNumArgs() const override
Definition: AMDGPULibFunc.cpp:934
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:477
llvm::Mangler
Definition: Mangler.h:27
llvm::Type::getInt8Ty
static IntegerType * getInt8Ty(LLVMContext &C)
Definition: Type.cpp:201
llvm::cl::ReallyHidden
@ ReallyHidden
Definition: CommandLine.h:144
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:203
llvm::AMDGPUMangledLibFunc::parseFuncName
bool parseFuncName(StringRef &mangledName) override
Definition: AMDGPULibFunc.cpp:654
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::RISCVFenceField::R
@ R
Definition: RISCVBaseInfo.h:193
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:1048
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:312
llvm::AMDGPULibFunc
Wrapper class for AMDGPULIbFuncImpl.
Definition: AMDGPULibFunc.h:357
CommandLine.h
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:749
llvm::Type::getDoubleTy
static Type * getDoubleTy(LLVMContext &C)
Definition: Type.cpp:191
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:959
llvm::AMDGPULibFuncImpl::Name
std::string Name
Definition: AMDGPULibFunc.h:352
Param
Value * Param
Definition: NVPTXLowerArgs.cpp:163
llvm::AMDGPULibFuncBase::IMG1DB
@ IMG1DB
Definition: AMDGPULibFunc.h:274
llvm::FunctionType::param_begin
param_iterator param_begin() const
Definition: DerivedTypes.h:128
parseVecSize
static int parseVecSize(StringRef &mangledName)
Definition: AMDGPULibFunc.cpp:531
StringMap.h
llvm::AMDGPUMangledLibFunc::getFunctionType
FunctionType * getFunctionType(Module &M) const override
Definition: AMDGPULibFunc.cpp:917
llvm::FixedVectorType::get
static FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition: Type.cpp:648
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:938
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:1390
llvm::AMDGPUMangledLibFunc::getUnmangledName
static StringRef getUnmangledName(StringRef MangledName)
Definition: AMDGPULibFunc.cpp:697
llvm::AMDGPULibFuncBase::NOPFX
@ NOPFX
Definition: AMDGPULibFunc.h:247
llvm::StringMap< int >
llvm::SmallString< 128 >
llvm::AMDGPUMangledLibFunc::AMDGPUMangledLibFunc
AMDGPUMangledLibFunc()
Definition: AMDGPULibFunc.cpp:507
ValueSymbolTable.h
AMDGPULibFunc.h
llvm::cl::opt< bool >
llvm::AMDGPUUnmangledLibFunc::AMDGPUUnmangledLibFunc
AMDGPUUnmangledLibFunc()
Definition: AMDGPULibFunc.cpp:515
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:126
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:724
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: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:232
StringExtras.h
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
llvm::AMDGPULibFuncBase::CONST
@ CONST
Definition: AMDGPULibFunc.h:287
llvm::AMDGPULibFunc::getNumArgs
unsigned getNumArgs() const
Definition: AMDGPULibFunc.h:372
llvm::AMDGPUAS::LOCAL_ADDRESS
@ LOCAL_ADDRESS
Address space for local memory.
Definition: AMDGPU.h:354
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::AMDGPUMangledLibFunc::getNumArgs
unsigned getNumArgs() const override
Definition: AMDGPULibFunc.cpp:930
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
isDigit
static bool isDigit(const char C)
Definition: RustDemangle.cpp:205
llvm::AMDGPULibFuncBase::U32
@ U32
Definition: AMDGPULibFunc.h:264
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:683
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:542
llvm::AMDGPULibFunc::operator=
AMDGPULibFunc & operator=(const AMDGPULibFunc &F)
Definition: AMDGPULibFunc.cpp:1028
llvm::AMDGPULibFuncBase::IMG1D
@ IMG1D
Definition: AMDGPULibFunc.h:276
llvm::Type::getInt64Ty
static IntegerType * getInt64Ty(LLVMContext &C)
Definition: Type.cpp:204
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:653
llvm::Type::getHalfTy
static Type * getHalfTy(LLVMContext &C)
Definition: Type.cpp:188
llvm::AMDGPUMangledLibFunc
Definition: AMDGPULibFunc.h:407
llvm::AMDGPULibFuncBase::I64
@ I64
Definition: AMDGPULibFunc.h:269
Function.h
llvm::AMDGPULibFunc::AMDGPULibFunc
AMDGPULibFunc()
Definition: AMDGPULibFunc.h:359
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:738
StringSwitch.h
llvm::orc::ReadOnly
static constexpr sys::Memory::ProtectionFlags ReadOnly
Definition: DebugObjectManagerPlugin.cpp:111
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:658
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:202
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::AMDGPUAS::GLOBAL_ADDRESS
@ GLOBAL_ADDRESS
Address space for global memory (RAT0, VTX0).
Definition: AMDGPU.h:350
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:389
llvm::cl::desc
Definition: CommandLine.h:414
getIntrinsicParamType
static Type * getIntrinsicParamType(LLVMContext &C, const AMDGPULibFunc::Param &P, bool useAddrSpace)
Definition: AMDGPULibFunc.cpp:875
raw_ostream.h
llvm::AMDGPUUnmangledLibFunc
Definition: AMDGPULibFunc.h:436
llvm::AMDGPU::VGPRIndexMode::Id
Id
Definition: SIDefines.h:228
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:157
llvm::AMDGPULibFunc::getFunction
static Function * getFunction(llvm::Module *M, const AMDGPULibFunc &fInfo)
Definition: AMDGPULibFunc.cpp:945
llvm::AMDGPULibFuncBase::NATIVE
@ NATIVE
Definition: AMDGPULibFunc.h:248
llvm::Type::getFloatTy
static Type * getFloatTy(LLVMContext &C)
Definition: Type.cpp:190
llvm::FunctionType
Class to represent function types.
Definition: DerivedTypes.h:103
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:37