Recommit [NFC] Better encapsulation of llvm::Optional Storage
[llvm-complete.git] / include / llvm / Analysis / TargetLibraryInfo.h
blobfc6811e88623b7f5b0543314ebf88f85c0812ec9
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 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_ANALYSIS_TARGETLIBRARYINFO_H
10 #define LLVM_ANALYSIS_TARGETLIBRARYINFO_H
12 #include "llvm/ADT/DenseMap.h"
13 #include "llvm/ADT/Optional.h"
14 #include "llvm/ADT/Triple.h"
15 #include "llvm/IR/CallSite.h"
16 #include "llvm/IR/Function.h"
17 #include "llvm/IR/Module.h"
18 #include "llvm/IR/PassManager.h"
19 #include "llvm/Pass.h"
21 namespace llvm {
22 template <typename T> class ArrayRef;
24 /// Describes a possible vectorization of a function.
25 /// Function 'VectorFnName' is equivalent to 'ScalarFnName' vectorized
26 /// by a factor 'VectorizationFactor'.
27 struct VecDesc {
28 StringRef ScalarFnName;
29 StringRef VectorFnName;
30 unsigned VectorizationFactor;
33 enum LibFunc {
34 #define TLI_DEFINE_ENUM
35 #include "llvm/Analysis/TargetLibraryInfo.def"
37 NumLibFuncs
40 /// Implementation of the target library information.
41 ///
42 /// This class constructs tables that hold the target library information and
43 /// make it available. However, it is somewhat expensive to compute and only
44 /// depends on the triple. So users typically interact with the \c
45 /// TargetLibraryInfo wrapper below.
46 class TargetLibraryInfoImpl {
47 friend class TargetLibraryInfo;
49 unsigned char AvailableArray[(NumLibFuncs+3)/4];
50 llvm::DenseMap<unsigned, std::string> CustomNames;
51 static StringRef const StandardNames[NumLibFuncs];
52 bool ShouldExtI32Param, ShouldExtI32Return, ShouldSignExtI32Param;
54 enum AvailabilityState {
55 StandardName = 3, // (memset to all ones)
56 CustomName = 1,
57 Unavailable = 0 // (memset to all zeros)
59 void setState(LibFunc F, AvailabilityState State) {
60 AvailableArray[F/4] &= ~(3 << 2*(F&3));
61 AvailableArray[F/4] |= State << 2*(F&3);
63 AvailabilityState getState(LibFunc F) const {
64 return static_cast<AvailabilityState>((AvailableArray[F/4] >> 2*(F&3)) & 3);
67 /// Vectorization descriptors - sorted by ScalarFnName.
68 std::vector<VecDesc> VectorDescs;
69 /// Scalarization descriptors - same content as VectorDescs but sorted based
70 /// on VectorFnName rather than ScalarFnName.
71 std::vector<VecDesc> ScalarDescs;
73 /// Return true if the function type FTy is valid for the library function
74 /// F, regardless of whether the function is available.
75 bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc F,
76 const DataLayout *DL) const;
78 public:
79 /// List of known vector-functions libraries.
80 ///
81 /// The vector-functions library defines, which functions are vectorizable
82 /// and with which factor. The library can be specified by either frontend,
83 /// or a commandline option, and then used by
84 /// addVectorizableFunctionsFromVecLib for filling up the tables of
85 /// vectorizable functions.
86 enum VectorLibrary {
87 NoLibrary, // Don't use any vector library.
88 Accelerate, // Use Accelerate framework.
89 SVML // Intel short vector math library.
92 TargetLibraryInfoImpl();
93 explicit TargetLibraryInfoImpl(const Triple &T);
95 // Provide value semantics.
96 TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI);
97 TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI);
98 TargetLibraryInfoImpl &operator=(const TargetLibraryInfoImpl &TLI);
99 TargetLibraryInfoImpl &operator=(TargetLibraryInfoImpl &&TLI);
101 /// Searches for a particular function name.
103 /// If it is one of the known library functions, return true and set F to the
104 /// corresponding value.
105 bool getLibFunc(StringRef funcName, LibFunc &F) const;
107 /// Searches for a particular function name, also checking that its type is
108 /// valid for the library function matching that name.
110 /// If it is one of the known library functions, return true and set F to the
111 /// corresponding value.
112 bool getLibFunc(const Function &FDecl, LibFunc &F) const;
114 /// Forces a function to be marked as unavailable.
115 void setUnavailable(LibFunc F) {
116 setState(F, Unavailable);
119 /// Forces a function to be marked as available.
120 void setAvailable(LibFunc F) {
121 setState(F, StandardName);
124 /// Forces a function to be marked as available and provide an alternate name
125 /// that must be used.
126 void setAvailableWithName(LibFunc F, StringRef Name) {
127 if (StandardNames[F] != Name) {
128 setState(F, CustomName);
129 CustomNames[F] = Name;
130 assert(CustomNames.find(F) != CustomNames.end());
131 } else {
132 setState(F, StandardName);
136 /// Disables all builtins.
138 /// This can be used for options like -fno-builtin.
139 void disableAllFunctions();
141 /// Add a set of scalar -> vector mappings, queryable via
142 /// getVectorizedFunction and getScalarizedFunction.
143 void addVectorizableFunctions(ArrayRef<VecDesc> Fns);
145 /// Calls addVectorizableFunctions with a known preset of functions for the
146 /// given vector library.
147 void addVectorizableFunctionsFromVecLib(enum VectorLibrary VecLib);
149 /// Return true if the function F has a vector equivalent with vectorization
150 /// factor VF.
151 bool isFunctionVectorizable(StringRef F, unsigned VF) const {
152 return !getVectorizedFunction(F, VF).empty();
155 /// Return true if the function F has a vector equivalent with any
156 /// vectorization factor.
157 bool isFunctionVectorizable(StringRef F) const;
159 /// Return the name of the equivalent of F, vectorized with factor VF. If no
160 /// such mapping exists, return the empty string.
161 StringRef getVectorizedFunction(StringRef F, unsigned VF) const;
163 /// Return true if the function F has a scalar equivalent, and set VF to be
164 /// the vectorization factor.
165 bool isFunctionScalarizable(StringRef F, unsigned &VF) const {
166 return !getScalarizedFunction(F, VF).empty();
169 /// Return the name of the equivalent of F, scalarized. If no such mapping
170 /// exists, return the empty string.
172 /// Set VF to the vectorization factor.
173 StringRef getScalarizedFunction(StringRef F, unsigned &VF) const;
175 /// Set to true iff i32 parameters to library functions should have signext
176 /// or zeroext attributes if they correspond to C-level int or unsigned int,
177 /// respectively.
178 void setShouldExtI32Param(bool Val) {
179 ShouldExtI32Param = Val;
182 /// Set to true iff i32 results from library functions should have signext
183 /// or zeroext attributes if they correspond to C-level int or unsigned int,
184 /// respectively.
185 void setShouldExtI32Return(bool Val) {
186 ShouldExtI32Return = Val;
189 /// Set to true iff i32 parameters to library functions should have signext
190 /// attribute if they correspond to C-level int or unsigned int.
191 void setShouldSignExtI32Param(bool Val) {
192 ShouldSignExtI32Param = Val;
195 /// Returns the size of the wchar_t type in bytes or 0 if the size is unknown.
196 /// This queries the 'wchar_size' metadata.
197 unsigned getWCharSize(const Module &M) const;
200 /// Provides information about what library functions are available for
201 /// the current target.
203 /// This both allows optimizations to handle them specially and frontends to
204 /// disable such optimizations through -fno-builtin etc.
205 class TargetLibraryInfo {
206 friend class TargetLibraryAnalysis;
207 friend class TargetLibraryInfoWrapperPass;
209 const TargetLibraryInfoImpl *Impl;
211 public:
212 explicit TargetLibraryInfo(const TargetLibraryInfoImpl &Impl) : Impl(&Impl) {}
214 // Provide value semantics.
215 TargetLibraryInfo(const TargetLibraryInfo &TLI) : Impl(TLI.Impl) {}
216 TargetLibraryInfo(TargetLibraryInfo &&TLI) : Impl(TLI.Impl) {}
217 TargetLibraryInfo &operator=(const TargetLibraryInfo &TLI) {
218 Impl = TLI.Impl;
219 return *this;
221 TargetLibraryInfo &operator=(TargetLibraryInfo &&TLI) {
222 Impl = TLI.Impl;
223 return *this;
226 /// Searches for a particular function name.
228 /// If it is one of the known library functions, return true and set F to the
229 /// corresponding value.
230 bool getLibFunc(StringRef funcName, LibFunc &F) const {
231 return Impl->getLibFunc(funcName, F);
234 bool getLibFunc(const Function &FDecl, LibFunc &F) const {
235 return Impl->getLibFunc(FDecl, F);
238 /// If a callsite does not have the 'nobuiltin' attribute, return if the
239 /// called function is a known library function and set F to that function.
240 bool getLibFunc(ImmutableCallSite CS, LibFunc &F) const {
241 return !CS.isNoBuiltin() && CS.getCalledFunction() &&
242 getLibFunc(*(CS.getCalledFunction()), F);
245 /// Tests whether a library function is available.
246 bool has(LibFunc F) const {
247 return Impl->getState(F) != TargetLibraryInfoImpl::Unavailable;
249 bool isFunctionVectorizable(StringRef F, unsigned VF) const {
250 return Impl->isFunctionVectorizable(F, VF);
252 bool isFunctionVectorizable(StringRef F) const {
253 return Impl->isFunctionVectorizable(F);
255 StringRef getVectorizedFunction(StringRef F, unsigned VF) const {
256 return Impl->getVectorizedFunction(F, VF);
259 /// Tests if the function is both available and a candidate for optimized code
260 /// generation.
261 bool hasOptimizedCodeGen(LibFunc F) const {
262 if (Impl->getState(F) == TargetLibraryInfoImpl::Unavailable)
263 return false;
264 switch (F) {
265 default: break;
266 case LibFunc_copysign: case LibFunc_copysignf: case LibFunc_copysignl:
267 case LibFunc_fabs: case LibFunc_fabsf: case LibFunc_fabsl:
268 case LibFunc_sin: case LibFunc_sinf: case LibFunc_sinl:
269 case LibFunc_cos: case LibFunc_cosf: case LibFunc_cosl:
270 case LibFunc_sqrt: case LibFunc_sqrtf: case LibFunc_sqrtl:
271 case LibFunc_sqrt_finite: case LibFunc_sqrtf_finite:
272 case LibFunc_sqrtl_finite:
273 case LibFunc_fmax: case LibFunc_fmaxf: case LibFunc_fmaxl:
274 case LibFunc_fmin: case LibFunc_fminf: case LibFunc_fminl:
275 case LibFunc_floor: case LibFunc_floorf: case LibFunc_floorl:
276 case LibFunc_nearbyint: case LibFunc_nearbyintf: case LibFunc_nearbyintl:
277 case LibFunc_ceil: case LibFunc_ceilf: case LibFunc_ceill:
278 case LibFunc_rint: case LibFunc_rintf: case LibFunc_rintl:
279 case LibFunc_round: case LibFunc_roundf: case LibFunc_roundl:
280 case LibFunc_trunc: case LibFunc_truncf: case LibFunc_truncl:
281 case LibFunc_log2: case LibFunc_log2f: case LibFunc_log2l:
282 case LibFunc_exp2: case LibFunc_exp2f: case LibFunc_exp2l:
283 case LibFunc_memcmp: case LibFunc_strcmp: case LibFunc_strcpy:
284 case LibFunc_stpcpy: case LibFunc_strlen: case LibFunc_strnlen:
285 case LibFunc_memchr: case LibFunc_mempcpy:
286 return true;
288 return false;
291 StringRef getName(LibFunc F) const {
292 auto State = Impl->getState(F);
293 if (State == TargetLibraryInfoImpl::Unavailable)
294 return StringRef();
295 if (State == TargetLibraryInfoImpl::StandardName)
296 return Impl->StandardNames[F];
297 assert(State == TargetLibraryInfoImpl::CustomName);
298 return Impl->CustomNames.find(F)->second;
301 /// Returns extension attribute kind to be used for i32 parameters
302 /// corresponding to C-level int or unsigned int. May be zeroext, signext,
303 /// or none.
304 Attribute::AttrKind getExtAttrForI32Param(bool Signed = true) const {
305 if (Impl->ShouldExtI32Param)
306 return Signed ? Attribute::SExt : Attribute::ZExt;
307 if (Impl->ShouldSignExtI32Param)
308 return Attribute::SExt;
309 return Attribute::None;
312 /// Returns extension attribute kind to be used for i32 return values
313 /// corresponding to C-level int or unsigned int. May be zeroext, signext,
314 /// or none.
315 Attribute::AttrKind getExtAttrForI32Return(bool Signed = true) const {
316 if (Impl->ShouldExtI32Return)
317 return Signed ? Attribute::SExt : Attribute::ZExt;
318 return Attribute::None;
321 /// \copydoc TargetLibraryInfoImpl::getWCharSize()
322 unsigned getWCharSize(const Module &M) const {
323 return Impl->getWCharSize(M);
326 /// Handle invalidation from the pass manager.
328 /// If we try to invalidate this info, just return false. It cannot become
329 /// invalid even if the module or function changes.
330 bool invalidate(Module &, const PreservedAnalyses &,
331 ModuleAnalysisManager::Invalidator &) {
332 return false;
334 bool invalidate(Function &, const PreservedAnalyses &,
335 FunctionAnalysisManager::Invalidator &) {
336 return false;
340 /// Analysis pass providing the \c TargetLibraryInfo.
342 /// Note that this pass's result cannot be invalidated, it is immutable for the
343 /// life of the module.
344 class TargetLibraryAnalysis : public AnalysisInfoMixin<TargetLibraryAnalysis> {
345 public:
346 typedef TargetLibraryInfo Result;
348 /// Default construct the library analysis.
350 /// This will use the module's triple to construct the library info for that
351 /// module.
352 TargetLibraryAnalysis() {}
354 /// Construct a library analysis with preset info.
356 /// This will directly copy the preset info into the result without
357 /// consulting the module's triple.
358 TargetLibraryAnalysis(TargetLibraryInfoImpl PresetInfoImpl)
359 : PresetInfoImpl(std::move(PresetInfoImpl)) {}
361 TargetLibraryInfo run(Module &M, ModuleAnalysisManager &);
362 TargetLibraryInfo run(Function &F, FunctionAnalysisManager &);
364 private:
365 friend AnalysisInfoMixin<TargetLibraryAnalysis>;
366 static AnalysisKey Key;
368 Optional<TargetLibraryInfoImpl> PresetInfoImpl;
370 StringMap<std::unique_ptr<TargetLibraryInfoImpl>> Impls;
372 TargetLibraryInfoImpl &lookupInfoImpl(const Triple &T);
375 class TargetLibraryInfoWrapperPass : public ImmutablePass {
376 TargetLibraryInfoImpl TLIImpl;
377 TargetLibraryInfo TLI;
379 virtual void anchor();
381 public:
382 static char ID;
383 TargetLibraryInfoWrapperPass();
384 explicit TargetLibraryInfoWrapperPass(const Triple &T);
385 explicit TargetLibraryInfoWrapperPass(const TargetLibraryInfoImpl &TLI);
387 TargetLibraryInfo &getTLI() { return TLI; }
388 const TargetLibraryInfo &getTLI() const { return TLI; }
391 } // end namespace llvm
393 #endif