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