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