From 0042944a05c2bada008edd3f3bccecbedb98b746 Mon Sep 17 00:00:00 2001 From: vlefevre Date: Mon, 7 Jul 2014 12:43:59 +0000 Subject: =?UTF-8?q?Added=20debug=20of=20branch=20prediction=20/=20--enable?= =?UTF-8?q?-debug-prediction=20configure=20option=20(patch=20from=20Patric?= =?UTF-8?q?k=20P=C3=A9lissier,=20with=20some=20changes).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@9141 280ebfd0-de03-0410-8827-d642c229c3f4 --- src/exceptions.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- src/mpfr-impl.h | 48 +++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 89 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/exceptions.c b/src/exceptions.c index 912702eef..5dafa2c62 100644 --- a/src/exceptions.c +++ b/src/exceptions.c @@ -1,4 +1,4 @@ -/* Exception flags and utilities. +/* Exception flags and utilities. Constructors and destructors (debug). Copyright 2001-2014 Free Software Foundation, Inc. Contributed by the AriC and Caramel projects, INRIA. @@ -413,3 +413,46 @@ mpfr_overflow (mpfr_ptr x, mpfr_rnd_t rnd_mode, int sign) __gmpfr_flags |= MPFR_FLAGS_INEXACT | MPFR_FLAGS_OVERFLOW; return sign > 0 ? inex : -inex; } + +/**************************************************************************/ + +/* Code related to constructors and destructors (for debugging) should + be put here. The reason is that such code must be in an object file + that will be kept by the linker for symbol resolution, and symbols + __gmpfr_emin and __gmpfr_emax from this file will be used by every + program calling a MPFR math function (where rounding is involved). */ + +#if defined MPFR_DEBUG_PREDICTION + +/* Print prediction statistics at the end of a program. + * + * Code to debug branch prediction, based on Ulrich Drepper's paper + * "What Every Programmer Should Know About Memory": + * http://people.freebsd.org/~lstewart/articles/cpumemory.pdf + */ + +extern long int __start_predict_data; +extern long int __stop_predict_data; +extern long int __start_predict_line; +extern const char *__start_predict_file; + +static void __attribute__ ((destructor)) +predprint (void) +{ + long int *s = &__start_predict_data; + long int *e = &__stop_predict_data; + long int *sl = &__start_predict_line; + const char **sf = &__start_predict_file; + + while (s < e) + { + printf("%s:%ld: incorrect=%ld, correct=%ld%s\n", + *sf, *sl, s[0], s[1], + s[0] > s[1] ? " <==== WARNING" : ""); + ++sl; + ++sf; + s += 2; + } +} + +#endif diff --git a/src/mpfr-impl.h b/src/mpfr-impl.h index a56754b99..91f53ca74 100644 --- a/src/mpfr-impl.h +++ b/src/mpfr-impl.h @@ -1047,12 +1047,54 @@ typedef union { mp_size_t s; mp_limb_t l; } mpfr_size_limb_t; /* Theses macros help the compiler to determine if a test is likely or unlikely. The !! is necessary in case x is larger than a long. */ -#if __MPFR_GNUC(3,0) || __MPFR_ICC(8,1,0) -# define MPFR_LIKELY(x) (__builtin_expect(!!(x),1)) -# define MPFR_UNLIKELY(x) (__builtin_expect(!!(x),0)) +#if defined MPFR_DEBUG_PREDICTION && __MPFR_GNUC(3,0) + +/* Code to debug branch prediction, based on Ulrich Drepper's paper + * "What Every Programmer Should Know About Memory": + * http://people.freebsd.org/~lstewart/articles/cpumemory.pdf + */ +asm (".section predict_data, \"aw\"; .previous\n" + ".section predict_line, \"a\"; .previous\n" + ".section predict_file, \"a\"; .previous"); +# if defined __x86_64__ +# define MPFR_DEBUGPRED__(e,E) \ + ({ long int _e = !!(e); \ + asm volatile (".pushsection predict_data\n" \ + "..predictcnt%=: .quad 0; .quad 0\n" \ + ".section predict_line; .quad %c1\n" \ + ".section predict_file; .quad %c2; .popsection\n" \ + "addq $1,..predictcnt%=(,%0,8)" \ + : : "r" (_e == E), "i" (__LINE__), "i" (__FILE__)); \ + __builtin_expect (_e, E); \ + }) +# elif defined __i386__ +# define MPFR_DEBUGPRED__(e,E) \ + ({ long int _e = !!(e); \ + asm volatile (".pushsection predict_data\n" \ + "..predictcnt%=: .long 0; .long 0\n" \ + ".section predict_line; .long %c1\n" \ + ".section predict_file; .long %c2; .popsection\n" \ + "incl ..predictcnt%=(,%0,4)" \ + : : "r" (_e == E), "i" (__LINE__), "i" (__FILE__)); \ + __builtin_expect (_e, E); \ + }) +# else +# error "MPFR_DEBUGPRED__ definition missing" +# endif + +# define MPFR_LIKELY(x) MPFR_DEBUGPRED__ ((x), 1) +# define MPFR_UNLIKELY(x) MPFR_DEBUGPRED__ ((x), 0) + +#elif __MPFR_GNUC(3,0) || __MPFR_ICC(8,1,0) + +# define MPFR_LIKELY(x) (__builtin_expect(!!(x), 1)) +# define MPFR_UNLIKELY(x) (__builtin_expect(!!(x), 0)) + #else + # define MPFR_LIKELY(x) (x) # define MPFR_UNLIKELY(x) (x) + #endif /* Declare that some variable is initialized before being used (without a -- cgit v1.2.1