summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorvlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2014-06-30 09:57:36 +0000
committervlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2014-06-30 09:57:36 +0000
commitdb110f3c56448f3084cc474bf4185ee2486ae96b (patch)
tree24f505fec32f9b67f9820330704f60a79bf9ada8 /src
parent4be6dad958efb74af2abde7c50f654ebcbb4d7d2 (diff)
downloadmpfr-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.c2
-rw-r--r--src/mpfr.h35
-rw-r--r--src/mul_ui.c2
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;