Coverage Report

Created: 2019-02-20 00:17

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/Analysis/TargetLibraryInfo.h
Line
Count
Source (jump to first uncovered line)
1
//===-- TargetLibraryInfo.h - Library information ---------------*- C++ -*-===//
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
#ifndef LLVM_ANALYSIS_TARGETLIBRARYINFO_H
10
#define LLVM_ANALYSIS_TARGETLIBRARYINFO_H
11
12
#include "llvm/ADT/DenseMap.h"
13
#include "llvm/ADT/Optional.h"
14
#include "llvm/ADT/Triple.h"
15
#include "llvm/IR/CallSite.h"
16
#include "llvm/IR/Function.h"
17
#include "llvm/IR/Module.h"
18
#include "llvm/IR/PassManager.h"
19
#include "llvm/Pass.h"
20
21
namespace llvm {
22
template <typename T> class ArrayRef;
23
24
/// Describes a possible vectorization of a function.
25
/// Function 'VectorFnName' is equivalent to 'ScalarFnName' vectorized
26
/// by a factor 'VectorizationFactor'.
27
struct VecDesc {
28
  StringRef ScalarFnName;
29
  StringRef VectorFnName;
30
  unsigned VectorizationFactor;
31
};
32
33
  enum LibFunc {
34
#define TLI_DEFINE_ENUM
35
#include "llvm/Analysis/TargetLibraryInfo.def"
36
37
    NumLibFuncs
38
  };
39
40
/// Implementation of the target library information.
41
///
42
/// This class constructs tables that hold the target library information and
43
/// make it available. However, it is somewhat expensive to compute and only
44
/// depends on the triple. So users typically interact with the \c
45
/// TargetLibraryInfo wrapper below.
46
class TargetLibraryInfoImpl {
47
  friend class TargetLibraryInfo;
48
49
  unsigned char AvailableArray[(NumLibFuncs+3)/4];
50
  llvm::DenseMap<unsigned, std::string> CustomNames;
51
  static StringRef const StandardNames[NumLibFuncs];
52
  bool ShouldExtI32Param, ShouldExtI32Return, ShouldSignExtI32Param;
53
54
  enum AvailabilityState {
55
    StandardName = 3, // (memset to all ones)
56
    CustomName = 1,
57
    Unavailable = 0  // (memset to all zeros)
58
  };
59
7.75M
  void setState(LibFunc F, AvailabilityState State) {
60
7.75M
    AvailableArray[F/4] &= ~(3 << 2*(F&3));
61
7.75M
    AvailableArray[F/4] |= State << 2*(F&3);
62
7.75M
  }
63
26.9M
  AvailabilityState getState(LibFunc F) const {
64
26.9M
    return static_cast<AvailabilityState>((AvailableArray[F/4] >> 2*(F&3)) & 3);
65
26.9M
  }
66
67
  /// Vectorization descriptors - sorted by ScalarFnName.
68
  std::vector<VecDesc> VectorDescs;
69
  /// Scalarization descriptors - same content as VectorDescs but sorted based
70
  /// on VectorFnName rather than ScalarFnName.
71
  std::vector<VecDesc> ScalarDescs;
72
73
  /// Return true if the function type FTy is valid for the library function
74
  /// F, regardless of whether the function is available.
75
  bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc F,
76
                              const DataLayout *DL) const;
77
78
public:
79
  /// List of known vector-functions libraries.
80
  ///
81
  /// The vector-functions library defines, which functions are vectorizable
82
  /// and with which factor. The library can be specified by either frontend,
83
  /// or a commandline option, and then used by
84
  /// addVectorizableFunctionsFromVecLib for filling up the tables of
85
  /// vectorizable functions.
86
  enum VectorLibrary {
87
    NoLibrary,  // Don't use any vector library.
88
    Accelerate, // Use Accelerate framework.
89
    SVML        // Intel short vector math library.
90
  };
91
92
  TargetLibraryInfoImpl();
93
  explicit TargetLibraryInfoImpl(const Triple &T);
94
95
  // Provide value semantics.
96
  TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI);
97
  TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI);
98
  TargetLibraryInfoImpl &operator=(const TargetLibraryInfoImpl &TLI);
99
  TargetLibraryInfoImpl &operator=(TargetLibraryInfoImpl &&TLI);
100
101
  /// Searches for a particular function name.
102
  ///
103
  /// If it is one of the known library functions, return true and set F to the
104
  /// corresponding value.
105
  bool getLibFunc(StringRef funcName, LibFunc &F) const;
106
107
  /// Searches for a particular function name, also checking that its type is
108
  /// valid for the library function matching that name.
109
  ///
110
  /// If it is one of the known library functions, return true and set F to the
111
  /// corresponding value.
