1283625Sdim//===-- TargetLibraryInfo.h - Library information ---------------*- C++ -*-===//
2283625Sdim//
3283625Sdim//                     The LLVM Compiler Infrastructure
4283625Sdim//
5283625Sdim// This file is distributed under the University of Illinois Open Source
6283625Sdim// License. See LICENSE.TXT for details.
7283625Sdim//
8283625Sdim//===----------------------------------------------------------------------===//
9283625Sdim
10283625Sdim#ifndef LLVM_ANALYSIS_TARGETLIBRARYINFO_H
11283625Sdim#define LLVM_ANALYSIS_TARGETLIBRARYINFO_H
12283625Sdim
13283625Sdim#include "llvm/ADT/DenseMap.h"
14283625Sdim#include "llvm/ADT/ArrayRef.h"
15283625Sdim#include "llvm/ADT/Optional.h"
16283625Sdim#include "llvm/ADT/Triple.h"
17283625Sdim#include "llvm/IR/Function.h"
18283625Sdim#include "llvm/IR/Module.h"
19283625Sdim#include "llvm/Pass.h"
20283625Sdim
21283625Sdimnamespace llvm {
22283625Sdim/// VecDesc - Describes a possible vectorization of a function.
23283625Sdim/// Function 'VectorFnName' is equivalent to 'ScalarFnName' vectorized
24283625Sdim/// by a factor 'VectorizationFactor'.
25283625Sdimstruct VecDesc {
26283625Sdim  const char *ScalarFnName;
27283625Sdim  const char *VectorFnName;
28283625Sdim  unsigned VectorizationFactor;
29283625Sdim};
30283625Sdimclass PreservedAnalyses;
31283625Sdim
32283625Sdim  namespace LibFunc {
33283625Sdim    enum Func {
34283625Sdim#define TLI_DEFINE_ENUM
35283625Sdim#include "llvm/Analysis/TargetLibraryInfo.def"
36283625Sdim
37283625Sdim      NumLibFuncs
38283625Sdim    };
39283625Sdim  }
40283625Sdim
41283625Sdim/// \brief Implementation of the target library information.
42283625Sdim///
43283625Sdim/// This class constructs tables that hold the target library information and
44283625Sdim/// make it available. However, it is somewhat expensive to compute and only
45296417Sdim/// depends on the triple. So users typically interact with the \c
46283625Sdim/// TargetLibraryInfo wrapper below.
47283625Sdimclass TargetLibraryInfoImpl {
48283625Sdim  friend class TargetLibraryInfo;
49283625Sdim
50283625Sdim  unsigned char AvailableArray[(LibFunc::NumLibFuncs+3)/4];
51283625Sdim  llvm::DenseMap<unsigned, std::string> CustomNames;
52283625Sdim  static const char *const StandardNames[LibFunc::NumLibFuncs];
53283625Sdim
54283625Sdim  enum AvailabilityState {
55283625Sdim    StandardName = 3, // (memset to all ones)
56283625Sdim    CustomName = 1,
57283625Sdim    Unavailable = 0  // (memset to all zeros)
58283625Sdim  };
59283625Sdim  void setState(LibFunc::Func F, AvailabilityState State) {
60283625Sdim    AvailableArray[F/4] &= ~(3 << 2*(F&3));
61283625Sdim    AvailableArray[F/4] |= State << 2*(F&3);
62283625Sdim  }
63283625Sdim  AvailabilityState getState(LibFunc::Func F) const {
64283625Sdim    return static_cast<AvailabilityState>((AvailableArray[F/4] >> 2*(F&3)) & 3);
65283625Sdim  }
66283625Sdim
67283625Sdim  /// Vectorization descriptors - sorted by ScalarFnName.
68283625Sdim  std::vector<VecDesc> VectorDescs;
69283625Sdim  /// Scalarization descriptors - same content as VectorDescs but sorted based
70283625Sdim  /// on VectorFnName rather than ScalarFnName.
71283625Sdim  std::vector<VecDesc> ScalarDescs;
72283625Sdim
73283625Sdimpublic:
74283625Sdim  /// \brief  List of known vector-functions libraries.
75283625Sdim  ///
76283625Sdim  /// The vector-functions library defines, which functions are vectorizable
77283625Sdim  /// and with which factor. The library can be specified by either frontend,
78283625Sdim  /// or a commandline option, and then used by
79283625Sdim  /// addVectorizableFunctionsFromVecLib for filling up the tables of
80283625Sdim  /// vectorizable functions.
81283625Sdim  enum VectorLibrary {
82283625Sdim    NoLibrary, // Don't use any vector library.
83283625Sdim    Accelerate // Use Accelerate framework.
84283625Sdim  };
85283625Sdim
86283625Sdim  TargetLibraryInfoImpl();
87283625Sdim  explicit TargetLibraryInfoImpl(const Triple &T);
88283625Sdim
89283625Sdim  // Provide value semantics.
90283625Sdim  TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI);
91283625Sdim  TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI);
92283625Sdim  TargetLibraryInfoImpl &operator=(const TargetLibraryInfoImpl &TLI);
93283625Sdim  TargetLibraryInfoImpl &operator=(TargetLibraryInfoImpl &&TLI);
94283625Sdim
95283625Sdim  /// \brief Searches for a particular function name.
96283625Sdim  ///
97283625Sdim  /// If it is one of the known library functions, return true and set F to the
98283625Sdim  /// corresponding value.
99283625Sdim  bool getLibFunc(StringRef funcName, LibFunc::Func &F) const;
100283625Sdim
101283625Sdim  /// \brief Forces a function to be marked as unavailable.
102283625Sdim  void setUnavailable(LibFunc::Func F) {
103283625Sdim    setState(F, Unavailable);
104283625Sdim  }
105283625Sdim
106283625Sdim  /// \brief Forces a function to be marked as available.
107283625Sdim  void setAvailable(LibFunc::Func F) {
108283625Sdim    setState(F, StandardName);
109283625Sdim  }
110283625Sdim
111283625Sdim  /// \brief Forces a function to be marked as available and provide an
112283625Sdim  /// alternate name that must be used.
113283625Sdim  void setAvailableWithName(LibFunc::Func F, StringRef Name) {
114283625Sdim    if (StandardNames[F] != Name) {
115283625Sdim      setState(F, CustomName);
116283625Sdim      CustomNames[F] = Name;
117283625Sdim      assert(CustomNames.find(F) != CustomNames.end());
118283625Sdim    } else {
119283625Sdim      setState(F, StandardName);
120283625Sdim    }
121283625Sdim  }
122283625Sdim
123283625Sdim  /// \brief Disables all builtins.
124283625Sdim  ///
125283625Sdim  /// This can be used for options like -fno-builtin.
126283625Sdim  void disableAllFunctions();
127283625Sdim
128283625Sdim  /// addVectorizableFunctions - Add a set of scalar -> vector mappings,
129283625Sdim  /// queryable via getVectorizedFunction and getScalarizedFunction.
130283625Sdim  void addVectorizableFunctions(ArrayRef<VecDesc> Fns);
131283625Sdim
132283625Sdim  /// Calls addVectorizableFunctions with a known preset of functions for the
133283625Sdim  /// given vector library.
134283625Sdim  void addVectorizableFunctionsFromVecLib(enum VectorLibrary VecLib);
135283625Sdim
136283625Sdim  /// isFunctionVectorizable - Return true if the function F has a
137283625Sdim  /// vector equivalent with vectorization factor VF.
138283625Sdim  bool isFunctionVectorizable(StringRef F, unsigned VF) const {
139283625Sdim    return !getVectorizedFunction(F, VF).empty();
140283625Sdim  }
141283625Sdim
142283625Sdim  /// isFunctionVectorizable - Return true if the function F has a
143283625Sdim  /// vector equivalent with any vectorization factor.
144283625Sdim  bool isFunctionVectorizable(StringRef F) const;
145283625Sdim
146283625Sdim  /// getVectorizedFunction - Return the name of the equivalent of
147283625Sdim  /// F, vectorized with factor VF. If no such mapping exists,
148283625Sdim  /// return the empty string.
149283625Sdim  StringRef getVectorizedFunction(StringRef F, unsigned VF) const;
150283625Sdim
151283625Sdim  /// isFunctionScalarizable - Return true if the function F has a
152283625Sdim  /// scalar equivalent, and set VF to be the vectorization factor.
153283625Sdim  bool isFunctionScalarizable(StringRef F, unsigned &VF) const {
154283625Sdim    return !getScalarizedFunction(F, VF).empty();
155283625Sdim  }
156283625Sdim
157283625Sdim  /// getScalarizedFunction - Return the name of the equivalent of
158283625Sdim  /// F, scalarized. If no such mapping exists, return the empty string.
159283625Sdim  ///
160283625Sdim  /// Set VF to the vectorization factor.
161283625Sdim  StringRef getScalarizedFunction(StringRef F, unsigned &VF) const;
162283625Sdim};
163283625Sdim
164283625Sdim/// \brief Provides information about what library functions are available for
165283625Sdim/// the current target.
166283625Sdim///
167283625Sdim/// This both allows optimizations to handle them specially and frontends to
168283625Sdim/// disable such optimizations through -fno-builtin etc.
169283625Sdimclass TargetLibraryInfo {
170283625Sdim  friend class TargetLibraryAnalysis;
171283625Sdim  friend class TargetLibraryInfoWrapperPass;
172283625Sdim
173283625Sdim  const TargetLibraryInfoImpl *Impl;
174283625Sdim
175283625Sdimpublic:
176283625Sdim  explicit TargetLibraryInfo(const TargetLibraryInfoImpl &Impl) : Impl(&Impl) {}
177283625Sdim
178283625Sdim  // Provide value semantics.
179283625Sdim  TargetLibraryInfo(const TargetLibraryInfo &TLI) : Impl(TLI.Impl) {}
180283625Sdim  TargetLibraryInfo(TargetLibraryInfo &&TLI) : Impl(TLI.Impl) {}
181283625Sdim  TargetLibraryInfo &operator=(const TargetLibraryInfo &TLI) {
182283625Sdim    Impl = TLI.Impl;
183283625Sdim    return *this;
184283625Sdim  }
185283625Sdim  TargetLibraryInfo &operator=(TargetLibraryInfo &&TLI) {
186283625Sdim    Impl = TLI.Impl;
187283625Sdim    return *this;
188283625Sdim  }
189283625Sdim
190283625Sdim  /// \brief Searches for a particular function name.
191283625Sdim  ///
192283625Sdim  /// If it is one of the known library functions, return true and set F to the
193283625Sdim  /// corresponding value.
194283625Sdim  bool getLibFunc(StringRef funcName, LibFunc::Func &F) const {
195283625Sdim    return Impl->getLibFunc(funcName, F);
196283625Sdim  }
197283625Sdim
198283625Sdim  /// \brief Tests whether a library function is available.
199283625Sdim  bool has(LibFunc::Func F) const {
200283625Sdim    return Impl->getState(F) != TargetLibraryInfoImpl::Unavailable;
201283625Sdim  }
202283625Sdim  bool isFunctionVectorizable(StringRef F, unsigned VF) const {
203283625Sdim    return Impl->isFunctionVectorizable(F, VF);
204296417Sdim  }
205283625Sdim  bool isFunctionVectorizable(StringRef F) const {
206283625Sdim    return Impl->isFunctionVectorizable(F);
207296417Sdim  }
208283625Sdim  StringRef getVectorizedFunction(StringRef F, unsigned VF) const {
209283625Sdim    return Impl->getVectorizedFunction(F, VF);
210296417Sdim  }
211283625Sdim
212283625Sdim  /// \brief Tests if the function is both available and a candidate for
213283625Sdim  /// optimized code generation.
214283625Sdim  bool hasOptimizedCodeGen(LibFunc::Func F) const {
215283625Sdim    if (Impl->getState(F) == TargetLibraryInfoImpl::Unavailable)
216283625Sdim      return false;
217283625Sdim    switch (F) {
218283625Sdim    default: break;
219283625Sdim    case LibFunc::copysign:  case LibFunc::copysignf:  case LibFunc::copysignl:
220283625Sdim    case LibFunc::fabs:      case LibFunc::fabsf:      case LibFunc::fabsl:
221283625Sdim    case LibFunc::sin:       case LibFunc::sinf:       case LibFunc::sinl:
222283625Sdim    case LibFunc::cos:       case LibFunc::cosf:       case LibFunc::cosl:
223283625Sdim    case LibFunc::sqrt:      case LibFunc::sqrtf:      case LibFunc::sqrtl:
224283625Sdim    case LibFunc::sqrt_finite: case LibFunc::sqrtf_finite:
225283625Sdim                                                  case LibFunc::sqrtl_finite:
226283625Sdim    case LibFunc::fmax:      case LibFunc::fmaxf:      case LibFunc::fmaxl:
227283625Sdim    case LibFunc::fmin:      case LibFunc::fminf:      case LibFunc::fminl:
228283625Sdim    case LibFunc::floor:     case LibFunc::floorf:     case LibFunc::floorl:
229283625Sdim    case LibFunc::nearbyint: case LibFunc::nearbyintf: case LibFunc::nearbyintl:
230283625Sdim    case LibFunc::ceil:      case LibFunc::ceilf:      case LibFunc::ceill:
231283625Sdim    case LibFunc::rint:      case LibFunc::rintf:      case LibFunc::rintl:
232283625Sdim    case LibFunc::round:     case LibFunc::roundf:     case LibFunc::roundl:
233283625Sdim    case LibFunc::trunc:     case LibFunc::truncf:     case LibFunc::truncl:
234283625Sdim    case LibFunc::log2:      case LibFunc::log2f:      case LibFunc::log2l:
235283625Sdim    case LibFunc::exp2:      case LibFunc::exp2f:      case LibFunc::exp2l:
236283625Sdim    case LibFunc::memcmp:    case LibFunc::strcmp:     case LibFunc::strcpy:
237283625Sdim    case LibFunc::stpcpy:    case LibFunc::strlen:     case LibFunc::strnlen:
238283625Sdim    case LibFunc::memchr:
239283625Sdim      return true;
240283625Sdim    }
241283625Sdim    return false;
242283625Sdim  }
243283625Sdim
244283625Sdim  StringRef getName(LibFunc::Func F) const {
245283625Sdim    auto State = Impl->getState(F);
246283625Sdim    if (State == TargetLibraryInfoImpl::Unavailable)
247283625Sdim      return StringRef();
248283625Sdim    if (State == TargetLibraryInfoImpl::StandardName)
249283625Sdim      return Impl->StandardNames[F];
250283625Sdim    assert(State == TargetLibraryInfoImpl::CustomName);
251283625Sdim    return Impl->CustomNames.find(F)->second;
252283625Sdim  }
253283625Sdim
254283625Sdim  /// \brief Handle invalidation from the pass manager.
255283625Sdim  ///
256283625Sdim  /// If we try to invalidate this info, just return false. It cannot become
257283625Sdim  /// invalid even if the module changes.
258283625Sdim  bool invalidate(Module &, const PreservedAnalyses &) { return false; }
259283625Sdim};
260283625Sdim
261283625Sdim/// \brief Analysis pass providing the \c TargetLibraryInfo.
262283625Sdim///
263283625Sdim/// Note that this pass's result cannot be invalidated, it is immutable for the
264283625Sdim/// life of the module.
265283625Sdimclass TargetLibraryAnalysis {
266283625Sdimpublic:
267283625Sdim  typedef TargetLibraryInfo Result;
268283625Sdim
269283625Sdim  /// \brief Opaque, unique identifier for this analysis pass.
270283625Sdim  static void *ID() { return (void *)&PassID; }
271283625Sdim
272283625Sdim  /// \brief Default construct the library analysis.
273283625Sdim  ///
274283625Sdim  /// This will use the module's triple to construct the library info for that
275283625Sdim  /// module.
276283625Sdim  TargetLibraryAnalysis() {}
277283625Sdim
278283625Sdim  /// \brief Construct a library analysis with preset info.
279283625Sdim  ///
280283625Sdim  /// This will directly copy the preset info into the result without
281283625Sdim  /// consulting the module's triple.
282283625Sdim  TargetLibraryAnalysis(TargetLibraryInfoImpl PresetInfoImpl)
283283625Sdim      : PresetInfoImpl(std::move(PresetInfoImpl)) {}
284283625Sdim
285283625Sdim  // Move semantics. We spell out the constructors for MSVC.
286283625Sdim  TargetLibraryAnalysis(TargetLibraryAnalysis &&Arg)
287283625Sdim      : PresetInfoImpl(std::move(Arg.PresetInfoImpl)), Impls(std::move(Arg.Impls)) {}
288283625Sdim  TargetLibraryAnalysis &operator=(TargetLibraryAnalysis &&RHS) {
289283625Sdim    PresetInfoImpl = std::move(RHS.PresetInfoImpl);
290283625Sdim    Impls = std::move(RHS.Impls);
291283625Sdim    return *this;
292283625Sdim  }
293283625Sdim
294283625Sdim  TargetLibraryInfo run(Module &M);
295283625Sdim  TargetLibraryInfo run(Function &F);
296283625Sdim
297283625Sdim  /// \brief Provide access to a name for this pass for debugging purposes.
298283625Sdim  static StringRef name() { return "TargetLibraryAnalysis"; }
299283625Sdim
300283625Sdimprivate:
301283625Sdim  static char PassID;
302283625Sdim
303283625Sdim  Optional<TargetLibraryInfoImpl> PresetInfoImpl;
304283625Sdim
305283625Sdim  StringMap<std::unique_ptr<TargetLibraryInfoImpl>> Impls;
306283625Sdim
307283625Sdim  TargetLibraryInfoImpl &lookupInfoImpl(Triple T);
308283625Sdim};
309283625Sdim
310283625Sdimclass TargetLibraryInfoWrapperPass : public ImmutablePass {
311283625Sdim  TargetLibraryInfoImpl TLIImpl;
312283625Sdim  TargetLibraryInfo TLI;
313283625Sdim
314283625Sdim  virtual void anchor();
315283625Sdim
316283625Sdimpublic:
317283625Sdim  static char ID;
318283625Sdim  TargetLibraryInfoWrapperPass();
319283625Sdim  explicit TargetLibraryInfoWrapperPass(const Triple &T);
320283625Sdim  explicit TargetLibraryInfoWrapperPass(const TargetLibraryInfoImpl &TLI);
321283625Sdim
322283625Sdim  TargetLibraryInfo &getTLI() { return TLI; }
323283625Sdim  const TargetLibraryInfo &getTLI() const { return TLI; }
324283625Sdim};
325283625Sdim
326283625Sdim} // end namespace llvm
327283625Sdim
328283625Sdim#endif
329