Coverage Report

Created: 2019-07-24 05:18

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