xref: /aosp_15_r20/external/llvm/include/llvm/Analysis/TargetLibraryInfo.h (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1 //===-- TargetLibraryInfo.h - Library information ---------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef LLVM_ANALYSIS_TARGETLIBRARYINFO_H
11 #define LLVM_ANALYSIS_TARGETLIBRARYINFO_H
12 
13 #include "llvm/ADT/DenseMap.h"
14 #include "llvm/ADT/Optional.h"
15 #include "llvm/ADT/Triple.h"
16 #include "llvm/IR/Function.h"
17 #include "llvm/IR/Module.h"
18 #include "llvm/IR/PassManager.h"
19 #include "llvm/Pass.h"
20 
21 // BEGIN ANDROID-SPECIFIC
22 #ifdef _WIN32
23 #ifdef fseeko
24 #undef fseeko
25 #endif
26 #ifdef ftello
27 #undef ftello
28 #endif
29 #endif  // _WIN32
30 
31 #ifdef ANDROID_HOST_MUSL
32 # ifdef fopen64
33 #  undef fopen64
34 # endif
35 # ifdef fseeko64
36 #  undef fseeko64
37 # endif
38 # ifdef ftello64
39 #  undef ftello64
40 # endif
41 # ifdef tmpfile64
42 #  undef tmpfile64
43 # endif
44 #endif
45 // END ANDROID-SPECIFIC
46 
47 namespace llvm {
48 template <typename T> class ArrayRef;
49 
50 /// Describes a possible vectorization of a function.
51 /// Function 'VectorFnName' is equivalent to 'ScalarFnName' vectorized
52 /// by a factor 'VectorizationFactor'.
53 struct VecDesc {
54   const char *ScalarFnName;
55   const char *VectorFnName;
56   unsigned VectorizationFactor;
57 };
58 
59   namespace LibFunc {
60     enum Func {
61 #define TLI_DEFINE_ENUM
62 #include "llvm/Analysis/TargetLibraryInfo.def"
63 
64       NumLibFuncs
65     };
66   }
67 
68 /// Implementation of the target library information.
69 ///
70 /// This class constructs tables that hold the target library information and
71 /// make it available. However, it is somewhat expensive to compute and only
72 /// depends on the triple. So users typically interact with the \c
73 /// TargetLibraryInfo wrapper below.
74 class TargetLibraryInfoImpl {
75   friend class TargetLibraryInfo;
76 
77   unsigned char AvailableArray[(LibFunc::NumLibFuncs+3)/4];
78   llvm::DenseMap<unsigned, std::string> CustomNames;
79   static const char *const StandardNames[LibFunc::NumLibFuncs];
80 
81   enum AvailabilityState {
82     StandardName = 3, // (memset to all ones)
83     CustomName = 1,
84     Unavailable = 0  // (memset to all zeros)
85   };
setState(LibFunc::Func F,AvailabilityState State)86   void setState(LibFunc::Func F, AvailabilityState State) {
87     AvailableArray[F/4] &= ~(3 << 2*(F&3));
88     AvailableArray[F/4] |= State << 2*(F&3);
89   }
getState(LibFunc::Func F)90   AvailabilityState getState(LibFunc::Func F) const {
91     return static_cast<AvailabilityState>((AvailableArray[F/4] >> 2*(F&3)) & 3);
92   }
93 
94   /// Vectorization descriptors - sorted by ScalarFnName.
95   std::vector<VecDesc> VectorDescs;
96   /// Scalarization descriptors - same content as VectorDescs but sorted based
97   /// on VectorFnName rather than ScalarFnName.
98   std::vector<VecDesc> ScalarDescs;
99 
100   /// Return true if the function type FTy is valid for the library function
101   /// F, regardless of whether the function is available.
102   bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc::Func F,
103                               const DataLayout *DL) const;
104 
105 public:
106   /// List of known vector-functions libraries.
107   ///
108   /// The vector-functions library defines, which functions are vectorizable
109   /// and with which factor. The library can be specified by either frontend,
110   /// or a commandline option, and then used by
111   /// addVectorizableFunctionsFromVecLib for filling up the tables of
112   /// vectorizable functions.
113   enum VectorLibrary {
114     NoLibrary, // Don't use any vector library.
115     Accelerate // Use Accelerate framework.
116   };
117 
118   TargetLibraryInfoImpl();
119   explicit TargetLibraryInfoImpl(const Triple &T);
120 
121   // Provide value semantics.
122   TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI);
123   TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI);
124   TargetLibraryInfoImpl &operator=(const TargetLibraryInfoImpl &TLI);
125   TargetLibraryInfoImpl &operator=(TargetLibraryInfoImpl &&TLI);
126 
127   /// Searches for a particular function name.
128   ///
129   /// If it is one of the known library functions, return true and set F to the
130   /// corresponding value.
131   bool getLibFunc(StringRef funcName, LibFunc::Func &F) const;
132 
133   /// Searches for a particular function name, also checking that its type is
134   /// valid for the library function matching that name.
135   ///
136   /// If it is one of the known library functions, return true and set F to the
137   /// corresponding value.
138   bool getLibFunc(const Function &FDecl, LibFunc::Func &F) const;
139 
140   /// Forces a function to be marked as unavailable.
setUnavailable(LibFunc::Func F)141   void setUnavailable(LibFunc::Func F) {
142     setState(F, Unavailable);
143   }
144 
145   /// Forces a function to be marked as available.
setAvailable(LibFunc::Func F)146   void setAvailable(LibFunc::Func F) {
147     setState(F, StandardName);
148   }
149 
150   /// Forces a function to be marked as available and provide an alternate name
151   /// that must be used.
setAvailableWithName(LibFunc::Func F,StringRef Name)152   void setAvailableWithName(LibFunc::Func F, StringRef Name) {
153     if (StandardNames[F] != Name) {
154       setState(F, CustomName);
155       CustomNames[F] = Name;
156       assert(CustomNames.find(F) != CustomNames.end());
157     } else {
158       setState(F, StandardName);
159     }
160   }
161 
162   /// Disables all builtins.
163   ///
164   /// This can be used for options like -fno-builtin.
165   void disableAllFunctions();
166 
167   /// Add a set of scalar -> vector mappings, queryable via
168   /// getVectorizedFunction and getScalarizedFunction.
169   void addVectorizableFunctions(ArrayRef<VecDesc> Fns);
170 
171   /// Calls addVectorizableFunctions with a known preset of functions for the
172   /// given vector library.
173   void addVectorizableFunctionsFromVecLib(enum VectorLibrary VecLib);
174 
175   /// Return true if the function F has a vector equivalent with vectorization
176   /// factor VF.
isFunctionVectorizable(StringRef F,unsigned VF)177   bool isFunctionVectorizable(StringRef F, unsigned VF) const {
178     return !getVectorizedFunction(F, VF).empty();
179   }
180 
181   /// Return true if the function F has a vector equivalent with any
182   /// vectorization factor.
183   bool isFunctionVectorizable(StringRef F) const;
184 
185   /// Return the name of the equivalent of F, vectorized with factor VF. If no
186   /// such mapping exists, return the empty string.
187   StringRef getVectorizedFunction(StringRef F, unsigned VF) const;
188 
189   /// Return true if the function F has a scalar equivalent, and set VF to be
190   /// the vectorization factor.
isFunctionScalarizable(StringRef F,unsigned & VF)191   bool isFunctionScalarizable(StringRef F, unsigned &VF) const {
192     return !getScalarizedFunction(F, VF).empty();
193   }
194 
195   /// Return the name of the equivalent of F, scalarized. If no such mapping
196   /// exists, return the empty string.
197   ///
198   /// Set VF to the vectorization factor.
199   StringRef getScalarizedFunction(StringRef F, unsigned &VF) const;
200 };
201 
202 /// Provides information about what library functions are available for
203 /// the current target.
204 ///
205 /// This both allows optimizations to handle them specially and frontends to
206 /// disable such optimizations through -fno-builtin etc.
207 class TargetLibraryInfo {
208   friend class TargetLibraryAnalysis;
209   friend class TargetLibraryInfoWrapperPass;
210 
211   const TargetLibraryInfoImpl *Impl;
212 
213 public:
TargetLibraryInfo(const TargetLibraryInfoImpl & Impl)214   explicit TargetLibraryInfo(const TargetLibraryInfoImpl &Impl) : Impl(&Impl) {}
215 
216   // Provide value semantics.
TargetLibraryInfo(const TargetLibraryInfo & TLI)217   TargetLibraryInfo(const TargetLibraryInfo &TLI) : Impl(TLI.Impl) {}
TargetLibraryInfo(TargetLibraryInfo && TLI)218   TargetLibraryInfo(TargetLibraryInfo &&TLI) : Impl(TLI.Impl) {}
219   TargetLibraryInfo &operator=(const TargetLibraryInfo &TLI) {
220     Impl = TLI.Impl;
221     return *this;
222   }
223   TargetLibraryInfo &operator=(TargetLibraryInfo &&TLI) {
224     Impl = TLI.Impl;
225     return *this;
226   }
227 
228   /// Searches for a particular function name.
229   ///
230   /// If it is one of the known library functions, return true and set F to the
231   /// corresponding value.
getLibFunc(StringRef funcName,LibFunc::Func & F)232   bool getLibFunc(StringRef funcName, LibFunc::Func &F) const {
233     return Impl->getLibFunc(funcName, F);
234   }
235 
getLibFunc(const Function & FDecl,LibFunc::Func & F)236   bool getLibFunc(const Function &FDecl, LibFunc::Func &F) const {
237     return Impl->getLibFunc(FDecl, F);
238   }
239 
240   /// Tests whether a library function is available.
has(LibFunc::Func F)241   bool has(LibFunc::Func F) const {
242     return Impl->getState(F) != TargetLibraryInfoImpl::Unavailable;
243   }
isFunctionVectorizable(StringRef F,unsigned VF)244   bool isFunctionVectorizable(StringRef F, unsigned VF) const {
245     return Impl->isFunctionVectorizable(F, VF);
246   }
isFunctionVectorizable(StringRef F)247   bool isFunctionVectorizable(StringRef F) const {
248     return Impl->isFunctionVectorizable(F);
249   }
getVectorizedFunction(StringRef F,unsigned VF)250   StringRef getVectorizedFunction(StringRef F, unsigned VF) const {
251     return Impl->getVectorizedFunction(F, VF);
252   }
253 
254   /// Tests if the function is both available and a candidate for optimized code
255   /// generation.
hasOptimizedCodeGen(LibFunc::Func F)256   bool hasOptimizedCodeGen(LibFunc::Func F) const {
257     if (Impl->getState(F) == TargetLibraryInfoImpl::Unavailable)
258       return false;
259     switch (F) {
260     default: break;
261     case LibFunc::copysign:  case LibFunc::copysignf:  case LibFunc::copysignl:
262     case LibFunc::fabs:      case LibFunc::fabsf:      case LibFunc::fabsl:
263     case LibFunc::sin:       case LibFunc::sinf:       case LibFunc::sinl:
264     case LibFunc::cos:       case LibFunc::cosf:       case LibFunc::cosl:
265     case LibFunc::sqrt:      case LibFunc::sqrtf:      case LibFunc::sqrtl:
266     case LibFunc::sqrt_finite: case LibFunc::sqrtf_finite:
267                                                   case LibFunc::sqrtl_finite:
268     case LibFunc::fmax:      case LibFunc::fmaxf:      case LibFunc::fmaxl:
269     case LibFunc::fmin:      case LibFunc::fminf:      case LibFunc::fminl:
270     case LibFunc::floor:     case LibFunc::floorf:     case LibFunc::floorl:
271     case LibFunc::nearbyint: case LibFunc::nearbyintf: case LibFunc::nearbyintl:
272     case LibFunc::ceil:      case LibFunc::ceilf:      case LibFunc::ceill:
273     case LibFunc::rint:      case LibFunc::rintf:      case LibFunc::rintl:
274     case LibFunc::round:     case LibFunc::roundf:     case LibFunc::roundl:
275     case LibFunc::trunc:     case LibFunc::truncf:     case LibFunc::truncl:
276     case LibFunc::log2:      case LibFunc::log2f:      case LibFunc::log2l:
277     case LibFunc::exp2:      case LibFunc::exp2f:      case LibFunc::exp2l:
278     case LibFunc::memcmp:    case LibFunc::strcmp:     case LibFunc::strcpy:
279     case LibFunc::stpcpy:    case LibFunc::strlen:     case LibFunc::strnlen:
280     case LibFunc::memchr:
281       return true;
282     }
283     return false;
284   }
285 
getName(LibFunc::Func F)286   StringRef getName(LibFunc::Func F) const {
287     auto State = Impl->getState(F);
288     if (State == TargetLibraryInfoImpl::Unavailable)
289       return StringRef();
290     if (State == TargetLibraryInfoImpl::StandardName)
291       return Impl->StandardNames[F];
292     assert(State == TargetLibraryInfoImpl::CustomName);
293     return Impl->CustomNames.find(F)->second;
294   }
295 
296   /// Handle invalidation from the pass manager.
297   ///
298   /// If we try to invalidate this info, just return false. It cannot become
299   /// invalid even if the module changes.
invalidate(Module &,const PreservedAnalyses &)300   bool invalidate(Module &, const PreservedAnalyses &) { return false; }
301 };
302 
303 /// Analysis pass providing the \c TargetLibraryInfo.
304 ///
305 /// Note that this pass's result cannot be invalidated, it is immutable for the
306 /// life of the module.
307 class TargetLibraryAnalysis : public AnalysisInfoMixin<TargetLibraryAnalysis> {
308 public:
309   typedef TargetLibraryInfo Result;
310 
311   /// Default construct the library analysis.
312   ///
313   /// This will use the module's triple to construct the library info for that
314   /// module.
TargetLibraryAnalysis()315   TargetLibraryAnalysis() {}
316 
317   /// Construct a library analysis with preset info.
318   ///
319   /// This will directly copy the preset info into the result without
320   /// consulting the module's triple.
TargetLibraryAnalysis(TargetLibraryInfoImpl PresetInfoImpl)321   TargetLibraryAnalysis(TargetLibraryInfoImpl PresetInfoImpl)
322       : PresetInfoImpl(std::move(PresetInfoImpl)) {}
323 
324   // Move semantics. We spell out the constructors for MSVC.
TargetLibraryAnalysis(TargetLibraryAnalysis && Arg)325   TargetLibraryAnalysis(TargetLibraryAnalysis &&Arg)
326       : PresetInfoImpl(std::move(Arg.PresetInfoImpl)), Impls(std::move(Arg.Impls)) {}
327   TargetLibraryAnalysis &operator=(TargetLibraryAnalysis &&RHS) {
328     PresetInfoImpl = std::move(RHS.PresetInfoImpl);
329     Impls = std::move(RHS.Impls);
330     return *this;
331   }
332 
333   TargetLibraryInfo run(Module &M, ModuleAnalysisManager &);
334   TargetLibraryInfo run(Function &F, FunctionAnalysisManager &);
335 
336 private:
337   friend AnalysisInfoMixin<TargetLibraryAnalysis>;
338   static char PassID;
339 
340   Optional<TargetLibraryInfoImpl> PresetInfoImpl;
341 
342   StringMap<std::unique_ptr<TargetLibraryInfoImpl>> Impls;
343 
344   TargetLibraryInfoImpl &lookupInfoImpl(const Triple &T);
345 };
346 
347 class TargetLibraryInfoWrapperPass : public ImmutablePass {
348   TargetLibraryInfoImpl TLIImpl;
349   TargetLibraryInfo TLI;
350 
351   virtual void anchor();
352 
353 public:
354   static char ID;
355   TargetLibraryInfoWrapperPass();
356   explicit TargetLibraryInfoWrapperPass(const Triple &T);
357   explicit TargetLibraryInfoWrapperPass(const TargetLibraryInfoImpl &TLI);
358 
getTLI()359   TargetLibraryInfo &getTLI() { return TLI; }
getTLI()360   const TargetLibraryInfo &getTLI() const { return TLI; }
361 };
362 
363 } // end namespace llvm
364 
365 #endif
366