summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorvlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2014-07-07 12:43:59 +0000
committervlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2014-07-07 12:43:59 +0000
commit0042944a05c2bada008edd3f3bccecbedb98b746 (patch)
tree41407ff34314f00b2e51e7ed0d5cf4e110562f14 /src
parent8f2321df512efa7b6de2a71f6b48406053aa0671 (diff)
downloadmpfr-0042944a05c2bada008edd3f3bccecbedb98b746.tar.gz
Added debug of branch prediction / --enable-debug-prediction configure
option (patch from Patrick PĂ©lissier, with some changes). git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@9141 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'src')
-rw-r--r--src/exceptions.c45
-rw-r--r--src/mpfr-impl.h48
2 files changed, 89 insertions, 4 deletions
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