This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch master updated. glibc-2.19-644-ge6d90d6


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  e6d90d675d4cae810be76a5ff41b8ae8bd6bc914 (commit)
      from  88a4647493fbc2a3f6b1348df010bb0a9c5aed55 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=e6d90d675d4cae810be76a5ff41b8ae8bd6bc914

commit e6d90d675d4cae810be76a5ff41b8ae8bd6bc914
Author: Wilco Dijkstra <wdijkstr@arm.com>
Date:   Mon Jun 23 17:15:41 2014 +0100

    Add generic HAVE_RM_CTX implementation
    
    This patch adds a generic implementation of HAVE_RM_CTX using standard
    fenv calls. As a result math functions using SET_RESTORE_ROUND* macros
    do not suffer from a large slowdown on targets which do not implement
    optimized libc_fe*_ctx inline functions. Most of the libc_fe* inline
    functions are now unused and could be removed in the future (there are
    a few math functions left which use a mixture of standard fenv calls
    and libc_fe* inline functions - they could be updated to use
    SET_RESTORE_ROUND or improved to avoid expensive fenv manipulations
    across just a few FP instructions).
    
    libc_feholdsetround*_noex_ctx is added to enable better optimization of
    SET_RESTORE_ROUND_NOEX* implementations.
    
    Performance measurements on ARM and x86 of sin() show significant gains
    over the current default, fairly close to a highly optimized fenv_private:
    
                            ARM   x86
    no fenv_private      : 100%  100%
    generic HAVE_RM_CTX  : 250%  350%
    fenv_private (CTX)   : 250%  450%
    
    2014-06-23  Will Newton  <will.newton@linaro.org>
    	    Wilco  <wdijkstr@arm.com>
    
    	* sysdeps/generic/math_private.h: Add generic HAVE_RM_CTX
    	implementation.  Include get-rounding-mode.h.
    	[!HAVE_RM_CTX]: Define HAVE_RM_CTX to zero.
    	[!libc_feholdsetround_noex_ctx]: Define
    	libc_feholdsetround_noex_ctx.
    	[!libc_feholdsetround_noexf_ctx]: Define
    	libc_feholdsetround_noexf_ctx.
    	[!libc_feholdsetround_noexl_ctx]: Define
    	libc_feholdsetround_noexl_ctx.
    	(libc_feholdsetround_ctx): New function.
    	(libc_feresetround_ctx): New function.
    	(libc_feholdsetround_noex_ctx): New function.
    	(libc_feresetround_noex_ctx): New function.

diff --git a/ChangeLog b/ChangeLog
index 8a4fe09..bac46f0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2014-06-23  Will Newton  <will.newton@linaro.org>
+	    Wilco  <wdijkstr@arm.com>
+
+	* sysdeps/generic/math_private.h: Add generic HAVE_RM_CTX
+	implementation.  Include get-rounding-mode.h.
+	[!HAVE_RM_CTX]: Define HAVE_RM_CTX to zero.
+	[!libc_feholdsetround_noex_ctx]: Define
+	libc_feholdsetround_noex_ctx.
+	[!libc_feholdsetround_noexf_ctx]: Define
+	libc_feholdsetround_noexf_ctx.
+	[!libc_feholdsetround_noexl_ctx]: Define
+	libc_feholdsetround_noexl_ctx.
+	(libc_feholdsetround_ctx): New function.
+	(libc_feresetround_ctx): New function.
+	(libc_feholdsetround_noex_ctx): New function.
+	(libc_feresetround_noex_ctx): New function.
+
 2014-06-23  Roland McGrath  <roland@hack.frob.com>
 
 	* sysdeps/unix/sysv/linux/mips/nptl/bits/pthreadtypes.h: Moved ...
diff --git a/sysdeps/generic/math_private.h b/sysdeps/generic/math_private.h
index 9b881a3..94c1e4a 100644
--- a/sysdeps/generic/math_private.h
+++ b/sysdeps/generic/math_private.h
@@ -20,6 +20,7 @@
 #include <stdint.h>
 #include <sys/types.h>
 #include <fenv.h>
+#include <get-rounding-mode.h>
 
 /* The original fdlibm code used statements like:
 	n0 = ((*(int*)&one)>>29)^1;		* index of high word *
@@ -551,12 +552,26 @@ default_libc_feupdateenv_test (fenv_t *e, int ex)
 # define libc_feresetround_noexl libc_fesetenvl
 #endif
 
+#ifndef HAVE_RM_CTX
+# define HAVE_RM_CTX 0
+#endif
+
 #if HAVE_RM_CTX
 /* Set/Restore Rounding Modes only when necessary.  If defined, these functions
    set/restore floating point state only if the state needed within the lexical
    block is different from the current state.  This saves a lot of time when
    the floating point unit is much slower than the fixed point units.  */
 
+# ifndef libc_feholdsetround_noex_ctx
+#   define libc_feholdsetround_noex_ctx  libc_feholdsetround_ctx
+# endif
+# ifndef libc_feholdsetround_noexf_ctx
+#   define libc_feholdsetround_noexf_ctx libc_feholdsetroundf_ctx
+# endif
+# ifndef libc_feholdsetround_noexl_ctx
+#   define libc_feholdsetround_noexl_ctx libc_feholdsetroundl_ctx
+# endif
+
 # ifndef libc_feresetround_noex_ctx
 #   define libc_feresetround_noex_ctx  libc_fesetenv_ctx
 # endif
@@ -567,24 +582,80 @@ default_libc_feupdateenv_test (fenv_t *e, int ex)
 #   define libc_feresetround_noexl_ctx libc_fesetenvl_ctx
 # endif
 
