Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:18

0001 //===-- TargetLibraryInfo.h - Library information ---------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_ANALYSIS_TARGETLIBRARYINFO_H
0010 #define LLVM_ANALYSIS_TARGETLIBRARYINFO_H
0011 
0012 #include "llvm/ADT/DenseMap.h"
0013 #include "llvm/IR/Constants.h"
0014 #include "llvm/IR/InstrTypes.h"
0015 #include "llvm/IR/Module.h"
0016 #include "llvm/IR/PassManager.h"
0017 #include "llvm/Pass.h"
0018 #include "llvm/TargetParser/Triple.h"
0019 #include <bitset>
0020 #include <optional>
0021 
0022 namespace llvm {
0023 
0024 template <typename T> class ArrayRef;
0025 
0026 /// Provides info so a possible vectorization of a function can be
0027 /// computed. Function 'VectorFnName' is equivalent to 'ScalarFnName'
0028 /// vectorized by a factor 'VectorizationFactor'.
0029 /// The VABIPrefix string holds information about isa, mask, vlen,
0030 /// and vparams so a scalar-to-vector mapping of the form:
0031 ///    _ZGV<isa><mask><vlen><vparams>_<scalarname>(<vectorname>)
0032 /// can be constructed where:
0033 ///
0034 /// <isa> = "_LLVM_"
0035 /// <mask> = "M" if masked, "N" if no mask.
0036 /// <vlen> = Number of concurrent lanes, stored in the `VectorizationFactor`
0037 ///          field of the `VecDesc` struct. If the number of lanes is scalable
0038 ///          then 'x' is printed instead.
0039 /// <vparams> = "v", as many as are the numArgs.
0040 /// <scalarname> = the name of the scalar function.
0041 /// <vectorname> = the name of the vector function.
0042 class VecDesc {
0043   StringRef ScalarFnName;
0044   StringRef VectorFnName;
0045   ElementCount VectorizationFactor;
0046   bool Masked;
0047   StringRef VABIPrefix;
0048 
0049 public:
0050   VecDesc() = delete;
0051   VecDesc(StringRef ScalarFnName, StringRef VectorFnName,
0052           ElementCount VectorizationFactor, bool Masked, StringRef VABIPrefix)
0053       : ScalarFnName(ScalarFnName), VectorFnName(VectorFnName),
0054         VectorizationFactor(VectorizationFactor), Masked(Masked),
0055         VABIPrefix(VABIPrefix) {}
0056 
0057   StringRef getScalarFnName() const { return ScalarFnName; }
0058   StringRef getVectorFnName() const { return VectorFnName; }
0059   ElementCount getVectorizationFactor() const { return VectorizationFactor; }
0060   bool isMasked() const { return Masked; }
0061   StringRef getVABIPrefix() const { return VABIPrefix; }
0062 
0063   /// Returns a vector function ABI variant string on the form:
0064   ///    _ZGV<isa><mask><vlen><vparams>_<scalarname>(<vectorname>)
0065   std::string getVectorFunctionABIVariantString() const;
0066 };
0067 
0068   enum LibFunc : unsigned {
0069 #define TLI_DEFINE_ENUM
0070 #include "llvm/Analysis/TargetLibraryInfo.def"
0071 
0072     NumLibFuncs,
0073     NotLibFunc
0074   };
0075 
0076 /// Implementation of the target library information.
0077 ///
0078 /// This class constructs tables that hold the target library information and
0079 /// make it available. However, it is somewhat expensive to compute and only
0080 /// depends on the triple. So users typically interact with the \c
0081 /// TargetLibraryInfo wrapper below.
0082 class TargetLibraryInfoImpl {
0083   friend class TargetLibraryInfo;
0084 
0085   unsigned char AvailableArray[(NumLibFuncs+3)/4];
0086   DenseMap<unsigned, std::string> CustomNames;
0087   static StringLiteral const StandardNames[NumLibFuncs];
0088   bool ShouldExtI32Param, ShouldExtI32Return, ShouldSignExtI32Param, ShouldSignExtI32Return;
0089   unsigned SizeOfInt;
0090 
0091   enum AvailabilityState {
0092     StandardName = 3, // (memset to all ones)
0093     CustomName = 1,
0094     Unavailable = 0  // (memset to all zeros)
0095   };
0096   void setState(LibFunc F, AvailabilityState State) {
0097     AvailableArray[F/4] &= ~(3 << 2*(F&3));
0098     AvailableArray[F/4] |= State << 2*(F&3);
0099   }
0100   AvailabilityState getState(LibFunc F) const {
0101     return static_cast<AvailabilityState>((AvailableArray[F/4] >> 2*(F&3)) & 3);
0102   }
0103 
0104   /// Vectorization descriptors - sorted by ScalarFnName.
0105   std::vector<VecDesc> VectorDescs;
0106   /// Scalarization descriptors - same content as VectorDescs but sorted based
0107   /// on VectorFnName rather than ScalarFnName.
0108   std::vector<VecDesc> ScalarDescs;
0109 
0110   /// Return true if the function type FTy is valid for the library function
0111   /// F, regardless of whether the function is available.
0112   bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc F,
0113                               const Module &M) const;
0114 
0115 public:
0116   /// List of known vector-functions libraries.
0117   ///
0118   /// The vector-functions library defines, which functions are vectorizable
0119   /// and with which factor. The library can be specified by either frontend,
0120   /// or a commandline option, and then used by
0121   /// addVectorizableFunctionsFromVecLib for filling up the tables of
0122   /// vectorizable functions.
0123   enum VectorLibrary {
0124     NoLibrary,        // Don't use any vector library.
0125     Accelerate,       // Use Accelerate framework.
0126     DarwinLibSystemM, // Use Darwin's libsystem_m.
0127     LIBMVEC_X86,      // GLIBC Vector Math library.
0128     MASSV,            // IBM MASS vector library.
0129     SVML,             // Intel short vector math library.
0130     SLEEFGNUABI, // SLEEF - SIMD Library for Evaluating Elementary Functions.
0131     ArmPL,       // Arm Performance Libraries.
0132     AMDLIBM      // AMD Math Vector library.
0133   };
0134 
0135   TargetLibraryInfoImpl();
0136   explicit TargetLibraryInfoImpl(const Triple &T);
0137 
0138   // Provide value semantics.
0139   TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI);
0140   TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI);
0141   TargetLibraryInfoImpl &operator=(const TargetLibraryInfoImpl &TLI);
0142   TargetLibraryInfoImpl &operator=(TargetLibraryInfoImpl &&TLI);
0143 
0144   /// Searches for a particular function name.
0145   ///
0146   /// If it is one of the known library functions, return true and set F to the
0147   /// corresponding value.
0148   bool getLibFunc(StringRef funcName, LibFunc &F) const;
0149 
0150   /// Searches for a particular function name, also checking that its type is
0151   /// valid for the library function matching that name.
0152   ///
0153   /// If it is one of the known library functions, return true and set F to the
0154   /// corresponding value.
0155   ///
0156   /// FDecl is assumed to have a parent Module when using this function.
0157   bool getLibFunc(const Function &FDecl, LibFunc &F) const;
0158 
0159   /// Searches for a function name using an Instruction \p Opcode.
0160   /// Currently, only the frem instruction is supported.
0161   bool getLibFunc(unsigned int Opcode, Type *Ty, LibFunc &F) const;
0162 
0163   /// Forces a function to be marked as unavailable.
0164   void setUnavailable(LibFunc F) {
0165     setState(F, Unavailable);
0166   }
0167 
0168   /// Forces a function to be marked as available.
0169   void setAvailable(LibFunc F) {
0170     setState(F, StandardName);
0171   }
0172 
0173   /// Forces a function to be marked as available and provide an alternate name
0174   /// that must be used.
0175   void setAvailableWithName(LibFunc F, StringRef Name) {
0176     if (StandardNames[F] != Name) {
0177       setState(F, CustomName);
0178       CustomNames[F] = std::string(Name);
0179       assert(CustomNames.contains(F));
0180     } else {
0181       setState(F, StandardName);
0182     }
0183   }
0184 
0185   /// Disables all builtins.
0186   ///
0187   /// This can be used for options like -fno-builtin.
0188   void disableAllFunctions();
0189 
0190   /// Add a set of scalar -> vector mappings, queryable via
0191   /// getVectorizedFunction and getScalarizedFunction.
0192   void addVectorizableFunctions(ArrayRef<VecDesc> Fns);
0193 
0194   /// Calls addVectorizableFunctions with a known preset of functions for the
0195   /// given vector library.
0196   void addVectorizableFunctionsFromVecLib(enum VectorLibrary VecLib,
0197                                           const llvm::Triple &TargetTriple);
0198 
0199   /// Return true if the function F has a vector equivalent with vectorization
0200   /// factor VF.
0201   bool isFunctionVectorizable(StringRef F, const ElementCount &VF) const {
0202     return !(getVectorizedFunction(F, VF, false).empty() &&
0203              getVectorizedFunction(F, VF, true).empty());
0204   }
0205 
0206   /// Return true if the function F has a vector equivalent with any
0207   /// vectorization factor.
0208   bool isFunctionVectorizable(StringRef F) const;
0209 
0210   /// Return the name of the equivalent of F, vectorized with factor VF. If no
0211   /// such mapping exists, return the empty string.
0212   StringRef getVectorizedFunction(StringRef F, const ElementCount &VF,
0213                                   bool Masked) const;
0214 
0215   /// Return a pointer to a VecDesc object holding all info for scalar to vector
0216   /// mappings in TLI for the equivalent of F, vectorized with factor VF.
0217   /// If no such mapping exists, return nullpointer.
0218   const VecDesc *getVectorMappingInfo(StringRef F, const ElementCount &VF,
0219                                       bool Masked) const;
0220 
0221   /// Set to true iff i32 parameters to library functions should have signext
0222   /// or zeroext attributes if they correspond to C-level int or unsigned int,
0223   /// respectively.
0224   void setShouldExtI32Param(bool Val) {
0225     ShouldExtI32Param = Val;
0226   }
0227 
0228   /// Set to true iff i32 results from library functions should have signext
0229   /// or zeroext attributes if they correspond to C-level int or unsigned int,
0230   /// respectively.
0231   void setShouldExtI32Return(bool Val) {
0232     ShouldExtI32Return = Val;
0233   }
0234 
0235   /// Set to true iff i32 parameters to library functions should have signext
0236   /// attribute if they correspond to C-level int or unsigned int.
0237   void setShouldSignExtI32Param(bool Val) {
0238     ShouldSignExtI32Param = Val;
0239   }
0240 
0241   /// Set to true iff i32 results from library functions should have signext
0242   /// attribute if they correspond to C-level int or unsigned int.
0243   void setShouldSignExtI32Return(bool Val) {
0244     ShouldSignExtI32Return = Val;
0245   }
0246 
0247   /// Returns the size of the wchar_t type in bytes or 0 if the size is unknown.
0248   /// This queries the 'wchar_size' metadata.
0249   unsigned getWCharSize(const Module &M) const;
0250 
0251   /// Returns the size of the size_t type in bits.
0252   unsigned getSizeTSize(const Module &M) const;
0253 
0254   /// Get size of a C-level int or unsigned int, in bits.
0255   unsigned getIntSize() const {
0256     return SizeOfInt;
0257   }
0258 
0259   /// Initialize the C-level size of an integer.
0260   void setIntSize(unsigned Bits) {
0261     SizeOfInt = Bits;
0262   }
0263 
0264   /// Returns the largest vectorization factor used in the list of
0265   /// vector functions.
0266   void getWidestVF(StringRef ScalarF, ElementCount &FixedVF,
0267                    ElementCount &Scalable) const;
0268 
0269   /// Returns true if call site / callee has cdecl-compatible calling
0270   /// conventions.
0271   static bool isCallingConvCCompatible(CallBase *CI);
0272   static bool isCallingConvCCompatible(Function *Callee);
0273 };
0274 
0275 /// Provides information about what library functions are available for
0276 /// the current target.
0277 ///
0278 /// This both allows optimizations to handle them specially and frontends to
0279 /// disable such optimizations through -fno-builtin etc.
0280 class TargetLibraryInfo {
0281   friend class TargetLibraryAnalysis;
0282   friend class TargetLibraryInfoWrapperPass;
0283 
0284   /// The global (module level) TLI info.
0285   const TargetLibraryInfoImpl *Impl;
0286 
0287   /// Support for -fno-builtin* options as function attributes, overrides
0288   /// information in global TargetLibraryInfoImpl.
0289   std::bitset<NumLibFuncs> OverrideAsUnavailable;
0290 
0291 public:
0292   explicit TargetLibraryInfo(const TargetLibraryInfoImpl &Impl,
0293                              std::optional<const Function *> F = std::nullopt)
0294       : Impl(&Impl) {
0295     if (!F)
0296       return;
0297     if ((*F)->hasFnAttribute("no-builtins"))
0298       disableAllFunctions();
0299     else {
0300       // Disable individual libc/libm calls in TargetLibraryInfo.
0301       LibFunc LF;
0302       AttributeSet FnAttrs = (*F)->getAttributes().getFnAttrs();
0303       for (const Attribute &Attr : FnAttrs) {
0304         if (!Attr.isStringAttribute())
0305           continue;
0306         auto AttrStr = Attr.getKindAsString();
0307         if (!AttrStr.consume_front("no-builtin-"))
0308           continue;
0309         if (getLibFunc(AttrStr, LF))
0310           setUnavailable(LF);
0311       }
0312     }
0313   }
0314 
0315   // Provide value semantics.
0316   TargetLibraryInfo(const TargetLibraryInfo &TLI) = default;
0317   TargetLibraryInfo(TargetLibraryInfo &&TLI) = default;
0318   TargetLibraryInfo &operator=(const TargetLibraryInfo &TLI) = default;
0319   TargetLibraryInfo &operator=(TargetLibraryInfo &&TLI) = default;
0320 
0321   /// Determine whether a callee with the given TLI can be inlined into
0322   /// caller with this TLI, based on 'nobuiltin' attributes. When requested,
0323   /// allow inlining into a caller with a superset of the callee's nobuiltin
0324   /// attributes, which is conservatively correct.
0325   bool areInlineCompatible(const TargetLibraryInfo &CalleeTLI,
0326                            bool AllowCallerSuperset) const {
0327     if (!AllowCallerSuperset)
0328       return OverrideAsUnavailable == CalleeTLI.OverrideAsUnavailable;
0329     // We can inline if the callee's nobuiltin attributes are no stricter than
0330     // the caller's.
0331     return (CalleeTLI.OverrideAsUnavailable & ~OverrideAsUnavailable).none();
0332   }
0333 
0334   /// Return true if the function type FTy is valid for the library function
0335   /// F, regardless of whether the function is available.
0336   bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc F,
0337                               const Module &M) const {
0338     return Impl->isValidProtoForLibFunc(FTy, F, M);
0339   }
0340 
0341   /// Searches for a particular function name.
0342   ///
0343   /// If it is one of the known library functions, return true and set F to the
0344   /// corresponding value.
0345   bool getLibFunc(StringRef funcName, LibFunc &F) const {
0346     return Impl->getLibFunc(funcName, F);
0347   }
0348 
0349   bool getLibFunc(const Function &FDecl, LibFunc &F) const {
0350     return Impl->getLibFunc(FDecl, F);
0351   }
0352 
0353   /// If a callbase does not have the 'nobuiltin' attribute, return if the
0354   /// called function is a known library function and set F to that function.
0355   bool getLibFunc(const CallBase &CB, LibFunc &F) const {
0356     return !CB.isNoBuiltin() && CB.getCalledFunction() &&
0357            getLibFunc(*(CB.getCalledFunction()), F);
0358   }
0359 
0360   /// Searches for a function name using an Instruction \p Opcode.
0361   /// Currently, only the frem instruction is supported.
0362   bool getLibFunc(unsigned int Opcode, Type *Ty, LibFunc &F) const {
0363     return Impl->getLibFunc(Opcode, Ty, F);
0364   }
0365 
0366   /// Disables all builtins.
0367   ///
0368   /// This can be used for options like -fno-builtin.
0369   void disableAllFunctions() LLVM_ATTRIBUTE_UNUSED {
0370     OverrideAsUnavailable.set();
0371   }
0372 
0373   /// Forces a function to be marked as unavailable.
0374   void setUnavailable(LibFunc F) LLVM_ATTRIBUTE_UNUSED {
0375     assert(F < OverrideAsUnavailable.size() && "out-of-bounds LibFunc");
0376     OverrideAsUnavailable.set(F);
0377   }
0378 
0379   TargetLibraryInfoImpl::AvailabilityState getState(LibFunc F) const {
0380     assert(F < OverrideAsUnavailable.size() && "out-of-bounds LibFunc");
0381     if (OverrideAsUnavailable[F])
0382       return TargetLibraryInfoImpl::Unavailable;
0383     return Impl->getState(F);
0384   }
0385 
0386   /// Tests whether a library function is available.
0387   bool has(LibFunc F) const {
0388     return getState(F) != TargetLibraryInfoImpl::Unavailable;
0389   }
0390   bool isFunctionVectorizable(StringRef F, const ElementCount &VF) const {
0391     return Impl->isFunctionVectorizable(F, VF);
0392   }
0393   bool isFunctionVectorizable(StringRef F) const {
0394     return Impl->isFunctionVectorizable(F);
0395   }
0396   StringRef getVectorizedFunction(StringRef F, const ElementCount &VF,
0397                                   bool Masked = false) const {
0398     return Impl->getVectorizedFunction(F, VF, Masked);
0399   }
0400   const VecDesc *getVectorMappingInfo(StringRef F, const ElementCount &VF,
0401                                       bool Masked) const {
0402     return Impl->getVectorMappingInfo(F, VF, Masked);
0403   }
0404 
0405   /// Tests if the function is both available and a candidate for optimized code
0406   /// generation.
0407   bool hasOptimizedCodeGen(LibFunc F) const {
0408     if (getState(F) == TargetLibraryInfoImpl::Unavailable)
0409       return false;
0410     switch (F) {
0411     default: break;
0412       // clang-format off
0413     case LibFunc_acos:         case LibFunc_acosf:      case LibFunc_acosl:
0414     case LibFunc_asin:         case LibFunc_asinf:      case LibFunc_asinl:
0415     case LibFunc_atan2:        case LibFunc_atan2f:     case LibFunc_atan2l:
0416     case LibFunc_atan:         case LibFunc_atanf:      case LibFunc_atanl:
0417     case LibFunc_ceil:         case LibFunc_ceilf:      case LibFunc_ceill:
0418     case LibFunc_copysign:     case LibFunc_copysignf:  case LibFunc_copysignl:
0419     case LibFunc_cos:          case LibFunc_cosf:       case LibFunc_cosl:
0420     case LibFunc_cosh:         case LibFunc_coshf:      case LibFunc_coshl:
0421     case LibFunc_exp2:         case LibFunc_exp2f:      case LibFunc_exp2l:
0422     case LibFunc_exp10:        case LibFunc_exp10f:     case LibFunc_exp10l:
0423     case LibFunc_fabs:         case LibFunc_fabsf:      case LibFunc_fabsl:
0424     case LibFunc_floor:        case LibFunc_floorf:     case LibFunc_floorl:
0425     case LibFunc_fmax:         case LibFunc_fmaxf:      case LibFunc_fmaxl:
0426     case LibFunc_fmin:         case LibFunc_fminf:      case LibFunc_fminl:
0427     case LibFunc_ldexp:        case LibFunc_ldexpf:     case LibFunc_ldexpl:
0428     case LibFunc_log2:         case LibFunc_log2f:      case LibFunc_log2l:
0429     case LibFunc_memcmp:       case LibFunc_bcmp:       case LibFunc_strcmp:
0430     case LibFunc_memcpy:       case LibFunc_memset:     case LibFunc_memmove:
0431     case LibFunc_nearbyint:    case LibFunc_nearbyintf: case LibFunc_nearbyintl:
0432     case LibFunc_rint:         case LibFunc_rintf:      case LibFunc_rintl:
0433     case LibFunc_round:        case LibFunc_roundf:     case LibFunc_roundl:
0434     case LibFunc_sin:          case LibFunc_sinf:       case LibFunc_sinl:
0435     case LibFunc_sinh:         case LibFunc_sinhf:      case LibFunc_sinhl:
0436     case LibFunc_sqrt:         case LibFunc_sqrtf:      case LibFunc_sqrtl:
0437     case LibFunc_sqrt_finite:  case LibFunc_sqrtf_finite:
0438                                                    case LibFunc_sqrtl_finite:
0439     case LibFunc_strcpy:       case LibFunc_stpcpy:     case LibFunc_strlen:
0440     case LibFunc_strnlen:      case LibFunc_memchr:     case LibFunc_mempcpy:
0441     case LibFunc_tan:          case LibFunc_tanf:       case LibFunc_tanl:
0442     case LibFunc_tanh:         case LibFunc_tanhf:      case LibFunc_tanhl:
0443     case LibFunc_trunc:        case LibFunc_truncf:     case LibFunc_truncl:
0444       // clang-format on
0445       return true;
0446     }
0447     return false;
0448   }
0449 
0450   StringRef getName(LibFunc F) const {
0451     auto State = getState(F);
0452     if (State == TargetLibraryInfoImpl::Unavailable)
0453       return StringRef();
0454     if (State == TargetLibraryInfoImpl::StandardName)
0455       return Impl->StandardNames[F];
0456     assert(State == TargetLibraryInfoImpl::CustomName);
0457     return Impl->CustomNames.find(F)->second;
0458   }
0459 
0460   static void initExtensionsForTriple(bool &ShouldExtI32Param,
0461                                       bool &ShouldExtI32Return,
0462                                       bool &ShouldSignExtI32Param,
0463                                       bool &ShouldSignExtI32Return,
0464                                       const Triple &T) {
0465     ShouldExtI32Param     = ShouldExtI32Return     = false;
0466     ShouldSignExtI32Param = ShouldSignExtI32Return = false;
0467 
0468     // PowerPC64, Sparc64, SystemZ need signext/zeroext on i32 parameters and
0469     // returns corresponding to C-level ints and unsigned ints.
0470     if (T.isPPC64() || T.getArch() == Triple::sparcv9 ||
0471         T.getArch() == Triple::systemz) {
0472       ShouldExtI32Param = true;
0473       ShouldExtI32Return = true;
0474     }
0475     // LoongArch, Mips, and riscv64, on the other hand, need signext on i32
0476     // parameters corresponding to both signed and unsigned ints.
0477     if (T.isLoongArch() || T.isMIPS() || T.isRISCV64()) {
0478       ShouldSignExtI32Param = true;
0479     }
0480     // LoongArch and riscv64 need signext on i32 returns corresponding to both
0481     // signed and unsigned ints.
0482     if (T.isLoongArch() || T.isRISCV64()) {
0483       ShouldSignExtI32Return = true;
0484     }
0485   }
0486 
0487   /// Returns extension attribute kind to be used for i32 parameters
0488   /// corresponding to C-level int or unsigned int.  May be zeroext, signext,
0489   /// or none.
0490 private:
0491   static Attribute::AttrKind getExtAttrForI32Param(bool ShouldExtI32Param_,
0492                                                    bool ShouldSignExtI32Param_,
0493                                                    bool Signed = true) {
0494     if (ShouldExtI32Param_)
0495       return Signed ? Attribute::SExt : Attribute::ZExt;
0496     if (ShouldSignExtI32Param_)
0497       return Attribute::SExt;
0498     return Attribute::None;
0499   }
0500 
0501 public:
0502   static Attribute::AttrKind getExtAttrForI32Param(const Triple &T,
0503                                                    bool Signed = true) {
0504     bool ShouldExtI32Param, ShouldExtI32Return;
0505     bool ShouldSignExtI32Param, ShouldSignExtI32Return;
0506     initExtensionsForTriple(ShouldExtI32Param, ShouldExtI32Return,
0507                             ShouldSignExtI32Param, ShouldSignExtI32Return, T);
0508     return getExtAttrForI32Param(ShouldExtI32Param, ShouldSignExtI32Param,
0509                                  Signed);
0510   }
0511 
0512   Attribute::AttrKind getExtAttrForI32Param(bool Signed = true) const {
0513     return getExtAttrForI32Param(Impl->ShouldExtI32Param,
0514                                  Impl->ShouldSignExtI32Param, Signed);
0515   }
0516 
0517   /// Returns extension attribute kind to be used for i32 return values
0518   /// corresponding to C-level int or unsigned int.  May be zeroext, signext,
0519   /// or none.
0520 private:
0521   static Attribute::AttrKind getExtAttrForI32Return(bool ShouldExtI32Return_,
0522                                                     bool ShouldSignExtI32Return_,
0523                                                     bool Signed) {
0524     if (ShouldExtI32Return_)
0525       return Signed ? Attribute::SExt : Attribute::ZExt;
0526     if (ShouldSignExtI32Return_)
0527       return Attribute::SExt;
0528     return Attribute::None;
0529   }
0530 
0531 public:
0532   static Attribute::AttrKind getExtAttrForI32Return(const Triple &T,
0533                                                    bool Signed = true) {
0534     bool ShouldExtI32Param, ShouldExtI32Return;
0535     bool ShouldSignExtI32Param, ShouldSignExtI32Return;
0536     initExtensionsForTriple(ShouldExtI32Param, ShouldExtI32Return,
0537                             ShouldSignExtI32Param, ShouldSignExtI32Return, T);
0538     return getExtAttrForI32Return(ShouldExtI32Return, ShouldSignExtI32Return,
0539                                   Signed);
0540   }
0541 
0542   Attribute::AttrKind getExtAttrForI32Return(bool Signed = true) const {
0543     return getExtAttrForI32Return(Impl->ShouldExtI32Return,
0544                                   Impl->ShouldSignExtI32Return, Signed);
0545   }
0546 
0547   // Helper to create an AttributeList for args (and ret val) which all have
0548   // the same signedness. Attributes in AL may be passed in to include them
0549   // as well in the returned AttributeList.
0550   AttributeList getAttrList(LLVMContext *C, ArrayRef<unsigned> ArgNos,
0551                             bool Signed, bool Ret = false,
0552                             AttributeList AL = AttributeList()) const {
0553     if (auto AK = getExtAttrForI32Param(Signed))
0554       for (auto ArgNo : ArgNos)
0555         AL = AL.addParamAttribute(*C, ArgNo, AK);
0556     if (Ret)
0557       if (auto AK = getExtAttrForI32Return(Signed))
0558         AL = AL.addRetAttribute(*C, AK);
0559     return AL;
0560   }
0561 
0562   /// \copydoc TargetLibraryInfoImpl::getWCharSize()
0563   unsigned getWCharSize(const Module &M) const {
0564     return Impl->getWCharSize(M);
0565   }
0566 
0567   /// \copydoc TargetLibraryInfoImpl::getSizeTSize()
0568   unsigned getSizeTSize(const Module &M) const { return Impl->getSizeTSize(M); }
0569 
0570   /// Returns an IntegerType corresponding to size_t.
0571   IntegerType *getSizeTType(const Module &M) const {
0572     return IntegerType::get(M.getContext(), getSizeTSize(M));
0573   }
0574 
0575   /// Returns a constant materialized as a size_t type.
0576   ConstantInt *getAsSizeT(uint64_t V, const Module &M) const {
0577     return ConstantInt::get(getSizeTType(M), V);
0578   }
0579 
0580   /// \copydoc TargetLibraryInfoImpl::getIntSize()
0581   unsigned getIntSize() const {
0582     return Impl->getIntSize();
0583   }
0584 
0585   /// Handle invalidation from the pass manager.
0586   ///
0587   /// If we try to invalidate this info, just return false. It cannot become
0588   /// invalid even if the module or function changes.
0589   bool invalidate(Module &, const PreservedAnalyses &,
0590                   ModuleAnalysisManager::Invalidator &) {
0591     return false;
0592   }
0593   bool invalidate(Function &, const PreservedAnalyses &,
0594                   FunctionAnalysisManager::Invalidator &) {
0595     return false;
0596   }
0597   /// Returns the largest vectorization factor used in the list of
0598   /// vector functions.
0599   void getWidestVF(StringRef ScalarF, ElementCount &FixedVF,
0600                    ElementCount &ScalableVF) const {
0601     Impl->getWidestVF(ScalarF, FixedVF, ScalableVF);
0602   }
0603 
0604   /// Check if the function "F" is listed in a library known to LLVM.
0605   bool isKnownVectorFunctionInLibrary(StringRef F) const {
0606     return this->isFunctionVectorizable(F);
0607   }
0608 };
0609 
0610 /// Analysis pass providing the \c TargetLibraryInfo.
0611 ///
0612 /// Note that this pass's result cannot be invalidated, it is immutable for the
0613 /// life of the module.
0614 class TargetLibraryAnalysis : public AnalysisInfoMixin<TargetLibraryAnalysis> {
0615 public:
0616   typedef TargetLibraryInfo Result;
0617 
0618   /// Default construct the library analysis.
0619   ///
0620   /// This will use the module's triple to construct the library info for that
0621   /// module.
0622   TargetLibraryAnalysis() = default;
0623 
0624   /// Construct a library analysis with baseline Module-level info.
0625   ///
0626   /// This will be supplemented with Function-specific info in the Result.
0627   TargetLibraryAnalysis(TargetLibraryInfoImpl BaselineInfoImpl)
0628       : BaselineInfoImpl(std::move(BaselineInfoImpl)) {}
0629 
0630   TargetLibraryInfo run(const Function &F, FunctionAnalysisManager &);
0631 
0632 private:
0633   friend AnalysisInfoMixin<TargetLibraryAnalysis>;
0634   static AnalysisKey Key;
0635 
0636   std::optional<TargetLibraryInfoImpl> BaselineInfoImpl;
0637 };
0638 
0639 class TargetLibraryInfoWrapperPass : public ImmutablePass {
0640   TargetLibraryAnalysis TLA;
0641   std::optional<TargetLibraryInfo> TLI;
0642 
0643   virtual void anchor();
0644 
0645 public:
0646   static char ID;
0647   TargetLibraryInfoWrapperPass();
0648   explicit TargetLibraryInfoWrapperPass(const Triple &T);
0649   explicit TargetLibraryInfoWrapperPass(const TargetLibraryInfoImpl &TLI);
0650 
0651   // FIXME: This should be removed when PlaceSafepoints is fixed to not create a
0652   // PassManager inside a pass.
0653   explicit TargetLibraryInfoWrapperPass(const TargetLibraryInfo &TLI);
0654 
0655   TargetLibraryInfo &getTLI(const Function &F) {
0656     FunctionAnalysisManager DummyFAM;
0657     TLI = TLA.run(F, DummyFAM);
0658     return *TLI;
0659   }
0660 };
0661 
0662 } // end namespace llvm
0663 
0664 #endif