1//===-- TargetLibraryInfo.h - Library information ---------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_ANALYSIS_TARGETLIBRARYINFO_H
10#define LLVM_ANALYSIS_TARGETLIBRARYINFO_H
11
12#include "llvm/ADT/BitVector.h"
13#include "llvm/ADT/DenseMap.h"
14#include "llvm/ADT/Optional.h"
15#include "llvm/IR/Function.h"
16#include "llvm/IR/InstrTypes.h"
17#include "llvm/IR/Module.h"
18#include "llvm/IR/PassManager.h"
19#include "llvm/Pass.h"
20
21namespace llvm {
22template <typename T> class ArrayRef;
23class Triple;
24
25/// Describes a possible vectorization of a function.
26/// Function 'VectorFnName' is equivalent to 'ScalarFnName' vectorized
27/// by a factor 'VectorizationFactor'.
28struct VecDesc {
29 StringRef ScalarFnName;
30 StringRef VectorFnName;
31 ElementCount VectorizationFactor;
32};
33
34 enum LibFunc : unsigned {
35#define TLI_DEFINE_ENUM
36#include "llvm/Analysis/TargetLibraryInfo.def"
37
38 NumLibFuncs,
39 NotLibFunc
40 };
41
42/// Implementation of the target library information.
43///
44/// This class constructs tables that hold the target library information and
45/// make it available. However, it is somewhat expensive to compute and only
46/// depends on the triple. So users typically interact with the \c
47/// TargetLibraryInfo wrapper below.
48class TargetLibraryInfoImpl {
49 friend class TargetLibraryInfo;
50
51 unsigned char AvailableArray[(NumLibFuncs+3)/4];
52 llvm::DenseMap<unsigned, std::string> CustomNames;
53 static StringLiteral const StandardNames[NumLibFuncs];
54 bool ShouldExtI32Param, ShouldExtI32Return, ShouldSignExtI32Param;
55
56 enum AvailabilityState {
57 StandardName = 3, // (memset to all ones)
58 CustomName = 1,
59 Unavailable = 0 // (memset to all zeros)
60 };
61 void setState(LibFunc F, AvailabilityState State) {
62 AvailableArray[F/4] &= ~(3 << 2*(F&3));
63 AvailableArray[F/4] |= State << 2*(F&3);
64 }
65 AvailabilityState getState(LibFunc F) const {
66 return static_cast<AvailabilityState>((AvailableArray[F/4] >> 2*(F&3)) & 3);
67 }
68
69 /// Vectorization descriptors - sorted by ScalarFnName.
70 std::vector<VecDesc> VectorDescs;
71 /// Scalarization descriptors - same content as VectorDescs but sorted based
72 /// on VectorFnName rather than ScalarFnName.
73 std::vector<VecDesc> ScalarDescs;
74
75 /// Return true if the function type FTy is valid for the library function
76 /// F, regardless of whether the function is available.
77 bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc F,
78 const DataLayout *DL) const;
79
80public:
81 /// List of known vector-functions libraries.
82 ///
83 /// The vector-functions library defines, which functions are vectorizable
84 /// and with which factor. The library can be specified by either frontend,
85 /// or a commandline option, and then used by
86 /// addVectorizableFunctionsFromVecLib for filling up the tables of
87 /// vectorizable functions.
88 enum VectorLibrary {
89 NoLibrary, // Don't use any vector library.
90 Accelerate, // Use Accelerate framework.
91 LIBMVEC_X86,// GLIBC Vector Math library.
92 MASSV, // IBM MASS vector library.
93 SVML // Intel short vector math library.
94 };
95
96 TargetLibraryInfoImpl();
97 explicit TargetLibraryInfoImpl(const Triple &T);
98
99 // Provide value semantics.
100 TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI);
101 TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI);
102 TargetLibraryInfoImpl &operator=(const TargetLibraryInfoImpl &TLI);
103 TargetLibraryInfoImpl &operator=(TargetLibraryInfoImpl &&TLI);
104
105 /// Searches for a particular function name.
106 ///
107 /// If it is one of the known library functions, return true and set F to the
108 /// corresponding value.
109 bool getLibFunc(StringRef funcName, LibFunc &F) const;
110
111 /// Searches for a particular function name, also checking that its type is
112 /// valid for the library function matching that name.
113 ///
114 /// If it is one of the known library functions, return true and set F to the
115 /// corresponding value.
116 bool getLibFunc(const Function &FDecl, LibFunc &F) const;
117
118 /// Forces a function to be marked as unavailable.
119 void setUnavailable(LibFunc F) {
120 setState(F, Unavailable);
121 }
122
123 /// Forces a function to be marked as available.
124 void setAvailable(LibFunc F) {
125 setState(F, StandardName);
126 }
127
128 /// Forces a function to be marked as available and provide an alternate name
129 /// that must be used.
130 void setAvailableWithName(LibFunc F, StringRef Name) {
131 if (StandardNames[F] != Name) {
132 setState(F, CustomName);
133 CustomNames[F] = std::string(Name);
134 assert(CustomNames.find(F) != CustomNames.end());
135 } else {
136 setState(F, StandardName);
137 }
138 }
139
140 /// Disables all builtins.
141 ///
142 /// This can be used for options like -fno-builtin.
143 void disableAllFunctions();
144
145 /// Add a set of scalar -> vector mappings, queryable via
146 /// getVectorizedFunction and getScalarizedFunction.
147 void addVectorizableFunctions(ArrayRef<VecDesc> Fns);
148
149 /// Calls addVectorizableFunctions with a known preset of functions for the
150 /// given vector library.
151 void addVectorizableFunctionsFromVecLib(enum VectorLibrary VecLib);
152
153 /// Return true if the function F has a vector equivalent with vectorization
154 /// factor VF.
155 bool isFunctionVectorizable(StringRef F, const ElementCount &VF) const {
156 return !getVectorizedFunction(F, VF).empty();
157 }
158
159 /// Return true if the function F has a vector equivalent with any
160 /// vectorization factor.
161 bool isFunctionVectorizable(StringRef F) const;
162
163 /// Return the name of the equivalent of F, vectorized with factor VF. If no
164 /// such mapping exists, return the empty string.
165 StringRef getVectorizedFunction(StringRef F, const ElementCount &VF) const;
166
167 /// Set to true iff i32 parameters to library functions should have signext
168 /// or zeroext attributes if they correspond to C-level int or unsigned int,
169 /// respectively.
170 void setShouldExtI32Param(bool Val) {
171 ShouldExtI32Param = Val;
172 }
173
174 /// Set to true iff i32 results from library functions should have signext
175 /// or zeroext attributes if they correspond to C-level int or unsigned int,
176 /// respectively.
177 void setShouldExtI32Return(bool Val) {
178 ShouldExtI32Return = Val;
179 }
180
181 /// Set to true iff i32 parameters to library functions should have signext
182 /// attribute if they correspond to C-level int or unsigned int.
183 void setShouldSignExtI32Param(bool Val) {
184 ShouldSignExtI32Param = Val;
185 }
186
187 /// Returns the size of the wchar_t type in bytes or 0 if the size is unknown.
188 /// This queries the 'wchar_size' metadata.
189 unsigned getWCharSize(const Module &M) const;
190
191 /// Returns the largest vectorization factor used in the list of
192 /// vector functions.
193 void getWidestVF(StringRef ScalarF, ElementCount &FixedVF,
194 ElementCount &Scalable) const;
195
196 /// Returns true if call site / callee has cdecl-compatible calling
197 /// conventions.
198 static bool isCallingConvCCompatible(CallBase *CI);
199 static bool isCallingConvCCompatible(Function *Callee);
200};
201
202/// Provides information about what library functions are available for
203/// the current target.
204///
205/// This both allows optimizations to handle them specially and frontends to
206/// disable such optimizations through -fno-builtin etc.
207class TargetLibraryInfo {
208 friend class TargetLibraryAnalysis;
209 friend class TargetLibraryInfoWrapperPass;
210
211 /// The global (module level) TLI info.
212 const TargetLibraryInfoImpl *Impl;
213
214 /// Support for -fno-builtin* options as function attributes, overrides
215 /// information in global TargetLibraryInfoImpl.
216 BitVector OverrideAsUnavailable;
217
218public:
219 explicit TargetLibraryInfo(const TargetLibraryInfoImpl &Impl,
220 Optional<const Function *> F = None)
221 : Impl(&Impl), OverrideAsUnavailable(NumLibFuncs) {
222 if (!F)
223 return;
224 if ((*F)->hasFnAttribute("no-builtins"))
225 disableAllFunctions();
226 else {
227 // Disable individual libc/libm calls in TargetLibraryInfo.
228 LibFunc LF;
229 AttributeSet FnAttrs = (*F)->getAttributes().getFnAttributes();
230 for (const Attribute &Attr : FnAttrs) {
231 if (!Attr.isStringAttribute())
232 continue;
233 auto AttrStr = Attr.getKindAsString();
234 if (!AttrStr.consume_front("no-builtin-"))
235 continue;
236 if (getLibFunc(AttrStr, LF))
237 setUnavailable(LF);
238 }
239 }
240 }
241
242 // Provide value semantics.
243 TargetLibraryInfo(const TargetLibraryInfo &TLI)
244 : Impl(TLI.Impl), OverrideAsUnavailable(TLI.OverrideAsUnavailable) {}
245 TargetLibraryInfo(TargetLibraryInfo &&TLI)
246 : Impl(TLI.Impl), OverrideAsUnavailable(TLI.OverrideAsUnavailable) {}
247 TargetLibraryInfo &operator=(const TargetLibraryInfo &TLI) {
248 Impl = TLI.Impl;
249 OverrideAsUnavailable = TLI.OverrideAsUnavailable;
250 return *this;
251 }
252 TargetLibraryInfo &operator=(TargetLibraryInfo &&TLI) {
253 Impl = TLI.Impl;
254 OverrideAsUnavailable = TLI.OverrideAsUnavailable;
255 return *this;
256 }
257
258 /// Determine whether a callee with the given TLI can be inlined into
259 /// caller with this TLI, based on 'nobuiltin' attributes. When requested,
260 /// allow inlining into a caller with a superset of the callee's nobuiltin
261 /// attributes, which is conservatively correct.
262 bool areInlineCompatible(const TargetLibraryInfo &CalleeTLI,
263 bool AllowCallerSuperset) const {
264 if (!AllowCallerSuperset)
265 return OverrideAsUnavailable == CalleeTLI.OverrideAsUnavailable;
266 BitVector B = OverrideAsUnavailable;
267 B |= CalleeTLI.OverrideAsUnavailable;
268 // We can inline if the union of the caller and callee's nobuiltin
269 // attributes is no stricter than the caller's nobuiltin attributes.
270 return B == OverrideAsUnavailable;
271 }
272
273 /// Searches for a particular function name.
274 ///
275 /// If it is one of the known library functions, return true and set F to the
276 /// corresponding value.
277 bool getLibFunc(StringRef funcName, LibFunc &F) const {
278 return Impl->getLibFunc(funcName, F);
279 }
280
281 bool getLibFunc(const Function &FDecl, LibFunc &F) const {
282 return Impl->getLibFunc(FDecl, F);
283 }
284
285 /// If a callbase does not have the 'nobuiltin' attribute, return if the
286 /// called function is a known library function and set F to that function.
287 bool getLibFunc(const CallBase &CB, LibFunc &F) const {
288 return !CB.isNoBuiltin() && CB.getCalledFunction() &&
289 getLibFunc(*(CB.getCalledFunction()), F);
290 }
291
292 /// Disables all builtins.
293 ///
294 /// This can be used for options like -fno-builtin.
295 void disableAllFunctions() LLVM_ATTRIBUTE_UNUSED {
296 OverrideAsUnavailable.set();
297 }
298
299 /// Forces a function to be marked as unavailable.
300 void setUnavailable(LibFunc F) LLVM_ATTRIBUTE_UNUSED {
301 OverrideAsUnavailable.set(F);
302 }
303
304 TargetLibraryInfoImpl::AvailabilityState getState(LibFunc F) const {
305 if (OverrideAsUnavailable[F])
306 return TargetLibraryInfoImpl::Unavailable;
307 return Impl->getState(F);
308 }
309
310 /// Tests whether a library function is available.
311 bool has(LibFunc F) const {
312 return getState(F) != TargetLibraryInfoImpl::Unavailable;
313 }
314 bool isFunctionVectorizable(StringRef F, const ElementCount &VF) const {
315 return Impl->isFunctionVectorizable(F, VF);
316 }
317 bool isFunctionVectorizable(StringRef F) const {
318 return Impl->isFunctionVectorizable(F);
319 }
320 StringRef getVectorizedFunction(StringRef F, const ElementCount &VF) const {
321 return Impl->getVectorizedFunction(F, VF);
322 }
323
324 /// Tests if the function is both available and a candidate for optimized code
325 /// generation.
326 bool hasOptimizedCodeGen(LibFunc F) const {
327 if (getState(F) == TargetLibraryInfoImpl::Unavailable)
328 return false;
329 switch (F) {
330 default: break;
331 case LibFunc_copysign: case LibFunc_copysignf: case LibFunc_copysignl:
332 case LibFunc_fabs: case LibFunc_fabsf: case LibFunc_fabsl:
333 case LibFunc_sin: case LibFunc_sinf: case LibFunc_sinl:
334 case LibFunc_cos: case LibFunc_cosf: case LibFunc_cosl:
335 case LibFunc_sqrt: case LibFunc_sqrtf: case LibFunc_sqrtl:
336 case LibFunc_sqrt_finite: case LibFunc_sqrtf_finite:
337 case LibFunc_sqrtl_finite:
338 case LibFunc_fmax: case LibFunc_fmaxf: case LibFunc_fmaxl:
339 case LibFunc_fmin: case LibFunc_fminf: case LibFunc_fminl:
340 case LibFunc_floor: case LibFunc_floorf: case LibFunc_floorl:
341 case LibFunc_nearbyint: case LibFunc_nearbyintf: case LibFunc_nearbyintl:
342 case LibFunc_ceil: case LibFunc_ceilf: case LibFunc_ceill:
343 case LibFunc_rint: case LibFunc_rintf: case LibFunc_rintl:
344 case LibFunc_round: case LibFunc_roundf: case LibFunc_roundl:
345 case LibFunc_trunc: case LibFunc_truncf: case LibFunc_truncl:
346 case LibFunc_log2: case LibFunc_log2f: case LibFunc_log2l:
347 case LibFunc_exp2: case LibFunc_exp2f: case LibFunc_exp2l:
348 case LibFunc_memcpy: case LibFunc_memset: case LibFunc_memmove:
349 case LibFunc_memcmp: case LibFunc_bcmp: case LibFunc_strcmp:
350 case LibFunc_strcpy: case LibFunc_stpcpy: case LibFunc_strlen:
351 case LibFunc_strnlen: case LibFunc_memchr: case LibFunc_mempcpy:
352 return true;
353 }
354 return false;
355 }
356
357 StringRef getName(LibFunc F) const {
358 auto State = getState(F);
359 if (State == TargetLibraryInfoImpl::Unavailable)
360 return StringRef();
361 if (State == TargetLibraryInfoImpl::StandardName)
362 return Impl->StandardNames[F];
363 assert(State == TargetLibraryInfoImpl::CustomName);
364 return Impl->CustomNames.find(F)->second;
365 }
366
367 /// Returns extension attribute kind to be used for i32 parameters
368 /// corresponding to C-level int or unsigned int. May be zeroext, signext,
369 /// or none.
370 Attribute::AttrKind getExtAttrForI32Param(bool Signed = true) const {
371 if (Impl->ShouldExtI32Param)
372 return Signed ? Attribute::SExt : Attribute::ZExt;
373 if (Impl->ShouldSignExtI32Param)
374 return Attribute::SExt;
375 return Attribute::None;
376 }
377
378 /// Returns extension attribute kind to be used for i32 return values
379 /// corresponding to C-level int or unsigned int. May be zeroext, signext,
380 /// or none.
381 Attribute::AttrKind getExtAttrForI32Return(bool Signed = true) const {
382 if (Impl->ShouldExtI32Return)
383 return Signed ? Attribute::SExt : Attribute::ZExt;
384 return Attribute::None;
385 }
386
387 /// \copydoc TargetLibraryInfoImpl::getWCharSize()
388 unsigned getWCharSize(const Module &M) const {
389 return Impl->getWCharSize(M);
390 }
391
392 /// Handle invalidation from the pass manager.
393 ///
394 /// If we try to invalidate this info, just return false. It cannot become
395 /// invalid even if the module or function changes.
396 bool invalidate(Module &, const PreservedAnalyses &,
397 ModuleAnalysisManager::Invalidator &) {
398 return false;
399 }
400 bool invalidate(Function &, const PreservedAnalyses &,
401 FunctionAnalysisManager::Invalidator &) {
402 return false;
403 }
404 /// Returns the largest vectorization factor used in the list of
405 /// vector functions.
406 void getWidestVF(StringRef ScalarF, ElementCount &FixedVF,
407 ElementCount &ScalableVF) const {
408 Impl->getWidestVF(ScalarF, FixedVF, ScalableVF);
409 }
410
411 /// Check if the function "F" is listed in a library known to LLVM.
412 bool isKnownVectorFunctionInLibrary(StringRef F) const {
413 return this->isFunctionVectorizable(F);
414 }
415};
416
417/// Analysis pass providing the \c TargetLibraryInfo.
418///
419/// Note that this pass's result cannot be invalidated, it is immutable for the
420/// life of the module.
421class TargetLibraryAnalysis : public AnalysisInfoMixin<TargetLibraryAnalysis> {
422public:
423 typedef TargetLibraryInfo Result;
424
425 /// Default construct the library analysis.
426 ///
427 /// This will use the module's triple to construct the library info for that
428 /// module.
429 TargetLibraryAnalysis() {}
430
431 /// Construct a library analysis with baseline Module-level info.
432 ///
433 /// This will be supplemented with Function-specific info in the Result.
434 TargetLibraryAnalysis(TargetLibraryInfoImpl BaselineInfoImpl)
435 : BaselineInfoImpl(std::move(BaselineInfoImpl)) {}
436
437 TargetLibraryInfo run(const Function &F, FunctionAnalysisManager &);
438
439private:
440 friend AnalysisInfoMixin<TargetLibraryAnalysis>;
441 static AnalysisKey Key;
442
443 Optional<TargetLibraryInfoImpl> BaselineInfoImpl;
444};
445
446class TargetLibraryInfoWrapperPass : public ImmutablePass {
447 TargetLibraryAnalysis TLA;
448 Optional<TargetLibraryInfo> TLI;
449
450 virtual void anchor();
451
452public:
453 static char ID;
454 TargetLibraryInfoWrapperPass();
455 explicit TargetLibraryInfoWrapperPass(const Triple &T);
456 explicit TargetLibraryInfoWrapperPass(const TargetLibraryInfoImpl &TLI);
457
458 TargetLibraryInfo &getTLI(const Function &F) {
459 FunctionAnalysisManager DummyFAM;
460 TLI = TLA.run(F, DummyFAM);
461 return *TLI;
462 }
463};
464
465} // end namespace llvm
466
467#endif
468