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