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