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