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