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/CallSite.h" 17 #include "llvm/IR/Function.h" 18 #include "llvm/IR/Module.h" 19 #include "llvm/IR/PassManager.h" 20 #include "llvm/Pass.h" 21 22 namespace llvm { 23 template <typename T> class ArrayRef; 24 25 /// Describes a possible vectorization of a function. 26 /// Function 'VectorFnName' is equivalent to 'ScalarFnName' vectorized 27 /// by a factor 'VectorizationFactor'. 28 struct VecDesc { 29 StringRef ScalarFnName; 30 StringRef VectorFnName; 31 unsigned VectorizationFactor; 32 }; 33 34 enum LibFunc { 35 #define TLI_DEFINE_ENUM 36 #include "llvm/Analysis/TargetLibraryInfo.def" 37 38 NumLibFuncs 39 }; 40 41 /// 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 typically interact with the \c 46 /// TargetLibraryInfo wrapper below. 47 class TargetLibraryInfoImpl { 48 friend class TargetLibraryInfo; 49 50 unsigned char AvailableArray[(NumLibFuncs+3)/4]; 51 llvm::DenseMap<unsigned, std::string> CustomNames; 52 static StringRef const StandardNames[NumLibFuncs]; 53 bool ShouldExtI32Param, ShouldExtI32Return, ShouldSignExtI32Param; 54 55 enum AvailabilityState { 56 StandardName = 3, // (memset to all ones) 57 CustomName = 1, 58 Unavailable = 0 // (memset to all zeros) 59 }; setState(LibFunc F,AvailabilityState State)60 void setState(LibFunc F, AvailabilityState State) { 61 AvailableArray[F/4] &= ~(3 << 2*(F&3)); 62 AvailableArray[F/4] |= State << 2*(F&3); 63 } getState(LibFunc F)64 AvailabilityState getState(LibFunc F) const { 65 return static_cast<AvailabilityState>((AvailableArray[F/4] >> 2*(F&3)) & 3); 66 } 67 68 /// Vectorization descriptors - sorted by ScalarFnName. 69 std::vector<VecDesc> VectorDescs; 70 /// Scalarization descriptors - same content as VectorDescs but sorted based 71 /// on VectorFnName rather than ScalarFnName. 72 std::vector<VecDesc> ScalarDescs; 73 74 /// Return true if the function type FTy is valid for the library function 75 /// F, regardless of whether the function is available. 76 bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc F, 77 const DataLayout *DL) const; 78 79 public: 80 /// List of known vector-functions libraries. 81 /// 82 /// The vector-functions library defines, which functions are vectorizable 83 /// and with which factor. The library can be specified by either frontend, 84 /// or a commandline option, and then used by 85 /// addVectorizableFunctionsFromVecLib for filling up the tables of 86 /// vectorizable functions. 87 enum VectorLibrary { 88 NoLibrary, // Don't use any vector library. 89 Accelerate, // Use Accelerate framework. 90 SVML // Intel short vector math library. 91 }; 92 93 TargetLibraryInfoImpl(); 94 explicit TargetLibraryInfoImpl(const Triple &T); 95 96 // Provide value semantics. 97 TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI); 98 TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI); 99 TargetLibraryInfoImpl &operator=(const TargetLibraryInfoImpl &TLI); 100 TargetLibraryInfoImpl &operator=(TargetLibraryInfoImpl &&TLI); 101 102 /// Searches for a particular function name. 103 /// 104 /// If it is one of the known library functions, return true and set F to the 105 /// corresponding value. 106 bool getLibFunc(StringRef funcName, LibFunc &F) const; 107 108 /// Searches for a particular function name, also checking that its type is 109 /// valid for the library function matching that name. 110 /// 111 /// If it is one of the known library functions, return true and set F to the 112 /// corresponding value. 113 bool getLibFunc(const Function &FDecl, LibFunc &F) const; 114 115 /// Forces a function to be marked as unavailable. setUnavailable(LibFunc F)116 void setUnavailable(LibFunc F) { 117 setState(F, Unavailable); 118 } 119 120 /// Forces a function to be marked as available. setAvailable(LibFunc F)121 void setAvailable(LibFunc F) { 122 setState(F, StandardName); 123 } 124 125 /// Forces a function to be marked as available and provide an alternate name 126 /// that must be used. setAvailableWithName(LibFunc F,StringRef Name)127 void setAvailableWithName(LibFunc F, StringRef Name) { 128 if (StandardNames[F] != Name) { 129 setState(F, CustomName); 130 CustomNames[F] = Name; 131 assert(CustomNames.find(F) != CustomNames.end()); 132 } else { 133 setState(F, StandardName); 134 } 135 } 136 137 /// Disables all builtins. 138 /// 139 /// This can be used for options like -fno-builtin. 140 void disableAllFunctions(); 141 142 /// Add a set of scalar -> vector mappings, queryable via 143 /// getVectorizedFunction and getScalarizedFunction. 144 void addVectorizableFunctions(ArrayRef<VecDesc> Fns); 145 146 /// Calls addVectorizableFunctions with a known preset of functions for the 147 /// given vector library. 148 void addVectorizableFunctionsFromVecLib(enum VectorLibrary VecLib); 149 150 /// Return true if the function F has a vector equivalent with vectorization 151 /// factor VF. isFunctionVectorizable(StringRef F,unsigned VF)152 bool isFunctionVectorizable(StringRef F, unsigned VF) const { 153 return !getVectorizedFunction(F, VF).empty(); 154 } 155 156 /// Return true if the function F has a vector equivalent with any 157 /// vectorization factor. 158 bool isFunctionVectorizable(StringRef F) const; 159 160 /// Return the name of the equivalent of F, vectorized with factor VF. If no 161 /// such mapping exists, return the empty string. 162 StringRef getVectorizedFunction(StringRef F, unsigned VF) const; 163 164 /// Return true if the function F has a scalar equivalent, and set VF to be 165 /// the vectorization factor. isFunctionScalarizable(StringRef F,unsigned & VF)166 bool isFunctionScalarizable(StringRef F, unsigned &VF) const { 167 return !getScalarizedFunction(F, VF).empty(); 168 } 169 170 /// Return the name of the equivalent of F, scalarized. If no such mapping 171 /// exists, return the empty string. 172 /// 173 /// Set VF to the vectorization factor. 174 StringRef getScalarizedFunction(StringRef F, unsigned &VF) const; 175 176 /// Set to true iff i32 parameters to library functions should have signext 177 /// or zeroext attributes if they correspond to C-level int or unsigned int, 178 /// respectively. setShouldExtI32Param(bool Val)179 void setShouldExtI32Param(bool Val) { 180 ShouldExtI32Param = Val; 181 } 182 183 /// Set to true iff i32 results from library functions should have signext 184 /// or zeroext attributes if they correspond to C-level int or unsigned int, 185 /// respectively. setShouldExtI32Return(bool Val)186 void setShouldExtI32Return(bool Val) { 187 ShouldExtI32Return = Val; 188 } 189 190 /// Set to true iff i32 parameters to library functions should have signext 191 /// attribute if they correspond to C-level int or unsigned int. setShouldSignExtI32Param(bool Val)192 void setShouldSignExtI32Param(bool Val) { 193 ShouldSignExtI32Param = Val; 194 } 195 196 /// Returns the size of the wchar_t type in bytes or 0 if the size is unknown. 197 /// This queries the 'wchar_size' metadata. 198 unsigned getWCharSize(const Module &M) const; 199 }; 200 201 /// Provides information about what library functions are available for 202 /// the current target. 203 /// 204 /// This both allows optimizations to handle them specially and frontends to 205 /// disable such optimizations through -fno-builtin etc. 206 class TargetLibraryInfo { 207 friend class TargetLibraryAnalysis; 208 friend class TargetLibraryInfoWrapperPass; 209 210 const TargetLibraryInfoImpl *Impl; 211 212 public: TargetLibraryInfo(const TargetLibraryInfoImpl & Impl)213 explicit TargetLibraryInfo(const TargetLibraryInfoImpl &Impl) : Impl(&Impl) {} 214 215 // Provide value semantics. TargetLibraryInfo(const TargetLibraryInfo & TLI)216 TargetLibraryInfo(const TargetLibraryInfo &TLI) : Impl(TLI.Impl) {} TargetLibraryInfo(TargetLibraryInfo && TLI)217 TargetLibraryInfo(TargetLibraryInfo &&TLI) : Impl(TLI.Impl) {} 218 TargetLibraryInfo &operator=(const TargetLibraryInfo &TLI) { 219 Impl = TLI.Impl; 220 return *this; 221 } 222 TargetLibraryInfo &operator=(TargetLibraryInfo &&TLI) { 223 Impl = TLI.Impl; 224 return *this; 225 } 226 227 /// Searches for a particular function name. 228 /// 229 /// If it is one of the known library functions, return true and set F to the 230 /// corresponding value. getLibFunc(StringRef funcName,LibFunc & F)231 bool getLibFunc(StringRef funcName, LibFunc &F) const { 232 return Impl->getLibFunc(funcName, F); 233 } 234 getLibFunc(const Function & FDecl,LibFunc & F)235 bool getLibFunc(const Function &FDecl, LibFunc &F) const { 236 return Impl->getLibFunc(FDecl, F); 237 } 238 239 /// If a callsite does not have the 'nobuiltin' attribute, return if the 240 /// called function is a known library function and set F to that function. getLibFunc(ImmutableCallSite CS,LibFunc & F)241 bool getLibFunc(ImmutableCallSite CS, LibFunc &F) const { 242 return !CS.isNoBuiltin() && CS.getCalledFunction() && 243 getLibFunc(*(CS.getCalledFunction()), F); 244 } 245 246 /// Tests whether a library function is available. has(LibFunc F)247 bool has(LibFunc F) const { 248 return Impl->getState(F) != TargetLibraryInfoImpl::Unavailable; 249 } isFunctionVectorizable(StringRef F,unsigned VF)250 bool isFunctionVectorizable(StringRef F, unsigned VF) const { 251 return Impl->isFunctionVectorizable(F, VF); 252 } isFunctionVectorizable(StringRef F)253 bool isFunctionVectorizable(StringRef F) const { 254 return Impl->isFunctionVectorizable(F); 255 } getVectorizedFunction(StringRef F,unsigned VF)256 StringRef getVectorizedFunction(StringRef F, unsigned VF) const { 257 return Impl->getVectorizedFunction(F, VF); 258 } 259 260 /// Tests if the function is both available and a candidate for optimized code 261 /// generation. hasOptimizedCodeGen(LibFunc F)262 bool hasOptimizedCodeGen(LibFunc F) const { 263 if (Impl->getState(F) == TargetLibraryInfoImpl::Unavailable) 264 return false; 265 switch (F) { 266 default: break; 267 case LibFunc_copysign: case LibFunc_copysignf: case LibFunc_copysignl: 268 case LibFunc_fabs: case LibFunc_fabsf: case LibFunc_fabsl: 269 case LibFunc_sin: case LibFunc_sinf: case LibFunc_sinl: 270 case LibFunc_cos: case LibFunc_cosf: case LibFunc_cosl: 271 case LibFunc_sqrt: case LibFunc_sqrtf: case LibFunc_sqrtl: 272 case LibFunc_sqrt_finite: case LibFunc_sqrtf_finite: 273 case LibFunc_sqrtl_finite: 274 case LibFunc_fmax: case LibFunc_fmaxf: case LibFunc_fmaxl: 275 case LibFunc_fmin: case LibFunc_fminf: case LibFunc_fminl: 276 case LibFunc_floor: case LibFunc_floorf: case LibFunc_floorl: 277 case LibFunc_nearbyint: case LibFunc_nearbyintf: case LibFunc_nearbyintl: 278 case LibFunc_ceil: case LibFunc_ceilf: case LibFunc_ceill: 279 case LibFunc_rint: case LibFunc_rintf: case LibFunc_rintl: 280 case LibFunc_round: case LibFunc_roundf: case LibFunc_roundl: 281 case LibFunc_trunc: case LibFunc_truncf: case LibFunc_truncl: 282 case LibFunc_log2: case LibFunc_log2f: case LibFunc_log2l: 283 case LibFunc_exp2: case LibFunc_exp2f: case LibFunc_exp2l: 284 case LibFunc_memcmp: case LibFunc_strcmp: case LibFunc_strcpy: 285 case LibFunc_stpcpy: case LibFunc_strlen: case LibFunc_strnlen: 286 case LibFunc_memchr: case LibFunc_mempcpy: 287 return true; 288 } 289 return false; 290 } 291 getName(LibFunc F)292 StringRef getName(LibFunc F) const { 293 auto State = Impl->getState(F); 294 if (State == TargetLibraryInfoImpl::Unavailable) 295 return StringRef(); 296 if (State == TargetLibraryInfoImpl::StandardName) 297 return Impl->StandardNames[F]; 298 assert(State == TargetLibraryInfoImpl::CustomName); 299 return Impl->CustomNames.find(F)->second; 300 } 301 302 /// Returns extension attribute kind to be used for i32 parameters 303 /// corresponding to C-level int or unsigned int. May be zeroext, signext, 304 /// or none. 305 Attribute::AttrKind getExtAttrForI32Param(bool Signed = true) const { 306 if (Impl->ShouldExtI32Param) 307 return Signed ? Attribute::SExt : Attribute::ZExt; 308 if (Impl->ShouldSignExtI32Param) 309 return Attribute::SExt; 310 return Attribute::None; 311 } 312 313 /// Returns extension attribute kind to be used for i32 return values 314 /// corresponding to C-level int or unsigned int. May be zeroext, signext, 315 /// or none. 316 Attribute::AttrKind getExtAttrForI32Return(bool Signed = true) const { 317 if (Impl->ShouldExtI32Return) 318 return Signed ? Attribute::SExt : Attribute::ZExt; 319 return Attribute::None; 320 } 321 322 /// \copydoc TargetLibraryInfoImpl::getWCharSize() getWCharSize(const Module & M)323 unsigned getWCharSize(const Module &M) const { 324 return Impl->getWCharSize(M); 325 } 326 327 /// Handle invalidation from the pass manager. 328 /// 329 /// If we try to invalidate this info, just return false. It cannot become 330 /// invalid even if the module or function changes. invalidate(Module &,const PreservedAnalyses &,ModuleAnalysisManager::Invalidator &)331 bool invalidate(Module &, const PreservedAnalyses &, 332 ModuleAnalysisManager::Invalidator &) { 333 return false; 334 } invalidate(Function &,const PreservedAnalyses &,FunctionAnalysisManager::Invalidator &)335 bool invalidate(Function &, const PreservedAnalyses &, 336 FunctionAnalysisManager::Invalidator &) { 337 return false; 338 } 339 }; 340 341 /// Analysis pass providing the \c TargetLibraryInfo. 342 /// 343 /// Note that this pass's result cannot be invalidated, it is immutable for the 344 /// life of the module. 345 class TargetLibraryAnalysis : public AnalysisInfoMixin<TargetLibraryAnalysis> { 346 public: 347 typedef TargetLibraryInfo Result; 348 349 /// Default construct the library analysis. 350 /// 351 /// This will use the module's triple to construct the library info for that 352 /// module. TargetLibraryAnalysis()353 TargetLibraryAnalysis() {} 354 355 /// Construct a library analysis with preset info. 356 /// 357 /// This will directly copy the preset info into the result without 358 /// consulting the module's triple. TargetLibraryAnalysis(TargetLibraryInfoImpl PresetInfoImpl)359 TargetLibraryAnalysis(TargetLibraryInfoImpl PresetInfoImpl) 360 : PresetInfoImpl(std::move(PresetInfoImpl)) {} 361 362 TargetLibraryInfo run(Module &M, ModuleAnalysisManager &); 363 TargetLibraryInfo run(Function &F, FunctionAnalysisManager &); 364 365 private: 366 friend AnalysisInfoMixin<TargetLibraryAnalysis>; 367 static AnalysisKey Key; 368 369 Optional<TargetLibraryInfoImpl> PresetInfoImpl; 370 371 StringMap<std::unique_ptr<TargetLibraryInfoImpl>> Impls; 372 373 TargetLibraryInfoImpl &lookupInfoImpl(const Triple &T); 374 }; 375 376 class TargetLibraryInfoWrapperPass : public ImmutablePass { 377 TargetLibraryInfoImpl TLIImpl; 378 TargetLibraryInfo TLI; 379 380 virtual void anchor(); 381 382 public: 383 static char ID; 384 TargetLibraryInfoWrapperPass(); 385 explicit TargetLibraryInfoWrapperPass(const Triple &T); 386 explicit TargetLibraryInfoWrapperPass(const TargetLibraryInfoImpl &TLI); 387 getTLI()388 TargetLibraryInfo &getTLI() { return TLI; } getTLI()389 const TargetLibraryInfo &getTLI() const { return TLI; } 390 }; 391 392 } // end namespace llvm 393 394 #endif 395