Macroize function declarations in math_private.h

Submitted by Gabriel Ferreira Teles Gomes on March 17, 2017, 7:02 p.m.

Details

Message ID 1489777376-2786-1-git-send-email-gftg@linux.vnet.ibm.com
State New
Headers show

Commit Message

Gabriel Ferreira Teles Gomes March 17, 2017, 7:02 p.m.
This patch macroizes the declaration of many functions in
math_private.h, in order to reduce repetitiveness in the declaration
of float128 versions of these functions, as suggested in
https://sourceware.org/ml/libc-alpha/2016-11/msg00423.html

-- 8< --
This patch moves the declaration of many floating-point functions from
math_private.h to math_private_commons.h and macroize the declaration
to be dependent on floating-point type.  For each of float, double,
and long double, the new header file is included once.  This reduces
the amount of repetitive boilerplate that will be required when adding
float128 versions of these functions.

Tested for powerpc64le and s390x.

2017-03-17  Gabriel F. T. Gomes  <gftg@linux.vnet.ibm.com>

	* sysdeps/generic/math_private.h: Move the declaration of many
	functions to sysdeps/generic/math_private_common.h.
	* sysdeps/generic/math_private_common.h: New file with the
	declarations of the functions removed from math_private.h
	macroized by floating-point type.
---
 sysdeps/generic/math_private.h        | 218 +++++-----------------------------
 sysdeps/generic/math_private_common.h | 146 +++++++++++++++++++++++
 2 files changed, 174 insertions(+), 190 deletions(-)
 create mode 100644 sysdeps/generic/math_private_common.h

Comments

Joseph S. Myers March 21, 2017, 6:32 p.m.
On Fri, 17 Mar 2017, Gabriel F. T. Gomes wrote:

> 2017-03-17  Gabriel F. T. Gomes  <gftg@linux.vnet.ibm.com>
> 
> 	* sysdeps/generic/math_private.h: Move the declaration of many
> 	functions to sysdeps/generic/math_private_common.h.
> 	* sysdeps/generic/math_private_common.h: New file with the
> 	declarations of the functions removed from math_private.h
> 	macroized by floating-point type.

I don't think math_private_common.h is a good name.  Calling something 
"common" raises the question of what it's common between - not between 
different architectures, for example, as that's implied by 
sysdeps/generic.  Something like "calls" might be better than "common".

There are also various complications in here that look like they are 
replicating peculiarities of the existing header, when it might be better 
to clean up those peculiarities first so it's easier for the new 
arrangements to preserve semantics.  Thus:

> +#define _Mint_ int32_t

It would seem better to make float, double, long double code consistent 
about whether this type is int or int32_t, so such a macro is no longer 
needed.

> +#if defined __MATH_DECLARING_LONG_DOUBLE && !defined NO_LONG_DOUBLE
> +/* Prototypes required to compile the ldbl-96 support without warnings.  */
> +extern int __MSUF (__finite) (_Mdouble_);
> +extern int __MSUF (__ilogb) (_Mdouble_);
> +extern int __MSUF (__isinf) (_Mdouble_);
> +extern int __MSUF (__isnan) (_Mdouble_);
> +extern _Mdouble_ __MSUF (__atan) (_Mdouble_);
> +extern _Mdouble_ __MSUF (__expm1) (_Mdouble_);
> +extern _Mdouble_ __MSUF (__floor) (_Mdouble_);
> +extern _Mdouble_ __MSUF (__frexp) (_Mdouble_, int *);
> +extern _Mdouble_ __MSUF (__ldexp) (_Mdouble_, int);
> +extern _Mdouble_ __MSUF (__log1p) (_Mdouble_);
> +extern _Mdouble_ __MSUF (__nan) (const char *);
> +extern _Mdouble_ __MSUF (__rint) (_Mdouble_);
> +extern _Mdouble_ __MSUF (__scalbn) (_Mdouble_, int);
> +extern _Mdouble_ __MSUF (__sqrt) (_Mdouble_ x);
> +extern _Mdouble_ __MSUF (fabs) (_Mdouble_ x);
> +extern void __MSUF (__sincos) (_Mdouble_, _Mdouble_ *, _Mdouble_ *);
> +extern _Mdouble_ __MSUF (__logb) (_Mdouble_ x);
> +extern _Mdouble_ __MSUF (__significand) (_Mdouble_ x);
> +#endif

