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