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