• 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/CallSite.h"
17 #include "llvm/IR/Function.h"
18 #include "llvm/IR/Module.h"
19 #include "llvm/IR/PassManager.h"
20 #include "llvm/Pass.h"
21 
22 namespace llvm {
23 template <typename T> class ArrayRef;
24 
25 /// Describes a possible vectorization of a function.
26 /// Function 'VectorFnName' is equivalent to 'ScalarFnName' vectorized
27 /// by a factor 'VectorizationFactor'.
28 struct VecDesc {
29   StringRef ScalarFnName;
30   StringRef VectorFnName;
31   unsigned VectorizationFactor;
32 };
33 
34   enum LibFunc {
35 #define TLI_DEFINE_ENUM
36 #include "llvm/Analysis/TargetLibraryInfo.def"
37 
38     NumLibFuncs
39   };
40 
41 /// Implementation of the target library information.
42 ///
43 /// This class constructs tables that hold the target library information and
44 /// make it available. However, it is somewhat expensive to compute and only
45 /// depends on the triple. So users typically interact with the \c
46 /// TargetLibraryInfo wrapper below.
47 class TargetLibraryInfoImpl {
48   friend class TargetLibraryInfo;
49 
50   unsigned char AvailableArray[(NumLibFuncs+3)/4];
51   llvm::DenseMap<unsigned, std::string> CustomNames;
52   static StringRef const StandardNames[NumLibFuncs];
53   bool ShouldExtI32Param, ShouldExtI32Return, ShouldSignExtI32Param;
54 
55   enum AvailabilityState {
56     StandardName = 3, // (memset to all ones)
57     CustomName = 1,
58     Unavailable = 0  // (memset to all zeros)
59   };
setState(LibFunc F,AvailabilityState State)60   void setState(LibFunc F, AvailabilityState State) {
61     AvailableArray[F/4] &= ~(3 << 2*(F&3));
62     AvailableArray[F/4] |= State << 2*(F&3);
63   }
getState(LibFunc F)64   AvailabilityState getState(LibFunc F) const {
65     return static_cast<AvailabilityState>((AvailableArray[F/4] >> 2*(F&3)) & 3);
66   }
67 
68   /// Vectorization descriptors - sorted by ScalarFnName.
69   std::vector<VecDesc> VectorDescs;
70   /// Scalarization descriptors - same content as VectorDescs but sorted based
71   /// on VectorFnName rather than ScalarFnName.
72   std::vector<VecDesc> ScalarDescs;
73 
74   /// Return true if the function type FTy is valid for the library function
75   /// F, regardless of whether the function is available.
76   bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc F,
77                               const DataLayout *DL) const;
78 
79 public:
80   /// List of known vector-functions libraries.
81   ///
82   /// The vector-functions library defines, which functions are vectorizable
83   /// and with which factor. The library can be specified by either frontend,
84   /// or a commandline option, and then used by
85   /// addVectorizableFunctionsFromVecLib for filling up the tables of
86   /// vectorizable functions.
87   enum VectorLibrary {
88     NoLibrary,  // Don't use any vector library.
89     Accelerate, // Use Accelerate framework.
90     SVML        // Intel short vector math library.
91   };
92 
93   TargetLibraryInfoImpl();
94   explicit TargetLibraryInfoImpl(const Triple &T);
95 
96   // Provide value semantics.
97   TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI);
98   TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI);
99   TargetLibraryInfoImpl &operator=(const TargetLibraryInfoImpl &TLI);
100   TargetLibraryInfoImpl &operator=(TargetLibraryInfoImpl &&TLI);
101 
102   /// Searches for a particular function name.
103   ///
104   /// If it is one of the known library functions, return true and set F to the
105   /// corresponding value.
106   bool getLibFunc(StringRef funcName, LibFunc &F) const;
107 
108   /// Searches for a particular function name, also checking that its type is
109   /// valid for the library function matching that name.
110   ///
111   /// If it is one of the known library functions, return true and set F to the
112   /// corresponding value.
113   bool getLibFunc(const Function &FDecl, LibFunc &F) const;
114 
115   /// Forces a function to be marked as unavailable.
setUnavailable(LibFunc F)116   void setUnavailable(LibFunc F) {
117     setState(F, Unavailable);
118   }
119 
120   /// Forces a function to be marked as available.
setAvailable(LibFunc F)121   void setAvailable(LibFunc F) {
122     setState(F, StandardName);
123   }
124 
125   /// Forces a function to be marked as available and provide an alternate name
126   /// that must be used.
setAvailableWithName(LibFunc F,StringRef Name)127   void setAvailableWithName(LibFunc F, StringRef Name) {
128     if (StandardNames[F] != Name) {
129       setState(F, CustomName);
130       CustomNames[F] = Name;
131       assert(CustomNames.find(F) != CustomNames.end());
132     } else {
133       setState(F, StandardName);
134     }
135   }
136 
137   /// Disables all builtins.
138   ///
139   /// This can be used for options like -fno-builtin.
140   void disableAllFunctions();
141 
142   /// Add a set of scalar -> vector mappings, queryable via
143   /// getVectorizedFunction and getScalarizedFunction.
144   void addVectorizableFunctions(ArrayRef<VecDesc> Fns);
145 
146   /// Calls addVectorizableFunctions with a known preset of functions for the
147   /// given vector library.
148   void addVectorizableFunctionsFromVecLib(enum VectorLibrary VecLib);
149 
150   /// Return true if the function F has a vector equivalent with vectorization
151   /// factor VF.
isFunctionVectorizable(StringRef F,unsigned VF)152   bool isFunctionVectorizable(StringRef F, unsigned VF) const {
153     return !getVectorizedFunction(F, VF).empty();
154   }
155 
156   /// Return true if the function F has a vector equivalent with any
157   /// vectorization factor.
158   bool isFunctionVectorizable(StringRef F) const;
159 
160   /// Return the name of the equivalent of F, vectorized with factor VF. If no
161   /// such mapping exists, return the empty string.
162   StringRef getVectorizedFunction(StringRef F, unsigned VF) const;
163 
164   /// Return true if the function F has a scalar equivalent, and set VF to be
165   /// the vectorization factor.
isFunctionScalarizable(StringRef F,unsigned & VF)166   bool isFunctionScalarizable(StringRef F, unsigned &VF) const {
167     return !getScalarizedFunction(F, VF).empty();
168   }
169 
170   /// Return the name of the equivalent of F, scalarized. If no such mapping
171   /// exists, return the empty string.
172   ///
173   /// Set VF to the vectorization factor.
174   StringRef getScalarizedFunction(StringRef F, unsigned &VF) const;
175 
176   /// Set to true iff i32 parameters to library functions should have signext
177   /// or zeroext attributes if they correspond to C-level int or unsigned int,
178   /// respectively.
setShouldExtI32Param(bool Val)179   void setShouldExtI32Param(bool Val) {
180     ShouldExtI32Param = Val;
181   }
182 
183   /// Set to true iff i32 results from library functions should have signext
184   /// or zeroext attributes if they correspond to C-level int or unsigned int,
185   /// respectively.
setShouldExtI32Return(bool Val)186   void setShouldExtI32Return(bool Val) {
187     ShouldExtI32Return = Val;
188   }
189 
190   /// Set to true iff i32 parameters to library functions should have signext
191   /// attribute if they correspond to C-level int or unsigned int.
setShouldSignExtI32Param(bool Val)192   void setShouldSignExtI32Param(bool Val) {
193     ShouldSignExtI32Param = Val;
194   }
195 
196   /// Returns the size of the wchar_t type in bytes or 0 if the size is unknown.
197   /// This queries the 'wchar_size' metadata.
198   unsigned getWCharSize(const Module &M) const;
199 };
200 
201 /// Provides information about what library functions are available for
202 /// the current target.
203 ///
204 /// This both allows optimizations to handle them specially and frontends to
205 /// disable such optimizations through -fno-builtin etc.
206 class TargetLibraryInfo {
207   friend class TargetLibraryAnalysis;
208   friend class TargetLibraryInfoWrapperPass;
209 
210   const TargetLibraryInfoImpl *Impl;
211 
212 public:
TargetLibraryInfo(const TargetLibraryInfoImpl & Impl)213   explicit TargetLibraryInfo(const TargetLibraryInfoImpl &Impl) : Impl(&Impl) {}
214 
215   // Provide value semantics.
TargetLibraryInfo(const TargetLibraryInfo & TLI)216   TargetLibraryInfo(const TargetLibraryInfo &TLI) : Impl(TLI.Impl) {}
TargetLibraryInfo(TargetLibraryInfo && TLI)217   TargetLibraryInfo(TargetLibraryInfo &&TLI) : Impl(TLI.Impl) {}
218   TargetLibraryInfo &operator=(const TargetLibraryInfo &TLI) {
219     Impl = TLI.Impl;
220     return *this;
221   }
222   TargetLibraryInfo &operator=(TargetLibraryInfo &&TLI) {
223     Impl = TLI.Impl;
224     return *this;
225   }
226 
227   /// Searches for a particular function name.
228   ///
229   /// If it is one of the known library functions, return true and set F to the
230   /// corresponding value.
getLibFunc(StringRef funcName,LibFunc & F)231   bool getLibFunc(StringRef funcName, LibFunc &F) const {
232     return Impl->getLibFunc(funcName, F);
233   }
234 
getLibFunc(const Function & FDecl,LibFunc & F)235   bool getLibFunc(const Function &FDecl, LibFunc &F) const {
236     return Impl->getLibFunc(FDecl, F);
237   }
238 
239   /// If a callsite does not have the 'nobuiltin' attribute, return if the
240   /// called function is a known library function and set F to that function.
getLibFunc(ImmutableCallSite CS,LibFunc & F)241   bool getLibFunc(ImmutableCallSite CS, LibFunc &F) const {
242     return !CS.isNoBuiltin() && CS.getCalledFunction() &&
243            getLibFunc(*(CS.getCalledFunction()), F);
244   }
245 
246   /// Tests whether a library function is available.
has(LibFunc F)247   bool has(LibFunc F) const {
248     return Impl->getState(F) != TargetLibraryInfoImpl::Unavailable;
249   }
isFunctionVectorizable(StringRef F,unsigned VF)250   bool isFunctionVectorizable(StringRef F, unsigned VF) const {
251     return Impl->isFunctionVectorizable(F, VF);
252   }
isFunctionVectorizable(StringRef F)253   bool isFunctionVectorizable(StringRef F) const {
254     return Impl->isFunctionVectorizable(F);
255   }
getVectorizedFunction(StringRef F,unsigned VF)256   StringRef getVectorizedFunction(StringRef F, unsigned VF) const {
257     return Impl->getVectorizedFunction(F, VF);
258   }
259 
260   /// Tests if the function is both available and a candidate for optimized code
261   /// generation.
hasOptimizedCodeGen(LibFunc F)262   bool hasOptimizedCodeGen(LibFunc F) const {
263     if (Impl->getState(F) == TargetLibraryInfoImpl::Unavailable)
264       return false;
265     switch (F) {
266     default: break;
267     case LibFunc_copysign:     case LibFunc_copysignf:  case LibFunc_copysignl:
268     case LibFunc_fabs:         case LibFunc_fabsf:      case LibFunc_fabsl:
269     case LibFunc_sin:          case LibFunc_sinf:       case LibFunc_sinl:
270     case LibFunc_cos:          case LibFunc_cosf:       case LibFunc_cosl:
271     case LibFunc_sqrt:         case LibFunc_sqrtf:      case LibFunc_sqrtl:
272     case LibFunc_sqrt_finite:  case LibFunc_sqrtf_finite:
273                                                    case LibFunc_sqrtl_finite:
274     case LibFunc_fmax:         case LibFunc_fmaxf:      case LibFunc_fmaxl:
275     case LibFunc_fmin:         case LibFunc_fminf:      case LibFunc_fminl:
276     case LibFunc_floor:        case LibFunc_floorf:     case LibFunc_floorl:
277     case LibFunc_nearbyint:    case LibFunc_nearbyintf: case LibFunc_nearbyintl:
278     case LibFunc_ceil:         case LibFunc_ceilf:      case LibFunc_ceill:
279     case LibFunc_rint:         case LibFunc_rintf:      case LibFunc_rintl:
280     case LibFunc_round:        case LibFunc_roundf:     case LibFunc_roundl:
281     case LibFunc_trunc:        case LibFunc_truncf:     case LibFunc_truncl:
282     case LibFunc_log2:         case LibFunc_log2f:      case LibFunc_log2l:
283     case LibFunc_exp2:         case LibFunc_exp2f:      case LibFunc_exp2l:
284     case LibFunc_memcmp:       case LibFunc_strcmp:     case LibFunc_strcpy:
285     case LibFunc_stpcpy:       case LibFunc_strlen:     case LibFunc_strnlen:
286     case LibFunc_memchr:       case LibFunc_mempcpy:
287       return true;
288     }
289     return false;
290   }
291 
getName(LibFunc F)292   StringRef getName(LibFunc F) const {
293     auto State = Impl->getState(F);
294     if (State == TargetLibraryInfoImpl::Unavailable)
295       return StringRef();
296     if (State == TargetLibraryInfoImpl::StandardName)
297       return Impl->StandardNames[F];
298     assert(State == TargetLibraryInfoImpl::CustomName);
299     return Impl->CustomNames.find(F)->second;
300   }
301 
302   /// Returns extension attribute kind to be used for i32 parameters
303   /// corresponding to C-level int or unsigned int.  May be zeroext, signext,
304   /// or none.
305   Attribute::AttrKind getExtAttrForI32Param(bool Signed = true) const {
306     if (Impl->ShouldExtI32Param)
307       return Signed ? Attribute::SExt : Attribute::ZExt;
308     if (Impl->ShouldSignExtI32Param)
309       return Attribute::SExt;
310     return Attribute::None;
311   }
312 
313   /// Returns extension attribute kind to be used for i32 return values
314   /// corresponding to C-level int or unsigned int.  May be zeroext, signext,
315   /// or none.
316   Attribute::AttrKind getExtAttrForI32Return(bool Signed = true) const {
317     if (Impl->ShouldExtI32Return)
318       return Signed ? Attribute::SExt : Attribute::ZExt;
319     return Attribute::None;
320   }
321 
322   /// \copydoc TargetLibraryInfoImpl::getWCharSize()
getWCharSize(const Module & M)323   unsigned getWCharSize(const Module &M) const {
324     return Impl->getWCharSize(M);
325   }
326 
327   /// Handle invalidation from the pass manager.
328   ///
329   /// If we try to invalidate this info, just return false. It cannot become
330   /// invalid even if the module or function changes.
invalidate(Module &,const PreservedAnalyses &,ModuleAnalysisManager::Invalidator &)331   bool invalidate(Module &, const PreservedAnalyses &,
332                   ModuleAnalysisManager::Invalidator &) {
333     return false;
334   }
invalidate(Function &,const PreservedAnalyses &,FunctionAnalysisManager::Invalidator &)335   bool invalidate(Function &, const PreservedAnalyses &,
336                   FunctionAnalysisManager::Invalidator &) {
337     return false;
338   }
339 };
340 
341 /// Analysis pass providing the \c TargetLibraryInfo.
342 ///
343 /// Note that this pass's result cannot be invalidated, it is immutable for the
344 /// life of the module.
345 class TargetLibraryAnalysis : public AnalysisInfoMixin<TargetLibraryAnalysis> {
346 public:
347   typedef TargetLibraryInfo Result;
348 
349   /// Default construct the library analysis.
350   ///
351   /// This will use the module's triple to construct the library info for that
352   /// module.
TargetLibraryAnalysis()353   TargetLibraryAnalysis() {}
354 
355   /// Construct a library analysis with preset info.
356   ///
357   /// This will directly copy the preset info into the result without
358   /// consulting the module's triple.
TargetLibraryAnalysis(TargetLibraryInfoImpl PresetInfoImpl)359   TargetLibraryAnalysis(TargetLibraryInfoImpl PresetInfoImpl)
360       : PresetInfoImpl(std::move(PresetInfoImpl)) {}
361 
362   TargetLibraryInfo run(Module &M, ModuleAnalysisManager &);
363   TargetLibraryInfo run(Function &F, FunctionAnalysisManager &);
364 
365 private:
366   friend AnalysisInfoMixin<TargetLibraryAnalysis>;
367   static AnalysisKey Key;
368 
369   Optional<TargetLibraryInfoImpl> PresetInfoImpl;
370 
371   StringMap<std::unique_ptr<TargetLibraryInfoImpl>> Impls;
372 
373   TargetLibraryInfoImpl &lookupInfoImpl(const Triple &T);
374 };
375 
376 class TargetLibraryInfoWrapperPass : public ImmutablePass {
377   TargetLibraryInfoImpl TLIImpl;
378   TargetLibraryInfo TLI;
379 
380   virtual void anchor();
381 
382 public:
383   static char ID;
384   TargetLibraryInfoWrapperPass();
385   explicit TargetLibraryInfoWrapperPass(const Triple &T);
386   explicit TargetLibraryInfoWrapperPass(const TargetLibraryInfoImpl &TLI);
387 
getTLI()388   TargetLibraryInfo &getTLI() { return TLI; }
getTLI()389   const TargetLibraryInfo &getTLI() const { return TLI; }
390 };
391 
392 } // end namespace llvm
393 
394 #endif
395