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