+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
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
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)
#
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)
#
(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).
/*
* 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;
}
}