On Wed, May 27, 2020 at 12:32:36PM +0200, 'Marco Elver' via Clang Built Linux wrote: > If the compiler supports C11's _Generic, use it to speed up compilation > times of __unqual_scalar_typeof(). GCC version 4.9 or later and > all supported versions of Clang support the feature (the oldest > supported compiler that doesn't support _Generic is GCC 4.8, for which > we use the slower alternative). > > The non-_Generic variant relies on multiple expansions of > __pick_integer_type -> __pick_scalar_type -> __builtin_choose_expr, > which increases pre-processed code size, and can cause compile times to > increase in files with numerous expansions of READ_ONCE(), or other > users of __unqual_scalar_typeof(). > > Summary of compile-time benchmarking done by Arnd Bergmann [1]: > > <baseline normalized time> clang-11 gcc-9 > this patch 0.78 0.91 > ideal 0.76 0.86 > > [1] > https://lkml.kernel.org/r/CAK8P3a3UYQeXhiufUevz=rwe09wm_vstcd9w+kvjhjcoeqy...@mail.gmail.com > > Further compile-testing done with: > gcc 4.8, 4.9, 5.5, 6.4, 7.5, 8.4; > clang 9, 10. > > Reported-by: Arnd Bergmann <[email protected]> > Signed-off-by: Marco Elver <[email protected]> > Cc: Borislav Petkov <[email protected]> > Cc: Ingo Molnar <[email protected]> > Cc: Nick Desaulniers <[email protected]> > Cc: Paul E. McKenney <[email protected]> > Cc: Peter Zijlstra <[email protected]> > Cc: Stephen Rothwell <[email protected]> > Cc: Thomas Gleixner <[email protected]> > Cc: Will Deacon <[email protected]> > Link: > https://lkml.kernel.org/r/CAK8P3a0RJtbVi1JMsfik=jkhcnfv+djn_fedg-ylw+ueqw3...@mail.gmail.com > --- > Same version as in: > https://lkml.kernel.org/r/[email protected] > --- > include/linux/compiler_types.h | 22 +++++++++++++++++++++- > 1 file changed, 21 insertions(+), 1 deletion(-) > > diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h > index 5faf68eae204..a529fa263906 100644 > --- a/include/linux/compiler_types.h > +++ b/include/linux/compiler_types.h > @@ -245,7 +245,9 @@ struct ftrace_likely_data { > /* > * __unqual_scalar_typeof(x) - Declare an unqualified scalar type, leaving > * non-scalar types unchanged. > - * > + */ > +#if defined(CONFIG_CC_IS_GCC) && CONFIG_GCC_VERSION < 40900 > +/* > * We build this out of a couple of helper macros in a vain attempt to > * help you keep your lunch down while reading it. > */ > @@ -267,6 +269,24 @@ struct ftrace_likely_data { > __pick_integer_type(x, int, > \ > __pick_integer_type(x, long, > \ > __pick_integer_type(x, long long, > x)))))) > +#else > +/* > + * If supported, prefer C11 _Generic for better compile-times. As above, > 'char' > + * is not type-compatible with 'signed char', and we define a separate case. > + */ > +#define __scalar_type_to_expr_cases(type) \ > + type: (type)0, unsigned type: (unsigned type)0 > + > +#define __unqual_scalar_typeof(x) typeof( \ > + _Generic((x), \ > + __scalar_type_to_expr_cases(char), \ > + signed char: (signed char)0, \ > + __scalar_type_to_expr_cases(short), \ > + __scalar_type_to_expr_cases(int), \ > + __scalar_type_to_expr_cases(long), \ > + __scalar_type_to_expr_cases(long long), \ > + default: (x))) > +#endif > > /* Is this type a native word size -- useful for atomic operations */ > #define __native_word(t) \ > -- > 2.27.0.rc0.183.gde8f92d652-goog >
Reviewed-by: Nathan Chancellor <[email protected]> Tested-by: Nathan Chancellor <[email protected]> # build

