1 // CLN internal inlining hints
3 #ifndef _CL_MAYBE_INLINE_H
4 #define _CL_MAYBE_INLINE_H
7 * Selectively inline a function in *some* translation units.
9 * The need to inline a function in some places and not in others came from
12 * 1) Some functions, like cl_SF_zerop or cl_FF_zerop, are just a single
13 * machine instruction when inlined. Putting their definitions into a public
14 * header would expose too many internals of the library, leading violation
15 * of abstraction and increased compilation times. Still, it would be nice
16 * to use the inline version of these functions in the library itself.
18 * 2) Some functions, like cl_{SF,FF,DF,LF}_idecode, are usually only
19 * invoked through a dispatcher cl_F_idecode that does nothing but dispatch
20 * the call to the right function. Here inlining is used, regardless of
21 * the size of the inlined functions, because it removes one function call
22 * from the chain of function calls. A compiler cannot know that this
23 * caller is the main caller for the 4 inlined functions.
25 * 3) Similarly, cl_I_from_NDS would be a bottleneck if not inlined: every
26 * creation of a new cl_I goes through this function. A compiler cannot
27 * know a priori the bottlenecks.
29 * Hence, there is a set of macros which help to create inline and
30 * non-inline versions of a function without duplicating the code.
34 * 1. In the public header, declare function as usual:
36 * extern cl_bar cl_foo(const cl_baz&);
38 * 2. Put the definition into a separate file, say, cl_foo.cc, in the
43 * #include "cl_macros.h"
44 * #include "whatever/you/need.h"
46 * CL_INLINE cl_bar CL_INLINE_DECL(cl_foo)(const cl_baz& x)
48 * // the actual code goes here
51 * This provides normal (non-inline) version of a function cl_foo.
53 * 3. In order to use the inline version, do
57 * #include "cl_inline.h"
58 * #include "path/to/cl_foo.cc"
60 * This will declare and define function cl_foo_inline, which is an inline
64 * The name of the inline version *really* has to be different, since ISO C++
65 * demands (in 7.1.2.4)
67 * "If a function with external linkage is declared inline in one translation
68 * unit, it shall be declared inline in all translation units in which it
69 * appears; no diagnostic is required."
71 * Feel free to implement this functionality in a better *standard-compliant*
72 * way. Or submit a DR (defect report) to the standard committee.
75 #define CL_INLINE_DECL(fcn) fcn
78 * Use these macros to provide inline and non-inline versions of a function
79 * which uses an inline version of other function(s).
82 #define CL_INLINE2_DECL(fcn) fcn
85 * Some functions (zerop, signum, etc) just dispatch the call to the
86 * appropriate type-specific functions. It would be nice to have these
87 * type-specific functions inlined. However, the compiler can not know that,
88 * unless one gives it a hint.
92 * const cl_foo CL_FLATTEN cl_bar(const cl_R& x)
99 * 1. This is only a *hint*, it's always up to the compiler to NOT inline
101 * 2. It's ignored if the optimization is switched off.
104 #define CL_FLATTEN __attribute__((flatten))
110 * Tell the compiler to inline a function more aggressively, i.e. even if the
111 * optimization is switched off.
115 * cl_blah CL_INLINE_HINT cl_foo(const cl_baz& x)
121 * 1. This is only a hint, it does NOT guarantee the function will be
122 * actually always inlined.
123 * 2. CL_INLINE and CL_INLINE2 macros set this attribute automagically.
126 #define CL_INLINE_HINT __attribute__((always_inline))
128 #define CL_INLINE_HINT
131 #endif /* _CL_MAYBE_INLINE_H */