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