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