diff options
author | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2014-06-30 09:57:36 +0000 |
---|---|---|
committer | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2014-06-30 09:57:36 +0000 |
commit | db110f3c56448f3084cc474bf4185ee2486ae96b (patch) | |
tree | 24f505fec32f9b67f9820330704f60a79bf9ada8 /src | |
parent | 4be6dad958efb74af2abde7c50f654ebcbb4d7d2 (diff) | |
download | mpfr-db110f3c56448f3084cc474bf4185ee2486ae96b.tar.gz |
New macros for mpfr_{mul,div}_ui to optimize the call when the integer
is a constant number that is a power of 2.
New macros for mpfr_{mul,div}_si to optimize the call when the integer
is a constant number that is positive.
(Modified patch from Patrick PĂ©lissier)
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@9111 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'src')
-rw-r--r-- | src/div_ui.c | 2 | ||||
-rw-r--r-- | src/mpfr.h | 35 | ||||
-rw-r--r-- | src/mul_ui.c | 2 |
3 files changed, 39 insertions, 0 deletions
diff --git a/src/div_ui.c b/src/div_ui.c index bed6b6e00..beee07d0d 100644 --- a/src/div_ui.c +++ b/src/div_ui.c @@ -24,6 +24,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., #include "mpfr-impl.h" /* returns 0 if result exact, non-zero otherwise */ +#undef mpfr_div_ui MPFR_HOT_FUNCTION_ATTR int mpfr_div_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mpfr_rnd_t rnd_mode) { @@ -259,6 +260,7 @@ mpfr_div_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mpfr_rnd_t rnd_mode return mpfr_check_range (y, inexact, rnd_mode); } +#undef mpfr_div_si int mpfr_div_si (mpfr_ptr y, mpfr_srcptr x, long int u, mpfr_rnd_t rnd_mode) { diff --git a/src/mpfr.h b/src/mpfr.h index c344ce674..6178fece3 100644 --- a/src/mpfr.h +++ b/src/mpfr.h @@ -905,6 +905,7 @@ __MPFR_DECLSPEC int mpfr_custom_get_kind _MPFR_PROTO ((mpfr_srcptr)); be used. */ #if defined (__GNUC__) && !defined(__ICC) && !defined(__cplusplus) #if (__GNUC__ >= 2) + #undef mpfr_cmp_ui /* We use the fact that mpfr_sgn on NaN sets the erange flag and returns 0. But warning! mpfr_sgn is specified as a macro in the API, thus the macro @@ -913,11 +914,13 @@ __MPFR_DECLSPEC int mpfr_custom_get_kind _MPFR_PROTO ((mpfr_srcptr)); (__builtin_constant_p (_u) && (mpfr_ulong) (_u) == 0 ? \ (mpfr_sgn) (_f) : \ mpfr_cmp_ui_2exp ((_f), (_u), 0)) + #undef mpfr_cmp_si #define mpfr_cmp_si(_f,_s) \ (__builtin_constant_p (_s) && (mpfr_long) (_s) >= 0 ? \ mpfr_cmp_ui ((_f), (mpfr_ulong) (mpfr_long) (_s)) : \ mpfr_cmp_si_2exp ((_f), (_s), 0)) + #if __GNUC__ > 2 || __GNUC_MINOR__ >= 95 #undef mpfr_set_ui #define mpfr_set_ui(_f,_u,_r) \ @@ -929,11 +932,43 @@ __MPFR_DECLSPEC int mpfr_custom_get_kind _MPFR_PROTO ((mpfr_srcptr)); (mpfr_void) (_r); 0; }) : \ mpfr_set_ui_2exp ((_f), (_u), 0, (_r))) #endif + #undef mpfr_set_si #define mpfr_set_si(_f,_s,_r) \ (__builtin_constant_p (_s) && (mpfr_long) (_s) >= 0 ? \ mpfr_set_ui ((_f), (mpfr_ulong) (mpfr_long) (_s), (_r)) : \ mpfr_set_si_2exp ((_f), (_s), 0, (_r))) + +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +/* If the source is a constant number that is a power of 2, + optimize the call */ +#undef mpfr_mul_ui +#define mpfr_mul_ui(_f, _g, _u,_r) \ + (__builtin_constant_p (_u) && (mpfr_ulong) (_u) >= 1 && \ + ((mpfr_ulong) (_u) & ((mpfr_ulong) (_u) - 1)) == 0 ? \ + mpfr_mul_2si((_f), (_g), __builtin_ctzl (_u), (_r)) : \ + mpfr_mul_ui ((_f), (_g), (_u), (_r))) +#undef mpfr_div_ui +#define mpfr_div_ui(_f, _g, _u,_r) \ + (__builtin_constant_p (_u) && (mpfr_ulong) (_u) >= 1 && \ + ((mpfr_ulong) (_u) & ((mpfr_ulong) (_u) - 1)) == 0 ? \ + mpfr_mul_2si((_f), (_g), -__builtin_ctzl (_u), (_r)) : \ + mpfr_div_ui ((_f), (_g), (_u), (_r))) +#endif + +/* If the source is a constant number that is positive, + optimize the call */ +#undef mpfr_mul_si +#define mpfr_mul_si(_f, _g, _s,_r) \ + (__builtin_constant_p (_s) && (mpfr_long) (_s) >= 0 ? \ + mpfr_mul_ui ((_f), (_g), (mpfr_ulong) (mpfr_long) (_s), (_r)) : \ + mpfr_mul_si ((_f), (_g), (_s), (_r))) +#undef mpfr_div_si +#define mpfr_div_si(_f, _g, _s,_r) \ + (__builtin_constant_p (_s) && (mpfr_long) (_s) >= 0 ? \ + mpfr_div_ui ((_f), (_g), (mpfr_ulong) (mpfr_long) (_s), (_r)) : \ + mpfr_div_si ((_f), (_g), (_s), (_r))) + #endif #endif diff --git a/src/mul_ui.c b/src/mul_ui.c index 4c3e063b0..2ad96e50e 100644 --- a/src/mul_ui.c +++ b/src/mul_ui.c @@ -24,6 +24,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., #define MPFR_NEED_LONGLONG_H #include "mpfr-impl.h" +#undef mpfr_mul_ui MPFR_HOT_FUNCTION_ATTR int mpfr_mul_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mpfr_rnd_t rnd_mode) { @@ -118,6 +119,7 @@ mpfr_mul_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mpfr_rnd_t rnd_mode return inexact; } +#undef mpfr_mul_si int mpfr_mul_si (mpfr_ptr y, mpfr_srcptr x, long int u, mpfr_rnd_t rnd_mode) { int res; |