[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 0f5b1fcdf0b 13/16: Help GCC compute modiff_incr
From: |
Paul Eggert |
Subject: |
master 0f5b1fcdf0b 13/16: Help GCC compute modiff_incr |
Date: |
Sun, 14 May 2023 22:28:25 -0400 (EDT) |
branch: master
commit 0f5b1fcdf0be8c1b3084518f1c4f6f375828094b
Author: Paul Eggert <eggert@cs.ucla.edu>
Commit: Paul Eggert <eggert@cs.ucla.edu>
Help GCC compute modiff_incr
* src/floatfns.c: Don’t include count-leading-zeros.h,
since we no longer use it directly.
(ecount_leading_zeros): Remove.
(Flogb): Use elogb instead of doing it by hand.
* src/lisp.h: Include count-leading-zeros.h.
(elogb): New macro.
(modiff_incr): Use it so that on typical platforms we
use a hardware instruction instead of a loop.
---
src/floatfns.c | 12 +-----------
src/lisp.h | 20 ++++++++++++++++++--
2 files changed, 19 insertions(+), 13 deletions(-)
diff --git a/src/floatfns.c b/src/floatfns.c
index 13f0ca3e129..e40364f8188 100644
--- a/src/floatfns.c
+++ b/src/floatfns.c
@@ -55,8 +55,6 @@ along with GNU Emacs. If not, see
<https://www.gnu.org/licenses/>. */
#include <math.h>
-#include <count-leading-zeros.h>
-
/* Emacs needs proper handling of +/-inf; correct printing as well as
important packages depend on it. Make sure the user didn't specify
-ffinite-math-only, either directly or implicitly with -Ofast or
@@ -304,14 +302,6 @@ DEFUN ("float", Ffloat, Sfloat, 1, 1, 0,
return FLOATP (arg) ? arg : make_float (XFLOATINT (arg));
}
-static int
-ecount_leading_zeros (EMACS_UINT x)
-{
- return (EMACS_UINT_WIDTH == UINT_WIDTH ? count_leading_zeros (x)
- : EMACS_UINT_WIDTH == ULONG_WIDTH ? count_leading_zeros_l (x)
- : count_leading_zeros_ll (x));
-}
-
DEFUN ("logb", Flogb, Slogb, 1, 1, 0,
doc: /* Returns largest integer <= the base 2 log of the magnitude of
ARG.
This is the same as the exponent of a float. */)
@@ -338,7 +328,7 @@ This is the same as the exponent of a float. */)
EMACS_INT i = XFIXNUM (arg);
if (i == 0)
return make_float (-HUGE_VAL);
- value = EMACS_UINT_WIDTH - 1 - ecount_leading_zeros (eabs (i));
+ value = elogb (eabs (i));
}
return make_fixnum (value);
diff --git a/src/lisp.h b/src/lisp.h
index 8f7d44bfb0d..c9a64f07427 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -30,6 +30,7 @@ along with GNU Emacs. If not, see
<https://www.gnu.org/licenses/>. */
#include <limits.h>
#include <attribute.h>
+#include <count-leading-zeros.h>
#include <intprops.h>
#include <verify.h>
@@ -3904,6 +3905,20 @@ integer_to_uintmax (Lisp_Object num, uintmax_t *n)
}
}
+/* Return floor (log2 (N)) as an int, where 0 < N <= ULLONG_MAX. */
+#if (201112 <= __STDC_VERSION__ && INT_MAX <= UINT_MAX \
+ && LONG_MAX <= ULONG_MAX && LLONG_MAX <= ULLONG_MAX)
+# define elogb(n) \
+ _Generic (+(n), \
+ int: UINT_WIDTH - 1 - count_leading_zeros (n), \
+ unsigned int: UINT_WIDTH - 1 - count_leading_zeros (n), \
+ long: ULONG_WIDTH - 1 - count_leading_zeros_l (n), \
+ unsigned long: ULONG_WIDTH - 1 - count_leading_zeros_l (n), \
+ default: ULLONG_WIDTH - 1 - count_leading_zeros_ll (n))
+#else
+# define elogb(n) (ULLONG_WIDTH - 1 - count_leading_zeros_ll (n))
+#endif
+
/* A modification count. These are wide enough, and incremented
rarely enough, so that they should never overflow a 60-bit counter
in practice, and the code below assumes this so a compiler can
@@ -3913,11 +3928,12 @@ typedef intmax_t modiff_count;
INLINE modiff_count
modiff_incr (modiff_count *a, ptrdiff_t len)
{
- modiff_count a0 = *a; int incr = len ? 1 : 0;
+ modiff_count a0 = *a;
/* Increase the counter more for a large modification and less for a
small modification. Increase it logarithmically to avoid
increasing it too much. */
- while (len >>= 1) incr++;
+ verify (PTRDIFF_MAX <= ULLONG_MAX);
+ int incr = len == 0 ? 1 : elogb (len) + 1;
bool modiff_overflow = INT_ADD_WRAPV (a0, incr, a);
eassert (!modiff_overflow && *a >> 30 >> 30 == 0);
return a0;
- master updated (e7dc30c1d58 -> ebf5e4ca1cd), Paul Eggert, 2023/05/14
- master b77d357ea35 01/16: Update from Gnulib by running admin/merge-gnulib, Paul Eggert, 2023/05/14
- master 8c0671b9cbf 02/16: Avoid duplicate configure-time codeset tests, Paul Eggert, 2023/05/14
- master 3e3f34d71e9 03/16: Fix ebrowse -f buffer overflow, Paul Eggert, 2023/05/14
- master 92d4bda2797 04/16: Fix movemail fd leak, Paul Eggert, 2023/05/14
- master 0c11c2ae71f 10/16: Pacify GCC 13 -Wanalyzer-out-of-bounds, Paul Eggert, 2023/05/14
- master 85c4efc9f41 14/16: Prefer UINTMAX_WIDTH in print_object, Paul Eggert, 2023/05/14
- master 919e1b81a4a 11/16: Pacify GCC 13 -Wnull-dereference in itree.c, Paul Eggert, 2023/05/14
- master 67ee74f8e55 05/16: Pacify GCC 13 -fanalyzer in tty_menu_activate, Paul Eggert, 2023/05/14
- master 0b9677a192b 07/16: Work around GCC bug 109579 in ccl.c, Paul Eggert, 2023/05/14
- master 0f5b1fcdf0b 13/16: Help GCC compute modiff_incr,
Paul Eggert <=
- master 7166737b5c9 06/16: Work around GCC bug 109577, Paul Eggert, 2023/05/14
- master 9eef5a678c3 08/16: Do not use -Wanalyzer-fd-leak, Paul Eggert, 2023/05/14
- master 4fedd5af4cc 09/16: Work around GCC bug 109847 in buffer.c, Paul Eggert, 2023/05/14
- master 3cd8ce87d29 12/16: Work after 2038 on 32-bit GNU/Linux, Paul Eggert, 2023/05/14
- master 9f8a5989b65 15/16: Prefer PTRDIFF_WIDTH in sort.c, Paul Eggert, 2023/05/14
- master ebf5e4ca1cd 16/16: Prefer _WIDTH macros to sizeof in pdumper.c, Paul Eggert, 2023/05/14