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/IR/InstrTypes.h" 15 #include "llvm/IR/PassManager.h" 16 #include "llvm/Pass.h" 17 #include "llvm/TargetParser/Triple.h" 18 #include <optional> 19 20 namespace llvm { 21 22 template <typename T> class ArrayRef; 23 class Function; 24 class Module; 25 class Triple; 26 27 /// Provides info so a possible vectorization of a function can be 28 /// computed. Function 'VectorFnName' is equivalent to 'ScalarFnName' 29 /// vectorized by a factor 'VectorizationFactor'. 30 /// The VABIPrefix string holds information about isa, mask, vlen, 31 /// and vparams so a scalar-to-vector mapping of the form: 32 /// _ZGV<isa><mask><vlen><vparams>_<scalarname>(<vectorname>) 33 /// can be constructed where: 34 /// 35 /// <isa> = "_LLVM_" 36 /// <mask> = "M" if masked, "N" if no mask. 37 /// <vlen> = Number of concurrent lanes, stored in the `VectorizationFactor` 38 /// field of the `VecDesc` struct. If the number of lanes is scalable 39 /// then 'x' is printed instead. 40 /// <vparams> = "v", as many as are the numArgs. 41 /// <scalarname> = the name of the scalar function. 42 /// <vectorname> = the name of the vector function. 43 class VecDesc { 44 StringRef ScalarFnName; 45 StringRef VectorFnName; 46 ElementCount VectorizationFactor; 47 bool Masked; 48 StringRef VABIPrefix; 49 50 public: 51 VecDesc() = delete; VecDesc(StringRef ScalarFnName,StringRef VectorFnName,ElementCount VectorizationFactor,bool Masked,StringRef VABIPrefix)52 VecDesc(StringRef ScalarFnName, StringRef VectorFnName, 53 ElementCount VectorizationFactor, bool Masked, StringRef VABIPrefix) 54 : ScalarFnName(ScalarFnName), VectorFnName(VectorFnName), 55 VectorizationFactor(VectorizationFactor), Masked(Masked), 56 VABIPrefix(VABIPrefix) {} 57 getScalarFnName()58 StringRef getScalarFnName() const { return ScalarFnName; } getVectorFnName()59 StringRef getVectorFnName() const { return VectorFnName; } getVectorizationFactor()60 ElementCount getVectorizationFactor() const { return VectorizationFactor; } isMasked()61 bool isMasked() const { return Masked; } getVABIPrefix()62 StringRef getVABIPrefix() const { return VABIPrefix; } 63 64 /// Returns a vector function ABI variant string on the form: 65 /// _ZGV<isa><mask><vlen><vparams>_<scalarname>(<vectorname>) 66 std::string getVectorFunctionABIVariantString() const; 67 }; 68 69 enum LibFunc : unsigned { 70 #define TLI_DEFINE_ENUM 71 #include "llvm/Analysis/TargetLibraryInfo.def" 72 73 NumLibFuncs, 74 NotLibFunc 75 }; 76 77 /// Implementation of the target library information. 78 /// 79 /// This class constructs tables that hold the target library information and 80 /// make it available. However, it is somewhat expensive to compute and only 81 /// depends on the triple. So users typically interact with the \c 82 /// TargetLibraryInfo wrapper below. 83 class TargetLibraryInfoImpl { 84 friend class TargetLibraryInfo; 85 86 unsigned char AvailableArray[(NumLibFuncs+3)/4]; 87 DenseMap<unsigned, std::string> CustomNames; 88 static StringLiteral const StandardNames[NumLibFuncs]; 89 bool ShouldExtI32Param, ShouldExtI32Return, ShouldSignExtI32Param, ShouldSignExtI32Return; 90 unsigned SizeOfInt; 91 92 enum AvailabilityState { 93 StandardName = 3, // (memset to all ones) 94 CustomName = 1, 95 Unavailable = 0 // (memset to all zeros) 96 }; setState(LibFunc F,AvailabilityState State)97 void setState(LibFunc F, AvailabilityState State) { 98 AvailableArray[F/4] &= ~(3 << 2*(F&3)); 99 AvailableArray[F/4] |= State << 2*(F&3); 100 } getState(LibFunc F)101 AvailabilityState getState(LibFunc F) const { 102 return static_cast<AvailabilityState>((AvailableArray[F/4] >> 2*(F&3)) & 3); 103 } 104 105 /// Vectorization descriptors - sorted by ScalarFnName. 106 std::vector<VecDesc> VectorDescs; 107 /// Scalarization descriptors - same content as VectorDescs but sorted based 108 /// on VectorFnName rather than ScalarFnName. 109 std::vector<VecDesc> ScalarDescs; 110 111 /// Return true if the function type FTy is valid for the library function 112 /// F, regardless of whether the function is available. 113 bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc F, 114 const Module &M) const; 115 116 public: 117 /// List of known vector-functions libraries. 118 /// 119 /// The vector-functions library defines, which functions are vectorizable 120 /// and with which factor. The library can be specified by either frontend, 121 /// or a commandline option, and then used by 122 /// addVectorizableFunctionsFromVecLib for filling up the tables of 123 /// vectorizable functions. 124 enum VectorLibrary { 125 NoLibrary, // Don't use any vector library. 126 Accelerate, // Use Accelerate framework. 127 DarwinLibSystemM, // Use Darwin's libsystem_m. 128 LIBMVEC_X86, // GLIBC Vector Math library. 129 MASSV, // IBM MASS vector library. 130 SVML, // Intel short vector math library. 131 SLEEFGNUABI, // SLEEF - SIMD Library for Evaluating Elementary Functions. 132 ArmPL // Arm Performance Libraries. 133 }; 134 135 TargetLibraryInfoImpl(); 136 explicit TargetLibraryInfoImpl(const Triple &T); 137 138 // Provide value semantics. 139 TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI); 140 TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI); 141 TargetLibraryInfoImpl &operator=(const TargetLibraryInfoImpl &TLI); 142 TargetLibraryInfoImpl &operator=(TargetLibraryInfoImpl &&TLI); 143 144 /// Searches for a particular function name. 145 /// 146 /// If it is one of the known library functions, return true and set F to the 147 /// corresponding value. 148 bool getLibFunc(StringRef funcName, LibFunc &F) const; 149 150 /// Searches for a particular function name, also checking that its type is 151 /// valid for the library function matching that name. 152 /// 153 /// If it is one of the known library functions, return true and set F to the 154 /// corresponding value. 155 /// 156 /// FDecl is assumed to have a parent Module when using this function. 157 bool getLibFunc(const Function &FDecl, LibFunc &F) const; 158 159 /// Searches for a function name using an Instruction \p Opcode. 160 /// Currently, only the frem instruction is supported. 161 bool getLibFunc(unsigned int Opcode, Type *Ty, LibFunc &F) const; 162 163 /// Forces a function to be marked as unavailable. setUnavailable(LibFunc F)164 void setUnavailable(LibFunc F) { 165 setState(F, Unavailable); 166 } 167 168 /// Forces a function to be marked as available. setAvailable(LibFunc F)169 void setAvailable(LibFunc F) { 170 setState(F, StandardName); 171 } 172 173 /// Forces a function to be marked as available and provide an alternate name 174 /// that must be used. setAvailableWithName(LibFunc F,StringRef Name)175 void setAvailableWithName(LibFunc F, StringRef Name) { 176 if (StandardNames[F] != Name) { 177 setState(F, CustomName); 178 CustomNames[F] = std::string(Name); 179 assert(CustomNames.contains(F)); 180 } else { 181 setState(F, StandardName); 182 } 183 } 184 185 /// Disables all builtins. 186 /// 187 /// This can be used for options like -fno-builtin. 188 void disableAllFunctions(); 189 190 /// Add a set of scalar -> vector mappings, queryable via 191 /// getVectorizedFunction and getScalarizedFunction. 192 void addVectorizableFunctions(ArrayRef<VecDesc> Fns); 193 194 /// Calls addVectorizableFunctions with a known preset of functions for the 195 /// given vector library. 196 void addVectorizableFunctionsFromVecLib(enum VectorLibrary VecLib, 197 const llvm::Triple &TargetTriple); 198 199 /// Return true if the function F has a vector equivalent with vectorization 200 /// factor VF. isFunctionVectorizable(StringRef F,const ElementCount & VF)201 bool isFunctionVectorizable(StringRef F, const ElementCount &VF) const { 202 return !(getVectorizedFunction(F, VF, false).empty() && 203 getVectorizedFunction(F, VF, true).empty()); 204 } 205 206 /// Return true if the function F has a vector equivalent with any 207 /// vectorization factor. 208 bool isFunctionVectorizable(StringRef F) const; 209 210 /// Return the name of the equivalent of F, vectorized with factor VF. If no 211 /// such mapping exists, return the empty string. 212 StringRef getVectorizedFunction(StringRef F, const ElementCount &VF, 213 bool Masked) const; 214 215 /// Return a pointer to a VecDesc object holding all info for scalar to vector 216 /// mappings in TLI for the equivalent of F, vectorized with factor VF. 217 /// If no such mapping exists, return nullpointer. 218 const VecDesc *getVectorMappingInfo(StringRef F, const ElementCount &VF, 219 bool Masked) const; 220 221 /// Set to true iff i32 parameters to library functions should have signext 222 /// or zeroext attributes if they correspond to C-level int or unsigned int, 223 /// respectively. setShouldExtI32Param(bool Val)224 void setShouldExtI32Param(bool Val) { 225 ShouldExtI32Param = Val; 226 } 227 228 /// Set to true iff i32 results from library functions should have signext 229 /// or zeroext attributes if they correspond to C-level int or unsigned int, 230 /// respectively. setShouldExtI32Return(bool Val)231 void setShouldExtI32Return(bool Val) { 232 ShouldExtI32Return = Val; 233 } 234 235 /// Set to true iff i32 parameters to library functions should have signext 236 /// attribute if they correspond to C-level int or unsigned int. setShouldSignExtI32Param(bool Val)237 void setShouldSignExtI32Param(bool Val) { 238 ShouldSignExtI32Param = Val; 239 } 240 241 /// Set to true iff i32 results from library functions should have signext 242 /// attribute if they correspond to C-level int or unsigned int. setShouldSignExtI32Return(bool Val)243 void setShouldSignExtI32Return(bool Val) { 244 ShouldSignExtI32Return = Val; 245 } 246 247 /// Returns the size of the wchar_t type in bytes or 0 if the size is unknown. 248 /// This queries the 'wchar_size' metadata. 249 unsigned getWCharSize(const Module &M) const; 250 251 /// Returns the size of the size_t type in bits. 252 unsigned getSizeTSize(const Module &M) const; 253 254 /// Get size of a C-level int or unsigned int, in bits. getIntSize()255 unsigned getIntSize() const { 256 return SizeOfInt; 257 } 258 259 /// Initialize the C-level size of an integer. setIntSize(unsigned Bits)260 void setIntSize(unsigned Bits) { 261 SizeOfInt = Bits; 262 } 263 264 /// Returns the largest vectorization factor used in the list of 265 /// vector functions. 266 void getWidestVF(StringRef ScalarF, ElementCount &FixedVF, 267 ElementCount &Scalable) const; 268 269 /// Returns true if call site / callee has cdecl-compatible calling 270 /// conventions. 271 static bool isCallingConvCCompatible(CallBase *CI); 272 static bool isCallingConvCCompatible(Function *Callee); 273 }; 274 275 /// Provides information about what library functions are available for 276 /// the current target. 277 /// 278 /// This both allows optimizations to handle them specially and frontends to 279 /// disable such optimizations through -fno-builtin etc. 280 class TargetLibraryInfo { 281 friend class TargetLibraryAnalysis; 282 friend class TargetLibraryInfoWrapperPass; 283 284 /// The global (module level) TLI info. 285 const TargetLibraryInfoImpl *Impl; 286 287 /// Support for -fno-builtin* options as function attributes, overrides 288 /// information in global TargetLibraryInfoImpl. 289 BitVector OverrideAsUnavailable; 290 291 public: 292 explicit TargetLibraryInfo(const TargetLibraryInfoImpl &Impl, 293 std::optional<const Function *> F = std::nullopt) 294 : Impl(&Impl), OverrideAsUnavailable(NumLibFuncs) { 295 if (!F) 296 return; 297 if ((*F)->hasFnAttribute("no-builtins")) 298 disableAllFunctions(); 299 else { 300 // Disable individual libc/libm calls in TargetLibraryInfo. 301 LibFunc LF; 302 AttributeSet FnAttrs = (*F)->getAttributes().getFnAttrs(); 303 for (const Attribute &Attr : FnAttrs) { 304 if (!Attr.isStringAttribute()) 305 continue; 306 auto AttrStr = Attr.getKindAsString(); 307 if (!AttrStr.consume_front("no-builtin-")) 308 continue; 309 if (getLibFunc(AttrStr, LF)) 310 setUnavailable(LF); 311 } 312 } 313 } 314 315 // Provide value semantics. 316 TargetLibraryInfo(const TargetLibraryInfo &TLI) = default; TargetLibraryInfo(TargetLibraryInfo && TLI)317 TargetLibraryInfo(TargetLibraryInfo &&TLI) 318 : Impl(TLI.Impl), OverrideAsUnavailable(TLI.OverrideAsUnavailable) {} 319 TargetLibraryInfo &operator=(const TargetLibraryInfo &TLI) = default; 320 TargetLibraryInfo &operator=(TargetLibraryInfo &&TLI) { 321 Impl = TLI.Impl; 322 OverrideAsUnavailable = TLI.OverrideAsUnavailable; 323 return *this; 324 } 325 326 /// Determine whether a callee with the given TLI can be inlined into 327 /// caller with this TLI, based on 'nobuiltin' attributes. When requested, 328 /// allow inlining into a caller with a superset of the callee's nobuiltin 329 /// attributes, which is conservatively correct. areInlineCompatible(const TargetLibraryInfo & CalleeTLI,bool AllowCallerSuperset)330 bool areInlineCompatible(const TargetLibraryInfo &CalleeTLI, 331 bool AllowCallerSuperset) const { 332 if (!AllowCallerSuperset) 333 return OverrideAsUnavailable == CalleeTLI.OverrideAsUnavailable; 334 BitVector B = OverrideAsUnavailable; 335 B |= CalleeTLI.OverrideAsUnavailable; 336 // We can inline if the union of the caller and callee's nobuiltin 337 // attributes is no stricter than the caller's nobuiltin attributes. 338 return B == OverrideAsUnavailable; 339 } 340 341 /// Return true if the function type FTy is valid for the library function 342 /// F, regardless of whether the function is available. isValidProtoForLibFunc(const FunctionType & FTy,LibFunc F,const Module & M)343 bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc F, 344 const Module &M) const { 345 return Impl->isValidProtoForLibFunc(FTy, F, M); 346 } 347 348 /// Searches for a particular function name. 349 /// 350 /// If it is one of the known library functions, return true and set F to the 351 /// corresponding value. getLibFunc(StringRef funcName,LibFunc & F)352 bool getLibFunc(StringRef funcName, LibFunc &F) const { 353 return Impl->getLibFunc(funcName, F); 354 } 355 getLibFunc(const Function & FDecl,LibFunc & F)356 bool getLibFunc(const Function &FDecl, LibFunc &F) const { 357 return Impl->getLibFunc(FDecl, F); 358 } 359 360 /// If a callbase does not have the 'nobuiltin' attribute, return if the 361 /// called function is a known library function and set F to that function. getLibFunc(const CallBase & CB,LibFunc & F)362 bool getLibFunc(const CallBase &CB, LibFunc &F) const { 363 return !CB.isNoBuiltin() && CB.getCalledFunction() && 364 getLibFunc(*(CB.getCalledFunction()), F); 365 } 366 367 /// Searches for a function name using an Instruction \p Opcode. 368 /// Currently, only the frem instruction is supported. getLibFunc(unsigned int Opcode,Type * Ty,LibFunc & F)369 bool getLibFunc(unsigned int Opcode, Type *Ty, LibFunc &F) const { 370 return Impl->getLibFunc(Opcode, Ty, F); 371 } 372 373 /// Disables all builtins. 374 /// 375 /// This can be used for options like -fno-builtin. disableAllFunctions()376 void disableAllFunctions() LLVM_ATTRIBUTE_UNUSED { 377 OverrideAsUnavailable.set(); 378 } 379 380 /// Forces a function to be marked as unavailable. setUnavailable(LibFunc F)381 void setUnavailable(LibFunc F) LLVM_ATTRIBUTE_UNUSED { 382 OverrideAsUnavailable.set(F); 383 } 384 getState(LibFunc F)385 TargetLibraryInfoImpl::AvailabilityState getState(LibFunc F) const { 386 if (OverrideAsUnavailable[F]) 387 return TargetLibraryInfoImpl::Unavailable; 388 return Impl->getState(F); 389 } 390 391 /// Tests whether a library function is available. has(LibFunc F)392 bool has(LibFunc F) const { 393 return getState(F) != TargetLibraryInfoImpl::Unavailable; 394 } isFunctionVectorizable(StringRef F,const ElementCount & VF)395 bool isFunctionVectorizable(StringRef F, const ElementCount &VF) const { 396 return Impl->isFunctionVectorizable(F, VF); 397 } isFunctionVectorizable(StringRef F)398 bool isFunctionVectorizable(StringRef F) const { 399 return Impl->isFunctionVectorizable(F); 400 } 401 StringRef getVectorizedFunction(StringRef F, const ElementCount &VF, 402 bool Masked = false) const { 403 return Impl->getVectorizedFunction(F, VF, Masked); 404 } getVectorMappingInfo(StringRef F,const ElementCount & VF,bool Masked)405 const VecDesc *getVectorMappingInfo(StringRef F, const ElementCount &VF, 406 bool Masked) const { 407 return Impl->getVectorMappingInfo(F, VF, Masked); 408 } 409 410 /// Tests if the function is both available and a candidate for optimized code 411 /// generation. hasOptimizedCodeGen(LibFunc F)412 bool hasOptimizedCodeGen(LibFunc F) const { 413 if (getState(F) == TargetLibraryInfoImpl::Unavailable) 414 return false; 415 switch (F) { 416 default: break; 417 case LibFunc_copysign: case LibFunc_copysignf: case LibFunc_copysignl: 418 case LibFunc_fabs: case LibFunc_fabsf: case LibFunc_fabsl: 419 case LibFunc_sin: case LibFunc_sinf: case LibFunc_sinl: 420 case LibFunc_cos: case LibFunc_cosf: case LibFunc_cosl: 421 case LibFunc_sqrt: case LibFunc_sqrtf: case LibFunc_sqrtl: 422 case LibFunc_sqrt_finite: case LibFunc_sqrtf_finite: 423 case LibFunc_sqrtl_finite: 424 case LibFunc_fmax: case LibFunc_fmaxf: case LibFunc_fmaxl: 425 case LibFunc_fmin: case LibFunc_fminf: case LibFunc_fminl: 426 case LibFunc_floor: case LibFunc_floorf: case LibFunc_floorl: 427 case LibFunc_nearbyint: case LibFunc_nearbyintf: case LibFunc_nearbyintl: 428 case LibFunc_ceil: case LibFunc_ceilf: case LibFunc_ceill: 429 case LibFunc_rint: case LibFunc_rintf: case LibFunc_rintl: 430 case LibFunc_round: case LibFunc_roundf: case LibFunc_roundl: 431 case LibFunc_trunc: case LibFunc_truncf: case LibFunc_truncl: 432 case LibFunc_log2: case LibFunc_log2f: case LibFunc_log2l: 433 case LibFunc_exp2: case LibFunc_exp2f: case LibFunc_exp2l: 434 case LibFunc_ldexp: case LibFunc_ldexpf: case LibFunc_ldexpl: 435 case LibFunc_memcpy: case LibFunc_memset: case LibFunc_memmove: 436 case LibFunc_memcmp: case LibFunc_bcmp: case LibFunc_strcmp: 437 case LibFunc_strcpy: case LibFunc_stpcpy: case LibFunc_strlen: 438 case LibFunc_strnlen: case LibFunc_memchr: case LibFunc_mempcpy: 439 return true; 440 } 441 return false; 442 } 443 getName(LibFunc F)444 StringRef getName(LibFunc F) const { 445 auto State = getState(F); 446 if (State == TargetLibraryInfoImpl::Unavailable) 447 return StringRef(); 448 if (State == TargetLibraryInfoImpl::StandardName) 449 return Impl->StandardNames[F]; 450 assert(State == TargetLibraryInfoImpl::CustomName); 451 return Impl->CustomNames.find(F)->second; 452 } 453 initExtensionsForTriple(bool & ShouldExtI32Param,bool & ShouldExtI32Return,bool & ShouldSignExtI32Param,bool & ShouldSignExtI32Return,const Triple & T)454 static void initExtensionsForTriple(bool &ShouldExtI32Param, 455 bool &ShouldExtI32Return, 456 bool &ShouldSignExtI32Param, 457 bool &ShouldSignExtI32Return, 458 const Triple &T) { 459 ShouldExtI32Param = ShouldExtI32Return = false; 460 ShouldSignExtI32Param = ShouldSignExtI32Return = false; 461 462 // PowerPC64, Sparc64, SystemZ need signext/zeroext on i32 parameters and 463 // returns corresponding to C-level ints and unsigned ints. 464 if (T.isPPC64() || T.getArch() == Triple::sparcv9 || 465 T.getArch() == Triple::systemz) { 466 ShouldExtI32Param = true; 467 ShouldExtI32Return = true; 468 } 469 // LoongArch, Mips, and riscv64, on the other hand, need signext on i32 470 // parameters corresponding to both signed and unsigned ints. 471 if (T.isLoongArch() || T.isMIPS() || T.isRISCV64()) { 472 ShouldSignExtI32Param = true; 473 } 474 // LoongArch and riscv64 need signext on i32 returns corresponding to both 475 // signed and unsigned ints. 476 if (T.isLoongArch() || T.isRISCV64()) { 477 ShouldSignExtI32Return = true; 478 } 479 } 480 481 /// Returns extension attribute kind to be used for i32 parameters 482 /// corresponding to C-level int or unsigned int. May be zeroext, signext, 483 /// or none. 484 private: 485 static Attribute::AttrKind getExtAttrForI32Param(bool ShouldExtI32Param_, 486 bool ShouldSignExtI32Param_, 487 bool Signed = true) { 488 if (ShouldExtI32Param_) 489 return Signed ? Attribute::SExt : Attribute::ZExt; 490 if (ShouldSignExtI32Param_) 491 return Attribute::SExt; 492 return Attribute::None; 493 } 494 495 public: 496 static Attribute::AttrKind getExtAttrForI32Param(const Triple &T, 497 bool Signed = true) { 498 bool ShouldExtI32Param, ShouldExtI32Return; 499 bool ShouldSignExtI32Param, ShouldSignExtI32Return; 500 initExtensionsForTriple(ShouldExtI32Param, ShouldExtI32Return, 501 ShouldSignExtI32Param, ShouldSignExtI32Return, T); 502 return getExtAttrForI32Param(ShouldExtI32Param, ShouldSignExtI32Param, 503 Signed); 504 } 505 506 Attribute::AttrKind getExtAttrForI32Param(bool Signed = true) const { 507 return getExtAttrForI32Param(Impl->ShouldExtI32Param, 508 Impl->ShouldSignExtI32Param, Signed); 509 } 510 511 /// Returns extension attribute kind to be used for i32 return values 512 /// corresponding to C-level int or unsigned int. May be zeroext, signext, 513 /// or none. 514 private: getExtAttrForI32Return(bool ShouldExtI32Return_,bool ShouldSignExtI32Return_,bool Signed)515 static Attribute::AttrKind getExtAttrForI32Return(bool ShouldExtI32Return_, 516 bool ShouldSignExtI32Return_, 517 bool Signed) { 518 if (ShouldExtI32Return_) 519 return Signed ? Attribute::SExt : Attribute::ZExt; 520 if (ShouldSignExtI32Return_) 521 return Attribute::SExt; 522 return Attribute::None; 523 } 524 525 public: 526 static Attribute::AttrKind getExtAttrForI32Return(const Triple &T, 527 bool Signed = true) { 528 bool ShouldExtI32Param, ShouldExtI32Return; 529 bool ShouldSignExtI32Param, ShouldSignExtI32Return; 530 initExtensionsForTriple(ShouldExtI32Param, ShouldExtI32Return, 531 ShouldSignExtI32Param, ShouldSignExtI32Return, T); 532 return getExtAttrForI32Return(ShouldExtI32Return, ShouldSignExtI32Return, 533 Signed); 534 } 535 536 Attribute::AttrKind getExtAttrForI32Return(bool Signed = true) const { 537 return getExtAttrForI32Return(Impl->ShouldExtI32Return, 538 Impl->ShouldSignExtI32Return, Signed); 539 } 540 541 // Helper to create an AttributeList for args (and ret val) which all have 542 // the same signedness. Attributes in AL may be passed in to include them 543 // as well in the returned AttributeList. 544 AttributeList getAttrList(LLVMContext *C, ArrayRef<unsigned> ArgNos, 545 bool Signed, bool Ret = false, 546 AttributeList AL = AttributeList()) const { 547 if (auto AK = getExtAttrForI32Param(Signed)) 548 for (auto ArgNo : ArgNos) 549 AL = AL.addParamAttribute(*C, ArgNo, AK); 550 if (Ret) 551 if (auto AK = getExtAttrForI32Return(Signed)) 552 AL = AL.addRetAttribute(*C, AK); 553 return AL; 554 } 555 556 /// \copydoc TargetLibraryInfoImpl::getWCharSize() getWCharSize(const Module & M)557 unsigned getWCharSize(const Module &M) const { 558 return Impl->getWCharSize(M); 559 } 560 561 /// \copydoc TargetLibraryInfoImpl::getSizeTSize() getSizeTSize(const Module & M)562 unsigned getSizeTSize(const Module &M) const { return Impl->getSizeTSize(M); } 563 564 /// \copydoc TargetLibraryInfoImpl::getIntSize() getIntSize()565 unsigned getIntSize() const { 566 return Impl->getIntSize(); 567 } 568 569 /// Handle invalidation from the pass manager. 570 /// 571 /// If we try to invalidate this info, just return false. It cannot become 572 /// invalid even if the module or function changes. invalidate(Module &,const PreservedAnalyses &,ModuleAnalysisManager::Invalidator &)573 bool invalidate(Module &, const PreservedAnalyses &, 574 ModuleAnalysisManager::Invalidator &) { 575 return false; 576 } invalidate(Function &,const PreservedAnalyses &,FunctionAnalysisManager::Invalidator &)577 bool invalidate(Function &, const PreservedAnalyses &, 578 FunctionAnalysisManager::Invalidator &) { 579 return false; 580 } 581 /// Returns the largest vectorization factor used in the list of 582 /// vector functions. getWidestVF(StringRef ScalarF,ElementCount & FixedVF,ElementCount & ScalableVF)583 void getWidestVF(StringRef ScalarF, ElementCount &FixedVF, 584 ElementCount &ScalableVF) const { 585 Impl->getWidestVF(ScalarF, FixedVF, ScalableVF); 586 } 587 588 /// Check if the function "F" is listed in a library known to LLVM. isKnownVectorFunctionInLibrary(StringRef F)589 bool isKnownVectorFunctionInLibrary(StringRef F) const { 590 return this->isFunctionVectorizable(F); 591 } 592 }; 593 594 /// Analysis pass providing the \c TargetLibraryInfo. 595 /// 596 /// Note that this pass's result cannot be invalidated, it is immutable for the 597 /// life of the module. 598 class TargetLibraryAnalysis : public AnalysisInfoMixin<TargetLibraryAnalysis> { 599 public: 600 typedef TargetLibraryInfo Result; 601 602 /// Default construct the library analysis. 603 /// 604 /// This will use the module's triple to construct the library info for that 605 /// module. 606 TargetLibraryAnalysis() = default; 607 608 /// Construct a library analysis with baseline Module-level info. 609 /// 610 /// This will be supplemented with Function-specific info in the Result. TargetLibraryAnalysis(TargetLibraryInfoImpl BaselineInfoImpl)611 TargetLibraryAnalysis(TargetLibraryInfoImpl BaselineInfoImpl) 612 : BaselineInfoImpl(std::move(BaselineInfoImpl)) {} 613 614 TargetLibraryInfo run(const Function &F, FunctionAnalysisManager &); 615 616 private: 617 friend AnalysisInfoMixin<TargetLibraryAnalysis>; 618 static AnalysisKey Key; 619 620 std::optional<TargetLibraryInfoImpl> BaselineInfoImpl; 621 }; 622 623 class TargetLibraryInfoWrapperPass : public ImmutablePass { 624 TargetLibraryAnalysis TLA; 625 std::optional<TargetLibraryInfo> TLI; 626 627 virtual void anchor(); 628 629 public: 630 static char ID; 631 TargetLibraryInfoWrapperPass(); 632 explicit TargetLibraryInfoWrapperPass(const Triple &T); 633 explicit TargetLibraryInfoWrapperPass(const TargetLibraryInfoImpl &TLI); 634 getTLI(const Function & F)635 TargetLibraryInfo &getTLI(const Function &F) { 636 FunctionAnalysisManager DummyFAM; 637 TLI = TLA.run(F, DummyFAM); 638 return *TLI; 639 } 640 }; 641 642 } // end namespace llvm 643 644 #endif 645