| 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; |
| 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 | |
| 60 | StringRef getScalarFnName() const { return ScalarFnName; } |
| 61 | StringRef getVectorFnName() const { return VectorFnName; } |
| 62 | ElementCount getVectorizationFactor() const { return VectorizationFactor; } |
| 63 | bool isMasked() const { return Masked; } |
| 64 | StringRef getVABIPrefix() const { return VABIPrefix; } |
| 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 | }; |
| 100 | void setState(LibFunc F, AvailabilityState State) { |
| 101 | AvailableArray[F/4] &= ~(3 << 2*(F&3)); |
| 102 | AvailableArray[F/4] |= State << 2*(F&3); |
| 103 | } |
| 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 | LLVM_ABI 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. |
| 168 | void setUnavailable(LibFunc F) { |
| 169 | setState(F, State: Unavailable); |
| 170 | } |
| 171 | |
| 172 | /// Forces a function to be marked as available. |
| 173 | void setAvailable(LibFunc F) { |
| 174 | setState(F, State: StandardName); |
| 175 | } |
| 176 | |
| 177 | /// Forces a function to be marked as available and provide an alternate name |
| 178 | /// that must be used. |
| 179 | void setAvailableWithName(LibFunc F, StringRef Name) { |
| 180 | if (StandardNames[F] != Name) { |
| 181 | setState(F, State: CustomName); |
| 182 | CustomNames[F] = std::string(Name); |
| 183 | assert(CustomNames.contains(F)); |
| 184 | } else { |
| 185 | setState(F, State: 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. |
| 206 | bool isFunctionVectorizable(StringRef F, const ElementCount &VF) const { |
| 207 | return !(getVectorizedFunction(F, VF, Masked: false).empty() && |
| 208 | getVectorizedFunction(F, VF, Masked: 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. |
| 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. |
| 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. |
| 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. |
| 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. |
| 260 | unsigned getIntSize() const { |
| 261 | return SizeOfInt; |
| 262 | } |
| 263 | |
| 264 | /// Initialize the C-level size of an integer. |
| 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(Kind: "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(Prefix: "no-builtin-" )) |
| 315 | continue; |
| 316 | if (getLibFunc(funcName: AttrStr, F&: 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. |
| 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. |
| 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. |
| 352 | bool getLibFunc(StringRef funcName, LibFunc &F) const { |
| 353 | return Impl->getLibFunc(funcName, F); |
| 354 | } |
| 355 | |
| 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. |
| 362 | bool getLibFunc(const CallBase &CB, LibFunc &F) const { |
| 363 | return !CB.isNoBuiltin() && CB.getCalledFunction() && |
| 364 | getLibFunc(FDecl: *(CB.getCalledFunction()), F); |
| 365 | } |
| 366 | |
| 367 | /// Searches for a function name using an Instruction \p Opcode. |
| 368 | /// Currently, only the frem instruction is supported. |
| 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. |
| 376 | void disableAllFunctions() LLVM_ATTRIBUTE_UNUSED { |
| 377 | OverrideAsUnavailable.set(); |
| 378 | } |
| 379 | |
| 380 | /// Forces a function to be marked as unavailable. |
| 381 | void setUnavailable(LibFunc F) LLVM_ATTRIBUTE_UNUSED { |
| 382 | assert(F < OverrideAsUnavailable.size() && "out-of-bounds LibFunc" ); |
| 383 | OverrideAsUnavailable.set(position: F); |
| 384 | } |
| 385 | |
| 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. |
| 394 | bool has(LibFunc F) const { |
| 395 | return getState(F) != TargetLibraryInfoImpl::Unavailable; |
| 396 | } |
| 397 | bool isFunctionVectorizable(StringRef F, const ElementCount &VF) const { |
| 398 | return Impl->isFunctionVectorizable(F, VF); |
| 399 | } |
| 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 | } |
| 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. |
| 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 | |
| 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(Val: F)->second; |
| 465 | } |
| 466 | |
| 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_: ShouldExtI32Param, ShouldSignExtI32Param_: ShouldSignExtI32Param, |
| 516 | Signed); |
| 517 | } |
| 518 | |
| 519 | Attribute::AttrKind getExtAttrForI32Param(bool Signed = true) const { |
| 520 | return getExtAttrForI32Param(ShouldExtI32Param_: Impl->ShouldExtI32Param, |
| 521 | ShouldSignExtI32Param_: 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: |
| 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_: ShouldExtI32Return, ShouldSignExtI32Return_: ShouldSignExtI32Return, |
| 546 | Signed); |
| 547 | } |
| 548 | |
| 549 | Attribute::AttrKind getExtAttrForI32Return(bool Signed = true) const { |
| 550 | return getExtAttrForI32Return(ShouldExtI32Return_: Impl->ShouldExtI32Return, |
| 551 | ShouldSignExtI32Return_: 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&: *C, ArgNo, Kind: AK); |
| 563 | if (Ret) |
| 564 | if (auto AK = getExtAttrForI32Return(Signed)) |
| 565 | AL = AL.addRetAttribute(C&: *C, Kind: AK); |
| 566 | return AL; |
| 567 | } |
| 568 | |
| 569 | /// \copydoc TargetLibraryInfoImpl::getWCharSize() |
| 570 | unsigned getWCharSize(const Module &M) const { |
| 571 | return Impl->getWCharSize(M); |
| 572 | } |
| 573 | |
| 574 | /// \copydoc TargetLibraryInfoImpl::getSizeTSize() |
| 575 | unsigned getSizeTSize(const Module &M) const { return Impl->getSizeTSize(M); } |
| 576 | |
| 577 | /// Returns an IntegerType corresponding to size_t. |
| 578 | IntegerType *getSizeTType(const Module &M) const { |
| 579 | return IntegerType::get(C&: M.getContext(), NumBits: getSizeTSize(M)); |
| 580 | } |
| 581 | |
| 582 | /// Returns a constant materialized as a size_t type. |
| 583 | ConstantInt *getAsSizeT(uint64_t V, const Module &M) const { |
| 584 | return ConstantInt::get(Ty: getSizeTType(M), V); |
| 585 | } |
| 586 | |
| 587 | /// \copydoc TargetLibraryInfoImpl::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. |
| 596 | bool invalidate(Module &, const PreservedAnalyses &, |
| 597 | ModuleAnalysisManager::Invalidator &) { |
| 598 | return false; |
| 599 | } |
| 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. |
| 606 | void getWidestVF(StringRef ScalarF, ElementCount &FixedVF, |
| 607 | ElementCount &ScalableVF) const { |
| 608 | Impl->getWidestVF(ScalarF, FixedVF, Scalable&: ScalableVF); |
| 609 | } |
| 610 | |
| 611 | /// Check if the function "F" is listed in a library known to LLVM. |
| 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. |
| 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 | |
| 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 | |