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