112
  bool getLibFunc(const Function &FDecl, LibFunc &F) const;
113
114
  /// Forces a function to be marked as unavailable.
115
7.59M
  void setUnavailable(LibFunc F) {
116
7.59M
    setState(F, Unavailable);
117
7.59M
  }
118
119
  /// Forces a function to be marked as available.
120
127k
  void setAvailable(LibFunc F) {
121
127k
    setState(F, StandardName);
122
127k
  }
123
124
  /// Forces a function to be marked as available and provide an alternate name
125
  /// that must be used.
126
39.0k
  void setAvailableWithName(LibFunc F, StringRef Name) {
127
39.0k
    if (
StandardNames[F] != Name39.0k
) {
128
39.0k
      setState(F, CustomName);
129
39.0k
      CustomNames[F] = Name;
130
39.0k
      assert(CustomNames.find(F) != CustomNames.end());
131
18.4E
    } else {
132
18.4E
      setState(F, StandardName);
133
18.4E
    }
134
39.0k
  }
135
136
  /// Disables all builtins.
137
  ///
138
  /// This can be used for options like -fno-builtin.
139
  void disableAllFunctions();
140
141
  /// Add a set of scalar -> vector mappings, queryable via
142
  /// getVectorizedFunction and getScalarizedFunction.
143
  void addVectorizableFunctions(ArrayRef<VecDesc> Fns);
144
145
  /// Calls addVectorizableFunctions with a known preset of functions for the
146
  /// given vector library.
147
  void addVectorizableFunctionsFromVecLib(enum VectorLibrary VecLib);
148
149
  /// Return true if the function F has a vector equivalent with vectorization
150
  /// factor VF.
151
1.24k
  bool isFunctionVectorizable(StringRef F, unsigned VF) const {
152
1.24k
    return !getVectorizedFunction(F, VF).empty();
153
1.24k
  }
154
155
  /// Return true if the function F has a vector equivalent with any
156
  /// vectorization factor.
157
  bool isFunctionVectorizable(StringRef F) const;
158
159
  /// Return the name of the equivalent of F, vectorized with factor VF. If no
160
  /// such mapping exists, return the empty string.
161
  StringRef getVectorizedFunction(StringRef F, unsigned VF) const;
162
163
  /// Return true if the function F has a scalar equivalent, and set VF to be
164
  /// the vectorization factor.
165
0
  bool isFunctionScalarizable(StringRef F, unsigned &VF) const {
166
0
    return !getScalarizedFunction(F, VF).empty();
167
0
  }
168
169
  /// Return the name of the equivalent of F, scalarized. If no such mapping
170
  /// exists, return the empty string.
171
  ///
172
  /// Set VF to the vectorization factor.
173
  StringRef getScalarizedFunction(StringRef F, unsigned &VF) const;
174
175
  /// Set to true iff i32 parameters to library functions should have signext
176
  /// or zeroext attributes if they correspond to C-level int or unsigned int,
177
  /// respectively.
178
95.3k
  void setShouldExtI32Param(bool Val) {
179
95.3k
    ShouldExtI32Param = Val;
180
95.3k
  }
181
182
  /// Set to true iff i32 results from library functions should have signext
183
  /// or zeroext attributes if they correspond to C-level int or unsigned int,
184
  /// respectively.
185
95.3k
  void setShouldExtI32Return(bool Val) {
186
95.3k
    ShouldExtI32Return = Val;
187
95.3k
  }
188
189
  /// Set to true iff i32 parameters to library functions should have signext
190
  /// attribute if they correspond to C-level int or unsigned int.
191
95.3k
  void setShouldSignExtI32Param(bool Val) {
192
95.3k
    ShouldSignExtI32Param = Val;
193
95.3k
  }
194
195
  /// Returns the size of the wchar_t type in bytes or 0 if the size is unknown.
196
  /// This queries the 'wchar_size' metadata.
197
  unsigned getWCharSize(const Module &M) const;
