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