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