-# ifndef libc_feholdsetround_53bit_ctx
-#   define libc_feholdsetround_53bit_ctx libc_feholdsetround_ctx
-# endif
+#else
 
-# ifndef libc_feresetround_53bit_ctx
-#   define libc_feresetround_53bit_ctx libc_feresetround_ctx
-# endif
+/* Default implementation using standard fenv functions.
+   Avoid unnecessary rounding mode changes by first checking the
+   current rounding mode.  Note the use of __glibc_unlikely is
+   important for performance.  */
 
-# define SET_RESTORE_ROUND_GENERIC(RM,ROUNDFUNC,CLEANUPFUNC) \
-  struct rm_ctx ctx __attribute__((cleanup(CLEANUPFUNC ## _ctx)));	      \
-  ROUNDFUNC ## _ctx (&ctx, (RM))
-#else
-# define SET_RESTORE_ROUND_GENERIC(RM, ROUNDFUNC, CLEANUPFUNC) \
-  fenv_t __libc_save_rm __attribute__((cleanup(CLEANUPFUNC)));	\
-  ROUNDFUNC (&__libc_save_rm, (RM))
+static __always_inline void
+libc_feholdsetround_ctx (struct rm_ctx *ctx, int round)
+{
+  ctx->updated_status = false;
+
+  /* Update rounding mode only if different.  */
+  if (__glibc_unlikely (round != get_rounding_mode ()))
+    {
+      ctx->updated_status = true;
+      fegetenv (&ctx->env);
+      fesetround (round);
+    }
+}
+
+static __always_inline void
+libc_feresetround_ctx (struct rm_ctx *ctx)
+{
+  /* Restore the rounding mode if updated.  */
+  if (__glibc_unlikely (ctx->updated_status))
+    feupdateenv (&ctx->env);
+}
+
+static __always_inline void
+libc_feholdsetround_noex_ctx (struct rm_ctx *ctx, int round)
+{
+  /* Save exception flags and rounding mode.  */
+  fegetenv (&ctx->env);
+
+  /* Update rounding mode only if different.  */
+  if (__glibc_unlikely (round != get_rounding_mode ()))
+    fesetround (round);
+}
+
+static __always_inline void
+libc_feresetround_noex_ctx (struct rm_ctx *ctx)
+{
+  /* Restore exception flags and rounding mode.  */
+  fesetenv (&ctx->env);
+}
+
+# define libc_feholdsetroundf_ctx libc_feholdsetround_ctx
+# define libc_feholdsetroundl_ctx libc_feholdsetround_ctx
+# define libc_feresetroundf_ctx   libc_feresetround_ctx
+# define libc_feresetroundl_ctx   libc_feresetround_ctx
+
+# define libc_feholdsetround_noexf_ctx libc_feholdsetround_noex_ctx
+# define libc_feholdsetround_noexl_ctx libc_feholdsetround_noex_ctx
+# define libc_feresetround_noexf_ctx   libc_feresetround_noex_ctx
+# define libc_feresetround_noexl_ctx   libc_feresetround_noex_ctx
+
+#endif
+
+#ifndef libc_feholdsetround_53bit_ctx
+#  define libc_feholdsetround_53bit_ctx libc_feholdsetround_ctx
+#endif
+#ifndef libc_feresetround_53bit_ctx
+#  define libc_feresetround_53bit_ctx libc_feresetround_ctx
 #endif
 
-/* Save and restore the rounding mode within a lexical block.  */
+#define SET_RESTORE_ROUND_GENERIC(RM,ROUNDFUNC,CLEANUPFUNC) \
+  struct rm_ctx ctx __attribute__((cleanup (CLEANUPFUNC ## _ctx))); \
+  ROUNDFUNC ## _ctx (&ctx, (RM))
+
+/* Set the rounding mode within a lexical block.  Restore the rounding mode to
+   the value at the start of the block.  The exception mode must be preserved.
+   Exceptions raised within the block must be set in the exception flags.
+   Non-stop mode may be enabled inside the block.  */
 
 #define SET_RESTORE_ROUND(RM) \
   SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround, libc_feresetround)
@@ -593,15 +664,21 @@ default_libc_feupdateenv_test (fenv_t *e, int ex)
 #define SET_RESTORE_ROUNDL(RM) \
   SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetroundl, libc_feresetroundl)
 
-/* Save and restore the rounding mode within a lexical block, and also
-   the set of exceptions raised within the block may be discarded.  */
+/* Set the rounding mode within a lexical block.  Restore the rounding mode to
+   the value at the start of the block.  The exception mode must be preserved.
+   Exceptions raised within the block must be discarded, and exception flags
+   are restored to the value at the start of the block.
+   Non-stop mode may be enabled inside the block.  */
 
 #define SET_RESTORE_ROUND_NOEX(RM) \
-  SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround, libc_feresetround_noex)
+  SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_noex, \
+			     libc_feresetround_noex)
 #define SET_RESTORE_ROUND_NOEXF(RM) \
-  SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetroundf, libc_feresetround_noexf)
+  SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_noexf, \
+			     libc_feresetround_noexf)
 #define SET_RESTORE_ROUND_NOEXL(RM) \
-  SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetroundl, libc_feresetround_noexl)
+  SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_noexl, \
+			     libc_feresetround_noexl)
 
 /* Like SET_RESTORE_ROUND, but also set rounding precision to 53 bits.  */
 #define SET_RESTORE_ROUND_53BIT(RM) \

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                      |   17 ++++++
 sysdeps/generic/math_private.h |  115 +++++++++++++++++++++++++++++++++-------
 2 files changed, 113 insertions(+), 19 deletions(-)


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]