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