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 AMDLIBM // AMD Math Vector library. 134 }; 135 136 TargetLibraryInfoImpl(); 137 explicit TargetLibraryInfoImpl(const Triple &T); 138 139 // Provide value semantics. 140 TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI); 141 TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI); 142 TargetLibraryInfoImpl &operator=(const TargetLibraryInfoImpl &TLI); 143 TargetLibraryInfoImpl &operator=(TargetLibraryInfoImpl &&TLI); 144 145 /// Searches for a particular function name. 146 /// 147 /// If it is one of the known library functions, return true and set F to the 148 /// corresponding value. 149 bool getLibFunc(StringRef funcName, LibFunc &F) const; 150 151 /// Searches for a particular function name, also checking that its type is 152 /// valid for the library function matching that name. 153 /// 154 /// If it is one of the known library functions, return true and set F to the 155 /// corresponding value. 156 /// 157 /// FDecl is assumed to have a parent Module when using this function. 158 bool getLibFunc(const Function &FDecl, LibFunc &F) const; 159 160 /// Searches for a function name using an Instruction \p Opcode. 161 /// Currently, only the frem instruction is supported. 162 bool getLibFunc(unsigned int Opcode, Type *Ty, LibFunc &F) const; 163 164 /// Forces a function to be marked as unavailable. setUnavailable(LibFunc F)165 void setUnavailable(LibFunc F) { 166 setState(F, Unavailable); 167 } 168 169 /// Forces a function to be marked as available. setAvailable(LibFunc F)170 void setAvailable(LibFunc F) { 171 setState(F, StandardName); 172 } 173 174 /// Forces a function to be marked as available and provide an alternate name 175 /// that must be used. setAvailableWithName(LibFunc F,StringRef Name)176 void setAvailableWithName(LibFunc F, StringRef Name) { 177 if (StandardNames[F] != Name) { 178 setState(F, CustomName); 179 CustomNames[F] = std::string(Name); 180 assert(CustomNames.contains(F)); 181 } else { 182 setState(F, StandardName); 183 } 184 } 185 186 /// Disables all builtins. 187 /// 188 /// This can be used for options like -fno-builtin. 189 void disableAllFunctions(); 190 191 /// Add a set of scalar -> vector mappings, queryable via 192 /// getVectorizedFunction and getScalarizedFunction. 193 void addVectorizableFunctions(ArrayRef<VecDesc> Fns); 194 195 /// Calls addVectorizableFunctions with a known preset of functions for the 196 /// given vector library. 197 void addVectorizableFunctionsFromVecLib(enum VectorLibrary VecLib, 198 const llvm::Triple &TargetTriple); 199 200 /// Return true if the function F has a vector equivalent with vectorization 201 /// factor VF. isFunctionVectorizable(StringRef F,const ElementCount & VF)202 bool isFunctionVectorizable(StringRef F, const ElementCount &VF) const { 203 return !(getVectorizedFunction(F, VF, false).empty() && 204 getVectorizedFunction(F, VF, true).empty()); 205 } 206 207 /// Return true if the function F has a vector equivalent with any 208 /// vectorization factor. 209 bool isFunctionVectorizable(StringRef F) const; 210 211 /// Return the name of the equivalent of F, vectorized with factor VF. If no 212 /// such mapping exists, return the empty string. 213 StringRef getVectorizedFunction(StringRef F, const ElementCount &VF, 214 bool Masked) const; 215 216 /// Return a pointer to a VecDesc object holding all info for scalar to vector 217 /// mappings in TLI for the equivalent of F, vectorized with factor VF. 218 /// If no such mapping exists, return nullpointer. 219 const VecDesc *getVectorMappingInfo(StringRef F, const ElementCount &VF, 220 bool Masked) const; 221 222 /// Set to true iff i32 parameters to library functions should have signext 223 /// or zeroext attributes if they correspond to C-level int or unsigned int, 224 /// respectively. setShouldExtI32Param(bool Val)225 void setShouldExtI32Param(bool Val) { 226 ShouldExtI32Param = Val; 227 } 228 229 /// Set to true iff i32 results from library functions should have signext 230 /// or zeroext attributes if they correspond to C-level int or unsigned int, 231 /// respectively. setShouldExtI32Return(bool Val)232 void setShouldExtI32Return(bool Val) { 233 ShouldExtI32Return = Val; 234 } 235 236 /// Set to true iff i32 parameters to library functions should have signext 237 /// attribute if they correspond to C-level int or unsigned int. setShouldSignExtI32Param(bool Val)238 void setShouldSignExtI32Param(bool Val) { 239 ShouldSignExtI32Param = Val; 240 } 241 242 /// Set to true iff i32 results from library functions should have signext 243 /// attribute if they correspond to C-level int or unsigned int. setShouldSignExtI32Return(bool Val)244 void setShouldSignExtI32Return(bool Val) { 245 ShouldSignExtI32Return = Val; 246 } 247 248 /// Returns the size of the wchar_t type in bytes or 0 if the size is unknown. 249 /// This queries the 'wchar_size' metadata. 250 unsigned getWCharSize(const Module &M) const; 251 252 /// Returns the size of the size_t type in bits. 253 unsigned getSizeTSize(const Module &M) const; 254 255 /// Get size of a C-level int or unsigned int, in bits. getIntSize()256 unsigned getIntSize() const { 257 return SizeOfInt; 258 } 259 260 /// Initialize the C-level size of an integer. setIntSize(unsigned Bits)261 void setIntSize(unsigned Bits) { 262 SizeOfInt = Bits; 263 } 264 265 /// Returns the largest vectorization factor used in the list of 266 /// vector functions. 267 void getWidestVF(StringRef ScalarF, ElementCount &FixedVF, 268 ElementCount &Scalable) const; 269 270 /// Returns true if call site / callee has cdecl-compatible calling 271 /// conventions. 272 static bool isCallingConvCCompatible(CallBase *CI); 273 static bool isCallingConvCCompatible(Function *Callee); 274 }; 275 276 /// Provides information about what library functions are available for 277 /// the current target. 278 /// 279 /// This both allows optimizations to handle them specially and frontends to 280 /// disable such optimizations through -fno-builtin etc. 281 class TargetLibraryInfo { 282 friend class TargetLibraryAnalysis; 283 friend class TargetLibraryInfoWrapperPass; 284 285 /// The global (module level) TLI info. 286 const TargetLibraryInfoImpl *Impl; 287 288 /// Support for -fno-builtin* options as function attributes, overrides 289 /// information in global TargetLibraryInfoImpl. 290 BitVector OverrideAsUnavailable; 291 292 public: 293 explicit TargetLibraryInfo(const TargetLibraryInfoImpl &Impl, 294 std::optional<const Function *> F = std::nullopt) 295 : Impl(&Impl), OverrideAsUnavailable(NumLibFuncs) { 296 if (!F) 297 return; 298 if ((*F)->hasFnAttribute("no-builtins")) 299 disableAllFunctions(); 300 else { 301 // Disable individual libc/libm calls in TargetLibraryInfo. 302 LibFunc LF; 303 AttributeSet FnAttrs = (*F)->getAttributes().getFnAttrs(); 304 for (const Attribute &Attr : FnAttrs) { 305 if (!Attr.isStringAttribute()) 306 continue; 307 auto AttrStr = Attr.getKindAsString(); 308 if (!AttrStr.consume_front("no-builtin-")) 309 continue; 310 if (getLibFunc(AttrStr, LF)) 311 setUnavailable(LF); 312 } 313 } 314 } 315 316 // Provide value semantics. 317 TargetLibraryInfo(const TargetLibraryInfo &TLI) = default; 318 TargetLibraryInfo(TargetLibraryInfo &&TLI) = default; 319 TargetLibraryInfo &operator=(const TargetLibraryInfo &TLI) = default; 320 TargetLibraryInfo &operator=(TargetLibraryInfo &&TLI) = default; 321 322 /// Determine whether a callee with the given TLI can be inlined into 323 /// caller with this TLI, based on 'nobuiltin' attributes. When requested, 324 /// allow inlining into a caller with a superset of the callee's nobuiltin 325 /// attributes, which is conservatively correct. areInlineCompatible(const TargetLibraryInfo & CalleeTLI,bool AllowCallerSuperset)326 bool areInlineCompatible(const TargetLibraryInfo &CalleeTLI, 327 bool AllowCallerSuperset) const { 328 if (!AllowCallerSuperset) 329 return OverrideAsUnavailable == CalleeTLI.OverrideAsUnavailable; 330 // We can inline if the callee's nobuiltin attributes are no stricter than 331 // the caller's. 332 return !CalleeTLI.OverrideAsUnavailable.test(OverrideAsUnavailable); 333 } 334 335 /// Return true if the function type FTy is valid for the library function 336 /// F, regardless of whether the function is available. isValidProtoForLibFunc(const FunctionType & FTy,LibFunc F,const Module & M)337 bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc F, 338 const Module &M) const { 339 return Impl->isValidProtoForLibFunc(FTy, F, M); 340 } 341 342 /// Searches for a particular function name. 343 /// 344 /// If it is one of the known library functions, return true and set F to the 345 /// corresponding value. getLibFunc(StringRef funcName,LibFunc & F)346 bool getLibFunc(StringRef funcName, LibFunc &F) const { 347 return Impl->getLibFunc(funcName, F); 348 } 349 getLibFunc(const Function & FDecl,LibFunc & F)350 bool getLibFunc(const Function &FDecl, LibFunc &F) const { 351 return Impl->getLibFunc(FDecl, F); 352 } 353 354 /// If a callbase does not have the 'nobuiltin' attribute, return if the 355 /// called function is a known library function and set F to that function. getLibFunc(const CallBase & CB,LibFunc & F)356 bool getLibFunc(const CallBase &CB, LibFunc &F) const { 357 return !CB.isNoBuiltin() && CB.getCalledFunction() && 358 getLibFunc(*(CB.getCalledFunction()), F); 359 } 360 361 /// Searches for a function name using an Instruction \p Opcode. 362 /// Currently, only the frem instruction is supported. getLibFunc(unsigned int Opcode,Type * Ty,LibFunc & F)363 bool getLibFunc(unsigned int Opcode, Type *Ty, LibFunc &F) const { 364 return Impl->getLibFunc(Opcode, Ty, F); 365 } 366 367 /// Disables all builtins. 368 /// 369 /// This can be used for options like -fno-builtin. disableAllFunctions()370 void disableAllFunctions() LLVM_ATTRIBUTE_UNUSED { 371 OverrideAsUnavailable.set(); 372 } 373 374 /// Forces a function to be marked as unavailable. setUnavailable(LibFunc F)375 void setUnavailable(LibFunc F) LLVM_ATTRIBUTE_UNUSED { 376 OverrideAsUnavailable.set(F); 377 } 378 getState(LibFunc F)379 TargetLibraryInfoImpl::AvailabilityState getState(LibFunc F) const { 380 if (OverrideAsUnavailable[F]) 381 return TargetLibraryInfoImpl::Unavailable; 382 return Impl->getState(F); 383 } 384 385 /// Tests whether a library function is available. has(LibFunc F)386 bool has(LibFunc F) const { 387 return getState(F) != TargetLibraryInfoImpl::Unavailable; 388 } isFunctionVectorizable(StringRef F,const ElementCount & VF)389 bool isFunctionVectorizable(StringRef F, const ElementCount &VF) const { 390 return Impl->isFunctionVectorizable(F, VF); 391 } isFunctionVectorizable(StringRef F)392 bool isFunctionVectorizable(StringRef F) const { 393 return Impl->isFunctionVectorizable(F); 394 } 395 StringRef getVectorizedFunction(StringRef F, const ElementCount &VF, 396 bool Masked = false) const { 397 return Impl->getVectorizedFunction(F, VF, Masked); 398 } getVectorMappingInfo(StringRef F,const ElementCount & VF,bool Masked)399 const VecDesc *getVectorMappingInfo(StringRef F, const ElementCount &VF, 400 bool Masked) const { 401 return Impl->getVectorMappingInfo(F, VF, Masked); 402 } 403 404 /// Tests if the function is both available and a candidate for optimized code 405 /// generation. hasOptimizedCodeGen(LibFunc F)406 bool hasOptimizedCodeGen(LibFunc F) const { 407 if (getState(F) == TargetLibraryInfoImpl::Unavailable) 408 return false; 409 switch (F) { 410 default: break; 411 // clang-format off 412 case LibFunc_copysign: case LibFunc_copysignf: case LibFunc_copysignl: 413 case LibFunc_fabs: case LibFunc_fabsf: case LibFunc_fabsl: 414 case LibFunc_sin: case LibFunc_sinf: case LibFunc_sinl: 415 case LibFunc_cos: case LibFunc_cosf: case LibFunc_cosl: 416 case LibFunc_tan: case LibFunc_tanf: case LibFunc_tanl: 417 case LibFunc_sqrt: case LibFunc_sqrtf: case LibFunc_sqrtl: 418 case LibFunc_sqrt_finite: case LibFunc_sqrtf_finite: 419 case LibFunc_sqrtl_finite: 420 case LibFunc_fmax: case LibFunc_fmaxf: case LibFunc_fmaxl: 421 case LibFunc_fmin: case LibFunc_fminf: case LibFunc_fminl: 422 case LibFunc_floor: case LibFunc_floorf: case LibFunc_floorl: 423 case LibFunc_nearbyint: case LibFunc_nearbyintf: case LibFunc_nearbyintl: 424 case LibFunc_ceil: case LibFunc_ceilf: case LibFunc_ceill: 425 case LibFunc_rint: case LibFunc_rintf: case LibFunc_rintl: 426 case LibFunc_round: case LibFunc_roundf: case LibFunc_roundl: 427 case LibFunc_trunc: case LibFunc_truncf: case LibFunc_truncl: 428 case LibFunc_log2: case LibFunc_log2f: case LibFunc_log2l: 429 case LibFunc_exp2: case LibFunc_exp2f: case LibFunc_exp2l: 430 case LibFunc_ldexp: case LibFunc_ldexpf: case LibFunc_ldexpl: 431 case LibFunc_memcpy: case LibFunc_memset: case LibFunc_memmove: 432 case LibFunc_memcmp: case LibFunc_bcmp: case LibFunc_strcmp: 433 case LibFunc_strcpy: case LibFunc_stpcpy: case LibFunc_strlen: 434 case LibFunc_strnlen: case LibFunc_memchr: case LibFunc_mempcpy: 435 // clang-format on 436 return true; 437 } 438 return false; 439 } 440 getName(LibFunc F)441 StringRef getName(LibFunc F) const { 442 auto State = getState(F); 443 if (State == TargetLibraryInfoImpl::Unavailable) 444 return StringRef(); 445 if (State == TargetLibraryInfoImpl::StandardName) 446 return Impl->StandardNames[F]; 447 assert(State == TargetLibraryInfoImpl::CustomName); 448 return Impl->CustomNames.find(F)->second; 449 } 450 initExtensionsForTriple(bool & ShouldExtI32Param,bool & ShouldExtI32Return,bool & ShouldSignExtI32Param,bool & ShouldSignExtI32Return,const Triple & T)451 static void initExtensionsForTriple(bool &ShouldExtI32Param, 452 bool &ShouldExtI32Return, 453 bool &ShouldSignExtI32Param, 454 bool &ShouldSignExtI32Return, 455 const Triple &T) { 456 ShouldExtI32Param = ShouldExtI32Return = false; 457 ShouldSignExtI32Param = ShouldSignExtI32Return = false; 458 459 // PowerPC64, Sparc64, SystemZ need signext/zeroext on i32 parameters and 460 // returns corresponding to C-level ints and unsigned ints. 461 if (T.isPPC64() || T.getArch() == Triple::sparcv9 || 462 T.getArch() == Triple::systemz) { 463 ShouldExtI32Param = true; 464 ShouldExtI32Return = true; 465 } 466 // LoongArch, Mips, and riscv64, on the other hand, need signext on i32 467 // parameters corresponding to both signed and unsigned ints. 468 if (T.isLoongArch() || T.isMIPS() || T.isRISCV64()) { 469 ShouldSignExtI32Param = true; 470 } 471 // LoongArch and riscv64 need signext on i32 returns corresponding to both 472 // signed and unsigned ints. 473 if (T.isLoongArch() || T.isRISCV64()) { 474 ShouldSignExtI32Return = true; 475 } 476 } 477 478 /// Returns extension attribute kind to be used for i32 parameters 479 /// corresponding to C-level int or unsigned int. May be zeroext, signext, 480 /// or none. 481 private: 482 static Attribute::AttrKind getExtAttrForI32Param(bool ShouldExtI32Param_, 483 bool ShouldSignExtI32Param_, 484 bool Signed = true) { 485 if (ShouldExtI32Param_) 486 return Signed ? Attribute::SExt : Attribute::ZExt; 487 if (ShouldSignExtI32Param_) 488 return Attribute::SExt; 489 return Attribute::None; 490 } 491 492 public: 493 static Attribute::AttrKind getExtAttrForI32Param(const Triple &T, 494 bool Signed = true) { 495 bool ShouldExtI32Param, ShouldExtI32Return; 496 bool ShouldSignExtI32Param, ShouldSignExtI32Return; 497 initExtensionsForTriple(ShouldExtI32Param, ShouldExtI32Return, 498 ShouldSignExtI32Param, ShouldSignExtI32Return, T); 499 return getExtAttrForI32Param(ShouldExtI32Param, ShouldSignExtI32Param, 500 Signed); 501 } 502 503 Attribute::AttrKind getExtAttrForI32Param(bool Signed = true) const { 504 return getExtAttrForI32Param(Impl->ShouldExtI32Param, 505 Impl->ShouldSignExtI32Param, Signed); 506 } 507 508 /// Returns extension attribute kind to be used for i32 return values 509 /// corresponding to C-level int or unsigned int. May be zeroext, signext, 510 /// or none. 511 private: getExtAttrForI32Return(bool ShouldExtI32Return_,bool ShouldSignExtI32Return_,bool Signed)512 static Attribute::AttrKind getExtAttrForI32Return(bool ShouldExtI32Return_, 513 bool ShouldSignExtI32Return_, 514 bool Signed) { 515 if (ShouldExtI32Return_) 516 return Signed ? Attribute::SExt : Attribute::ZExt; 517 if (ShouldSignExtI32Return_) 518 return Attribute::SExt; 519 return Attribute::None; 520 } 521 522 public: 523 static Attribute::AttrKind getExtAttrForI32Return(const Triple &T, 524 bool Signed = true) { 525 bool ShouldExtI32Param, ShouldExtI32Return; 526 bool ShouldSignExtI32Param, ShouldSignExtI32Return; 527 initExtensionsForTriple(ShouldExtI32Param, ShouldExtI32Return, 528 ShouldSignExtI32Param, ShouldSignExtI32Return, T); 529 return getExtAttrForI32Return(ShouldExtI32Return, ShouldSignExtI32Return, 530 Signed); 531 } 532 533 Attribute::AttrKind getExtAttrForI32Return(bool Signed = true) const { 534 return getExtAttrForI32Return(Impl->ShouldExtI32Return, 535 Impl->ShouldSignExtI32Return, Signed); 536 } 537 538 // Helper to create an AttributeList for args (and ret val) which all have 539 // the same signedness. Attributes in AL may be passed in to include them 540 // as well in the returned AttributeList. 541 AttributeList getAttrList(LLVMContext *C, ArrayRef<unsigned> ArgNos, 542 bool Signed, bool Ret = false, 543 AttributeList AL = AttributeList()) const { 544 if (auto AK = getExtAttrForI32Param(Signed)) 545 for (auto ArgNo : ArgNos) 546 AL = AL.addParamAttribute(*C, ArgNo, AK); 547 if (Ret) 548 if (auto AK = getExtAttrForI32Return(Signed)) 549 AL = AL.addRetAttribute(*C, AK); 550 return AL; 551 } 552 553 /// \copydoc TargetLibraryInfoImpl::getWCharSize() getWCharSize(const Module & M)554 unsigned getWCharSize(const Module &M) const { 555 return Impl->getWCharSize(M); 556 } 557 558 /// \copydoc TargetLibraryInfoImpl::getSizeTSize() getSizeTSize(const Module & M)559 unsigned getSizeTSize(const Module &M) const { return Impl->getSizeTSize(M); } 560 561 /// \copydoc TargetLibraryInfoImpl::getIntSize() getIntSize()562 unsigned getIntSize() const { 563 return Impl->getIntSize(); 564 } 565 566 /// Handle invalidation from the pass manager. 567 /// 568 /// If we try to invalidate this info, just return false. It cannot become 569 /// invalid even if the module or function changes. invalidate(Module &,const PreservedAnalyses &,ModuleAnalysisManager::Invalidator &)570 bool invalidate(Module &, const PreservedAnalyses &, 571 ModuleAnalysisManager::Invalidator &) { 572 return false; 573 } invalidate(Function &,const PreservedAnalyses &,FunctionAnalysisManager::Invalidator &)574 bool invalidate(Function &, const PreservedAnalyses &, 575 FunctionAnalysisManager::Invalidator &) { 576 return false; 577 } 578 /// Returns the largest vectorization factor used in the list of 579 /// vector functions. getWidestVF(StringRef ScalarF,ElementCount & FixedVF,ElementCount & ScalableVF)580 void getWidestVF(StringRef ScalarF, ElementCount &FixedVF, 581 ElementCount &ScalableVF) const { 582 Impl->getWidestVF(ScalarF, FixedVF, ScalableVF); 583 } 584 585 /// Check if the function "F" is listed in a library known to LLVM. isKnownVectorFunctionInLibrary(StringRef F)586 bool isKnownVectorFunctionInLibrary(StringRef F) const { 587 return this->isFunctionVectorizable(F); 588 } 589 }; 590 591 /// Analysis pass providing the \c TargetLibraryInfo. 592 /// 593 /// Note that this pass's result cannot be invalidated, it is immutable for the 594 /// life of the module. 595 class TargetLibraryAnalysis : public AnalysisInfoMixin<TargetLibraryAnalysis> { 596 public: 597 typedef TargetLibraryInfo Result; 598 599 /// Default construct the library analysis. 600 /// 601 /// This will use the module's triple to construct the library info for that 602 /// module. 603 TargetLibraryAnalysis() = default; 604 605 /// Construct a library analysis with baseline Module-level info. 606 /// 607 /// This will be supplemented with Function-specific info in the Result. TargetLibraryAnalysis(TargetLibraryInfoImpl BaselineInfoImpl)608 TargetLibraryAnalysis(TargetLibraryInfoImpl BaselineInfoImpl) 609 : BaselineInfoImpl(std::move(BaselineInfoImpl)) {} 610 611 TargetLibraryInfo run(const Function &F, FunctionAnalysisManager &); 612 613 private: 614 friend AnalysisInfoMixin<TargetLibraryAnalysis>; 615 static AnalysisKey Key; 616 617 std::optional<TargetLibraryInfoImpl> BaselineInfoImpl; 618 }; 619 620 class TargetLibraryInfoWrapperPass : public ImmutablePass { 621 TargetLibraryAnalysis TLA; 622 std::optional<TargetLibraryInfo> TLI; 623 624 virtual void anchor(); 625 626 public: 627 static char ID; 628 TargetLibraryInfoWrapperPass(); 629 explicit TargetLibraryInfoWrapperPass(const Triple &T); 630 explicit TargetLibraryInfoWrapperPass(const TargetLibraryInfoImpl &TLI); 631 632 // FIXME: This should be removed when PlaceSafepoints is fixed to not create a 633 // PassManager inside a pass. 634 explicit TargetLibraryInfoWrapperPass(const TargetLibraryInfo &TLI); 635 getTLI(const Function & F)636 TargetLibraryInfo &getTLI(const Function &F) { 637 FunctionAnalysisManager DummyFAM; 638 TLI = TLA.run(F, DummyFAM); 639 return *TLI; 640 } 641 }; 642 643 } // end namespace llvm 644 645 #endif 646