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