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