xref: /netbsd-src/external/apache2/llvm/dist/llvm/include/llvm/Analysis/TargetLibraryInfo.h (revision 82d56013d7b633d116a93943de88e08335357a7c)
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 
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     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.
setUnavailable(LibFunc F)120   void setUnavailable(LibFunc F) {
121     setState(F, Unavailable);
122   }
123 
124   /// Forces a function to be marked as available.
setAvailable(LibFunc F)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.
setAvailableWithName(LibFunc F,StringRef Name)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.
isFunctionVectorizable(StringRef F,const ElementCount & 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.
setShouldExtI32Param(bool Val)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.
setShouldExtI32Return(bool Val)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.
setShouldSignExtI32Param(bool Val)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.
208 class 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 
219 public:
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.
TargetLibraryInfo(const TargetLibraryInfo & TLI)244   TargetLibraryInfo(const TargetLibraryInfo &TLI)
245       : Impl(TLI.Impl), OverrideAsUnavailable(TLI.OverrideAsUnavailable) {}
TargetLibraryInfo(TargetLibraryInfo && TLI)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.
areInlineCompatible(const TargetLibraryInfo & CalleeTLI,bool AllowCallerSuperset)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.
getLibFunc(StringRef funcName,LibFunc & F)278   bool getLibFunc(StringRef funcName, LibFunc &F) const {
279     return Impl->getLibFunc(funcName, F);
280   }
281 
getLibFunc(const Function & FDecl,LibFunc & F)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.
getLibFunc(const CallBase & CB,LibFunc & F)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.
disableAllFunctions()296   void disableAllFunctions() LLVM_ATTRIBUTE_UNUSED {
297     OverrideAsUnavailable.set();
298   }
299 
300   /// Forces a function to be marked as unavailable.
setUnavailable(LibFunc F)301   void setUnavailable(LibFunc F) LLVM_ATTRIBUTE_UNUSED {
302     OverrideAsUnavailable.set(F);
303   }
304 
getState(LibFunc F)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.
has(LibFunc F)312   bool has(LibFunc F) const {
313     return getState(F) != TargetLibraryInfoImpl::Unavailable;
314   }
isFunctionVectorizable(StringRef F,const ElementCount & VF)315   bool isFunctionVectorizable(StringRef F, const ElementCount &VF) const {
316     return Impl->isFunctionVectorizable(F, VF);
317   }
isFunctionVectorizable(StringRef F)318   bool isFunctionVectorizable(StringRef F) const {
319     return Impl->isFunctionVectorizable(F);
320   }
getVectorizedFunction(StringRef F,const ElementCount & VF)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.
hasOptimizedCodeGen(LibFunc F)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 
getName(LibFunc F)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()
getWCharSize(const Module & M)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.
invalidate(Module &,const PreservedAnalyses &,ModuleAnalysisManager::Invalidator &)397   bool invalidate(Module &, const PreservedAnalyses &,
398                   ModuleAnalysisManager::Invalidator &) {
399     return false;
400   }
invalidate(Function &,const PreservedAnalyses &,FunctionAnalysisManager::Invalidator &)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.
getWidestVF(StringRef ScalarF,ElementCount & FixedVF,ElementCount & ScalableVF)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.
isKnownVectorFunctionInLibrary(StringRef F)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.
422 class TargetLibraryAnalysis : public AnalysisInfoMixin<TargetLibraryAnalysis> {
423 public:
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.
TargetLibraryAnalysis()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.
TargetLibraryAnalysis(TargetLibraryInfoImpl BaselineInfoImpl)435   TargetLibraryAnalysis(TargetLibraryInfoImpl BaselineInfoImpl)
436       : BaselineInfoImpl(std::move(BaselineInfoImpl)) {}
437 
438   TargetLibraryInfo run(const Function &F, FunctionAnalysisManager &);
439 
440 private:
441   friend AnalysisInfoMixin<TargetLibraryAnalysis>;
442   static AnalysisKey Key;
443 
444   Optional<TargetLibraryInfoImpl> BaselineInfoImpl;
445 };
446 
447 class TargetLibraryInfoWrapperPass : public ImmutablePass {
448   TargetLibraryAnalysis TLA;
449   Optional<TargetLibraryInfo> TLI;
450 
451   virtual void anchor();
452 
453 public:
454   static char ID;
455   TargetLibraryInfoWrapperPass();
456   explicit TargetLibraryInfoWrapperPass(const Triple &T);
457   explicit TargetLibraryInfoWrapperPass(const TargetLibraryInfoImpl &TLI);
458 
getTLI(const Function & F)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