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