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; TargetLibraryInfo(TargetLibraryInfo && TLI)318 TargetLibraryInfo(TargetLibraryInfo &&TLI) 319 : Impl(TLI.Impl), OverrideAsUnavailable(TLI.OverrideAsUnavailable) {} 320 TargetLibraryInfo &operator=(const TargetLibraryInfo &TLI) = default; 321 TargetLibraryInfo &operator=(TargetLibraryInfo &&TLI) { 322 Impl = TLI.Impl; 323 OverrideAsUnavailable = TLI.OverrideAsUnavailable; 324 return *this; 325 } 326 327 /// Determine whether a callee with the given TLI can be inlined into 328 /// caller with this TLI, based on 'nobuiltin' attributes. When requested, 329 /// allow inlining into a caller with a superset of the callee's nobuiltin 330 /// attributes, which is conservatively correct. areInlineCompatible(const TargetLibraryInfo & CalleeTLI,bool AllowCallerSuperset)331 bool areInlineCompatible(const TargetLibraryInfo &CalleeTLI, 332 bool AllowCallerSuperset) const { 333 if (!AllowCallerSuperset) 334 return OverrideAsUnavailable == CalleeTLI.OverrideAsUnavailable; 335 BitVector B = OverrideAsUnavailable; 336 B |= CalleeTLI.OverrideAsUnavailable; 337 // We can inline if the union of the caller and callee's nobuiltin 338 // attributes is no stricter than the caller's nobuiltin attributes. 339 return B == OverrideAsUnavailable; 340 } 341 342 /// Return true if the function type FTy is valid for the library function 343 /// F, regardless of whether the function is available. isValidProtoForLibFunc(const FunctionType & FTy,LibFunc F,const Module & M)344 bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc F, 345 const Module &M) const { 346 return Impl->isValidProtoForLibFunc(FTy, F, M); 347 } 348 349 /// Searches for a particular function name. 350 /// 351 /// If it is one of the known library functions, return true and set F to the 352 /// corresponding value. getLibFunc(StringRef funcName,LibFunc & F)353 bool getLibFunc(StringRef funcName, LibFunc &F) const { 354 return Impl->getLibFunc(funcName, F); 355 } 356 getLibFunc(const Function & FDecl,LibFunc & F)357 bool getLibFunc(const Function &FDecl, LibFunc &F) const { 358 return Impl->getLibFunc(FDecl, F); 359 } 360 361 /// If a callbase does not have the 'nobuiltin' attribute, return if the 362 /// called function is a known library function and set F to that function. getLibFunc(const CallBase & CB,LibFunc & F)363 bool getLibFunc(const CallBase &CB, LibFunc &F) const { 364 return !CB.isNoBuiltin() && CB.getCalledFunction() && 365 getLibFunc(*(CB.getCalledFunction()), F); 366 } 367 368 /// Searches for a function name using an Instruction \p Opcode. 369 /// Currently, only the frem instruction is supported. getLibFunc(unsigned int Opcode,Type * Ty,LibFunc & F)370 bool getLibFunc(unsigned int Opcode, Type *Ty, LibFunc &F) const { 371 return Impl->getLibFunc(Opcode, Ty, F); 372 } 373 374 /// Disables all builtins. 375 /// 376 /// This can be used for options like -fno-builtin. disableAllFunctions()377 void disableAllFunctions() LLVM_ATTRIBUTE_UNUSED { 378 OverrideAsUnavailable.set(); 379 } 380 381 /// Forces a function to be marked as unavailable. setUnavailable(LibFunc F)382 void setUnavailable(LibFunc F) LLVM_ATTRIBUTE_UNUSED { 383 OverrideAsUnavailable.set(F); 384 } 385 getState(LibFunc F)386 TargetLibraryInfoImpl::AvailabilityState getState(LibFunc F) const { 387 if (OverrideAsUnavailable[F]) 388 return TargetLibraryInfoImpl::Unavailable; 389 return Impl->getState(F); 390 } 391 392 /// Tests whether a library function is available. has(LibFunc F)393 bool has(LibFunc F) const { 394 return getState(F) != TargetLibraryInfoImpl::Unavailable; 395 } isFunctionVectorizable(StringRef F,const ElementCount & VF)396 bool isFunctionVectorizable(StringRef F, const ElementCount &VF) const { 397 return Impl->isFunctionVectorizable(F, VF); 398 } isFunctionVectorizable(StringRef F)399 bool isFunctionVectorizable(StringRef F) const { 400 return Impl->isFunctionVectorizable(F); 401 } 402 StringRef getVectorizedFunction(StringRef F, const ElementCount &VF, 403 bool Masked = false) const { 404 return Impl->getVectorizedFunction(F, VF, Masked); 405 } getVectorMappingInfo(StringRef F,const ElementCount & VF,bool Masked)406 const VecDesc *getVectorMappingInfo(StringRef F, const ElementCount &VF, 407 bool Masked) const { 408 return Impl->getVectorMappingInfo(F, VF, Masked); 409 } 410 411 /// Tests if the function is both available and a candidate for optimized code 412 /// generation. hasOptimizedCodeGen(LibFunc F)413 bool hasOptimizedCodeGen(LibFunc F) const { 414 if (getState(F) == TargetLibraryInfoImpl::Unavailable) 415 return false; 416 switch (F) { 417 default: break; 418 case LibFunc_copysign: case LibFunc_copysignf: case LibFunc_copysignl: 419 case LibFunc_fabs: case LibFunc_fabsf: case LibFunc_fabsl: 420 case LibFunc_sin: case LibFunc_sinf: case LibFunc_sinl: 421 case LibFunc_cos: case LibFunc_cosf: case LibFunc_cosl: 422 case LibFunc_sqrt: case LibFunc_sqrtf: case LibFunc_sqrtl: 423 case LibFunc_sqrt_finite: case LibFunc_sqrtf_finite: 424 case LibFunc_sqrtl_finite: 425 case LibFunc_fmax: case LibFunc_fmaxf: case LibFunc_fmaxl: 426 case LibFunc_fmin: case LibFunc_fminf: case LibFunc_fminl: 427 case LibFunc_floor: case LibFunc_floorf: case LibFunc_floorl: 428 case LibFunc_nearbyint: case LibFunc_nearbyintf: case LibFunc_nearbyintl: 429 case LibFunc_ceil: case LibFunc_ceilf: case LibFunc_ceill: 430 case LibFunc_rint: case LibFunc_rintf: case LibFunc_rintl: 431 case LibFunc_round: case LibFunc_roundf: case LibFunc_roundl: 432 case LibFunc_trunc: case LibFunc_truncf: case LibFunc_truncl: 433 case LibFunc_log2: case LibFunc_log2f: case LibFunc_log2l: 434 case LibFunc_exp2: case LibFunc_exp2f: case LibFunc_exp2l: 435 case LibFunc_ldexp: case LibFunc_ldexpf: case LibFunc_ldexpl: 436 case LibFunc_memcpy: case LibFunc_memset: case LibFunc_memmove: 437 case LibFunc_memcmp: case LibFunc_bcmp: case LibFunc_strcmp: 438 case LibFunc_strcpy: case LibFunc_stpcpy: case LibFunc_strlen: 439 case LibFunc_strnlen: case LibFunc_memchr: case LibFunc_mempcpy: 440 return true; 441 } 442 return false; 443 } 444 getName(LibFunc F)445 StringRef getName(LibFunc F) const { 446 auto State = getState(F); 447 if (State == TargetLibraryInfoImpl::Unavailable) 448 return StringRef(); 449 if (State == TargetLibraryInfoImpl::StandardName) 450 return Impl->StandardNames[F]; 451 assert(State == TargetLibraryInfoImpl::CustomName); 452 return Impl->CustomNames.find(F)->second; 453 } 454 initExtensionsForTriple(bool & ShouldExtI32Param,bool & ShouldExtI32Return,bool & ShouldSignExtI32Param,bool & ShouldSignExtI32Return,const Triple & T)455 static void initExtensionsForTriple(bool &ShouldExtI32Param, 456 bool &ShouldExtI32Return, 457 bool &ShouldSignExtI32Param, 458 bool &ShouldSignExtI32Return, 459 const Triple &T) { 460 ShouldExtI32Param = ShouldExtI32Return = false; 461 ShouldSignExtI32Param = ShouldSignExtI32Return = false; 462 463 // PowerPC64, Sparc64, SystemZ need signext/zeroext on i32 parameters and 464 // returns corresponding to C-level ints and unsigned ints. 465 if (T.isPPC64() || T.getArch() == Triple::sparcv9 || 466 T.getArch() == Triple::systemz) { 467 ShouldExtI32Param = true; 468 ShouldExtI32Return = true; 469 } 470 // LoongArch, Mips, and riscv64, on the other hand, need signext on i32 471 // parameters corresponding to both signed and unsigned ints. 472 if (T.isLoongArch() || T.isMIPS() || T.isRISCV64()) { 473 ShouldSignExtI32Param = true; 474 } 475 // LoongArch and riscv64 need signext on i32 returns corresponding to both 476 // signed and unsigned ints. 477 if (T.isLoongArch() || T.isRISCV64()) { 478 ShouldSignExtI32Return = true; 479 } 480 } 481 482 /// Returns extension attribute kind to be used for i32 parameters 483 /// corresponding to C-level int or unsigned int. May be zeroext, signext, 484 /// or none. 485 private: 486 static Attribute::AttrKind getExtAttrForI32Param(bool ShouldExtI32Param_, 487 bool ShouldSignExtI32Param_, 488 bool Signed = true) { 489 if (ShouldExtI32Param_) 490 return Signed ? Attribute::SExt : Attribute::ZExt; 491 if (ShouldSignExtI32Param_) 492 return Attribute::SExt; 493 return Attribute::None; 494 } 495 496 public: 497 static Attribute::AttrKind getExtAttrForI32Param(const Triple &T, 498 bool Signed = true) { 499 bool ShouldExtI32Param, ShouldExtI32Return; 500 bool ShouldSignExtI32Param, ShouldSignExtI32Return; 501 initExtensionsForTriple(ShouldExtI32Param, ShouldExtI32Return, 502 ShouldSignExtI32Param, ShouldSignExtI32Return, T); 503 return getExtAttrForI32Param(ShouldExtI32Param, ShouldSignExtI32Param, 504 Signed); 505 } 506 507 Attribute::AttrKind getExtAttrForI32Param(bool Signed = true) const { 508 return getExtAttrForI32Param(Impl->ShouldExtI32Param, 509 Impl->ShouldSignExtI32Param, Signed); 510 } 511 512 /// Returns extension attribute kind to be used for i32 return values 513 /// corresponding to C-level int or unsigned int. May be zeroext, signext, 514 /// or none. 515 private: getExtAttrForI32Return(bool ShouldExtI32Return_,bool ShouldSignExtI32Return_,bool Signed)516 static Attribute::AttrKind getExtAttrForI32Return(bool ShouldExtI32Return_, 517 bool ShouldSignExtI32Return_, 518 bool Signed) { 519 if (ShouldExtI32Return_) 520 return Signed ? Attribute::SExt : Attribute::ZExt; 521 if (ShouldSignExtI32Return_) 522 return Attribute::SExt; 523 return Attribute::None; 524 } 525 526 public: 527 static Attribute::AttrKind getExtAttrForI32Return(const Triple &T, 528 bool Signed = true) { 529 bool ShouldExtI32Param, ShouldExtI32Return; 530 bool ShouldSignExtI32Param, ShouldSignExtI32Return; 531 initExtensionsForTriple(ShouldExtI32Param, ShouldExtI32Return, 532 ShouldSignExtI32Param, ShouldSignExtI32Return, T); 533 return getExtAttrForI32Return(ShouldExtI32Return, ShouldSignExtI32Return, 534 Signed); 535 } 536 537 Attribute::AttrKind getExtAttrForI32Return(bool Signed = true) const { 538 return getExtAttrForI32Return(Impl->ShouldExtI32Return, 539 Impl->ShouldSignExtI32Return, Signed); 540 } 541 542 // Helper to create an AttributeList for args (and ret val) which all have 543 // the same signedness. Attributes in AL may be passed in to include them 544 // as well in the returned AttributeList. 545 AttributeList getAttrList(LLVMContext *C, ArrayRef<unsigned> ArgNos, 546 bool Signed, bool Ret = false, 547 AttributeList AL = AttributeList()) const { 548 if (auto AK = getExtAttrForI32Param(Signed)) 549 for (auto ArgNo : ArgNos) 550 AL = AL.addParamAttribute(*C, ArgNo, AK); 551 if (Ret) 552 if (auto AK = getExtAttrForI32Return(Signed)) 553 AL = AL.addRetAttribute(*C, AK); 554 return AL; 555 } 556 557 /// \copydoc TargetLibraryInfoImpl::getWCharSize() getWCharSize(const Module & M)558 unsigned getWCharSize(const Module &M) const { 559 return Impl->getWCharSize(M); 560 } 561 562 /// \copydoc TargetLibraryInfoImpl::getSizeTSize() getSizeTSize(const Module & M)563 unsigned getSizeTSize(const Module &M) const { return Impl->getSizeTSize(M); } 564 565 /// \copydoc TargetLibraryInfoImpl::getIntSize() getIntSize()566 unsigned getIntSize() const { 567 return Impl->getIntSize(); 568 } 569 570 /// Handle invalidation from the pass manager. 571 /// 572 /// If we try to invalidate this info, just return false. It cannot become 573 /// invalid even if the module or function changes. invalidate(Module &,const PreservedAnalyses &,ModuleAnalysisManager::Invalidator &)574 bool invalidate(Module &, const PreservedAnalyses &, 575 ModuleAnalysisManager::Invalidator &) { 576 return false; 577 } invalidate(Function &,const PreservedAnalyses &,FunctionAnalysisManager::Invalidator &)578 bool invalidate(Function &, const PreservedAnalyses &, 579 FunctionAnalysisManager::Invalidator &) { 580 return false; 581 } 582 /// Returns the largest vectorization factor used in the list of 583 /// vector functions. getWidestVF(StringRef ScalarF,ElementCount & FixedVF,ElementCount & ScalableVF)584 void getWidestVF(StringRef ScalarF, ElementCount &FixedVF, 585 ElementCount &ScalableVF) const { 586 Impl->getWidestVF(ScalarF, FixedVF, ScalableVF); 587 } 588 589 /// Check if the function "F" is listed in a library known to LLVM. isKnownVectorFunctionInLibrary(StringRef F)590 bool isKnownVectorFunctionInLibrary(StringRef F) const { 591 return this->isFunctionVectorizable(F); 592 } 593 }; 594 595 /// Analysis pass providing the \c TargetLibraryInfo. 596 /// 597 /// Note that this pass's result cannot be invalidated, it is immutable for the 598 /// life of the module. 599 class TargetLibraryAnalysis : public AnalysisInfoMixin<TargetLibraryAnalysis> { 600 public: 601 typedef TargetLibraryInfo Result; 602 603 /// Default construct the library analysis. 604 /// 605 /// This will use the module's triple to construct the library info for that 606 /// module. 607 TargetLibraryAnalysis() = default; 608 609 /// Construct a library analysis with baseline Module-level info. 610 /// 611 /// This will be supplemented with Function-specific info in the Result. TargetLibraryAnalysis(TargetLibraryInfoImpl BaselineInfoImpl)612 TargetLibraryAnalysis(TargetLibraryInfoImpl BaselineInfoImpl) 613 : BaselineInfoImpl(std::move(BaselineInfoImpl)) {} 614 615 TargetLibraryInfo run(const Function &F, FunctionAnalysisManager &); 616 617 private: 618 friend AnalysisInfoMixin<TargetLibraryAnalysis>; 619 static AnalysisKey Key; 620 621 std::optional<TargetLibraryInfoImpl> BaselineInfoImpl; 622 }; 623 624 class TargetLibraryInfoWrapperPass : public ImmutablePass { 625 TargetLibraryAnalysis TLA; 626 std::optional<TargetLibraryInfo> TLI; 627 628 virtual void anchor(); 629 630 public: 631 static char ID; 632 TargetLibraryInfoWrapperPass(); 633 explicit TargetLibraryInfoWrapperPass(const Triple &T); 634 explicit TargetLibraryInfoWrapperPass(const TargetLibraryInfoImpl &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