• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  
22  namespace llvm {
23  template <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'.
28  struct 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.
48  class 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    };
setState(LibFunc F,AvailabilityState State)61    void setState(LibFunc F, AvailabilityState State) {
62      AvailableArray[F/4] &= ~(3 << 2*(F&3));
63      AvailableArray[F/4] |= State << 2*(F&3);
64    }
getState(LibFunc F)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  
80  public:
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.
setUnavailable(LibFunc F)118    void setUnavailable(LibFunc F) {
119      setState(F, Unavailable);
120    }
121  
122    /// Forces a function to be marked as available.
setAvailable(LibFunc F)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.
setAvailableWithName(LibFunc F,StringRef Name)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.
isFunctionVectorizable(StringRef F,unsigned 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.
isFunctionScalarizable(StringRef F,unsigned & VF)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.
setShouldExtI32Param(bool Val)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.
setShouldExtI32Return(bool Val)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.
setShouldSignExtI32Param(bool Val)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.
212  class 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  
223  public:
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.
TargetLibraryInfo(const TargetLibraryInfo & TLI)248    TargetLibraryInfo(const TargetLibraryInfo &TLI)
249        : Impl(TLI.Impl), OverrideAsUnavailable(TLI.OverrideAsUnavailable) {}
TargetLibraryInfo(TargetLibraryInfo && TLI)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.
getLibFunc(StringRef funcName,LibFunc & F)267    bool getLibFunc(StringRef funcName, LibFunc &F) const {
268      return Impl->getLibFunc(funcName, F);
269    }
270  
getLibFunc(const Function & FDecl,LibFunc & F)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.
getLibFunc(ImmutableCallSite CS,LibFunc & F)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.
disableAllFunctions()285    void disableAllFunctions() LLVM_ATTRIBUTE_UNUSED {
286      OverrideAsUnavailable.set();
287    }
288  
289    /// Forces a function to be marked as unavailable.
setUnavailable(LibFunc F)290    void setUnavailable(LibFunc F) LLVM_ATTRIBUTE_UNUSED {
291      OverrideAsUnavailable.set(F);
292    }
293  
getState(LibFunc F)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.
has(LibFunc F)301    bool has(LibFunc F) const {
302      return getState(F) != TargetLibraryInfoImpl::Unavailable;
303    }
isFunctionVectorizable(StringRef F,unsigned VF)304    bool isFunctionVectorizable(StringRef F, unsigned VF) const {
305      return Impl->isFunctionVectorizable(F, VF);
306    }
isFunctionVectorizable(StringRef F)307    bool isFunctionVectorizable(StringRef F) const {
308      return Impl->isFunctionVectorizable(F);
309    }
getVectorizedFunction(StringRef F,unsigned VF)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.
hasOptimizedCodeGen(LibFunc F)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  
getName(LibFunc F)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()
getWCharSize(const Module & M)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.
invalidate(Module &,const PreservedAnalyses &,ModuleAnalysisManager::Invalidator &)385    bool invalidate(Module &, const PreservedAnalyses &,
386                    ModuleAnalysisManager::Invalidator &) {
387      return false;
388    }
invalidate(Function &,const PreservedAnalyses &,FunctionAnalysisManager::Invalidator &)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.
getWidestVF(StringRef ScalarF)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.
405  class TargetLibraryAnalysis : public AnalysisInfoMixin<TargetLibraryAnalysis> {
406  public:
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.
TargetLibraryAnalysis()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.
TargetLibraryAnalysis(TargetLibraryInfoImpl BaselineInfoImpl)418    TargetLibraryAnalysis(TargetLibraryInfoImpl BaselineInfoImpl)
419        : BaselineInfoImpl(std::move(BaselineInfoImpl)) {}
420  
421    TargetLibraryInfo run(const Function &F, FunctionAnalysisManager &);
422  
423  private:
424    friend AnalysisInfoMixin<TargetLibraryAnalysis>;
425    static AnalysisKey Key;
426  
427    Optional<TargetLibraryInfoImpl> BaselineInfoImpl;
428  };
429  
430  class TargetLibraryInfoWrapperPass : public ImmutablePass {
431    TargetLibraryAnalysis TLA;
432    Optional<TargetLibraryInfo> TLI;
433  
434    virtual void anchor();
435  
436  public:
437    static char ID;
438    TargetLibraryInfoWrapperPass();
439    explicit TargetLibraryInfoWrapperPass(const Triple &T);
440    explicit TargetLibraryInfoWrapperPass(const TargetLibraryInfoImpl &TLI);
441  
getTLI(const Function & F)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