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