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/IR/Function.h" 16 #include "llvm/IR/InstrTypes.h" 17 #include "llvm/IR/Module.h" 18 #include "llvm/IR/PassManager.h" 19 #include "llvm/Pass.h" 20 21 namespace llvm { 22 template <typename T> class ArrayRef; 23 class Triple; 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] = std::string(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 /// Determine whether a callee with the given TLI can be inlined into 264 /// caller with this TLI, based on 'nobuiltin' attributes. When requested, 265 /// allow inlining into a caller with a superset of the callee's nobuiltin 266 /// attributes, which is conservatively correct. areInlineCompatible(const TargetLibraryInfo & CalleeTLI,bool AllowCallerSuperset)267 bool areInlineCompatible(const TargetLibraryInfo &CalleeTLI, 268 bool AllowCallerSuperset) const { 269 if (!AllowCallerSuperset) 270 return OverrideAsUnavailable == CalleeTLI.OverrideAsUnavailable; 271 BitVector B = OverrideAsUnavailable; 272 B |= CalleeTLI.OverrideAsUnavailable; 273 // We can inline if the union of the caller and callee's nobuiltin 274 // attributes is no stricter than the caller's nobuiltin attributes. 275 return B == OverrideAsUnavailable; 276 } 277 278 /// Searches for a particular function name. 279 /// 280 /// If it is one of the known library functions, return true and set F to the 281 /// corresponding value. getLibFunc(StringRef funcName,LibFunc & F)282 bool getLibFunc(StringRef funcName, LibFunc &F) const { 283 return Impl->getLibFunc(funcName, F); 284 } 285 getLibFunc(const Function & FDecl,LibFunc & F)286 bool getLibFunc(const Function &FDecl, LibFunc &F) const { 287 return Impl->getLibFunc(FDecl, F); 288 } 289 290 /// If a callbase does not have the 'nobuiltin' attribute, return if the 291 /// called function is a known library function and set F to that function. getLibFunc(const CallBase & CB,LibFunc & F)292 bool getLibFunc(const CallBase &CB, LibFunc &F) const { 293 return !CB.isNoBuiltin() && CB.getCalledFunction() && 294 getLibFunc(*(CB.getCalledFunction()), F); 295 } 296 297 /// Disables all builtins. 298 /// 299 /// This can be used for options like -fno-builtin. disableAllFunctions()300 void disableAllFunctions() LLVM_ATTRIBUTE_UNUSED { 301 OverrideAsUnavailable.set(); 302 } 303 304 /// Forces a function to be marked as unavailable. setUnavailable(LibFunc F)305 void setUnavailable(LibFunc F) LLVM_ATTRIBUTE_UNUSED { 306 OverrideAsUnavailable.set(F); 307 } 308 getState(LibFunc F)309 TargetLibraryInfoImpl::AvailabilityState getState(LibFunc F) const { 310 if (OverrideAsUnavailable[F]) 311 return TargetLibraryInfoImpl::Unavailable; 312 return Impl->getState(F); 313 } 314 315 /// Tests whether a library function is available. has(LibFunc F)316 bool has(LibFunc F) const { 317 return getState(F) != TargetLibraryInfoImpl::Unavailable; 318 } isFunctionVectorizable(StringRef F,unsigned VF)319 bool isFunctionVectorizable(StringRef F, unsigned VF) const { 320 return Impl->isFunctionVectorizable(F, VF); 321 } isFunctionVectorizable(StringRef F)322 bool isFunctionVectorizable(StringRef F) const { 323 return Impl->isFunctionVectorizable(F); 324 } getVectorizedFunction(StringRef F,unsigned VF)325 StringRef getVectorizedFunction(StringRef F, unsigned VF) const { 326 return Impl->getVectorizedFunction(F, VF); 327 } 328 329 /// Tests if the function is both available and a candidate for optimized code 330 /// generation. hasOptimizedCodeGen(LibFunc F)331 bool hasOptimizedCodeGen(LibFunc F) const { 332 if (getState(F) == TargetLibraryInfoImpl::Unavailable) 333 return false; 334 switch (F) { 335 default: break; 336 case LibFunc_copysign: case LibFunc_copysignf: case LibFunc_copysignl: 337 case LibFunc_fabs: case LibFunc_fabsf: case LibFunc_fabsl: 338 case LibFunc_sin: case LibFunc_sinf: case LibFunc_sinl: 339 case LibFunc_cos: case LibFunc_cosf: case LibFunc_cosl: 340 case LibFunc_sqrt: case LibFunc_sqrtf: case LibFunc_sqrtl: 341 case LibFunc_sqrt_finite: case LibFunc_sqrtf_finite: 342 case LibFunc_sqrtl_finite: 343 case LibFunc_fmax: case LibFunc_fmaxf: case LibFunc_fmaxl: 344 case LibFunc_fmin: case LibFunc_fminf: case LibFunc_fminl: 345 case LibFunc_floor: case LibFunc_floorf: case LibFunc_floorl: 346 case LibFunc_nearbyint: case LibFunc_nearbyintf: case LibFunc_nearbyintl: 347 case LibFunc_ceil: case LibFunc_ceilf: case LibFunc_ceill: 348 case LibFunc_rint: case LibFunc_rintf: case LibFunc_rintl: 349 case LibFunc_round: case LibFunc_roundf: case LibFunc_roundl: 350 case LibFunc_trunc: case LibFunc_truncf: case LibFunc_truncl: 351 case LibFunc_log2: case LibFunc_log2f: case LibFunc_log2l: 352 case LibFunc_exp2: case LibFunc_exp2f: case LibFunc_exp2l: 353 case LibFunc_memcpy: case LibFunc_memset: case LibFunc_memmove: 354 case LibFunc_memcmp: case LibFunc_bcmp: case LibFunc_strcmp: 355 case LibFunc_strcpy: case LibFunc_stpcpy: case LibFunc_strlen: 356 case LibFunc_strnlen: case LibFunc_memchr: case LibFunc_mempcpy: 357 return true; 358 } 359 return false; 360 } 361 getName(LibFunc F)362 StringRef getName(LibFunc F) const { 363 auto State = getState(F); 364 if (State == TargetLibraryInfoImpl::Unavailable) 365 return StringRef(); 366 if (State == TargetLibraryInfoImpl::StandardName) 367 return Impl->StandardNames[F]; 368 assert(State == TargetLibraryInfoImpl::CustomName); 369 return Impl->CustomNames.find(F)->second; 370 } 371 372 /// Returns extension attribute kind to be used for i32 parameters 373 /// corresponding to C-level int or unsigned int. May be zeroext, signext, 374 /// or none. 375 Attribute::AttrKind getExtAttrForI32Param(bool Signed = true) const { 376 if (Impl->ShouldExtI32Param) 377 return Signed ? Attribute::SExt : Attribute::ZExt; 378 if (Impl->ShouldSignExtI32Param) 379 return Attribute::SExt; 380 return Attribute::None; 381 } 382 383 /// Returns extension attribute kind to be used for i32 return values 384 /// corresponding to C-level int or unsigned int. May be zeroext, signext, 385 /// or none. 386 Attribute::AttrKind getExtAttrForI32Return(bool Signed = true) const { 387 if (Impl->ShouldExtI32Return) 388 return Signed ? Attribute::SExt : Attribute::ZExt; 389 return Attribute::None; 390 } 391 392 /// \copydoc TargetLibraryInfoImpl::getWCharSize() getWCharSize(const Module & M)393 unsigned getWCharSize(const Module &M) const { 394 return Impl->getWCharSize(M); 395 } 396 397 /// Handle invalidation from the pass manager. 398 /// 399 /// If we try to invalidate this info, just return false. It cannot become 400 /// invalid even if the module or function changes. invalidate(Module &,const PreservedAnalyses &,ModuleAnalysisManager::Invalidator &)401 bool invalidate(Module &, const PreservedAnalyses &, 402 ModuleAnalysisManager::Invalidator &) { 403 return false; 404 } invalidate(Function &,const PreservedAnalyses &,FunctionAnalysisManager::Invalidator &)405 bool invalidate(Function &, const PreservedAnalyses &, 406 FunctionAnalysisManager::Invalidator &) { 407 return false; 408 } 409 /// Returns the largest vectorization factor used in the list of 410 /// vector functions. getWidestVF(StringRef ScalarF)411 unsigned getWidestVF(StringRef ScalarF) const { 412 return Impl->getWidestVF(ScalarF); 413 } 414 415 /// Check if the function "F" is listed in a library known to LLVM. isKnownVectorFunctionInLibrary(StringRef F)416 bool isKnownVectorFunctionInLibrary(StringRef F) const { 417 return this->isFunctionVectorizable(F); 418 } 419 }; 420 421 /// Analysis pass providing the \c TargetLibraryInfo. 422 /// 423 /// Note that this pass's result cannot be invalidated, it is immutable for the 424 /// life of the module. 425 class TargetLibraryAnalysis : public AnalysisInfoMixin<TargetLibraryAnalysis> { 426 public: 427 typedef TargetLibraryInfo Result; 428 429 /// Default construct the library analysis. 430 /// 431 /// This will use the module's triple to construct the library info for that 432 /// module. TargetLibraryAnalysis()433 TargetLibraryAnalysis() {} 434 435 /// Construct a library analysis with baseline Module-level info. 436 /// 437 /// This will be supplemented with Function-specific info in the Result. TargetLibraryAnalysis(TargetLibraryInfoImpl BaselineInfoImpl)438 TargetLibraryAnalysis(TargetLibraryInfoImpl BaselineInfoImpl) 439 : BaselineInfoImpl(std::move(BaselineInfoImpl)) {} 440 441 TargetLibraryInfo run(const Function &F, FunctionAnalysisManager &); 442 443 private: 444 friend AnalysisInfoMixin<TargetLibraryAnalysis>; 445 static AnalysisKey Key; 446 447 Optional<TargetLibraryInfoImpl> BaselineInfoImpl; 448 }; 449 450 class TargetLibraryInfoWrapperPass : public ImmutablePass { 451 TargetLibraryAnalysis TLA; 452 Optional<TargetLibraryInfo> TLI; 453 454 virtual void anchor(); 455 456 public: 457 static char ID; 458 TargetLibraryInfoWrapperPass(); 459 explicit TargetLibraryInfoWrapperPass(const Triple &T); 460 explicit TargetLibraryInfoWrapperPass(const TargetLibraryInfoImpl &TLI); 461 getTLI(const Function & F)462 TargetLibraryInfo &getTLI(const Function &F) { 463 FunctionAnalysisManager DummyFAM; 464 TLI = TLA.run(F, DummyFAM); 465 return *TLI; 466 } 467 }; 468 469 } // end namespace llvm 470 471 #endif 472