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/IR/InstrTypes.h"
15 #include "llvm/IR/PassManager.h"
16 #include "llvm/Pass.h"
17 #include "llvm/TargetParser/Triple.h"
18 #include <optional>
19 
20 namespace llvm {
21 
22 template <typename T> class ArrayRef;
23 class Function;
24 class Module;
25 class Triple;
26 
27 /// Provides info so a possible vectorization of a function can be
28 /// computed. Function 'VectorFnName' is equivalent to 'ScalarFnName'
29 /// vectorized by a factor 'VectorizationFactor'.
30 /// The VABIPrefix string holds information about isa, mask, vlen,
31 /// and vparams so a scalar-to-vector mapping of the form:
32 ///    _ZGV<isa><mask><vlen><vparams>_<scalarname>(<vectorname>)
33 /// can be constructed where:
34 ///
35 /// <isa> = "_LLVM_"
36 /// <mask> = "M" if masked, "N" if no mask.
37 /// <vlen> = Number of concurrent lanes, stored in the `VectorizationFactor`
38 ///          field of the `VecDesc` struct. If the number of lanes is scalable
39 ///          then 'x' is printed instead.
40 /// <vparams> = "v", as many as are the numArgs.
41 /// <scalarname> = the name of the scalar function.
42 /// <vectorname> = the name of the vector function.
43 class VecDesc {
44   StringRef ScalarFnName;
45   StringRef VectorFnName;
46   ElementCount VectorizationFactor;
47   bool Masked;
48   StringRef VABIPrefix;
49 
50 public:
51   VecDesc() = delete;
52   VecDesc(StringRef ScalarFnName, StringRef VectorFnName,
53           ElementCount VectorizationFactor, bool Masked, StringRef VABIPrefix)
54       : ScalarFnName(ScalarFnName), VectorFnName(VectorFnName),
55         VectorizationFactor(VectorizationFactor), Masked(Masked),
56         VABIPrefix(VABIPrefix) {}
57 
58   StringRef getScalarFnName() const { return ScalarFnName; }
59   StringRef getVectorFnName() const { return VectorFnName; }
60   ElementCount getVectorizationFactor() const { return VectorizationFactor; }
61   bool isMasked() const { return Masked; }
62   StringRef getVABIPrefix() const { return VABIPrefix; }
63 
64   /// Returns a vector function ABI variant string on the form:
65   ///    _ZGV<isa><mask><vlen><vparams>_<scalarname>(<vectorname>)
66   std::string getVectorFunctionABIVariantString() const;
67 };
68 
69   enum LibFunc : unsigned {
70 #define TLI_DEFINE_ENUM
71 #include "llvm/Analysis/TargetLibraryInfo.def"
72 
73     NumLibFuncs,
74     NotLibFunc
75   };
76 
77 /// Implementation of the target library information.
78 ///
79 /// This class constructs tables that hold the target library information and
80 /// make it available. However, it is somewhat expensive to compute and only
81 /// depends on the triple. So users typically interact with the \c
82 /// TargetLibraryInfo wrapper below.
83 class TargetLibraryInfoImpl {
84   friend class TargetLibraryInfo;
85 
86   unsigned char AvailableArray[(NumLibFuncs+3)/4];
87   DenseMap<unsigned, std::string> CustomNames;
88   static StringLiteral const StandardNames[NumLibFuncs];
89   bool ShouldExtI32Param, ShouldExtI32Return, ShouldSignExtI32Param, ShouldSignExtI32Return;
90   unsigned SizeOfInt;
91 
92   enum AvailabilityState {
93     StandardName = 3, // (memset to all ones)
94     CustomName = 1,
95     Unavailable = 0  // (memset to all zeros)
96   };
97   void setState(LibFunc F, AvailabilityState State) {
98     AvailableArray[F/4] &= ~(3 << 2*(F&3));
99     AvailableArray[F/4] |= State << 2*(F&3);
100   }
101   AvailabilityState getState(LibFunc F) const {
102     return static_cast<AvailabilityState>((AvailableArray[F/4] >> 2*(F&3)) & 3);
103   }
104 
105   /// Vectorization descriptors - sorted by ScalarFnName.
106   std::vector<VecDesc> VectorDescs;
107   /// Scalarization descriptors - same content as VectorDescs but sorted based
108   /// on VectorFnName rather than ScalarFnName.
109   std::vector<VecDesc> ScalarDescs;
110 
111   /// Return true if the function type FTy is valid for the library function
112   /// F, regardless of whether the function is available.
113   bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc F,
114                               const Module &M) const;
115 
116 public:
117   /// List of known vector-functions libraries.
118   ///
119   /// The vector-functions library defines, which functions are vectorizable
120   /// and with which factor. The library can be specified by either frontend,
121   /// or a commandline option, and then used by
122   /// addVectorizableFunctionsFromVecLib for filling up the tables of
123   /// vectorizable functions.
124   enum VectorLibrary {
125     NoLibrary,        // Don't use any vector library.
126     Accelerate,       // Use Accelerate framework.
127     DarwinLibSystemM, // Use Darwin's libsystem_m.
128     LIBMVEC_X86,      // GLIBC Vector Math library.
129     MASSV,            // IBM MASS vector library.
130     SVML,             // Intel short vector math library.
131     SLEEFGNUABI, // SLEEF - SIMD Library for Evaluating Elementary Functions.
132     ArmPL        // Arm Performance Libraries.
133   };
134 
135   TargetLibraryInfoImpl();
136   explicit TargetLibraryInfoImpl(const Triple &T);
137 
138   // Provide value semantics.
139   TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI);
140   TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI);
141   TargetLibraryInfoImpl &operator=(const TargetLibraryInfoImpl &TLI);
142   TargetLibraryInfoImpl &operator=(TargetLibraryInfoImpl &&TLI);
143 
144   /// Searches for a particular function name.
145   ///
146   /// If it is one of the known library functions, return true and set F to the
147   /// corresponding value.
148   bool getLibFunc(StringRef funcName, LibFunc &F) const;
149 
150   /// Searches for a particular function name, also checking that its type is
151   /// valid for the library function matching that name.
152   ///
153   /// If it is one of the known library functions, return true and set F to the
154   /// corresponding value.
155   ///
156   /// FDecl is assumed to have a parent Module when using this function.
157   bool getLibFunc(const Function &FDecl, LibFunc &F) const;
158 
159   /// Searches for a function name using an Instruction \p Opcode.
160   /// Currently, only the frem instruction is supported.
161   bool getLibFunc(unsigned int Opcode, Type *Ty, LibFunc &F) const;
162 
163   /// Forces a function to be marked as unavailable.
164   void setUnavailable(LibFunc F) {
165     setState(F, Unavailable);
166   }
167 
168   /// Forces a function to be marked as available.
169   void setAvailable(LibFunc F) {
170     setState(F, StandardName);
171   }
172 
173   /// Forces a function to be marked as available and provide an alternate name
174   /// that must be used.
175   void setAvailableWithName(LibFunc F, StringRef Name) {
176     if (StandardNames[F] != Name) {
177       setState(F, CustomName);
178       CustomNames[F] = std::string(Name);
179       assert(CustomNames.contains(F));
180     } else {
181       setState(F, StandardName);
182     }
183   }
184 
185   /// Disables all builtins.
186   ///
187   /// This can be used for options like -fno-builtin.
188   void disableAllFunctions();
189 
190   /// Add a set of scalar -> vector mappings, queryable via
191   /// getVectorizedFunction and getScalarizedFunction.
192   void addVectorizableFunctions(ArrayRef<VecDesc> Fns);
193 
194   /// Calls addVectorizableFunctions with a known preset of functions for the
195   /// given vector library.
196   void addVectorizableFunctionsFromVecLib(enum VectorLibrary VecLib,
197                                           const llvm::Triple &TargetTriple);
198 
199   /// Return true if the function F has a vector equivalent with vectorization
200   /// factor VF.
201   bool isFunctionVectorizable(StringRef F, const ElementCount &VF) const {
202     return !(getVectorizedFunction(F, VF, false).empty() &&
203              getVectorizedFunction(F, VF, true).empty());
204   }
205 
206   /// Return true if the function F has a vector equivalent with any
207   /// vectorization factor.
208   bool isFunctionVectorizable(StringRef F) const;
209 
210   /// Return the name of the equivalent of F, vectorized with factor VF. If no
211   /// such mapping exists, return the empty string.
212   StringRef getVectorizedFunction(StringRef F, const ElementCount &VF,
213                                   bool Masked) const;
214 
215   /// Return a pointer to a VecDesc object holding all info for scalar to vector
216   /// mappings in TLI for the equivalent of F, vectorized with factor VF.
217   /// If no such mapping exists, return nullpointer.
218   const VecDesc *getVectorMappingInfo(StringRef F, const ElementCount &VF,
219                                       bool Masked) const;
220 
221   /// Set to true iff i32 parameters to library functions should have signext
222   /// or zeroext attributes if they correspond to C-level int or unsigned int,
223   /// respectively.
224   void setShouldExtI32Param(bool Val) {
225     ShouldExtI32Param = Val;
226   }
227 
228   /// Set to true iff i32 results from library functions should have signext
229   /// or zeroext attributes if they correspond to C-level int or unsigned int,
230   /// respectively.
231   void setShouldExtI32Return(bool Val) {
232     ShouldExtI32Return = Val;
233   }
234 
235   /// Set to true iff i32 parameters to library functions should have signext
236   /// attribute if they correspond to C-level int or unsigned int.
237   void setShouldSignExtI32Param(bool Val) {
238     ShouldSignExtI32Param = Val;
239   }
240 
241   /// Set to true iff i32 results from library functions should have signext
242   /// attribute if they correspond to C-level int or unsigned int.
243   void setShouldSignExtI32Return(bool Val) {
244     ShouldSignExtI32Return = Val;
245   }
246 
247   /// Returns the size of the wchar_t type in bytes or 0 if the size is unknown.
248   /// This queries the 'wchar_size' metadata.
249   unsigned getWCharSize(const Module &M) const;
250 
251   /// Returns the size of the size_t type in bits.
252   unsigned getSizeTSize(const Module &M) const;
253 
254   /// Get size of a C-level int or unsigned int, in bits.
255   unsigned getIntSize() const {
256     return SizeOfInt;
257   }
258 
259   /// Initialize the C-level size of an integer.
260   void setIntSize(unsigned Bits) {
261     SizeOfInt = Bits;
262   }
263 
264   /// Returns the largest vectorization factor used in the list of
265   /// vector functions.
266   void getWidestVF(StringRef ScalarF, ElementCount &FixedVF,
267                    ElementCount &Scalable) const;
268 
269   /// Returns true if call site / callee has cdecl-compatible calling
270   /// conventions.
271   static bool isCallingConvCCompatible(CallBase *CI);
272   static bool isCallingConvCCompatible(Function *Callee);
273 };
274 
275 /// Provides information about what library functions are available for
276 /// the current target.
277 ///
278 /// This both allows optimizations to handle them specially and frontends to
279 /// disable such optimizations through -fno-builtin etc.
280 class TargetLibraryInfo {
281   friend class TargetLibraryAnalysis;
282   friend class TargetLibraryInfoWrapperPass;
283 
284   /// The global (module level) TLI info.
285   const TargetLibraryInfoImpl *Impl;
286 
287   /// Support for -fno-builtin* options as function attributes, overrides
288   /// information in global TargetLibraryInfoImpl.
289   BitVector OverrideAsUnavailable;
290 
291 public:
292   explicit TargetLibraryInfo(const TargetLibraryInfoImpl &Impl,
293                              std::optional<const Function *> F = std::nullopt)
294       : Impl(&Impl), OverrideAsUnavailable(NumLibFuncs) {
295     if (!F)
296       return;
297     if ((*F)->hasFnAttribute("no-builtins"))
298       disableAllFunctions();
299     else {
300       // Disable individual libc/libm calls in TargetLibraryInfo.
301       LibFunc LF;
302       AttributeSet FnAttrs = (*F)->getAttributes().getFnAttrs();
303       for (const Attribute &Attr : FnAttrs) {
304         if (!Attr.isStringAttribute())
305           continue;
306         auto AttrStr = Attr.getKindAsString();
307         if (!AttrStr.consume_front("no-builtin-"))
308           continue;
309         if (getLibFunc(AttrStr, LF))
310           setUnavailable(LF);
311       }
312     }
313   }
314 
315   // Provide value semantics.
316   TargetLibraryInfo(const TargetLibraryInfo &TLI) = default;
317   TargetLibraryInfo(TargetLibraryInfo &&TLI)
318       : Impl(TLI.Impl), OverrideAsUnavailable(TLI.OverrideAsUnavailable) {}
319   TargetLibraryInfo &operator=(const TargetLibraryInfo &TLI) = default;
320   TargetLibraryInfo &operator=(TargetLibraryInfo &&TLI) {
321     Impl = TLI.Impl;
322     OverrideAsUnavailable = TLI.OverrideAsUnavailable;
323     return *this;
324   }
325 
326   /// Determine whether a callee with the given TLI can be inlined into
327   /// caller with this TLI, based on 'nobuiltin' attributes. When requested,
328   /// allow inlining into a caller with a superset of the callee's nobuiltin
329   /// attributes, which is conservatively correct.
330   bool areInlineCompatible(const TargetLibraryInfo &CalleeTLI,
331                            bool AllowCallerSuperset) const {
332     if (!AllowCallerSuperset)
333       return OverrideAsUnavailable == CalleeTLI.OverrideAsUnavailable;
334     BitVector B = OverrideAsUnavailable;
335     B |= CalleeTLI.OverrideAsUnavailable;
336     // We can inline if the union of the caller and callee's nobuiltin
337     // attributes is no stricter than the caller's nobuiltin attributes.
338     return B == OverrideAsUnavailable;
339   }
340 
341   /// Return true if the function type FTy is valid for the library function
342   /// F, regardless of whether the function is available.
343   bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc F,
344                               const Module &M) const {
345     return Impl->isValidProtoForLibFunc(FTy, F, M);
346   }
347 
348   /// Searches for a particular function name.
349   ///
350   /// If it is one of the known library functions, return true and set F to the
351   /// corresponding value.
352   bool getLibFunc(StringRef funcName, LibFunc &F) const {
353     return Impl->getLibFunc(funcName, F);
354   }
355 
356   bool getLibFunc(const Function &FDecl, LibFunc &F) const {
357     return Impl->getLibFunc(FDecl, F);
358   }
359 
360   /// If a callbase does not have the 'nobuiltin' attribute, return if the
361   /// called function is a known library function and set F to that function.
362   bool getLibFunc(const CallBase &CB, LibFunc &F) const {
363     return !CB.isNoBuiltin() && CB.getCalledFunction() &&
364            getLibFunc(*(CB.getCalledFunction()), F);
365   }
366 
367   /// Searches for a function name using an Instruction \p Opcode.
368   /// Currently, only the frem instruction is supported.
369   bool getLibFunc(unsigned int Opcode, Type *Ty, LibFunc &F) const {
370     return Impl->getLibFunc(Opcode, Ty, F);
371   }
372 
373   /// Disables all builtins.
374   ///
375   /// This can be used for options like -fno-builtin.
376   void disableAllFunctions() LLVM_ATTRIBUTE_UNUSED {
377     OverrideAsUnavailable.set();
378   }
379 
380   /// Forces a function to be marked as unavailable.
381   void setUnavailable(LibFunc F) LLVM_ATTRIBUTE_UNUSED {
382     OverrideAsUnavailable.set(F);
383   }
384 
385   TargetLibraryInfoImpl::AvailabilityState getState(LibFunc F) const {
386     if (OverrideAsUnavailable[F])
387       return TargetLibraryInfoImpl::Unavailable;
388     return Impl->getState(F);
389   }
390 
391   /// Tests whether a library function is available.
392   bool has(LibFunc F) const {
393     return getState(F) != TargetLibraryInfoImpl::Unavailable;
394   }
395   bool isFunctionVectorizable(StringRef F, const ElementCount &VF) const {
396     return Impl->isFunctionVectorizable(F, VF);
397   }
398   bool isFunctionVectorizable(StringRef F) const {
399     return Impl->isFunctionVectorizable(F);
400   }
401   StringRef getVectorizedFunction(StringRef F, const ElementCount &VF,
402                                   bool Masked = false) const {
403     return Impl->getVectorizedFunction(F, VF, Masked);
404   }
405   const VecDesc *getVectorMappingInfo(StringRef F, const ElementCount &VF,
406                                       bool Masked) const {
407     return Impl->getVectorMappingInfo(F, VF, Masked);
408   }
409 
410   /// Tests if the function is both available and a candidate for optimized code
411   /// generation.
412   bool hasOptimizedCodeGen(LibFunc F) const {
413     if (getState(F) == TargetLibraryInfoImpl::Unavailable)
414       return false;
415     switch (F) {
416     default: break;
417     case LibFunc_copysign:     case LibFunc_copysignf:  case LibFunc_copysignl:
418     case LibFunc_fabs:         case LibFunc_fabsf:      case LibFunc_fabsl:
419     case LibFunc_sin:          case LibFunc_sinf:       case LibFunc_sinl:
420     case LibFunc_cos:          case LibFunc_cosf:       case LibFunc_cosl:
421     case LibFunc_sqrt:         case LibFunc_sqrtf:      case LibFunc_sqrtl:
422     case LibFunc_sqrt_finite:  case LibFunc_sqrtf_finite:
423                                                    case LibFunc_sqrtl_finite:
424     case LibFunc_fmax:         case LibFunc_fmaxf:      case LibFunc_fmaxl:
425     case LibFunc_fmin:         case LibFunc_fminf:      case LibFunc_fminl:
426     case LibFunc_floor:        case LibFunc_floorf:     case LibFunc_floorl:
427     case LibFunc_nearbyint:    case LibFunc_nearbyintf: case LibFunc_nearbyintl:
428     case LibFunc_ceil:         case LibFunc_ceilf:      case LibFunc_ceill:
429     case LibFunc_rint:         case LibFunc_rintf:      case LibFunc_rintl:
430     case LibFunc_round:        case LibFunc_roundf:     case LibFunc_roundl:
431     case LibFunc_trunc:        case LibFunc_truncf:     case LibFunc_truncl:
432     case LibFunc_log2:         case LibFunc_log2f:      case LibFunc_log2l:
433     case LibFunc_exp2:         case LibFunc_exp2f:      case LibFunc_exp2l:
434     case LibFunc_ldexp:        case LibFunc_ldexpf:     case LibFunc_ldexpl:
435     case LibFunc_memcpy:       case LibFunc_memset:     case LibFunc_memmove:
436     case LibFunc_memcmp:       case LibFunc_bcmp:       case LibFunc_strcmp:
437     case LibFunc_strcpy:       case LibFunc_stpcpy:     case LibFunc_strlen:
438     case LibFunc_strnlen:      case LibFunc_memchr:     case LibFunc_mempcpy:
439       return true;
440     }
441     return false;
442   }
443 
444   StringRef getName(LibFunc F) const {
445     auto State = getState(F);
446     if (State == TargetLibraryInfoImpl::Unavailable)
447       return StringRef();
448     if (State == TargetLibraryInfoImpl::StandardName)
449       return Impl->StandardNames[F];
450     assert(State == TargetLibraryInfoImpl::CustomName);
451     return Impl->CustomNames.find(F)->second;
452   }
453 
454   static void initExtensionsForTriple(bool &ShouldExtI32Param,
455                                       bool &ShouldExtI32Return,
456                                       bool &ShouldSignExtI32Param,
457                                       bool &ShouldSignExtI32Return,
458                                       const Triple &T) {
459     ShouldExtI32Param     = ShouldExtI32Return     = false;
460     ShouldSignExtI32Param = ShouldSignExtI32Return = false;
461 
462     // PowerPC64, Sparc64, SystemZ need signext/zeroext on i32 parameters and
463     // returns corresponding to C-level ints and unsigned ints.
464     if (T.isPPC64() || T.getArch() == Triple::sparcv9 ||
465         T.getArch() == Triple::systemz) {
466       ShouldExtI32Param = true;
467       ShouldExtI32Return = true;
468     }
469     // LoongArch, Mips, and riscv64, on the other hand, need signext on i32
470     // parameters corresponding to both signed and unsigned ints.
471     if (T.isLoongArch() || T.isMIPS() || T.isRISCV64()) {
472       ShouldSignExtI32Param = true;
473     }
474     // LoongArch and riscv64 need signext on i32 returns corresponding to both
475     // signed and unsigned ints.
476     if (T.isLoongArch() || T.isRISCV64()) {
477       ShouldSignExtI32Return = true;
478     }
479   }
480 
481   /// Returns extension attribute kind to be used for i32 parameters
482   /// corresponding to C-level int or unsigned int.  May be zeroext, signext,
483   /// or none.
484 private:
485   static Attribute::AttrKind getExtAttrForI32Param(bool ShouldExtI32Param_,
486                                                    bool ShouldSignExtI32Param_,
487                                                    bool Signed = true) {
488     if (ShouldExtI32Param_)
489       return Signed ? Attribute::SExt : Attribute::ZExt;
490     if (ShouldSignExtI32Param_)
491       return Attribute::SExt;
492     return Attribute::None;
493   }
494 
495 public:
496   static Attribute::AttrKind getExtAttrForI32Param(const Triple &T,
497                                                    bool Signed = true) {
498     bool ShouldExtI32Param, ShouldExtI32Return;
499     bool ShouldSignExtI32Param, ShouldSignExtI32Return;
500     initExtensionsForTriple(ShouldExtI32Param, ShouldExtI32Return,
501                             ShouldSignExtI32Param, ShouldSignExtI32Return, T);
502     return getExtAttrForI32Param(ShouldExtI32Param, ShouldSignExtI32Param,
503                                  Signed);
504   }
505 
506   Attribute::AttrKind getExtAttrForI32Param(bool Signed = true) const {
507     return getExtAttrForI32Param(Impl->ShouldExtI32Param,
508                                  Impl->ShouldSignExtI32Param, Signed);
509   }
510 
511   /// Returns extension attribute kind to be used for i32 return values
512   /// corresponding to C-level int or unsigned int.  May be zeroext, signext,
513   /// or none.
514 private:
515   static Attribute::AttrKind getExtAttrForI32Return(bool ShouldExtI32Return_,
516                                                     bool ShouldSignExtI32Return_,
517                                                     bool Signed) {
518     if (ShouldExtI32Return_)
519       return Signed ? Attribute::SExt : Attribute::ZExt;
520     if (ShouldSignExtI32Return_)
521       return Attribute::SExt;
522     return Attribute::None;
523   }
524 
525 public:
526   static Attribute::AttrKind getExtAttrForI32Return(const Triple &T,
527                                                    bool Signed = true) {
528     bool ShouldExtI32Param, ShouldExtI32Return;
529     bool ShouldSignExtI32Param, ShouldSignExtI32Return;
530     initExtensionsForTriple(ShouldExtI32Param, ShouldExtI32Return,
531                             ShouldSignExtI32Param, ShouldSignExtI32Return, T);
532     return getExtAttrForI32Return(ShouldExtI32Return, ShouldSignExtI32Return,
533                                   Signed);
534   }
535 
536   Attribute::AttrKind getExtAttrForI32Return(bool Signed = true) const {
537     return getExtAttrForI32Return(Impl->ShouldExtI32Return,
538                                   Impl->ShouldSignExtI32Return, Signed);
539   }
540 
541   // Helper to create an AttributeList for args (and ret val) which all have
542   // the same signedness. Attributes in AL may be passed in to include them
543   // as well in the returned AttributeList.
544   AttributeList getAttrList(LLVMContext *C, ArrayRef<unsigned> ArgNos,
545                             bool Signed, bool Ret = false,
546                             AttributeList AL = AttributeList()) const {
547     if (auto AK = getExtAttrForI32Param(Signed))
548       for (auto ArgNo : ArgNos)
549         AL = AL.addParamAttribute(*C, ArgNo, AK);
550     if (Ret)
551       if (auto AK = getExtAttrForI32Return(Signed))
552         AL = AL.addRetAttribute(*C, AK);
553     return AL;
554   }
555 
556   /// \copydoc TargetLibraryInfoImpl::getWCharSize()
557   unsigned getWCharSize(const Module &M) const {
558     return Impl->getWCharSize(M);
559   }
560 
561   /// \copydoc TargetLibraryInfoImpl::getSizeTSize()
562   unsigned getSizeTSize(const Module &M) const { return Impl->getSizeTSize(M); }
563 
564   /// \copydoc TargetLibraryInfoImpl::getIntSize()
565   unsigned getIntSize() const {
566     return Impl->getIntSize();
567   }
568 
569   /// Handle invalidation from the pass manager.
570   ///
571   /// If we try to invalidate this info, just return false. It cannot become
572   /// invalid even if the module or function changes.
573   bool invalidate(Module &, const PreservedAnalyses &,
574                   ModuleAnalysisManager::Invalidator &) {
575     return false;
576   }
577   bool invalidate(Function &, const PreservedAnalyses &,
578                   FunctionAnalysisManager::Invalidator &) {
579     return false;
580   }
581   /// Returns the largest vectorization factor used in the list of
582   /// vector functions.
583   void getWidestVF(StringRef ScalarF, ElementCount &FixedVF,
584                    ElementCount &ScalableVF) const {
585     Impl->getWidestVF(ScalarF, FixedVF, ScalableVF);
586   }
587 
588   /// Check if the function "F" is listed in a library known to LLVM.
589   bool isKnownVectorFunctionInLibrary(StringRef F) const {
590     return this->isFunctionVectorizable(F);
591   }
592 };
593 
594 /// Analysis pass providing the \c TargetLibraryInfo.
595 ///
596 /// Note that this pass's result cannot be invalidated, it is immutable for the
597 /// life of the module.
598 class TargetLibraryAnalysis : public AnalysisInfoMixin<TargetLibraryAnalysis> {
599 public:
600   typedef TargetLibraryInfo Result;
601 
602   /// Default construct the library analysis.
603   ///
604   /// This will use the module's triple to construct the library info for that
605   /// module.
606   TargetLibraryAnalysis() = default;
607 
608   /// Construct a library analysis with baseline Module-level info.
609   ///
610   /// This will be supplemented with Function-specific info in the Result.
611   TargetLibraryAnalysis(TargetLibraryInfoImpl BaselineInfoImpl)
612       : BaselineInfoImpl(std::move(BaselineInfoImpl)) {}
613 
614   TargetLibraryInfo run(const Function &F, FunctionAnalysisManager &);
615 
616 private:
617   friend AnalysisInfoMixin<TargetLibraryAnalysis>;
618   static AnalysisKey Key;
619 
620   std::optional<TargetLibraryInfoImpl> BaselineInfoImpl;
621 };
622 
623 class TargetLibraryInfoWrapperPass : public ImmutablePass {
624   TargetLibraryAnalysis TLA;
625   std::optional<TargetLibraryInfo> TLI;
626 
627   virtual void anchor();
628 
629 public:
630   static char ID;
631   TargetLibraryInfoWrapperPass();
632   explicit TargetLibraryInfoWrapperPass(const Triple &T);
633   explicit TargetLibraryInfoWrapperPass(const TargetLibraryInfoImpl &TLI);
634 
635   TargetLibraryInfo &getTLI(const Function &F) {
636     FunctionAnalysisManager DummyFAM;
637     TLI = TLA.run(F, DummyFAM);
638     return *TLI;
639   }
640 };
641 
642 } // end namespace llvm
643 
644 #endif
645