]> www.ginac.de Git - cln.git/blob - src/base/cl_maybe_inline.h
Use paths relative the `src' directory in the #include directives.
[cln.git] / src / base / cl_maybe_inline.h
1 // CLN internal inlining hints
2
3 #ifndef _CL_MAYBE_INLINE_H
4 #define _CL_MAYBE_INLINE_H
5
6 #include "cln/config.h"
7
8 /*
9  * Selectively inline a function in *some* translation units.
10  *
11  * The need to inline a function in some places and not in others came from
12  * three situations:
13  *
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.
19  *
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.
26  *
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.
30  *
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.
33  *
34  * Usage:
35  *
36  * 1. In the public header, declare function as usual:
37  *
38  * extern cl_bar cl_foo(const cl_baz&);
39  *
40  * 2. Put the definition into a separate file, say, cl_foo.cc, in the
41  * following way:
42  *
43  * // cl_foo.cc
44  *
45  * #include "cl_macros.h"
46  * #include "whatever/you/need.h"
47  *
48  * CL_INLINE cl_bar CL_INLINE_DECL(cl_foo)(const cl_baz& x)
49  * {
50  *   // the actual code goes here
51  * }
52  *
53  * This provides normal (non-inline) version of a function cl_foo.
54  *
55  * 3. In order to use the inline version, do
56  *
57  * // cl_blah.cc
58  *
59  * #include "cl_inline.h"
60  * #include "path/to/cl_foo.cc"
61  *
62  * This will declare and define function cl_foo_inline, which is an inline
63  * version of cl_foo.
64  *
65  * XXX:
66  * The name of the inline version *really* has to be different, since ISO C++
67  * demands (in 7.1.2.4)
68  *
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."
72  *
73  * Feel free to implement this functionality in a better *standard-compliant*
74  * way. Or submit a DR (defect report) to the standard committee.
75  */
76 #define CL_INLINE
77 #define CL_INLINE_DECL(fcn) fcn
78
79 /*
80  * Use these macros to provide inline and non-inline versions of a function
81  * which uses an inline version of other function(s). 
82  */
83 #define CL_INLINE2
84 #define CL_INLINE2_DECL(fcn) fcn
85
86 /*
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.
91  *
92  * Usage:
93  *
94  * const cl_foo CL_FLATTEN cl_bar(const cl_R& x)
95  * {
96  *   // the actual code
97  * }
98  *
99  * Please note: 
100  *
101  * 1. This is only a *hint*, it's always up to the compiler to NOT inline
102  *    a function.
103  * 2. It's ignored if the optimization is switched off.
104  */
105 #if defined(CL_HAVE_ATTRIBUTE_FLATTEN)
106 #define CL_FLATTEN __attribute__((flatten))
107 #else
108 #define CL_FLATTEN
109 #endif
110
111 /*
112  * Tell the compiler to inline a function more aggressively, i.e. even if the
113  * optimization is switched off.
114  *
115  * Usage:
116  *
117  * cl_blah CL_INLINE_HINT cl_foo(const cl_baz& x)
118  * {
119  *   // the actual code
120  * }
121  *
122  * Notes:
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.
126  */
127 #ifdef __GNUC__
128 #define CL_INLINE_HINT __attribute__((always_inline))
129 #else
130 #define CL_INLINE_HINT
131 #endif
132
133 #endif /* _CL_MAYBE_INLINE_H */