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