123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328 |
- //===-- TargetLibraryInfo.h - Library information ---------------*- C++ -*-===//
- //
- // The LLVM Compiler Infrastructure
- //
- // This file is distributed under the University of Illinois Open Source
- // License. See LICENSE.TXT for details.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_ANALYSIS_TARGETLIBRARYINFO_H
- #define LLVM_ANALYSIS_TARGETLIBRARYINFO_H
- #include "llvm/ADT/DenseMap.h"
- #include "llvm/ADT/ArrayRef.h"
- #include "llvm/ADT/Optional.h"
- #include "llvm/ADT/Triple.h"
- #include "llvm/IR/Function.h"
- #include "llvm/IR/Module.h"
- #include "llvm/Pass.h"
- namespace llvm {
- /// VecDesc - Describes a possible vectorization of a function.
- /// Function 'VectorFnName' is equivalent to 'ScalarFnName' vectorized
- /// by a factor 'VectorizationFactor'.
- struct VecDesc {
- const char *ScalarFnName;
- const char *VectorFnName;
- unsigned VectorizationFactor;
- };
- class PreservedAnalyses;
- namespace LibFunc {
- enum Func {
- #define TLI_DEFINE_ENUM
- #include "llvm/Analysis/TargetLibraryInfo.def"
- NumLibFuncs
- };
- }
- /// \brief Implementation of the target library information.
- ///
- /// This class constructs tables that hold the target library information and
- /// make it available. However, it is somewhat expensive to compute and only
- /// depends on the triple. So users typicaly interact with the \c
- /// TargetLibraryInfo wrapper below.
- class TargetLibraryInfoImpl {
- friend class TargetLibraryInfo;
- unsigned char AvailableArray[(LibFunc::NumLibFuncs+3)/4];
- llvm::DenseMap<unsigned, std::string> CustomNames;
- static const char *const StandardNames[LibFunc::NumLibFuncs];
- enum AvailabilityState {
- StandardName = 3, // (memset to all ones)
- CustomName = 1,
- Unavailable = 0 // (memset to all zeros)
- };
- void setState(LibFunc::Func F, AvailabilityState State) {
- AvailableArray[F/4] &= ~(3 << 2*(F&3));
- AvailableArray[F/4] |= State << 2*(F&3);
- }
- AvailabilityState getState(LibFunc::Func F) const {
- return static_cast<AvailabilityState>((AvailableArray[F/4] >> 2*(F&3)) & 3);
- }
- /// Vectorization descriptors - sorted by ScalarFnName.
- std::vector<VecDesc> VectorDescs;
- /// Scalarization descriptors - same content as VectorDescs but sorted based
- /// on VectorFnName rather than ScalarFnName.
- std::vector<VecDesc> ScalarDescs;
- public:
- /// \brief List of known vector-functions libraries.
- ///
- /// The vector-functions library defines, which functions are vectorizable
- /// and with which factor. The library can be specified by either frontend,
- /// or a commandline option, and then used by
- /// addVectorizableFunctionsFromVecLib for filling up the tables of
- /// vectorizable functions.
- enum VectorLibrary {
- NoLibrary, // Don't use any vector library.
- Accelerate // Use Accelerate framework.
- };
- TargetLibraryInfoImpl();
- explicit TargetLibraryInfoImpl(const Triple &T);
- // Provide value semantics.
- TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI);
- TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI);
- TargetLibraryInfoImpl &operator=(const TargetLibraryInfoImpl &TLI);
- TargetLibraryInfoImpl &operator=(TargetLibraryInfoImpl &&TLI);
- /// \brief Searches for a particular function name.
- ///
- /// If it is one of the known library functions, return true and set F to the
- /// corresponding value.
- bool getLibFunc(StringRef funcName, LibFunc::Func &F) const;
- /// \brief Forces a function to be marked as unavailable.
- void setUnavailable(LibFunc::Func F) {
- setState(F, Unavailable);
- }
- /// \brief Forces a function to be marked as available.
- void setAvailable(LibFunc::Func F) {
- setState(F, StandardName);
- }
- /// \brief Forces a function to be marked as available and provide an
- /// alternate name that must be used.
- void setAvailableWithName(LibFunc::Func F, StringRef Name) {
- if (StandardNames[F] != Name) {
- setState(F, CustomName);
- CustomNames[F] = Name;
- assert(CustomNames.find(F) != CustomNames.end());
- } else {
- setState(F, StandardName);
- }
- }
- /// \brief Disables all builtins.
- ///
- /// This can be used for options like -fno-builtin.
- void disableAllFunctions();
- /// addVectorizableFunctions - Add a set of scalar -> vector mappings,
- /// queryable via getVectorizedFunction and getScalarizedFunction.
- void addVectorizableFunctions(ArrayRef<VecDesc> Fns);
- /// Calls addVectorizableFunctions with a known preset of functions for the
- /// given vector library.
- void addVectorizableFunctionsFromVecLib(enum VectorLibrary VecLib);
- /// isFunctionVectorizable - Return true if the function F has a
- /// vector equivalent with vectorization factor VF.
- bool isFunctionVectorizable(StringRef F, unsigned VF) const {
- return !getVectorizedFunction(F, VF).empty();
- }
- /// isFunctionVectorizable - Return true if the function F has a
- /// vector equivalent with any vectorization factor.
- bool isFunctionVectorizable(StringRef F) const;
- /// getVectorizedFunction - Return the name of the equivalent of
- /// F, vectorized with factor VF. If no such mapping exists,
- /// return the empty string.
- StringRef getVectorizedFunction(StringRef F, unsigned VF) const;
- /// isFunctionScalarizable - Return true if the function F has a
- /// scalar equivalent, and set VF to be the vectorization factor.
- bool isFunctionScalarizable(StringRef F, unsigned &VF) const {
- return !getScalarizedFunction(F, VF).empty();
- }
- /// getScalarizedFunction - Return the name of the equivalent of
- /// F, scalarized. If no such mapping exists, return the empty string.
- ///
- /// Set VF to the vectorization factor.
- StringRef getScalarizedFunction(StringRef F, unsigned &VF) const;
- };
- /// \brief Provides information about what library functions are available for
- /// the current target.
- ///
- /// This both allows optimizations to handle them specially and frontends to
- /// disable such optimizations through -fno-builtin etc.
- class TargetLibraryInfo {
- friend class TargetLibraryAnalysis;
- friend class TargetLibraryInfoWrapperPass;
- const TargetLibraryInfoImpl *Impl;
- public:
- explicit TargetLibraryInfo(const TargetLibraryInfoImpl &Impl) : Impl(&Impl) {}
- // Provide value semantics.
- TargetLibraryInfo(const TargetLibraryInfo &TLI) : Impl(TLI.Impl) {}
- TargetLibraryInfo(TargetLibraryInfo &&TLI) : Impl(TLI.Impl) {}
- TargetLibraryInfo &operator=(const TargetLibraryInfo &TLI) {
- Impl = TLI.Impl;
- return *this;
- }
- TargetLibraryInfo &operator=(TargetLibraryInfo &&TLI) {
- Impl = TLI.Impl;
- return *this;
- }
- /// \brief Searches for a particular function name.
- ///
- /// If it is one of the known library functions, return true and set F to the
- /// corresponding value.
- bool getLibFunc(StringRef funcName, LibFunc::Func &F) const {
- return Impl->getLibFunc(funcName, F);
- }
- /// \brief Tests whether a library function is available.
- bool has(LibFunc::Func F) const {
- return Impl->getState(F) != TargetLibraryInfoImpl::Unavailable;
- }
- bool isFunctionVectorizable(StringRef F, unsigned VF) const {
- return Impl->isFunctionVectorizable(F, VF);
- };
- bool isFunctionVectorizable(StringRef F) const {
- return Impl->isFunctionVectorizable(F);
- };
- StringRef getVectorizedFunction(StringRef F, unsigned VF) const {
- return Impl->getVectorizedFunction(F, VF);
- };
- /// \brief Tests if the function is both available and a candidate for
- /// optimized code generation.
- bool hasOptimizedCodeGen(LibFunc::Func F) const {
- if (Impl->getState(F) == TargetLibraryInfoImpl::Unavailable)
- return false;
- switch (F) {
- default: break;
- case LibFunc::copysign: case LibFunc::copysignf: case LibFunc::copysignl:
- case LibFunc::fabs: case LibFunc::fabsf: case LibFunc::fabsl:
- case LibFunc::sin: case LibFunc::sinf: case LibFunc::sinl:
- case LibFunc::cos: case LibFunc::cosf: case LibFunc::cosl:
- case LibFunc::sqrt: case LibFunc::sqrtf: case LibFunc::sqrtl:
- case LibFunc::sqrt_finite: case LibFunc::sqrtf_finite:
- case LibFunc::sqrtl_finite:
- case LibFunc::fmax: case LibFunc::fmaxf: case LibFunc::fmaxl:
- case LibFunc::fmin: case LibFunc::fminf: case LibFunc::fminl:
- case LibFunc::floor: case LibFunc::floorf: case LibFunc::floorl:
- case LibFunc::nearbyint: case LibFunc::nearbyintf: case LibFunc::nearbyintl:
- case LibFunc::ceil: case LibFunc::ceilf: case LibFunc::ceill:
- case LibFunc::rint: case LibFunc::rintf: case LibFunc::rintl:
- case LibFunc::round: case LibFunc::roundf: case LibFunc::roundl:
- case LibFunc::trunc: case LibFunc::truncf: case LibFunc::truncl:
- case LibFunc::log2: case LibFunc::log2f: case LibFunc::log2l:
- case LibFunc::exp2: case LibFunc::exp2f: case LibFunc::exp2l:
- case LibFunc::memcmp: case LibFunc::strcmp: case LibFunc::strcpy:
- case LibFunc::stpcpy: case LibFunc::strlen: case LibFunc::strnlen:
- case LibFunc::memchr:
- return true;
- }
- return false;
- }
- StringRef getName(LibFunc::Func F) const {
- auto State = Impl->getState(F);
- if (State == TargetLibraryInfoImpl::Unavailable)
- return StringRef();
- if (State == TargetLibraryInfoImpl::StandardName)
- return Impl->StandardNames[F];
- assert(State == TargetLibraryInfoImpl::CustomName);
- return Impl->CustomNames.find(F)->second;
- }
- /// \brief Handle invalidation from the pass manager.
- ///
- /// If we try to invalidate this info, just return false. It cannot become
- /// invalid even if the module changes.
- bool invalidate(Module &, const PreservedAnalyses &) { return false; }
- };
- /// \brief Analysis pass providing the \c TargetLibraryInfo.
- ///
- /// Note that this pass's result cannot be invalidated, it is immutable for the
- /// life of the module.
- class TargetLibraryAnalysis {
- public:
- typedef TargetLibraryInfo Result;
- /// \brief Opaque, unique identifier for this analysis pass.
- static void *ID() { return (void *)&PassID; }
- /// \brief Default construct the library analysis.
- ///
- /// This will use the module's triple to construct the library info for that
- /// module.
- TargetLibraryAnalysis() {}
- /// \brief Construct a library analysis with preset info.
- ///
- /// This will directly copy the preset info into the result without
- /// consulting the module's triple.
- TargetLibraryAnalysis(TargetLibraryInfoImpl PresetInfoImpl)
- : PresetInfoImpl(std::move(PresetInfoImpl)) {}
- // Move semantics. We spell out the constructors for MSVC.
- TargetLibraryAnalysis(TargetLibraryAnalysis &&Arg)
- : PresetInfoImpl(std::move(Arg.PresetInfoImpl)), Impls(std::move(Arg.Impls)) {}
- TargetLibraryAnalysis &operator=(TargetLibraryAnalysis &&RHS) {
- PresetInfoImpl = std::move(RHS.PresetInfoImpl);
- Impls = std::move(RHS.Impls);
- return *this;
- }
- TargetLibraryInfo run(Module &M);
- TargetLibraryInfo run(Function &F);
- /// \brief Provide access to a name for this pass for debugging purposes.
- static StringRef name() { return "TargetLibraryAnalysis"; }
- private:
- static char PassID;
- Optional<TargetLibraryInfoImpl> PresetInfoImpl;
- StringMap<std::unique_ptr<TargetLibraryInfoImpl>> Impls;
- TargetLibraryInfoImpl &lookupInfoImpl(Triple T);
- };
- class TargetLibraryInfoWrapperPass : public ImmutablePass {
- TargetLibraryInfoImpl TLIImpl;
- TargetLibraryInfo TLI;
- virtual void anchor();
- public:
- static char ID;
- TargetLibraryInfoWrapperPass();
- explicit TargetLibraryInfoWrapperPass(const Triple &T);
- explicit TargetLibraryInfoWrapperPass(const TargetLibraryInfoImpl &TLI);
- TargetLibraryInfo &getTLI() { return TLI; }
- const TargetLibraryInfo &getTLI() const { return TLI; }
- };
- } // end namespace llvm
- #endif
|