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   };
64   void setState(LibFunc F, AvailabilityState State) {
65     AvailableArray[F/4] &= ~(3 << 2*(F&3));
66     AvailableArray[F/4] |= State << 2*(F&3);
67   }
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.
126   void setUnavailable(LibFunc F) {
127     setState(F, Unavailable);
128   }
129 
130   /// Forces a function to be marked as available.
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.
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.
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.
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.
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.
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.
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.
209   unsigned getIntSize() const {
210     return SizeOfInt;
211   }
212 
213   /// Initialize the C-level size of an integer.
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;
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.
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.
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.
306   bool getLibFunc(StringRef funcName, LibFunc &F) const {
307     return Impl->getLibFunc(funcName, F);
308   }
309 
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.
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.
324   void disableAllFunctions() LLVM_ATTRIBUTE_UNUSED {
325     OverrideAsUnavailable.set();
326   }
327 
328   /// Forces a function to be marked as unavailable.
329   void setUnavailable(LibFunc F) LLVM_ATTRIBUTE_UNUSED {
330     OverrideAsUnavailable.set(F);
331   }
332 
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.
340   bool has(LibFunc F) const {
341     return getState(F) != TargetLibraryInfoImpl::Unavailable;
342   }
343   bool isFunctionVectorizable(StringRef F, const ElementCount &VF) const {
344     return Impl->isFunctionVectorizable(F, VF);
345   }
346   bool isFunctionVectorizable(StringRef F) const {
347     return Impl->isFunctionVectorizable(F);
348   }
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.
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 
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 
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:
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()
499   unsigned getWCharSize(const Module &M) const {
500     return Impl->getWCharSize(M);
501   }
502 
503   /// \copydoc TargetLibraryInfoImpl::getSizeTSize()
504   unsigned getSizeTSize(const Module &M) const { return Impl->getSizeTSize(M); }
505 
506   /// \copydoc TargetLibraryInfoImpl::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.
515   bool invalidate(Module &, const PreservedAnalyses &,
516                   ModuleAnalysisManager::Invalidator &) {
517     return false;
518   }
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.
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.
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.
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 
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