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