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/IR/Function.h"
16#include "llvm/IR/InstrTypes.h"
17#include "llvm/IR/Module.h"
18#include "llvm/IR/PassManager.h"
19#include "llvm/Pass.h"
20
21namespace llvm {
22template <typename T> class ArrayRef;
23class Triple;
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  ElementCount 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    DarwinLibSystemM, // Use Darwin's libsystem_m.
92    LIBMVEC_X86,      // GLIBC Vector Math library.
93    MASSV,            // IBM MASS vector library.
94    SVML              // Intel short vector math library.
95  };
96
97  TargetLibraryInfoImpl();
98  explicit TargetLibraryInfoImpl(const Triple &T);
99
100  // Provide value semantics.
101  TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI);
102  TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI);
103  TargetLibraryInfoImpl &operator=(const TargetLibraryInfoImpl &TLI);
104  TargetLibraryInfoImpl &operator=(TargetLibraryInfoImpl &&TLI);
105
106  /// Searches for a particular function name.
107  ///
108  /// If it is one of the known library functions, return true and set F to the
109  /// corresponding value.
110  bool getLibFunc(StringRef funcName, LibFunc &F) const;
111
112  /// Searches for a particular function name, also checking that its type is
113  /// valid for the library function matching that name.
114  ///
115  /// If it is one of the known library functions, return true and set F to the
116  /// corresponding value.
117  bool getLibFunc(const Function &FDecl, LibFunc &F) const;
118
119  /// Forces a function to be marked as unavailable.
120  void setUnavailable(LibFunc F) {
121    setState(F, Unavailable);
122  }
123
124  /// Forces a function to be marked as available.
125  void setAvailable(LibFunc F) {
126    setState(F, StandardName);
127  }
128
129  /// Forces a function to be marked as available and provide an alternate name
130  /// that must be used.
131  void setAvailableWithName(LibFunc F, StringRef Name) {
132    if (StandardNames[F] != Name) {
133      setState(F, CustomName);
134      CustomNames[F] = std::string(Name);
135      assert(CustomNames.find(F) != CustomNames.end());
136    } else {
137      setState(F, StandardName);
138    }
139  }
140
141  /// Disables all builtins.
142  ///
143  /// This can be used for options like -fno-builtin.
144  void disableAllFunctions();
145
146  /// Add a set of scalar -> vector mappings, queryable via
147  /// getVectorizedFunction and getScalarizedFunction.
148  void addVectorizableFunctions(ArrayRef<VecDesc> Fns);
149
150  /// Calls addVectorizableFunctions with a known preset of functions for the
151  /// given vector library.
152  void addVectorizableFunctionsFromVecLib(enum VectorLibrary VecLib);
153
154  /// Return true if the function F has a vector equivalent with vectorization
155  /// factor VF.
156  bool isFunctionVectorizable(StringRef F, const ElementCount &VF) const {
157    return !getVectorizedFunction(F, VF).empty();
158  }
159
160  /// Return true if the function F has a vector equivalent with any
161  /// vectorization factor.
162  bool isFunctionVectorizable(StringRef F) const;
163
164  /// Return the name of the equivalent of F, vectorized with factor VF. If no
165  /// such mapping exists, return the empty string.
166  StringRef getVectorizedFunction(StringRef F, const ElementCount &VF) const;
167
168  /// Set to true iff i32 parameters to library functions should have signext
169  /// or zeroext attributes if they correspond to C-level int or unsigned int,
170  /// respectively.
171  void setShouldExtI32Param(bool Val) {
172    ShouldExtI32Param = Val;
173  }
174
175  /// Set to true iff i32 results from library functions should have signext
176  /// or zeroext attributes if they correspond to C-level int or unsigned int,
177  /// respectively.
178  void setShouldExtI32Return(bool Val) {
179    ShouldExtI32Return = Val;
180  }
181
182  /// Set to true iff i32 parameters to library functions should have signext
183  /// attribute if they correspond to C-level int or unsigned int.
184  void setShouldSignExtI32Param(bool Val) {
185    ShouldSignExtI32Param = Val;
186  }
187
188  /// Returns the size of the wchar_t type in bytes or 0 if the size is unknown.
189  /// This queries the 'wchar_size' metadata.
190  unsigned getWCharSize(const Module &M) const;
191
192  /// Returns the largest vectorization factor used in the list of
193  /// vector functions.
194  void getWidestVF(StringRef ScalarF, ElementCount &FixedVF,
195                   ElementCount &Scalable) const;
196
197  /// Returns true if call site / callee has cdecl-compatible calling
198  /// conventions.
199  static bool isCallingConvCCompatible(CallBase *CI);
200  static bool isCallingConvCCompatible(Function *Callee);
201};
202
203/// Provides information about what library functions are available for
204/// the current target.
205///
206/// This both allows optimizations to handle them specially and frontends to
207/// disable such optimizations through -fno-builtin etc.
208class TargetLibraryInfo {
209  friend class TargetLibraryAnalysis;
210  friend class TargetLibraryInfoWrapperPass;
211
212  /// The global (module level) TLI info.
213  const TargetLibraryInfoImpl *Impl;
214
215  /// Support for -fno-builtin* options as function attributes, overrides
216  /// information in global TargetLibraryInfoImpl.
217  BitVector OverrideAsUnavailable;
218
219public:
220  explicit TargetLibraryInfo(const TargetLibraryInfoImpl &Impl,
221                             Optional<const Function *> F = None)
222      : Impl(&Impl), OverrideAsUnavailable(NumLibFuncs) {
223    if (!F)
224      return;
225    if ((*F)->hasFnAttribute("no-builtins"))
226      disableAllFunctions();
227    else {
228      // Disable individual libc/libm calls in TargetLibraryInfo.
229      LibFunc LF;
230      AttributeSet FnAttrs = (*F)->getAttributes().getFnAttributes();
231      for (const Attribute &Attr : FnAttrs) {
232        if (!Attr.isStringAttribute())
233          continue;
234        auto AttrStr = Attr.getKindAsString();
235        if (!AttrStr.consume_front("no-builtin-"))
236          continue;
237        if (getLibFunc(AttrStr, LF))
238          setUnavailable(LF);
239      }
240    }
241  }
242
243  // Provide value semantics.
244  TargetLibraryInfo(const TargetLibraryInfo &TLI)
245      : Impl(TLI.Impl), OverrideAsUnavailable(TLI.OverrideAsUnavailable) {}
246  TargetLibraryInfo(TargetLibraryInfo &&TLI)
247      : Impl(TLI.Impl), OverrideAsUnavailable(TLI.OverrideAsUnavailable) {}
248  TargetLibraryInfo &operator=(const TargetLibraryInfo &TLI) {
249    Impl = TLI.Impl;
250    OverrideAsUnavailable = TLI.OverrideAsUnavailable;
251    return *this;
252  }
253  TargetLibraryInfo &operator=(TargetLibraryInfo &&TLI) {
254    Impl = TLI.Impl;
255    OverrideAsUnavailable = TLI.OverrideAsUnavailable;
256    return *this;
257  }
258
259  /// Determine whether a callee with the given TLI can be inlined into
260  /// caller with this TLI, based on 'nobuiltin' attributes. When requested,
261  /// allow inlining into a caller with a superset of the callee's nobuiltin
262  /// attributes, which is conservatively correct.
263  bool areInlineCompatible(const TargetLibraryInfo &CalleeTLI,
264                           bool AllowCallerSuperset) const {
265    if (!AllowCallerSuperset)
266      return OverrideAsUnavailable == CalleeTLI.OverrideAsUnavailable;
267    BitVector B = OverrideAsUnavailable;
268    B |= CalleeTLI.OverrideAsUnavailable;
269    // We can inline if the union of the caller and callee's nobuiltin
270    // attributes is no stricter than the caller's nobuiltin attributes.
271    return B == OverrideAsUnavailable;
272  }
273
274  /// Searches for a particular function name.
275  ///
276  /// If it is one of the known library functions, return true and set F to the
277  /// corresponding value.
278  bool getLibFunc(StringRef funcName, LibFunc &F) const {
279    return Impl->getLibFunc(funcName, F);
280  }
281
282  bool getLibFunc(const Function &FDecl, LibFunc &F) const {
283    return Impl->getLibFunc(FDecl, F);
284  }
285
286  /// If a callbase does not have the 'nobuiltin' attribute, return if the
287  /// called function is a known library function and set F to that function.
288  bool getLibFunc(const CallBase &CB, LibFunc &F) const {
289    return !CB.isNoBuiltin() && CB.getCalledFunction() &&
290           getLibFunc(*(CB.getCalledFunction()), F);
291  }
292
293  /// Disables all builtins.
294  ///
295  /// This can be used for options like -fno-builtin.
296  void disableAllFunctions() LLVM_ATTRIBUTE_UNUSED {
297    OverrideAsUnavailable.set();
298  }
299
300  /// Forces a function to be marked as unavailable.
301  void setUnavailable(LibFunc F) LLVM_ATTRIBUTE_UNUSED {
302    OverrideAsUnavailable.set(F);
303  }
304
305  TargetLibraryInfoImpl::AvailabilityState getState(LibFunc F) const {
306    if (OverrideAsUnavailable[F])
307      return TargetLibraryInfoImpl::Unavailable;
308    return Impl->getState(F);
309  }
310
311  /// Tests whether a library function is available.
312  bool has(LibFunc F) const {
313    return getState(F) != TargetLibraryInfoImpl::Unavailable;
314  }
315  bool isFunctionVectorizable(StringRef F, const ElementCount &VF) const {
316    return Impl->isFunctionVectorizable(F, VF);
317  }
318  bool isFunctionVectorizable(StringRef F) const {
319    return Impl->isFunctionVectorizable(F);
320  }
321  StringRef getVectorizedFunction(StringRef F, const ElementCount &VF) const {
322    return Impl->getVectorizedFunction(F, VF);
323  }
324
325  /// Tests if the function is both available and a candidate for optimized code
326  /// generation.
327  bool hasOptimizedCodeGen(LibFunc F) const {
328    if (getState(F) == TargetLibraryInfoImpl::Unavailable)
329      return false;
330    switch (F) {
331    default: break;
332    case LibFunc_copysign:     case LibFunc_copysignf:  case LibFunc_copysignl:
333    case LibFunc_fabs:         case LibFunc_fabsf:      case LibFunc_fabsl:
334    case LibFunc_sin:          case LibFunc_sinf:       case LibFunc_sinl:
335    case LibFunc_cos:          case LibFunc_cosf:       case LibFunc_cosl:
336    case LibFunc_sqrt:         case LibFunc_sqrtf:      case LibFunc_sqrtl:
337    case LibFunc_sqrt_finite:  case LibFunc_sqrtf_finite:
338                                                   case LibFunc_sqrtl_finite:
339    case LibFunc_fmax:         case LibFunc_fmaxf:      case LibFunc_fmaxl:
340    case LibFunc_fmin:         case LibFunc_fminf:      case LibFunc_fminl:
341    case LibFunc_floor:        case LibFunc_floorf:     case LibFunc_floorl:
342    case LibFunc_nearbyint:    case LibFunc_nearbyintf: case LibFunc_nearbyintl:
343    case LibFunc_ceil:         case LibFunc_ceilf:      case LibFunc_ceill:
344    case LibFunc_rint:         case LibFunc_rintf:      case LibFunc_rintl:
345    case LibFunc_round:        case LibFunc_roundf:     case LibFunc_roundl:
346    case LibFunc_trunc:        case LibFunc_truncf:     case LibFunc_truncl:
347    case LibFunc_log2:         case LibFunc_log2f:      case LibFunc_log2l:
348    case LibFunc_exp2:         case LibFunc_exp2f:      case LibFunc_exp2l:
349    case LibFunc_memcpy:       case LibFunc_memset:     case LibFunc_memmove:
350    case LibFunc_memcmp:       case LibFunc_bcmp:       case LibFunc_strcmp:
351    case LibFunc_strcpy:       case LibFunc_stpcpy:     case LibFunc_strlen:
352    case LibFunc_strnlen:      case LibFunc_memchr:     case LibFunc_mempcpy:
353      return true;
354    }
355    return false;
356  }
357
358  StringRef getName(LibFunc F) const {
359    auto State = getState(F);
360    if (State == TargetLibraryInfoImpl::Unavailable)
361      return StringRef();
362    if (State == TargetLibraryInfoImpl::StandardName)
363      return Impl->StandardNames[F];
364    assert(State == TargetLibraryInfoImpl::CustomName);
365    return Impl->CustomNames.find(F)->second;
366  }
367
368  /// Returns extension attribute kind to be used for i32 parameters
369  /// corresponding to C-level int or unsigned int.  May be zeroext, signext,
370  /// or none.
371  Attribute::AttrKind getExtAttrForI32Param(bool Signed = true) const {
372    if (Impl->ShouldExtI32Param)
373      return Signed ? Attribute::SExt : Attribute::ZExt;
374    if (Impl->ShouldSignExtI32Param)
375      return Attribute::SExt;
376    return Attribute::None;
377  }
378
379  /// Returns extension attribute kind to be used for i32 return values
380  /// corresponding to C-level int or unsigned int.  May be zeroext, signext,
381  /// or none.
382  Attribute::AttrKind getExtAttrForI32Return(bool Signed = true) const {
383    if (Impl->ShouldExtI32Return)
384      return Signed ? Attribute::SExt : Attribute::ZExt;
385    return Attribute::None;
386  }
387
388  /// \copydoc TargetLibraryInfoImpl::getWCharSize()
389  unsigned getWCharSize(const Module &M) const {
390    return Impl->getWCharSize(M);
391  }
392
393  /// Handle invalidation from the pass manager.
394  ///
395  /// If we try to invalidate this info, just return false. It cannot become
396  /// invalid even if the module or function changes.
397  bool invalidate(Module &, const PreservedAnalyses &,
398                  ModuleAnalysisManager::Invalidator &) {
399    return false;
400  }
401  bool invalidate(Function &, const PreservedAnalyses &,
402                  FunctionAnalysisManager::Invalidator &) {
403    return false;
404  }
405  /// Returns the largest vectorization factor used in the list of
406  /// vector functions.
407  void getWidestVF(StringRef ScalarF, ElementCount &FixedVF,
408                   ElementCount &ScalableVF) const {
409    Impl->getWidestVF(ScalarF, FixedVF, ScalableVF);
410  }
411
412  /// Check if the function "F" is listed in a library known to LLVM.
413  bool isKnownVectorFunctionInLibrary(StringRef F) const {
414    return this->isFunctionVectorizable(F);
415  }
416};
417
418/// Analysis pass providing the \c TargetLibraryInfo.
419///
420/// Note that this pass's result cannot be invalidated, it is immutable for the
421/// life of the module.
422class TargetLibraryAnalysis : public AnalysisInfoMixin<TargetLibraryAnalysis> {
423public:
424  typedef TargetLibraryInfo Result;
425
426  /// Default construct the library analysis.
427  ///
428  /// This will use the module's triple to construct the library info for that
429  /// module.
430  TargetLibraryAnalysis() {}
431
432  /// Construct a library analysis with baseline Module-level info.
433  ///
434  /// This will be supplemented with Function-specific info in the Result.
435  TargetLibraryAnalysis(TargetLibraryInfoImpl BaselineInfoImpl)
436      : BaselineInfoImpl(std::move(BaselineInfoImpl)) {}
437
438  TargetLibraryInfo run(const Function &F, FunctionAnalysisManager &);
439
440private:
441  friend AnalysisInfoMixin<TargetLibraryAnalysis>;
442  static AnalysisKey Key;
443
444  Optional<TargetLibraryInfoImpl> BaselineInfoImpl;
445};
446
447class TargetLibraryInfoWrapperPass : public ImmutablePass {
448  TargetLibraryAnalysis TLA;
449  Optional<TargetLibraryInfo> TLI;
450
451  virtual void anchor();
452
453public:
454  static char ID;
455  TargetLibraryInfoWrapperPass();
456  explicit TargetLibraryInfoWrapperPass(const Triple &T);
457  explicit TargetLibraryInfoWrapperPass(const TargetLibraryInfoImpl &TLI);
458
459  TargetLibraryInfo &getTLI(const Function &F) {
460    FunctionAnalysisManager DummyFAM;
461    TLI = TLA.run(F, DummyFAM);
462    return *TLI;
463  }
464};
465
466} // end namespace llvm
467
468#endif
469