None of thse should be needed.  math.h defines __MATHDECL and __MATHDECLX 
so that they declare both func and __func together for each function.  
It's questionable whether math.h *should* declare the __ versions in the 
absence of _LIBC, but I'd expect those declarations could be removed from 
math_private.h without causing any build issues, because of the public 
header declaring the functions for long double just as for other types.

Patch hide | download patch | download mbox

diff --git a/sysdeps/generic/math_private.h b/sysdeps/generic/math_private.h
index be65b94..8cdad09 100644
--- a/sysdeps/generic/math_private.h
+++ b/sysdeps/generic/math_private.h
@@ -184,166 +184,39 @@  do {								\
 /* Get long double macros from a separate header.  */
 #include <math_ldbl.h>
 
-/* ieee style elementary functions */
-extern double __ieee754_sqrt (double);
-extern double __ieee754_acos (double);
-extern double __ieee754_acosh (double);
-extern double __ieee754_log (double);
-extern double __ieee754_atanh (double);
-extern double __ieee754_asin (double);
-extern double __ieee754_atan2 (double,double);
-extern double __ieee754_exp (double);
-extern double __ieee754_exp2 (double);
-extern double __ieee754_exp10 (double);
-extern double __ieee754_cosh (double);
-extern double __ieee754_fmod (double,double);
-extern double __ieee754_pow (double,double);
-extern double __ieee754_lgamma_r (double,int *);
-extern double __ieee754_gamma_r (double,int *);
-extern double __ieee754_lgamma (double);
-extern double __ieee754_gamma (double);
-extern double __ieee754_log10 (double);
-extern double __ieee754_log2 (double);
-extern double __ieee754_sinh (double);
-extern double __ieee754_hypot (double,double);
-extern double __ieee754_j0 (double);
-extern double __ieee754_j1 (double);
-extern double __ieee754_y0 (double);
-extern double __ieee754_y1 (double);
-extern double __ieee754_jn (int,double);
-extern double __ieee754_yn (int,double);
-extern double __ieee754_remainder (double,double);
-extern int32_t __ieee754_rem_pio2 (double,double*);
-extern double __ieee754_scalb (double,double);
-extern int __ieee754_ilogb (double);
+/* Include function declarations for each floating-point.  */
+#define _Mdouble_ double
+#define _Mint_ int32_t
+#define _MSUF_
+#include <math_private_common.h>
+#undef _MSUF_
+#undef _Mint_
+#undef _Mdouble_
+
+#define _Mdouble_ float
+#define _Mint_ int32_t
+#define _MSUF_ f
+#define __MATH_DECLARING_FLOAT
+#include <math_private_common.h>
+#undef __MATH_DECLARING_FLOAT
+#undef _MSUF_
+#undef _Mint_
+#undef _Mdouble_
+
+#define _Mdouble_ long double
+#define _Mint_ int
+#define _MSUF_ l
+#define __MATH_DECLARING_LONG_DOUBLE
+#include <math_private_common.h>
+#undef __MATH_DECLARING_LONG_DOUBLE
+#undef _MSUF_
+#undef _Mint_
+#undef _Mdouble_
 
 /* fdlibm kernel function */
 extern double __kernel_standard (double,double,int);
 extern float __kernel_standard_f (float,float,int);
 extern long double __kernel_standard_l (long double,long double,int);
-extern double __kernel_sin (double,double,int);
-extern double __kernel_cos (double,double);
-extern double __kernel_tan (double,double,int);
-extern int    __kernel_rem_pio2 (double*,double*,int,int,int, const int32_t*);
-
-/* internal functions.  */
-extern double __copysign (double x, double __y);
-
-extern inline double __copysign (double x, double y)
-{ return __builtin_copysign (x, y); }
-
-/* ieee style elementary float functions */
-extern float __ieee754_sqrtf (float);
-extern float __ieee754_acosf (float);
-extern float __ieee754_acoshf (float);
-extern float __ieee754_logf (float);
-extern float __ieee754_atanhf (float);
-extern float __ieee754_asinf (float);
-extern float __ieee754_atan2f (float,float);
-extern float __ieee754_expf (float);
-extern float __ieee754_exp2f (float);
-extern float __ieee754_exp10f (float);
-extern float __ieee754_coshf (float);
-extern float __ieee754_fmodf (float,float);
-extern float __ieee754_powf (float,float);
-extern float __ieee754_lgammaf_r (float,int *);
-extern float __ieee754_gammaf_r (float,int *);
-extern float __ieee754_lgammaf (float);
-extern float __ieee754_gammaf (float);
-extern float __ieee754_log10f (float);
-extern float __ieee754_log2f (float);
-extern float __ieee754_sinhf (float);
-extern float __ieee754_hypotf (float,float);
-extern float __ieee754_j0f (float);
-extern float __ieee754_j1f (float);
-extern float __ieee754_y0f (float);
-extern float __ieee754_y1f (float);
-extern float __ieee754_jnf (int,float);
-extern float __ieee754_ynf (int,float);
-extern float __ieee754_remainderf (float,float);
-extern int32_t __ieee754_rem_pio2f (float,float*);
-extern float __ieee754_scalbf (float,float);
-extern int __ieee754_ilogbf (float);
-
-
-/* float versions of fdlibm kernel functions */
-extern float __kernel_sinf (float,float,int);
-extern float __kernel_cosf (float,float);
-extern float __kernel_tanf (float,float,int);
-extern int   __kernel_rem_pio2f (float*,float*,int,int,int, const int32_t*);
-
-/* internal functions.  */
-extern float __copysignf (float x, float __y);
-
-extern inline float __copysignf (float x, float y)
-{ return __builtin_copysignf (x, y); }
-
-/* ieee style elementary long double functions */
-extern long double __ieee754_sqrtl (long double);
-extern long double __ieee754_acosl (long double);
-extern long double __ieee754_acoshl (long double);
-extern long double __ieee754_logl (long double);
-extern long double __ieee754_atanhl (long double);
-extern long double __ieee754_asinl (long double);
-extern long double __ieee754_atan2l (long double,long double);
-extern long double __ieee754_expl (long double);
-extern long double __ieee754_exp2l (long double);
-extern long double __ieee754_exp10l (long double);
-extern long double __ieee754_coshl (long double);
-extern long double __ieee754_fmodl (long double,long double);
-extern long double __ieee754_powl (long double,long double);
-extern long double __ieee754_lgammal_r (long double,int *);
-extern long double __ieee754_gammal_r (long double,int *);
-extern long double __ieee754_lgammal (long double);
-extern long double __ieee754_gammal (long double);
-extern long double __ieee754_log10l (long double);
-extern long double __ieee754_log2l (long double);
-extern long double __ieee754_sinhl (long double);
-extern long double __ieee754_hypotl (long double,long double);
-extern long double __ieee754_j0l (long double);
-extern long double __ieee754_j1l (long double);
-extern long double __ieee754_y0l (long double);
-extern long double __ieee754_y1l (long double);
-extern long double __ieee754_jnl (int,long double);
-extern long double __ieee754_ynl (int,long double);
-extern long double __ieee754_remainderl (long double,long double);
-extern int   __ieee754_rem_pio2l (long double,long double*);
-extern long double __ieee754_scalbl (long double,long double);
-extern int   __ieee754_ilogbl (long double);
-
-/* long double versions of fdlibm kernel functions */
-extern long double __kernel_sinl (long double,long double,int);
-extern long double __kernel_cosl (long double,long double);
-extern long double __kernel_tanl (long double,long double,int);
-extern void __kernel_sincosl (long double,long double,
-			      long double *,long double *, int);
-
-#ifndef NO_LONG_DOUBLE
-/* prototypes required to compile the ldbl-96 support without warnings */
-extern int __finitel (long double);
-extern int __ilogbl (long double);
-extern int __isinfl (long double);
-extern int __isnanl (long double);
-extern long double __atanl (long double);
-extern long double __copysignl (long double, long double);
-extern long double __expm1l (long double);
-extern long double __floorl (long double);
-extern long double __frexpl (long double, int *);
-extern long double __ldexpl (long double, int);
-extern long double __log1pl (long double);
-extern long double __nanl (const char *);
-extern long double __rintl (long double);
-extern long double __scalbnl (long double, int);
-extern long double __sqrtl (long double x);
-extern long double fabsl (long double x);
-extern void __sincosl (long double, long double *, long double *);
-extern long double __logbl (long double x);
-extern long double __significandl (long double x);
-
-extern inline long double __copysignl (long double x, long double y)
-{ return __builtin_copysignl (x, y); }
-
-#endif
 
 /* Prototypes for functions of the IBM Accurate Mathematical Library.  */
 extern double __exp1 (double __x, double __xx, double __error);
@@ -362,41 +235,6 @@  extern double __slowexp (double __x);
 extern double __slowpow (double __x, double __y, double __z);
 extern void __docos (double __x, double __dx, double __v[]);
 
-/* Return X^2 + Y^2 - 1, computed without large cancellation error.
-   It is given that 1 > X >= Y >= epsilon / 2, and that X^2 + Y^2 >=
-   0.5.  */
-extern float __x2y2m1f (float x, float y);
-extern double __x2y2m1 (double x, double y);
-extern long double __x2y2m1l (long double x, long double y);
-
-/* Compute the product of X + X_EPS, X + X_EPS + 1, ..., X + X_EPS + N
-   - 1, in the form R * (1 + *EPS) where the return value R is an
-   approximation to the product and *EPS is set to indicate the
-   approximate error in the return value.  X is such that all the
-   values X + 1, ..., X + N - 1 are exactly representable, and X_EPS /
-   X is small enough that factors quadratic in it can be
-   neglected.  */
-extern float __gamma_productf (float x, float x_eps, int n, float *eps);
-extern double __gamma_product (double x, double x_eps, int n, double *eps);
-extern long double __gamma_productl (long double x, long double x_eps,
-				     int n, long double *eps);
-
-/* Compute lgamma of a negative argument X, if it is in a range
-   (depending on the floating-point format) for which expansion around
-   zeros is used, setting *SIGNGAMP accordingly.  */
-extern float __lgamma_negf (float x, int *signgamp);
-extern double __lgamma_neg (double x, int *signgamp);
-extern long double __lgamma_negl (long double x, int *signgamp);
-
-/* Compute the product of 1 + (T / (X + X_EPS)), 1 + (T / (X + X_EPS +
-   1)), ..., 1 + (T / (X + X_EPS + N - 1)), minus 1.  X is such that
-   all the values X + 1, ..., X + N - 1 are exactly representable, and
-   X_EPS / X is small enough that factors quadratic in it can be
-   neglected.  */
-extern double __lgamma_product (double t, double x, double x_eps, int n);
-extern long double __lgamma_productl (long double t, long double x,
-				      long double x_eps, int n);
-
 #ifndef math_opt_barrier
 # define math_opt_barrier(x) \
 ({ __typeof (x) __x = (x); __asm ("" : "+m" (__x)); __x; })
diff --git a/sysdeps/generic/math_private_common.h b/sysdeps/generic/math_private_common.h
new file mode 100644
index 0000000..b1f9644
--- /dev/null
+++ b/sysdeps/generic/math_private_common.h
@@ -0,0 +1,146 @@ 
+/* Private function declarations for libm.
+   Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define __MSUF_X(x, suffix) x ## suffix
+#define __MSUF_S(...) __MSUF_X (__VA_ARGS__)
+#define __MSUF(x) __MSUF_S (x, _MSUF_)
+
+#define __MSUF_R_X(x, suffix) x ## suffix ## _r
+#define __MSUF_R_S(...) __MSUF_R_X (__VA_ARGS__)
+#define __MSUF_R(x) __MSUF_R_S (x, _MSUF_)
+
+/* IEEE style elementary functions.  */
+extern _Mdouble_ __MSUF (__ieee754_acos) (_Mdouble_);
+extern _Mdouble_ __MSUF (__ieee754_acosh) (_Mdouble_);
+extern _Mdouble_ __MSUF (__ieee754_asin) (_Mdouble_);
+extern _Mdouble_ __MSUF (__ieee754_atan2) (_Mdouble_, _Mdouble_);
+extern _Mdouble_ __MSUF (__ieee754_atanh) (_Mdouble_);
+extern _Mdouble_ __MSUF (__ieee754_cosh) (_Mdouble_);
+extern _Mdouble_ __MSUF (__ieee754_exp) (_Mdouble_);
+extern _Mdouble_ __MSUF (__ieee754_exp10) (_Mdouble_);
+extern _Mdouble_ __MSUF (__ieee754_exp2) (_Mdouble_);
+extern _Mdouble_ __MSUF (__ieee754_fmod) (_Mdouble_, _Mdouble_);
+extern _Mdouble_ __MSUF (__ieee754_gamma) (_Mdouble_);
+extern _Mdouble_ __MSUF_R (__ieee754_gamma) (_Mdouble_, int *);
+extern _Mdouble_ __MSUF (__ieee754_hypot) (_Mdouble_, _Mdouble_);
+extern _Mdouble_ __MSUF (__ieee754_j0) (_Mdouble_);
+extern _Mdouble_ __MSUF (__ieee754_j1) (_Mdouble_);
+extern _Mdouble_ __MSUF (__ieee754_jn) (int, _Mdouble_);
+extern _Mdouble_ __MSUF (__ieee754_lgamma) (_Mdouble_);
+extern _Mdouble_ __MSUF_R (__ieee754_lgamma) (_Mdouble_, int *);
+extern _Mdouble_ __MSUF (__ieee754_log) (_Mdouble_);
+extern _Mdouble_ __MSUF (__ieee754_log10) (_Mdouble_);
+extern _Mdouble_ __MSUF (__ieee754_log2) (_Mdouble_);
+extern _Mdouble_ __MSUF (__ieee754_pow) (_Mdouble_, _Mdouble_);
+extern _Mdouble_ __MSUF (__ieee754_remainder) (_Mdouble_, _Mdouble_);
+extern _Mdouble_ __MSUF (__ieee754_sinh) (_Mdouble_);
+extern _Mdouble_ __MSUF (__ieee754_sqrt) (_Mdouble_);
+extern _Mdouble_ __MSUF (__ieee754_y0) (_Mdouble_);
+extern _Mdouble_ __MSUF (__ieee754_y1) (_Mdouble_);
+extern _Mdouble_ __MSUF (__ieee754_yn) (int, _Mdouble_);
+
+extern _Mdouble_ __MSUF (__ieee754_scalb) (_Mdouble_, _Mdouble_);
+extern int __MSUF (__ieee754_ilogb) (_Mdouble_);
+
+extern _Mint_ __MSUF (__ieee754_rem_pio2) (_Mdouble_, _Mdouble_ *);
+
+/* fdlibm kernel functions.  */
+extern _Mdouble_ __MSUF (__kernel_sin) (_Mdouble_, _Mdouble_, int);
+extern _Mdouble_ __MSUF (__kernel_cos) (_Mdouble_, _Mdouble_);
+extern _Mdouble_ __MSUF (__kernel_tan) (_Mdouble_, _Mdouble_, int);
+
+#if defined __MATH_DECLARING_LONG_DOUBLE
+extern void __MSUF (__kernel_sincos) (_Mdouble_, _Mdouble_,
+				      _Mdouble_ *, _Mdouble_ *, int);
+#endif
+
+#if !defined __MATH_DECLARING_LONG_DOUBLE
+extern int __MSUF (__kernel_rem_pio2) (_Mdouble_ *, _Mdouble_ *, int,
+				       int, int, const _Mint_ *);
+#endif
+
+/* Internal functions.  */
+#if !defined __MATH_DECLARING_LONG_DOUBLE || !defined NO_LONG_DOUBLE
+extern _Mdouble_ __MSUF (__copysign) (_Mdouble_ x, _Mdouble_ __y);
+
+extern inline _Mdouble_
+__MSUF (__copysign) (_Mdouble_ x, _Mdouble_ __y)
+{
+  return __MSUF (__builtin_copysign) (x, __y);
+}
+#endif
+
+#if defined __MATH_DECLARING_LONG_DOUBLE && !defined NO_LONG_DOUBLE
+/* Prototypes required to compile the ldbl-96 support without warnings.  */
+extern int __MSUF (__finite) (_Mdouble_);
+extern int __MSUF (__ilogb) (_Mdouble_);
+extern int __MSUF (__isinf) (_Mdouble_);
+extern int __MSUF (__isnan) (_Mdouble_);
+extern _Mdouble_ __MSUF (__atan) (_Mdouble_);
+extern _Mdouble_ __MSUF (__expm1) (_Mdouble_);
+extern _Mdouble_ __MSUF (__floor) (_Mdouble_);
+extern _Mdouble_ __MSUF (__frexp) (_Mdouble_, int *);
+extern _Mdouble_ __MSUF (__ldexp) (_Mdouble_, int);
+extern _Mdouble_ __MSUF (__log1p) (_Mdouble_);
+extern _Mdouble_ __MSUF (__nan) (const char *);
+extern _Mdouble_ __MSUF (__rint) (_Mdouble_);
+extern _Mdouble_ __MSUF (__scalbn) (_Mdouble_, int);
+extern _Mdouble_ __MSUF (__sqrt) (_Mdouble_ x);
+extern _Mdouble_ __MSUF (fabs) (_Mdouble_ x);
+extern void __MSUF (__sincos) (_Mdouble_, _Mdouble_ *, _Mdouble_ *);
+extern _Mdouble_ __MSUF (__logb) (_Mdouble_ x);
+extern _Mdouble_ __MSUF (__significand) (_Mdouble_ x);
+#endif
+
+/* Return X^2 + Y^2 - 1, computed without large cancellation error.
+   It is given that 1 > X >= Y >= epsilon / 2, and that X^2 + Y^2 >=
+   0.5.  */
+extern _Mdouble_ __MSUF (__x2y2m1) (_Mdouble_ x, _Mdouble_ y);
+
+/* Compute the product of X + X_EPS, X + X_EPS + 1, ..., X + X_EPS + N
+   - 1, in the form R * (1 + *EPS) where the return value R is an
+   approximation to the product and *EPS is set to indicate the
+   approximate error in the return value.  X is such that all the
+   values X + 1, ..., X + N - 1 are exactly representable, and X_EPS /
+   X is small enough that factors quadratic in it can be
+   neglected.  */
+extern _Mdouble_ __MSUF (__gamma_product) (_Mdouble_ x, _Mdouble_ x_eps,
+					   int n, _Mdouble_ *eps);
+
+/* Compute lgamma of a negative argument X, if it is in a range
+   (depending on the floating-point format) for which expansion around
+   zeros is used, setting *SIGNGAMP accordingly.  */
+extern _Mdouble_ __MSUF (__lgamma_neg) (_Mdouble_ x, int *signgamp);
+
+/* Compute the product of 1 + (T / (X + X_EPS)), 1 + (T / (X + X_EPS +
+   1)), ..., 1 + (T / (X + X_EPS + N - 1)), minus 1.  X is such that
+   all the values X + 1, ..., X + N - 1 are exactly representable, and
+   X_EPS / X is small enough that factors quadratic in it can be
+   neglected.  */
+#if !defined __MATH_DECLARING_FLOAT
+extern _Mdouble_ __MSUF (__lgamma_product) (_Mdouble_ t, _Mdouble_ x,
+					    _Mdouble_ x_eps, int n);
+#endif
+
+#undef __MSUF_X
+#undef __MSUF_S
+#undef __MSUF
+
+#undef __MSUF_R_X
+#undef __MSUF_R_S
+#undef __MSUF_R