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/ADT/Triple.h" 15 #include "llvm/IR/InstrTypes.h" 16 #include "llvm/IR/PassManager.h" 17 #include "llvm/Pass.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 /// Describes a possible vectorization of a function. 28 /// Function 'VectorFnName' is equivalent to 'ScalarFnName' vectorized 29 /// by a factor 'VectorizationFactor'. 30 struct VecDesc { 31 StringRef ScalarFnName; 32 StringRef VectorFnName; 33 ElementCount VectorizationFactor; 34 }; 35 36 enum LibFunc : unsigned { 37 #define TLI_DEFINE_ENUM 38 #include "llvm/Analysis/TargetLibraryInfo.def" 39 40 NumLibFuncs, 41 NotLibFunc 42 }; 43 44 /// Implementation of the target library information. 45 /// 46 /// This class constructs tables that hold the target library information and 47 /// make it available. However, it is somewhat expensive to compute and only 48 /// depends on the triple. So users typically interact with the \c 49 /// TargetLibraryInfo wrapper below. 50 class TargetLibraryInfoImpl { 51 friend class TargetLibraryInfo; 52 53 unsigned char AvailableArray[(NumLibFuncs+3)/4]; 54 DenseMap<unsigned, std::string> CustomNames; 55 static StringLiteral const StandardNames[NumLibFuncs]; 56 bool ShouldExtI32Param, ShouldExtI32Return, ShouldSignExtI32Param, ShouldSignExtI32Return; 57 unsigned SizeOfInt; 58 59 enum AvailabilityState { 60 StandardName = 3, // (memset to all ones) 61 CustomName = 1, 62 Unavailable = 0 // (memset to all zeros) 63 }; setState(LibFunc F,AvailabilityState State)64 void setState(LibFunc F, AvailabilityState State) { 65 AvailableArray[F/4] &= ~(3 << 2*(F&3)); 66 AvailableArray[F/4] |= State << 2*(F&3); 67 } getState(LibFunc F)68 AvailabilityState getState(LibFunc F) const { 69 return static_cast<AvailabilityState>((AvailableArray[F/4] >> 2*(F&3)) & 3); 70 } 71 72 /// Vectorization descriptors - sorted by ScalarFnName. 73 std::vector<VecDesc> VectorDescs; 74 /// Scalarization descriptors - same content as VectorDescs but sorted based 75 /// on VectorFnName rather than ScalarFnName. 76 std::vector<VecDesc> ScalarDescs; 77 78 /// Return true if the function type FTy is valid for the library function 79 /// F, regardless of whether the function is available. 80 bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc F, 81 const Module &M) const; 82 83 public: 84 /// List of known vector-functions libraries. 85 /// 86 /// The vector-functions library defines, which functions are vectorizable 87 /// and with which factor. The library can be specified by either frontend, 88 /// or a commandline option, and then used by 89 /// addVectorizableFunctionsFromVecLib for filling up the tables of 90 /// vectorizable functions. 91 enum VectorLibrary { 92 NoLibrary, // Don't use any vector library. 93 Accelerate, // Use Accelerate framework. 94 DarwinLibSystemM, // Use Darwin's libsystem_m. 95 LIBMVEC_X86, // GLIBC Vector Math library. 96 MASSV, // IBM MASS vector library. 97 SVML, // Intel short vector math library. 98 SLEEFGNUABI // SLEEF - SIMD Library for Evaluating Elementary Functions. 99 }; 100 101 TargetLibraryInfoImpl(); 102 explicit TargetLibraryInfoImpl(const Triple &T); 103 104 // Provide value semantics. 105 TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI); 106 TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI); 107 TargetLibraryInfoImpl &operator=(const TargetLibraryInfoImpl &TLI); 108 TargetLibraryInfoImpl &operator=(TargetLibraryInfoImpl &&TLI); 109 110 /// Searches for a particular function name. 111 /// 112 /// If it is one of the known library functions, return true and set F to the 113 /// corresponding value. 114 bool getLibFunc(StringRef funcName, LibFunc &F) const; 115 116 /// Searches for a particular function name, also checking that its type is 117 /// valid for the library function matching that name. 118 /// 119 /// If it is one of the known library functions, return true and set F to the 120 /// corresponding value. 121 /// 122 /// FDecl is assumed to have a parent Module when using this function. 123 bool getLibFunc(const Function &FDecl, LibFunc &F) const; 124 125 /// Forces a function to be marked as unavailable. setUnavailable(LibFunc F)126 void setUnavailable(LibFunc F) { 127 setState(F, Unavailable); 128 } 129 130 /// Forces a function to be marked as available. setAvailable(LibFunc F)131 void setAvailable(LibFunc F) { 132 setState(F, StandardName); 133 } 134 135 /// Forces a function to be marked as available and provide an alternate name 136 /// that must be used. setAvailableWithName(LibFunc F,StringRef Name)137 void setAvailableWithName(LibFunc F, StringRef Name) { 138 if (StandardNames[F] != Name) { 139 setState(F, CustomName); 140 CustomNames[F] = std::string(Name); 141 assert(CustomNames.find(F) != CustomNames.end()); 142 } else { 143 setState(F, StandardName); 144 } 145 } 146 147 /// Disables all builtins. 148 /// 149 /// This can be used for options like -fno-builtin. 150 void disableAllFunctions(); 151 152 /// Add a set of scalar -> vector mappings, queryable via 153 /// getVectorizedFunction and getScalarizedFunction. 154 void addVectorizableFunctions(ArrayRef<VecDesc> Fns); 155 156 /// Calls addVectorizableFunctions with a known preset of functions for the 157 /// given vector library. 158 void addVectorizableFunctionsFromVecLib(enum VectorLibrary VecLib, 159 const llvm::Triple &TargetTriple); 160 161 /// Return true if the function F has a vector equivalent with vectorization 162 /// factor VF. isFunctionVectorizable(StringRef F,const ElementCount & VF)163 bool isFunctionVectorizable(StringRef F, const ElementCount &VF) const { 164 return !getVectorizedFunction(F, VF).empty(); 165 } 166 167 /// Return true if the function F has a vector equivalent with any 168 /// vectorization factor. 169 bool isFunctionVectorizable(StringRef F) const; 170 171 /// Return the name of the equivalent of F, vectorized with factor VF. If no 172 /// such mapping exists, return the empty string. 173 StringRef getVectorizedFunction(StringRef F, const ElementCount &VF) const; 174 175 /// Set to true iff i32 parameters to library functions should have signext 176 /// or zeroext attributes if they correspond to C-level int or unsigned int, 177 /// respectively. setShouldExtI32Param(bool Val)178 void setShouldExtI32Param(bool Val) { 179 ShouldExtI32Param = Val; 180 } 181 182 /// Set to true iff i32 results from library functions should have signext 183 /// or zeroext attributes if they correspond to C-level int or unsigned int, 184 /// respectively. setShouldExtI32Return(bool Val)185 void setShouldExtI32Return(bool Val) { 186 ShouldExtI32Return = Val; 187 } 188 189 /// Set to true iff i32 parameters to library functions should have signext 190 /// attribute if they correspond to C-level int or unsigned int. setShouldSignExtI32Param(bool Val)191 void setShouldSignExtI32Param(bool Val) { 192 ShouldSignExtI32Param = Val; 193 } 194 195 /// Set to true iff i32 results from library functions should have signext 196 /// attribute if they correspond to C-level int or unsigned int. setShouldSignExtI32Return(bool Val)197 void setShouldSignExtI32Return(bool Val) { 198 ShouldSignExtI32Return = Val; 199 } 200 201 /// Returns the size of the wchar_t type in bytes or 0 if the size is unknown. 202 /// This queries the 'wchar_size' metadata. 203 unsigned getWCharSize(const Module &M) const; 204 205 /// Returns the size of the size_t type in bits. 206 unsigned getSizeTSize(const Module &M) const; 207 208 /// Get size of a C-level int or unsigned int, in bits. getIntSize()209 unsigned getIntSize() const { 210 return SizeOfInt; 211 } 212 213 /// Initialize the C-level size of an integer. setIntSize(unsigned Bits)214 void setIntSize(unsigned Bits) { 215 SizeOfInt = Bits; 216 } 217 218 /// Returns the largest vectorization factor used in the list of 219 /// vector functions. 220 void getWidestVF(StringRef ScalarF, ElementCount &FixedVF, 221 ElementCount &Scalable) const; 222 223 /// Returns true if call site / callee has cdecl-compatible calling 224 /// conventions. 225 static bool isCallingConvCCompatible(CallBase *CI); 226 static bool isCallingConvCCompatible(Function *Callee); 227 }; 228 229 /// Provides information about what library functions are available for 230 /// the current target. 231 /// 232 /// This both allows optimizations to handle them specially and frontends to 233 /// disable such optimizations through -fno-builtin etc. 234 class TargetLibraryInfo { 235 friend class TargetLibraryAnalysis; 236 friend class TargetLibraryInfoWrapperPass; 237 238 /// The global (module level) TLI info. 239 const TargetLibraryInfoImpl *Impl; 240 241 /// Support for -fno-builtin* options as function attributes, overrides 242 /// information in global TargetLibraryInfoImpl. 243 BitVector OverrideAsUnavailable; 244 245 public: 246 explicit TargetLibraryInfo(const TargetLibraryInfoImpl &Impl, 247 std::optional<const Function *> F = std::nullopt) 248 : Impl(&Impl), OverrideAsUnavailable(NumLibFuncs) { 249 if (!F) 250 return; 251 if ((*F)->hasFnAttribute("no-builtins")) 252 disableAllFunctions(); 253 else { 254 // Disable individual libc/libm calls in TargetLibraryInfo. 255 LibFunc LF; 256 AttributeSet FnAttrs = (*F)->getAttributes().getFnAttrs(); 257 for (const Attribute &Attr : FnAttrs) { 258 if (!Attr.isStringAttribute()) 259 continue; 260 auto AttrStr = Attr.getKindAsString(); 261 if (!AttrStr.consume_front("no-builtin-")) 262 continue; 263 if (getLibFunc(AttrStr, LF)) 264 setUnavailable(LF); 265 } 266 } 267 } 268 269 // Provide value semantics. 270 TargetLibraryInfo(const TargetLibraryInfo &TLI) = default; TargetLibraryInfo(TargetLibraryInfo && TLI)271 TargetLibraryInfo(TargetLibraryInfo &&TLI) 272 : Impl(TLI.Impl), OverrideAsUnavailable(TLI.OverrideAsUnavailable) {} 273 TargetLibraryInfo &operator=(const TargetLibraryInfo &TLI) = default; 274 TargetLibraryInfo &operator=(TargetLibraryInfo &&TLI) { 275 Impl = TLI.Impl; 276 OverrideAsUnavailable = TLI.OverrideAsUnavailable; 277 return *this; 278 } 279 280 /// Determine whether a callee with the given TLI can be inlined into 281 /// caller with this TLI, based on 'nobuiltin' attributes. When requested, 282 /// allow inlining into a caller with a superset of the callee's nobuiltin 283 /// attributes, which is conservatively correct. areInlineCompatible(const TargetLibraryInfo & CalleeTLI,bool AllowCallerSuperset)284 bool areInlineCompatible(const TargetLibraryInfo &CalleeTLI, 285 bool AllowCallerSuperset) const { 286 if (!AllowCallerSuperset) 287 return OverrideAsUnavailable == CalleeTLI.OverrideAsUnavailable; 288 BitVector B = OverrideAsUnavailable; 289 B |= CalleeTLI.OverrideAsUnavailable; 290 // We can inline if the union of the caller and callee's nobuiltin 291 // attributes is no stricter than the caller's nobuiltin attributes. 292 return B == OverrideAsUnavailable; 293 } 294 295 /// Return true if the function type FTy is valid for the library function 296 /// F, regardless of whether the function is available. isValidProtoForLibFunc(const FunctionType & FTy,LibFunc F,const Module & M)297 bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc F, 298 const Module &M) const { 299 return Impl->isValidProtoForLibFunc(FTy, F, M); 300 } 301 302 /// Searches for a particular function name. 303 /// 304 /// If it is one of the known library functions, return true and set F to the 305 /// corresponding value. getLibFunc(StringRef funcName,LibFunc & F)306 bool getLibFunc(StringRef funcName, LibFunc &F) const { 307 return Impl->getLibFunc(funcName, F); 308 } 309 getLibFunc(const Function & FDecl,LibFunc & F)310 bool getLibFunc(const Function &FDecl, LibFunc &F) const { 311 return Impl->getLibFunc(FDecl, F); 312 } 313 314 /// If a callbase does not have the 'nobuiltin' attribute, return if the 315 /// called function is a known library function and set F to that function. getLibFunc(const CallBase & CB,LibFunc & F)316 bool getLibFunc(const CallBase &CB, LibFunc &F) const { 317 return !CB.isNoBuiltin() && CB.getCalledFunction() && 318 getLibFunc(*(CB.getCalledFunction()), F); 319 } 320 321 /// Disables all builtins. 322 /// 323 /// This can be used for options like -fno-builtin. disableAllFunctions()324 void disableAllFunctions() LLVM_ATTRIBUTE_UNUSED { 325 OverrideAsUnavailable.set(); 326 } 327 328 /// Forces a function to be marked as unavailable. setUnavailable(LibFunc F)329 void setUnavailable(LibFunc F) LLVM_ATTRIBUTE_UNUSED { 330 OverrideAsUnavailable.set(F); 331 } 332 getState(LibFunc F)333 TargetLibraryInfoImpl::AvailabilityState getState(LibFunc F) const { 334 if (OverrideAsUnavailable[F]) 335 return TargetLibraryInfoImpl::Unavailable; 336 return Impl->getState(F); 337 } 338 339 /// Tests whether a library function is available. has(LibFunc F)340 bool has(LibFunc F) const { 341 return getState(F) != TargetLibraryInfoImpl::Unavailable; 342 } isFunctionVectorizable(StringRef F,const ElementCount & VF)343 bool isFunctionVectorizable(StringRef F, const ElementCount &VF) const { 344 return Impl->isFunctionVectorizable(F, VF); 345 } isFunctionVectorizable(StringRef F)346 bool isFunctionVectorizable(StringRef F) const { 347 return Impl->isFunctionVectorizable(F); 348 } getVectorizedFunction(StringRef F,const ElementCount & VF)349 StringRef getVectorizedFunction(StringRef F, const ElementCount &VF) const { 350 return Impl->getVectorizedFunction(F, VF); 351 } 352 353 /// Tests if the function is both available and a candidate for optimized code 354 /// generation. hasOptimizedCodeGen(LibFunc F)355 bool hasOptimizedCodeGen(LibFunc F) const { 356 if (getState(F) == TargetLibraryInfoImpl::Unavailable) 357 return false; 358 switch (F) { 359 default: break; 360 case LibFunc_copysign: case LibFunc_copysignf: case LibFunc_copysignl: 361 case LibFunc_fabs: case LibFunc_fabsf: case LibFunc_fabsl: 362 case LibFunc_sin: case LibFunc_sinf: case LibFunc_sinl: 363 case LibFunc_cos: case LibFunc_cosf: case LibFunc_cosl: 364 case LibFunc_sqrt: case LibFunc_sqrtf: case LibFunc_sqrtl: 365 case LibFunc_sqrt_finite: case LibFunc_sqrtf_finite: 366 case LibFunc_sqrtl_finite: 367 case LibFunc_fmax: case LibFunc_fmaxf: case LibFunc_fmaxl: 368 case LibFunc_fmin: case LibFunc_fminf: case LibFunc_fminl: 369 case LibFunc_floor: case LibFunc_floorf: case LibFunc_floorl: 370 case LibFunc_nearbyint: case LibFunc_nearbyintf: case LibFunc_nearbyintl: 371 case LibFunc_ceil: case LibFunc_ceilf: case LibFunc_ceill: 372 case LibFunc_rint: case LibFunc_rintf: case LibFunc_rintl: 373 case LibFunc_round: case LibFunc_roundf: case LibFunc_roundl: 374 case LibFunc_trunc: case LibFunc_truncf: case LibFunc_truncl: 375 case LibFunc_log2: case LibFunc_log2f: case LibFunc_log2l: 376 case LibFunc_exp2: case LibFunc_exp2f: case LibFunc_exp2l: 377 case LibFunc_memcpy: case LibFunc_memset: case LibFunc_memmove: 378 case LibFunc_memcmp: case LibFunc_bcmp: case LibFunc_strcmp: 379 case LibFunc_strcpy: case LibFunc_stpcpy: case LibFunc_strlen: 380 case LibFunc_strnlen: case LibFunc_memchr: case LibFunc_mempcpy: 381 return true; 382 } 383 return false; 384 } 385 getName(LibFunc F)386 StringRef getName(LibFunc F) const { 387 auto State = getState(F); 388 if (State == TargetLibraryInfoImpl::Unavailable) 389 return StringRef(); 390 if (State == TargetLibraryInfoImpl::StandardName) 391 return Impl->StandardNames[F]; 392 assert(State == TargetLibraryInfoImpl::CustomName); 393 return Impl->CustomNames.find(F)->second; 394 } 395 initExtensionsForTriple(bool & ShouldExtI32Param,bool & ShouldExtI32Return,bool & ShouldSignExtI32Param,bool & ShouldSignExtI32Return,const Triple & T)396 static void initExtensionsForTriple(bool &ShouldExtI32Param, 397 bool &ShouldExtI32Return, 398 bool &ShouldSignExtI32Param, 399 bool &ShouldSignExtI32Return, 400 const Triple &T) { 401 ShouldExtI32Param = ShouldExtI32Return = false; 402 ShouldSignExtI32Param = ShouldSignExtI32Return = false; 403 404 // PowerPC64, Sparc64, SystemZ need signext/zeroext on i32 parameters and 405 // returns corresponding to C-level ints and unsigned ints. 406 if (T.isPPC64() || T.getArch() == Triple::sparcv9 || 407 T.getArch() == Triple::systemz) { 408 ShouldExtI32Param = true; 409 ShouldExtI32Return = true; 410 } 411 // LoongArch, Mips, and riscv64, on the other hand, need signext on i32 412 // parameters corresponding to both signed and unsigned ints. 413 if (T.isLoongArch() || T.isMIPS() || T.isRISCV64()) { 414 ShouldSignExtI32Param = true; 415 } 416 // LoongArch and riscv64 need signext on i32 returns corresponding to both 417 // signed and unsigned ints. 418 if (T.isLoongArch() || T.isRISCV64()) { 419 ShouldSignExtI32Return = true; 420 } 421 } 422 423 /// Returns extension attribute kind to be used for i32 parameters 424 /// corresponding to C-level int or unsigned int. May be zeroext, signext, 425 /// or none. 426 private: 427 static Attribute::AttrKind getExtAttrForI32Param(bool ShouldExtI32Param_, 428 bool ShouldSignExtI32Param_, 429 bool Signed = true) { 430 if (ShouldExtI32Param_) 431 return Signed ? Attribute::SExt : Attribute::ZExt; 432 if (ShouldSignExtI32Param_) 433 return Attribute::SExt; 434 return Attribute::None; 435 } 436 437 public: 438 static Attribute::AttrKind getExtAttrForI32Param(const Triple &T, 439 bool Signed = true) { 440 bool ShouldExtI32Param, ShouldExtI32Return; 441 bool ShouldSignExtI32Param, ShouldSignExtI32Return; 442 initExtensionsForTriple(ShouldExtI32Param, ShouldExtI32Return, 443 ShouldSignExtI32Param, ShouldSignExtI32Return, T); 444 return getExtAttrForI32Param(ShouldExtI32Param, ShouldSignExtI32Param, 445 Signed); 446 } 447 448 Attribute::AttrKind getExtAttrForI32Param(bool Signed = true) const { 449 return getExtAttrForI32Param(Impl->ShouldExtI32Param, 450 Impl->ShouldSignExtI32Param, Signed); 451 } 452 453 /// Returns extension attribute kind to be used for i32 return values 454 /// corresponding to C-level int or unsigned int. May be zeroext, signext, 455 /// or none. 456 private: getExtAttrForI32Return(bool ShouldExtI32Return_,bool ShouldSignExtI32Return_,bool Signed)457 static Attribute::AttrKind getExtAttrForI32Return(bool ShouldExtI32Return_, 458 bool ShouldSignExtI32Return_, 459 bool Signed) { 460 if (ShouldExtI32Return_) 461 return Signed ? Attribute::SExt : Attribute::ZExt; 462 if (ShouldSignExtI32Return_) 463 return Attribute::SExt; 464 return Attribute::None; 465 } 466 467 public: 468 static Attribute::AttrKind getExtAttrForI32Return(const Triple &T, 469 bool Signed = true) { 470 bool ShouldExtI32Param, ShouldExtI32Return; 471 bool ShouldSignExtI32Param, ShouldSignExtI32Return; 472 initExtensionsForTriple(ShouldExtI32Param, ShouldExtI32Return, 473 ShouldSignExtI32Param, ShouldSignExtI32Return, T); 474 return getExtAttrForI32Return(ShouldExtI32Return, ShouldSignExtI32Return, 475 Signed); 476 } 477 478 Attribute::AttrKind getExtAttrForI32Return(bool Signed = true) const { 479 return getExtAttrForI32Return(Impl->ShouldExtI32Return, 480 Impl->ShouldSignExtI32Return, Signed); 481 } 482 483 // Helper to create an AttributeList for args (and ret val) which all have 484 // the same signedness. Attributes in AL may be passed in to include them 485 // as well in the returned AttributeList. 486 AttributeList getAttrList(LLVMContext *C, ArrayRef<unsigned> ArgNos, 487 bool Signed, bool Ret = false, 488 AttributeList AL = AttributeList()) const { 489 if (auto AK = getExtAttrForI32Param(Signed)) 490 for (auto ArgNo : ArgNos) 491 AL = AL.addParamAttribute(*C, ArgNo, AK); 492 if (Ret) 493 if (auto AK = getExtAttrForI32Return(Signed)) 494 AL = AL.addRetAttribute(*C, AK); 495 return AL; 496 } 497 498 /// \copydoc TargetLibraryInfoImpl::getWCharSize() getWCharSize(const Module & M)499 unsigned getWCharSize(const Module &M) const { 500 return Impl->getWCharSize(M); 501 } 502 503 /// \copydoc TargetLibraryInfoImpl::getSizeTSize() getSizeTSize(const Module & M)504 unsigned getSizeTSize(const Module &M) const { return Impl->getSizeTSize(M); } 505 506 /// \copydoc TargetLibraryInfoImpl::getIntSize() getIntSize()507 unsigned getIntSize() const { 508 return Impl->getIntSize(); 509 } 510 511 /// Handle invalidation from the pass manager. 512 /// 513 /// If we try to invalidate this info, just return false. It cannot become 514 /// invalid even if the module or function changes. invalidate(Module &,const PreservedAnalyses &,ModuleAnalysisManager::Invalidator &)515 bool invalidate(Module &, const PreservedAnalyses &, 516 ModuleAnalysisManager::Invalidator &) { 517 return false; 518 } invalidate(Function &,const PreservedAnalyses &,FunctionAnalysisManager::Invalidator &)519 bool invalidate(Function &, const PreservedAnalyses &, 520 FunctionAnalysisManager::Invalidator &) { 521 return false; 522 } 523 /// Returns the largest vectorization factor used in the list of 524 /// vector functions. getWidestVF(StringRef ScalarF,ElementCount & FixedVF,ElementCount & ScalableVF)525 void getWidestVF(StringRef ScalarF, ElementCount &FixedVF, 526 ElementCount &ScalableVF) const { 527 Impl->getWidestVF(ScalarF, FixedVF, ScalableVF); 528 } 529 530 /// Check if the function "F" is listed in a library known to LLVM. isKnownVectorFunctionInLibrary(StringRef F)531 bool isKnownVectorFunctionInLibrary(StringRef F) const { 532 return this->isFunctionVectorizable(F); 533 } 534 }; 535 536 /// Analysis pass providing the \c TargetLibraryInfo. 537 /// 538 /// Note that this pass's result cannot be invalidated, it is immutable for the 539 /// life of the module. 540 class TargetLibraryAnalysis : public AnalysisInfoMixin<TargetLibraryAnalysis> { 541 public: 542 typedef TargetLibraryInfo Result; 543 544 /// Default construct the library analysis. 545 /// 546 /// This will use the module's triple to construct the library info for that 547 /// module. 548 TargetLibraryAnalysis() = default; 549 550 /// Construct a library analysis with baseline Module-level info. 551 /// 552 /// This will be supplemented with Function-specific info in the Result. TargetLibraryAnalysis(TargetLibraryInfoImpl BaselineInfoImpl)553 TargetLibraryAnalysis(TargetLibraryInfoImpl BaselineInfoImpl) 554 : BaselineInfoImpl(std::move(BaselineInfoImpl)) {} 555 556 TargetLibraryInfo run(const Function &F, FunctionAnalysisManager &); 557 558 private: 559 friend AnalysisInfoMixin<TargetLibraryAnalysis>; 560 static AnalysisKey Key; 561 562 std::optional<TargetLibraryInfoImpl> BaselineInfoImpl; 563 }; 564 565 class TargetLibraryInfoWrapperPass : public ImmutablePass { 566 TargetLibraryAnalysis TLA; 567 std::optional<TargetLibraryInfo> TLI; 568 569 virtual void anchor(); 570 571 public: 572 static char ID; 573 TargetLibraryInfoWrapperPass(); 574 explicit TargetLibraryInfoWrapperPass(const Triple &T); 575 explicit TargetLibraryInfoWrapperPass(const TargetLibraryInfoImpl &TLI); 576 getTLI(const Function & F)577 TargetLibraryInfo &getTLI(const Function &F) { 578 FunctionAnalysisManager DummyFAM; 579 TLI = TLA.run(F, DummyFAM); 580 return *TLI; 581 } 582 }; 583 584 } // end namespace llvm 585 586 #endif 587