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