xref: /llvm-project/llvm/include/llvm/Analysis/TargetLibraryInfo.h (revision 22f0ebb19cd216a1748263c4dbabcd832206f3ea)
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/DenseMap.h"
13 #include "llvm/IR/Constants.h"
14 #include "llvm/IR/InstrTypes.h"
15 #include "llvm/IR/Module.h"
16 #include "llvm/IR/PassManager.h"
17 #include "llvm/Pass.h"
18 #include "llvm/TargetParser/Triple.h"
19 #include <bitset>
20 #include <optional>
21 
22 namespace llvm {
23 
24 template <typename T> class ArrayRef;
25 
26 /// Provides info so a possible vectorization of a function can be
27 /// computed. Function 'VectorFnName' is equivalent to 'ScalarFnName'
28 /// vectorized by a factor 'VectorizationFactor'.
29 /// The VABIPrefix string holds information about isa, mask, vlen,
30 /// and vparams so a scalar-to-vector mapping of the form:
31 ///    _ZGV<isa><mask><vlen><vparams>_<scalarname>(<vectorname>)
32 /// can be constructed where:
33 ///
34 /// <isa> = "_LLVM_"
35 /// <mask> = "M" if masked, "N" if no mask.
36 /// <vlen> = Number of concurrent lanes, stored in the `VectorizationFactor`
37 ///          field of the `VecDesc` struct. If the number of lanes is scalable
38 ///          then 'x' is printed instead.
39 /// <vparams> = "v", as many as are the numArgs.
40 /// <scalarname> = the name of the scalar function.
41 /// <vectorname> = the name of the vector function.
42 class VecDesc {
43   StringRef ScalarFnName;
44   StringRef VectorFnName;
45   ElementCount VectorizationFactor;
46   bool Masked;
47   StringRef VABIPrefix;
48 
49 public:
50   VecDesc() = delete;
51   VecDesc(StringRef ScalarFnName, StringRef VectorFnName,
52           ElementCount VectorizationFactor, bool Masked, StringRef VABIPrefix)
53       : ScalarFnName(ScalarFnName), VectorFnName(VectorFnName),
54         VectorizationFactor(VectorizationFactor), Masked(Masked),
55         VABIPrefix(VABIPrefix) {}
56 
57   StringRef getScalarFnName() const { return ScalarFnName; }
58   StringRef getVectorFnName() const { return VectorFnName; }
59   ElementCount getVectorizationFactor() const { return VectorizationFactor; }
60   bool isMasked() const { return Masked; }
61   StringRef getVABIPrefix() const { return VABIPrefix; }
62 
63   /// Returns a vector function ABI variant string on the form:
64   ///    _ZGV<isa><mask><vlen><vparams>_<scalarname>(<vectorname>)
65   std::string getVectorFunctionABIVariantString() const;
66 };
67 
68   enum LibFunc : unsigned {
69 #define TLI_DEFINE_ENUM
70 #include "llvm/Analysis/TargetLibraryInfo.def"
71 
72     NumLibFuncs,
73     NotLibFunc
74   };
75 
76 /// Implementation of the target library information.
77 ///
78 /// This class constructs tables that hold the target library information and
79 /// make it available. However, it is somewhat expensive to compute and only
80 /// depends on the triple. So users typically interact with the \c
81 /// TargetLibraryInfo wrapper below.
82 class TargetLibraryInfoImpl {
83   friend class TargetLibraryInfo;
84 
85   unsigned char AvailableArray[(NumLibFuncs+3)/4];
86   DenseMap<unsigned, std::string> CustomNames;
87   static StringLiteral const StandardNames[NumLibFuncs];
88   bool ShouldExtI32Param, ShouldExtI32Return, ShouldSignExtI32Param, ShouldSignExtI32Return;
89   unsigned SizeOfInt;
90 
91   enum AvailabilityState {
92     StandardName = 3, // (memset to all ones)
93     CustomName = 1,
94     Unavailable = 0  // (memset to all zeros)
95   };
96   void setState(LibFunc F, AvailabilityState State) {
97     AvailableArray[F/4] &= ~(3 << 2*(F&3));
98     AvailableArray[F/4] |= State << 2*(F&3);
99   }
100   AvailabilityState getState(LibFunc F) const {
101     return static_cast<AvailabilityState>((AvailableArray[F/4] >> 2*(F&3)) & 3);
102   }
103 
104   /// Vectorization descriptors - sorted by ScalarFnName.
105   std::vector<VecDesc> VectorDescs;
106   /// Scalarization descriptors - same content as VectorDescs but sorted based
107   /// on VectorFnName rather than ScalarFnName.
108   std::vector<VecDesc> ScalarDescs;
109 
110   /// Return true if the function type FTy is valid for the library function
111   /// F, regardless of whether the function is available.
112   bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc F,
113                               const Module &M) const;
114 
115 public:
116   /// List of known vector-functions libraries.
117   ///
118   /// The vector-functions library defines, which functions are vectorizable
119   /// and with which factor. The library can be specified by either frontend,
120   /// or a commandline option, and then used by
121   /// addVectorizableFunctionsFromVecLib for filling up the tables of
122   /// vectorizable functions.
123   enum VectorLibrary {
124     NoLibrary,        // Don't use any vector library.
125     Accelerate,       // Use Accelerate framework.
126     DarwinLibSystemM, // Use Darwin's libsystem_m.
127     LIBMVEC_X86,      // GLIBC Vector Math library.
128     MASSV,            // IBM MASS vector library.
129     SVML,             // Intel short vector math library.
130     SLEEFGNUABI, // SLEEF - SIMD Library for Evaluating Elementary Functions.
131     ArmPL,       // Arm Performance Libraries.
132     AMDLIBM      // AMD Math Vector library.
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   std::bitset<NumLibFuncs> OverrideAsUnavailable;
290 
291 public:
292   explicit TargetLibraryInfo(const TargetLibraryInfoImpl &Impl,
293                              std::optional<const Function *> F = std::nullopt)
294       : Impl(&Impl) {
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) = default;
318   TargetLibraryInfo &operator=(const TargetLibraryInfo &TLI) = default;
319   TargetLibraryInfo &operator=(TargetLibraryInfo &&TLI) = default;
320 
321   /// Determine whether a callee with the given TLI can be inlined into
322   /// caller with this TLI, based on 'nobuiltin' attributes. When requested,
323   /// allow inlining into a caller with a superset of the callee's nobuiltin
324   /// attributes, which is conservatively correct.
325   bool areInlineCompatible(const TargetLibraryInfo &CalleeTLI,
326                            bool AllowCallerSuperset) const {
327     if (!AllowCallerSuperset)
328       return OverrideAsUnavailable == CalleeTLI.OverrideAsUnavailable;
329     // We can inline if the callee's nobuiltin attributes are no stricter than
330     // the caller's.
331     return (CalleeTLI.OverrideAsUnavailable & ~OverrideAsUnavailable).none();
332   }
333 
334   /// Return true if the function type FTy is valid for the library function
335   /// F, regardless of whether the function is available.
336   bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc F,
337                               const Module &M) const {
338     return Impl->isValidProtoForLibFunc(FTy, F, M);
339   }
340 
341   /// Searches for a particular function name.
342   ///
343   /// If it is one of the known library functions, return true and set F to the
344   /// corresponding value.
345   bool getLibFunc(StringRef funcName, LibFunc &F) const {
346     return Impl->getLibFunc(funcName, F);
347   }
348 
349   bool getLibFunc(const Function &FDecl, LibFunc &F) const {
350     return Impl->getLibFunc(FDecl, F);
351   }
352 
353   /// If a callbase does not have the 'nobuiltin' attribute, return if the
354   /// called function is a known library function and set F to that function.
355   bool getLibFunc(const CallBase &CB, LibFunc &F) const {
356     return !CB.isNoBuiltin() && CB.getCalledFunction() &&
357            getLibFunc(*(CB.getCalledFunction()), F);
358   }
359 
360   /// Searches for a function name using an Instruction \p Opcode.
361   /// Currently, only the frem instruction is supported.
362   bool getLibFunc(unsigned int Opcode, Type *Ty, LibFunc &F) const {
363     return Impl->getLibFunc(Opcode, Ty, F);
364   }
365 
366   /// Disables all builtins.
367   ///
368   /// This can be used for options like -fno-builtin.
369   void disableAllFunctions() LLVM_ATTRIBUTE_UNUSED {
370     OverrideAsUnavailable.set();
371   }
372 
373   /// Forces a function to be marked as unavailable.
374   void setUnavailable(LibFunc F) LLVM_ATTRIBUTE_UNUSED {
375     assert(F < OverrideAsUnavailable.size() && "out-of-bounds LibFunc");
376     OverrideAsUnavailable.set(F);
377   }
378 
379   TargetLibraryInfoImpl::AvailabilityState getState(LibFunc F) const {
380     assert(F < OverrideAsUnavailable.size() && "out-of-bounds LibFunc");
381     if (OverrideAsUnavailable[F])
382       return TargetLibraryInfoImpl::Unavailable;
383     return Impl->getState(F);
384   }
385 
386   /// Tests whether a library function is available.
387   bool has(LibFunc F) const {
388     return getState(F) != TargetLibraryInfoImpl::Unavailable;
389   }
390   bool isFunctionVectorizable(StringRef F, const ElementCount &VF) const {
391     return Impl->isFunctionVectorizable(F, VF);
392   }
393   bool isFunctionVectorizable(StringRef F) const {
394     return Impl->isFunctionVectorizable(F);
395   }
396   StringRef getVectorizedFunction(StringRef F, const ElementCount &VF,
397                                   bool Masked = false) const {
398     return Impl->getVectorizedFunction(F, VF, Masked);
399   }
400   const VecDesc *getVectorMappingInfo(StringRef F, const ElementCount &VF,
401                                       bool Masked) const {
402     return Impl->getVectorMappingInfo(F, VF, Masked);
403   }
404 
405   /// Tests if the function is both available and a candidate for optimized code
406   /// generation.
407   bool hasOptimizedCodeGen(LibFunc F) const {
408     if (getState(F) == TargetLibraryInfoImpl::Unavailable)
409       return false;
410     switch (F) {
411     default: break;
412       // clang-format off
413     case LibFunc_acos:         case LibFunc_acosf:      case LibFunc_acosl:
414     case LibFunc_asin:         case LibFunc_asinf:      case LibFunc_asinl:
415     case LibFunc_atan2:        case LibFunc_atan2f:     case LibFunc_atan2l:
416     case LibFunc_atan:         case LibFunc_atanf:      case LibFunc_atanl:
417     case LibFunc_ceil:         case LibFunc_ceilf:      case LibFunc_ceill:
418     case LibFunc_copysign:     case LibFunc_copysignf:  case LibFunc_copysignl:
419     case LibFunc_cos:          case LibFunc_cosf:       case LibFunc_cosl:
420     case LibFunc_cosh:         case LibFunc_coshf:      case LibFunc_coshl:
421     case LibFunc_exp2:         case LibFunc_exp2f:      case LibFunc_exp2l:
422     case LibFunc_exp10:        case LibFunc_exp10f:     case LibFunc_exp10l:
423     case LibFunc_fabs:         case LibFunc_fabsf:      case LibFunc_fabsl:
424     case LibFunc_floor:        case LibFunc_floorf:     case LibFunc_floorl:
425     case LibFunc_fmax:         case LibFunc_fmaxf:      case LibFunc_fmaxl:
426     case LibFunc_fmin:         case LibFunc_fminf:      case LibFunc_fminl:
427     case LibFunc_ldexp:        case LibFunc_ldexpf:     case LibFunc_ldexpl:
428     case LibFunc_log2:         case LibFunc_log2f:      case LibFunc_log2l:
429     case LibFunc_memcmp:       case LibFunc_bcmp:       case LibFunc_strcmp:
430     case LibFunc_memcpy:       case LibFunc_memset:     case LibFunc_memmove:
431     case LibFunc_nearbyint:    case LibFunc_nearbyintf: case LibFunc_nearbyintl:
432     case LibFunc_rint:         case LibFunc_rintf:      case LibFunc_rintl:
433     case LibFunc_round:        case LibFunc_roundf:     case LibFunc_roundl:
434     case LibFunc_sin:          case LibFunc_sinf:       case LibFunc_sinl:
435     case LibFunc_sinh:         case LibFunc_sinhf:      case LibFunc_sinhl:
436     case LibFunc_sqrt:         case LibFunc_sqrtf:      case LibFunc_sqrtl:
437     case LibFunc_sqrt_finite:  case LibFunc_sqrtf_finite:
438                                                    case LibFunc_sqrtl_finite:
439     case LibFunc_strcpy:       case LibFunc_stpcpy:     case LibFunc_strlen:
440     case LibFunc_strnlen:      case LibFunc_memchr:     case LibFunc_mempcpy:
441     case LibFunc_tan:          case LibFunc_tanf:       case LibFunc_tanl:
442     case LibFunc_tanh:         case LibFunc_tanhf:      case LibFunc_tanhl:
443     case LibFunc_trunc:        case LibFunc_truncf:     case LibFunc_truncl:
444       // clang-format on
445       return true;
446     }
447     return false;
448   }
449 
450   StringRef getName(LibFunc F) const {
451     auto State = getState(F);
452     if (State == TargetLibraryInfoImpl::Unavailable)
453       return StringRef();
454     if (State == TargetLibraryInfoImpl::StandardName)
455       return Impl->StandardNames[F];
456     assert(State == TargetLibraryInfoImpl::CustomName);
457     return Impl->CustomNames.find(F)->second;
458   }
459 
460   static void initExtensionsForTriple(bool &ShouldExtI32Param,
461                                       bool &ShouldExtI32Return,
462                                       bool &ShouldSignExtI32Param,
463                                       bool &ShouldSignExtI32Return,
464                                       const Triple &T) {
465     ShouldExtI32Param     = ShouldExtI32Return     = false;
466     ShouldSignExtI32Param = ShouldSignExtI32Return = false;
467 
468     // PowerPC64, Sparc64, SystemZ need signext/zeroext on i32 parameters and
469     // returns corresponding to C-level ints and unsigned ints.
470     if (T.isPPC64() || T.getArch() == Triple::sparcv9 ||
471         T.getArch() == Triple::systemz) {
472       ShouldExtI32Param = true;
473       ShouldExtI32Return = true;
474     }
475     // LoongArch, Mips, and riscv64, on the other hand, need signext on i32
476     // parameters corresponding to both signed and unsigned ints.
477     if (T.isLoongArch() || T.isMIPS() || T.isRISCV64()) {
478       ShouldSignExtI32Param = true;
479     }
480     // LoongArch and riscv64 need signext on i32 returns corresponding to both
481     // signed and unsigned ints.
482     if (T.isLoongArch() || T.isRISCV64()) {
483       ShouldSignExtI32Return = true;
484     }
485   }
486 
487   /// Returns extension attribute kind to be used for i32 parameters
488   /// corresponding to C-level int or unsigned int.  May be zeroext, signext,
489   /// or none.
490 private:
491   static Attribute::AttrKind getExtAttrForI32Param(bool ShouldExtI32Param_,
492                                                    bool ShouldSignExtI32Param_,
493                                                    bool Signed = true) {
494     if (ShouldExtI32Param_)
495       return Signed ? Attribute::SExt : Attribute::ZExt;
496     if (ShouldSignExtI32Param_)
497       return Attribute::SExt;
498     return Attribute::None;
499   }
500 
501 public:
502   static Attribute::AttrKind getExtAttrForI32Param(const Triple &T,
503                                                    bool Signed = true) {
504     bool ShouldExtI32Param, ShouldExtI32Return;
505     bool ShouldSignExtI32Param, ShouldSignExtI32Return;
506     initExtensionsForTriple(ShouldExtI32Param, ShouldExtI32Return,
507                             ShouldSignExtI32Param, ShouldSignExtI32Return, T);
508     return getExtAttrForI32Param(ShouldExtI32Param, ShouldSignExtI32Param,
509                                  Signed);
510   }
511 
512   Attribute::AttrKind getExtAttrForI32Param(bool Signed = true) const {
513     return getExtAttrForI32Param(Impl->ShouldExtI32Param,
514                                  Impl->ShouldSignExtI32Param, Signed);
515   }
516 
517   /// Returns extension attribute kind to be used for i32 return values
518   /// corresponding to C-level int or unsigned int.  May be zeroext, signext,
519   /// or none.
520 private:
521   static Attribute::AttrKind getExtAttrForI32Return(bool ShouldExtI32Return_,
522                                                     bool ShouldSignExtI32Return_,
523                                                     bool Signed) {
524     if (ShouldExtI32Return_)
525       return Signed ? Attribute::SExt : Attribute::ZExt;
526     if (ShouldSignExtI32Return_)
527       return Attribute::SExt;
528     return Attribute::None;
529   }
530 
531 public:
532   static Attribute::AttrKind getExtAttrForI32Return(const Triple &T,
533                                                    bool Signed = true) {
534     bool ShouldExtI32Param, ShouldExtI32Return;
535     bool ShouldSignExtI32Param, ShouldSignExtI32Return;
536     initExtensionsForTriple(ShouldExtI32Param, ShouldExtI32Return,
537                             ShouldSignExtI32Param, ShouldSignExtI32Return, T);
538     return getExtAttrForI32Return(ShouldExtI32Return, ShouldSignExtI32Return,
539                                   Signed);
540   }
541 
542   Attribute::AttrKind getExtAttrForI32Return(bool Signed = true) const {
543     return getExtAttrForI32Return(Impl->ShouldExtI32Return,
544                                   Impl->ShouldSignExtI32Return, Signed);
545   }
546 
547   // Helper to create an AttributeList for args (and ret val) which all have
548   // the same signedness. Attributes in AL may be passed in to include them
549   // as well in the returned AttributeList.
550   AttributeList getAttrList(LLVMContext *C, ArrayRef<unsigned> ArgNos,
551                             bool Signed, bool Ret = false,
552                             AttributeList AL = AttributeList()) const {
553     if (auto AK = getExtAttrForI32Param(Signed))
554       for (auto ArgNo : ArgNos)
555         AL = AL.addParamAttribute(*C, ArgNo, AK);
556     if (Ret)
557       if (auto AK = getExtAttrForI32Return(Signed))
558         AL = AL.addRetAttribute(*C, AK);
559     return AL;
560   }
561 
562   /// \copydoc TargetLibraryInfoImpl::getWCharSize()
563   unsigned getWCharSize(const Module &M) const {
564     return Impl->getWCharSize(M);
565   }
566 
567   /// \copydoc TargetLibraryInfoImpl::getSizeTSize()
568   unsigned getSizeTSize(const Module &M) const { return Impl->getSizeTSize(M); }
569 
570   /// Returns an IntegerType corresponding to size_t.
571   IntegerType *getSizeTType(const Module &M) const {
572     return IntegerType::get(M.getContext(), getSizeTSize(M));
573   }
574 
575   /// Returns a constant materialized as a size_t type.
576   ConstantInt *getAsSizeT(uint64_t V, const Module &M) const {
577     return ConstantInt::get(getSizeTType(M), V);
578   }
579 
580   /// \copydoc TargetLibraryInfoImpl::getIntSize()
581   unsigned getIntSize() const {
582     return Impl->getIntSize();
583   }
584 
585   /// Handle invalidation from the pass manager.
586   ///
587   /// If we try to invalidate this info, just return false. It cannot become
588   /// invalid even if the module or function changes.
589   bool invalidate(Module &, const PreservedAnalyses &,
590                   ModuleAnalysisManager::Invalidator &) {
591     return false;
592   }
593   bool invalidate(Function &, const PreservedAnalyses &,
594                   FunctionAnalysisManager::Invalidator &) {
595     return false;
596   }
597   /// Returns the largest vectorization factor used in the list of
598   /// vector functions.
599   void getWidestVF(StringRef ScalarF, ElementCount &FixedVF,
600                    ElementCount &ScalableVF) const {
601     Impl->getWidestVF(ScalarF, FixedVF, ScalableVF);
602   }
603 
604   /// Check if the function "F" is listed in a library known to LLVM.
605   bool isKnownVectorFunctionInLibrary(StringRef F) const {
606     return this->isFunctionVectorizable(F);
607   }
608 };
609 
610 /// Analysis pass providing the \c TargetLibraryInfo.
611 ///
612 /// Note that this pass's result cannot be invalidated, it is immutable for the
613 /// life of the module.
614 class TargetLibraryAnalysis : public AnalysisInfoMixin<TargetLibraryAnalysis> {
615 public:
616   typedef TargetLibraryInfo Result;
617 
618   /// Default construct the library analysis.
619   ///
620   /// This will use the module's triple to construct the library info for that
621   /// module.
622   TargetLibraryAnalysis() = default;
623 
624   /// Construct a library analysis with baseline Module-level info.
625   ///
626   /// This will be supplemented with Function-specific info in the Result.
627   TargetLibraryAnalysis(TargetLibraryInfoImpl BaselineInfoImpl)
628       : BaselineInfoImpl(std::move(BaselineInfoImpl)) {}
629 
630   TargetLibraryInfo run(const Function &F, FunctionAnalysisManager &);
631 
632 private:
633   friend AnalysisInfoMixin<TargetLibraryAnalysis>;
634   static AnalysisKey Key;
635 
636   std::optional<TargetLibraryInfoImpl> BaselineInfoImpl;
637 };
638 
639 class TargetLibraryInfoWrapperPass : public ImmutablePass {
640   TargetLibraryAnalysis TLA;
641   std::optional<TargetLibraryInfo> TLI;
642 
643   virtual void anchor();
644 
645 public:
646   static char ID;
647   TargetLibraryInfoWrapperPass();
648   explicit TargetLibraryInfoWrapperPass(const Triple &T);
649   explicit TargetLibraryInfoWrapperPass(const TargetLibraryInfoImpl &TLI);
650 
651   // FIXME: This should be removed when PlaceSafepoints is fixed to not create a
652   // PassManager inside a pass.
653   explicit TargetLibraryInfoWrapperPass(const TargetLibraryInfo &TLI);
654 
655   TargetLibraryInfo &getTLI(const Function &F) {
656     FunctionAnalysisManager DummyFAM;
657     TLI = TLA.run(F, DummyFAM);
658     return *TLI;
659   }
660 };
661 
662 } // end namespace llvm
663 
664 #endif
665