2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 06:25:31 +00:00

Use GCC builtin for clz in RPZ lookup code (#42818)

This commit is contained in:
Mukund Sivaraman
2016-07-10 19:46:17 +05:30
parent df52e5c7d5
commit 27038b159b
5 changed files with 83 additions and 10 deletions

View File

@@ -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 4406. [bug] getrrsetbyname with a non absolute name could
trigger a infinite recursion bug in lwresd trigger a infinite recursion bug in lwresd
and named with lwres configured if when combined and named with lwres configured if when combined

View File

@@ -194,6 +194,9 @@ int sigwait(const unsigned int *set, int *sig);
MSVC and with C++ compilers. */ MSVC and with C++ compilers. */
#undef FLEXIBLE_ARRAY_MEMBER #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. */ /* Define to 1 if the compiler supports __builtin_expect. */
#undef HAVE_BUILTIN_EXPECT #undef HAVE_BUILTIN_EXPECT

39
configure vendored
View File

@@ -20183,6 +20183,45 @@ $as_echo "#define HAVE_BUILTIN_EXPECT 1" >>confdefs.h
fi 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) # CPU relax (for spin locks)
# #

View 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.]) AC_DEFINE(HAVE_BUILTIN_EXPECT, 1, [Define to 1 if the compiler supports __builtin_expect.])
fi 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) # CPU relax (for spin locks)
# #

View 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); (void)dns_name_concatenate(&tmp_name, dns_rootname, trig_name, NULL);
} }
/* #ifndef HAVE_BUILTIN_CLZ
* Find the first differing bit in a key (IP address) word. /**
* \brief Count Leading Zeros: Find the location of the left-most set
* bit.
*/ */
static inline int static inline unsigned int
ffs_keybit(dns_rpz_cidr_word_t w) { clz(dns_rpz_cidr_word_t w) {
int bit; unsigned int bit;
bit = DNS_RPZ_CIDR_WORD_BITS-1; bit = DNS_RPZ_CIDR_WORD_BITS-1;
if ((w & 0xffff0000) != 0) { if ((w & 0xffff0000) != 0) {
w >>= 16; w >>= 16;
bit -= 16; bit -= 16;
} }
if ((w & 0xff00) != 0) { if ((w & 0xff00) != 0) {
w >>= 8; w >>= 8;
bit -= 8; bit -= 8;
} }
if ((w & 0xf0) != 0) { if ((w & 0xf0) != 0) {
w >>= 4; w >>= 4;
bit -= 4; bit -= 4;
} }
if ((w & 0xc) != 0) { if ((w & 0xc) != 0) {
w >>= 2; w >>= 2;
bit -= 2; bit -= 2;
} }
if ((w & 2) != 0) if ((w & 2) != 0)
--bit; --bit;
return (bit); return (bit);
} }
#endif
/* /*
* Find the first differing bit in two keys (IP addresses). * 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 * find the first differing words
*/ */
for (i = 0; for (i = 0; bit < maxbit; i++, bit += DNS_RPZ_CIDR_WORD_BITS) {
bit < maxbit;
i++, bit += DNS_RPZ_CIDR_WORD_BITS) {
delta = key1->w[i] ^ key2->w[i]; delta = key1->w[i] ^ key2->w[i];
if (delta != 0) { if (ISC_UNLIKELY(delta != 0)) {
bit += ffs_keybit(delta); #ifdef HAVE_BUILTIN_CLZ
bit += __builtin_clz(delta);
#else
bit += clz(delta);
#endif
break; break;
} }
} }