198
};
199
200
/// Provides information about what library functions are available for
201
/// the current target.
202
///
203
/// This both allows optimizations to handle them specially and frontends to
204
/// disable such optimizations through -fno-builtin etc.
205
class TargetLibraryInfo {
206
  friend class TargetLibraryAnalysis;
207
  friend class TargetLibraryInfoWrapperPass;
208
209
  const TargetLibraryInfoImpl *Impl;
210
211
public:
212
119k
  explicit TargetLibraryInfo(const TargetLibraryInfoImpl &Impl) : Impl(&Impl) {}
213
214
  // Provide value semantics.
215
  TargetLibraryInfo(const TargetLibraryInfo &TLI) : Impl(TLI.Impl) {}
216
8.74k
  TargetLibraryInfo(TargetLibraryInfo &&TLI) : Impl(TLI.Impl) {}
217
  TargetLibraryInfo &operator=(const TargetLibraryInfo &TLI) {
218
    Impl = TLI.Impl;
219
    return *this;
220
  }
221
  TargetLibraryInfo &operator=(TargetLibraryInfo &&TLI) {
222
    Impl = TLI.Impl;
223
    return *this;
224
  }
225
226
  /// Searches for a particular function name.
227
  ///
228
  /// If it is one of the known library functions, return true and set F to the
229
  /// corresponding value.
230
26.1M
  bool getLibFunc(StringRef funcName, LibFunc &F) const {
231
26.1M
    return Impl->getLibFunc(funcName, F);
232
26.1M
  }
233
234
23.8M
  bool getLibFunc(const Function &FDecl, LibFunc &F) const {
235
23.8M
    return Impl->getLibFunc(FDecl, F);
236
23.8M
  }
237
238
  /// If a callsite does not have the 'nobuiltin' attribute, return if the
239
  /// called function is a known library function and set F to that function.
240
1.85M
  bool getLibFunc(ImmutableCallSite CS, LibFunc &F) const {
241
1.85M
    return !CS.isNoBuiltin() && 
CS.getCalledFunction()750k
&&
242
1.85M
           
getLibFunc(*(CS.getCalledFunction()), F)710k
;
243
1.85M
  }
244
245
  /// Tests whether a library function is available.
246
20.9M
  bool has(LibFunc F) const {
247
20.9M
    return Impl->getState(F) != TargetLibraryInfoImpl::Unavailable;
248
20.9M
  }
249
1.24k
  bool isFunctionVectorizable(StringRef F, unsigned VF) const {
250
1.24k
    return Impl->isFunctionVectorizable(F, VF);
251
1.24k
  }
252
30.5k
  bool isFunctionVectorizable(StringRef F) const {
253
30.5k
    return Impl->isFunctionVectorizable(F);
254
30.5k
  }
255
72
  StringRef getVectorizedFunction(StringRef F, unsigned VF) const {
256
72
    return Impl->getVectorizedFunction(F, VF);
257
72
  }
258
259
  /// Tests if the function is both available and a candidate for optimized code
260
  /// generation.
261
53.2k
  bool hasOptimizedCodeGen(LibFunc F) const {
262
53.2k
    if (Impl->getState(F) == TargetLibraryInfoImpl::Unavailable)
263
3.50k
      return false;
264
49.7k
    switch (F) {
265
49.7k
    
default: break42.3k
;
266
49.7k
    
case LibFunc_copysign: 7.43k
case LibFunc_copysignf: 7.43k
case LibFunc_copysignl:
267
7.43k
    case LibFunc_fabs:         case LibFunc_fabsf:      case LibFunc_fabsl:
268
7.43k
    case LibFunc_sin:          case LibFunc_sinf:       case LibFunc_sinl:
269
7.43k
    case LibFunc_cos:          case LibFunc_cosf:       case LibFunc_cosl:
270
7.43k
    case LibFunc_sqrt:         case LibFunc_sqrtf:      case LibFunc_sqrtl:
271
7.43k
    case LibFunc_sqrt_finite:  case LibFunc_sqrtf_finite:
272
7.43k
                                                   case LibFunc_sqrtl_finite:
273
7.43k
    case LibFunc_fmax:         case LibFunc_fmaxf:      case LibFunc_fmaxl:
274
7.43k
    case LibFunc_fmin:         case LibFunc_fminf:      case LibFunc_fminl:
275
7.43k
    case LibFunc_floor:        case LibFunc_floorf:     case LibFunc_floorl:
276
7.43k
    case LibFunc_nearbyint:    case LibFunc_nearbyintf: case LibFunc_nearbyintl:
277
7.43k
    case LibFunc_ceil:         case LibFunc_ceilf:      case LibFunc_ceill:
278
7.43k
    case LibFunc_rint:         case LibFunc_rintf:      case LibFunc_rintl:
279
7.43k
    case LibFunc_round:        case LibFunc_roundf:     case LibFunc_roundl:
280
7.43k
    case LibFunc_trunc:        case LibFunc_truncf:     case LibFunc_truncl:
281
7.43k
    case LibFunc_log2:         case LibFunc_log2f:      case LibFunc_log2l:
282
7.43k
    case LibFunc_exp2:         case LibFunc_exp2f:      case LibFunc_exp2l:
283
7.43k
    case LibFunc_memcmp:       case LibFunc_strcmp:     case LibFunc_strcpy:
284
7.43k
    case LibFunc_stpcpy:       case LibFunc_strlen:     case LibFunc_strnlen:
285
7.43k
    case LibFunc_memchr:       case LibFunc_mempcpy:
286
7.43k
      return true;
287
42.3k
    }
288
42.3k
    return false;
289
42.3k
  }
290
291
5.88M
  StringRef getName(LibFunc F) const {
292
5.88M
    auto State = Impl->getState(F);
293
5.88M
    if (State == TargetLibraryInfoImpl::Unavailable)
294
174
      return StringRef();
295
5.88M
    if (State == TargetLibraryInfoImpl::StandardName)
296
5.88M
      return Impl->StandardNames[F];
297
43
    assert(State == TargetLibraryInfoImpl::CustomName);
298
43
    return Impl->CustomNames.find(F)->second;
299
43
  }
300
301
  /// Returns extension attribute kind to be used for i32 parameters
302
  /// corresponding to C-level int or unsigned int.  May be zeroext, signext,
303
  /// or none.
304
228
  Attribute::AttrKind getExtAttrForI32Param(bool Signed = true) const {
305
228
    if (Impl->ShouldExtI32Param)
306
8
      return Signed ? 
Attribute::SExt0
: Attribute::ZExt;
307
220
    if (Impl->ShouldSignExtI32Param)
308
4
      return Attribute::SExt;
309
216
    return Attribute::None;
310
216
  }
311
312
  /// Returns extension attribute kind to be used for i32 return values
313
  /// corresponding to C-level int or unsigned int.  May be zeroext, signext,
314
  /// or none.
315
  Attribute::AttrKind getExtAttrForI32Return(bool Signed = true) const {
316
    if (Impl->ShouldExtI32Return)
317
      return Signed ? Attribute::SExt : Attribute::ZExt;
318
    return Attribute::None;
319
  }
320
321
  /// \copydoc TargetLibraryInfoImpl::getWCharSize()
322
73
  unsigned getWCharSize(const Module &M) const {
323
73
    return Impl->getWCharSize(M);
324
73
  }
325
326
  /// Handle invalidation from the pass manager.
327
  ///
328
  /// If we try to invalidate this info, just return false. It cannot become
329
  /// invalid even if the module or function changes.
330
  bool invalidate(Module &, const PreservedAnalyses &,
331
413
                  ModuleAnalysisManager::Invalidator &) {
332
413
    return false;
333
413
  }
334
  bool invalidate(Function &, const PreservedAnalyses &,
335
3.10k
                  FunctionAnalysisManager::Invalidator &) {
336
3.10k
    return false;
337
3.10k
  }
338
};
339
340
/// Analysis pass providing the \c TargetLibraryInfo.
341
///
342
/// Note that this pass's result cannot be invalidated, it is immutable for the
343
/// life of the module.
344
class TargetLibraryAnalysis : public AnalysisInfoMixin<TargetLibraryAnalysis> {
345
public:
346
  typedef TargetLibraryInfo Result;
347
348
  /// Default construct the library analysis.
349
  ///
350
  /// This will use the module's triple to construct the library info for that
351
  /// module.
352
2.46k
  TargetLibraryAnalysis() {}
353
354
  /// Construct a library analysis with preset info.
355
  ///
356
  /// This will directly copy the preset info into the result without
357
  /// consulting the module's triple.
358
  TargetLibraryAnalysis(TargetLibraryInfoImpl PresetInfoImpl)
359
84
      : PresetInfoImpl(std::move(PresetInfoImpl)) {}
360
361
  TargetLibraryInfo run(Module &M, ModuleAnalysisManager &);
362
  TargetLibraryInfo run(Function &F, FunctionAnalysisManager &);
363
364
private:
365
  friend AnalysisInfoMixin<TargetLibraryAnalysis>;
366
  static AnalysisKey Key;
367
368
  Optional<TargetLibraryInfoImpl> PresetInfoImpl;
369
370
  StringMap<std::unique_ptr<TargetLibraryInfoImpl>> Impls;
371
372
  TargetLibraryInfoImpl &lookupInfoImpl(const Triple &T);
373
};
374
375
class TargetLibraryInfoWrapperPass : public ImmutablePass {
376
  TargetLibraryInfoImpl TLIImpl;
377
  TargetLibraryInfo TLI;
378
379
  virtual void anchor();
380
381
public:
382
  static char ID;
383
  TargetLibraryInfoWrapperPass();
384
  explicit TargetLibraryInfoWrapperPass(const Triple &T);
385
  explicit TargetLibraryInfoWrapperPass(const TargetLibraryInfoImpl &TLI);
386
387
51.0M
  TargetLibraryInfo &getTLI() { return TLI; }
388
0
  const TargetLibraryInfo &getTLI() const { return TLI; }
389
};
390
391
} // end namespace llvm
392
393
#endif