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