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