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 | |