]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Use GCC builtin for clz in RPZ lookup code (#42818)
authorMukund Sivaraman <muks@isc.org>
Sun, 10 Jul 2016 14:16:17 +0000 (19:46 +0530)
committerMukund Sivaraman <muks@isc.org>
Sun, 10 Jul 2016 14:17:37 +0000 (19:47 +0530)
CHANGES
config.h.in
configure
configure.in
lib/dns/rpz.c

diff --git a/CHANGES b/CHANGES
index 00bf3997894187d382a9ac1edd182705a21d2c06..ffc15da81f7cb05631e33b87435b26a153f14b37 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+4407.  [performance]   Use GCC builtin for clz in RPZ lookup code.
+                       [RT #42818]
+
 4406.  [bug]           getrrsetbyname with a non absolute name could
                        trigger a infinite recursion bug in lwresd
                        and named with lwres configured if when combined
index 0f885b13294b2a82fce688598ee0276a6c05cec0..f3f947ebc659d13f7d6977d524e5ab78f72469c4 100644 (file)
@@ -194,6 +194,9 @@ int sigwait(const unsigned int *set, int *sig);
    MSVC and with C++ compilers. */
 #undef FLEXIBLE_ARRAY_MEMBER
 
+/* Define to 1 if the compiler supports __builtin_clz. */
+#undef HAVE_BUILTIN_CLZ
+
 /* Define to 1 if the compiler supports __builtin_expect. */
 #undef HAVE_BUILTIN_EXPECT
 
index bc9bb81fbf5fd907c49e0485b2b1b8648d599910..61222f18063093514b98f5761d8e45abc269ec20 100755 (executable)
--- a/configure
+++ b/configure
@@ -20183,6 +20183,45 @@ $as_echo "#define HAVE_BUILTIN_EXPECT 1" >>confdefs.h
 
 fi
 
+#
+# Check for __builtin_clz
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking compiler support for __builtin_clz" >&5
+$as_echo_n "checking compiler support for __builtin_clz... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+        return (__builtin_clz(0xff) == 24 ? 1 : 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+        have_builtin_clz=yes
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+
+        have_builtin_clz=no
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+if test "$have_builtin_clz" = "yes"; then
+
+$as_echo "#define HAVE_BUILTIN_CLZ 1" >>confdefs.h
+
+fi
+
 #
 # CPU relax (for spin locks)
 #
index 2da78c8f62f3a815b4615ae49fb19f26a444a751..9bf4aa2f8dc9cf75940ae6655f9bea900b67bb05 100644 (file)
@@ -4007,6 +4007,23 @@ if test "$have_builtin_expect" = "yes"; then
         AC_DEFINE(HAVE_BUILTIN_EXPECT, 1, [Define to 1 if the compiler supports __builtin_expect.])
 fi
 
+#
+# Check for __builtin_clz
+#
+AC_MSG_CHECKING([compiler support for __builtin_clz])
+AC_TRY_LINK(, [
+        return (__builtin_clz(0xff) == 24 ? 1 : 0);
+], [
+        have_builtin_clz=yes
+        AC_MSG_RESULT(yes)
+], [
+        have_builtin_clz=no
+        AC_MSG_RESULT(no)
+])
+if test "$have_builtin_clz" = "yes"; then
+        AC_DEFINE(HAVE_BUILTIN_CLZ, 1, [Define to 1 if the compiler supports __builtin_clz.])
+fi
+
 #
 # CPU relax (for spin locks)
 #
index b90b1489822d376333762b630988a24dfdcaf76d..ddd6eb2e1ac40a60b74128ba5d44d963a6b004f5 100644 (file)
@@ -970,34 +970,43 @@ name2data(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num,
        (void)dns_name_concatenate(&tmp_name, dns_rootname, trig_name, NULL);
 }
 
-/*
- * Find the first differing bit in a key (IP address) word.
+#ifndef HAVE_BUILTIN_CLZ
+/**
+ * \brief Count Leading Zeros: Find the location of the left-most set
+ * bit.
  */
-static inline int
-ffs_keybit(dns_rpz_cidr_word_t w) {
-       int bit;
+static inline unsigned int
+clz(dns_rpz_cidr_word_t w) {
+       unsigned int bit;
 
        bit = DNS_RPZ_CIDR_WORD_BITS-1;
+
        if ((w & 0xffff0000) != 0) {
                w >>= 16;
                bit -= 16;
        }
+
        if ((w & 0xff00) != 0) {
                w >>= 8;
                bit -= 8;
        }
+
        if ((w & 0xf0) != 0) {
                w >>= 4;
                bit -= 4;
        }
+
        if ((w & 0xc) != 0) {
                w >>= 2;
                bit -= 2;
        }
+
        if ((w & 2) != 0)
                --bit;
+
        return (bit);
 }
+#endif
 
 /*
  * Find the first differing bit in two keys (IP addresses).
@@ -1016,12 +1025,14 @@ diff_keys(const dns_rpz_cidr_key_t *key1, dns_rpz_prefix_t prefix1,
        /*
         * find the first differing words
         */
-       for (i = 0;
-            bit < maxbit;
-            i++, bit += DNS_RPZ_CIDR_WORD_BITS) {
+       for (i = 0; bit < maxbit; i++, bit += DNS_RPZ_CIDR_WORD_BITS) {
                delta = key1->w[i] ^ key2->w[i];
-               if (delta != 0) {
-                       bit += ffs_keybit(delta);
+               if (ISC_UNLIKELY(delta != 0)) {
+#ifdef HAVE_BUILTIN_CLZ
+                       bit += __builtin_clz(delta);
+#else
+                       bit += clz(delta);
+#endif
                        break;
                }
        }