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 | |
22 | namespace llvm { |
23 | template <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'. |
28 | struct 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. |
47 | class 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 | |
79 | public: |
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. |
206 | class TargetLibraryInfo { |
207 | friend class TargetLibraryAnalysis; |
208 | friend class TargetLibraryInfoWrapperPass; |
209 | |
210 | const TargetLibraryInfoImpl *Impl; |
211 | |
212 | public: |
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. |
345 | class TargetLibraryAnalysis : public AnalysisInfoMixin<TargetLibraryAnalysis> { |
346 | public: |
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 | |
365 | private: |
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 | |
376 | class TargetLibraryInfoWrapperPass : public ImmutablePass { |
377 | TargetLibraryInfoImpl TLIImpl; |
378 | TargetLibraryInfo TLI; |
379 | |
380 | virtual void anchor(); |
381 | |
382 | public: |
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 | |