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