From fe0f398e14941d7f21cf372ec8a4888691c99886 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Tue, 7 Feb 2023 11:27:51 -0800 Subject: [PATCH] ircd::util: Add popcount wrapping; consolidate callsites. --- include/ircd/ircd.h | 1 + include/ircd/m/query.h | 2 +- include/ircd/simd/popcnt.h | 7 +---- include/ircd/util/bitset.h | 2 +- include/ircd/util/popcount.h | 59 ++++++++++++++++++++++++++++++++++++ matrix/event.cc | 2 +- matrix/event_get.cc | 2 +- matrix/event_index.cc | 2 +- matrix/room_state_fetch.cc | 2 +- 9 files changed, 67 insertions(+), 12 deletions(-) create mode 100644 include/ircd/util/popcount.h diff --git a/include/ircd/ircd.h b/include/ircd/ircd.h index 8fa10bfd3..b25520d52 100644 --- a/include/ircd/ircd.h +++ b/include/ircd/ircd.h @@ -43,6 +43,7 @@ #include "byte_view.h" #include "buffer/buffer.h" #include "vg.h" +#include "util/popcount.h" #include "simd/simd.h" #include "simt/simt.h" #include "allocator/allocator.h" diff --git a/include/ircd/m/query.h b/include/ircd/m/query.h index a6eec974f..f04207fff 100644 --- a/include/ircd/m/query.h +++ b/include/ircd/m/query.h @@ -157,7 +157,7 @@ ircd::m::query(std::nothrow_t, const auto got { - __builtin_popcountl(mask) + popcount(mask) }; return ret; diff --git a/include/ircd/simd/popcnt.h b/include/ircd/simd/popcnt.h index e36df75df..0ccb8801a 100644 --- a/include/ircd/simd/popcnt.h +++ b/include/ircd/simd/popcnt.h @@ -25,12 +25,7 @@ noexcept { uint ret(0), i(0); for(; i < lanes(); ++i) - if constexpr(sizeof_lane() <= sizeof(int)) - ret += __builtin_popcount(a[i]); - else if constexpr(sizeof_lane() <= sizeof(long)) - ret += __builtin_popcountl(a[i]); - else - ret += __builtin_popcountll(a[i]); + ret += popcount(a[i]); return ret; } diff --git a/include/ircd/util/bitset.h b/include/ircd/util/bitset.h index 58948573e..6f1dd4e08 100644 --- a/include/ircd/util/bitset.h +++ b/include/ircd/util/bitset.h @@ -132,7 +132,7 @@ const { size_t ret(0); for(size_t i(0); i < words; ++i) - ret += std::popcount(buf[i]); + ret += popcount(buf[i]); return ret; } diff --git a/include/ircd/util/popcount.h b/include/ircd/util/popcount.h new file mode 100644 index 000000000..d0d639cb7 --- /dev/null +++ b/include/ircd/util/popcount.h @@ -0,0 +1,59 @@ +// The Construct +// +// Copyright (C) The Construct Developers, Authors & Contributors +// Copyright (C) 2016-2023 Jason Volk +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice is present in all copies. The +// full license for this software is available in the LICENSE file. + +#pragma once +#define HAVE_IRCD_UTIL_POPCOUNT_H + +namespace ircd { +inline namespace util +{ + template + constexpr int popcount(const T) noexcept; + + template<> constexpr int popcount(const unsigned long long) noexcept; + template<> constexpr int popcount(const unsigned long) noexcept; + template<> constexpr int popcount(const unsigned int) noexcept; +}} + +template<> +constexpr int +ircd::util::popcount(const unsigned long long a) +noexcept +{ + #if __has_feature(__cpp_lib_bitops) + return std::popcount(a); + #else + return __builtin_popcountll(a); + #endif +} + +template<> +constexpr int +ircd::util::popcount(const unsigned long a) +noexcept +{ + #if __has_feature(__cpp_lib_bitops) + return std::popcount(a); + #else + return __builtin_popcountl(a); + #endif +} + +template<> +constexpr int +ircd::util::popcount(const unsigned int a) +noexcept +{ + #if __has_feature(__cpp_lib_bitops) + return std::popcount(a); + #else + return __builtin_popcount(a); + #endif +} diff --git a/matrix/event.cc b/matrix/event.cc index f2e866eb4..c4d570780 100644 --- a/matrix/event.cc +++ b/matrix/event.cc @@ -1054,7 +1054,7 @@ ircd::m::exists_count(const vector_view &event_ids) const auto ret { - __builtin_popcountl(mask) + popcount(mask) }; assert(size_t(ret) <= event_ids.size()); diff --git a/matrix/event_get.cc b/matrix/event_get.cc index c326f871f..aae93ba9f 100644 --- a/matrix/event_get.cc +++ b/matrix/event_get.cc @@ -240,7 +240,7 @@ ircd::m::get(const vector_view &event_idx, const auto found { - __builtin_popcountl(mask) + popcount(mask) }; if(unlikely(size_t(found) < event_idx.size())) diff --git a/matrix/event_index.cc b/matrix/event_index.cc index 2966496f1..14120da71 100644 --- a/matrix/event_index.cc +++ b/matrix/event_index.cc @@ -200,7 +200,7 @@ ircd::m::index(const vector_view &out_, db::read(column, keys, bufs) }; - ret += __builtin_popcountl(found_mask); + ret += popcount(found_mask); } return ret; diff --git a/matrix/room_state_fetch.cc b/matrix/room_state_fetch.cc index 8a30fdbf4..9f893a52e 100644 --- a/matrix/room_state_fetch.cc +++ b/matrix/room_state_fetch.cc @@ -90,7 +90,7 @@ ircd::m::room_state_fetch_result(room::state::fetch &f, }; f.responses += i; - f.exists += __builtin_popcountl(exists); + f.exists += popcount(exists); for(size_t j(0); j < i; ++j) { if(exists & (1UL << j))