[core] Use __builtin_ctz for find_lowest_set_bit in FiniteSetMask

Replace the linear bit-scanning loop in find_next_set_bit with
__builtin_ctz (compiles to single-cycle NSAU on Xtensa). Also rename
to find_lowest_set_bit and drop the unused start_bit parameter since
all call sites pass 0.

This eliminates the standalone find_next_set_bit function and replaces
3 function calls + loops in compute_color_mode_ with inline NSAU
instructions.
This commit is contained in:
J. Nick Koston
2026-04-02 13:33:42 -10:00
parent 710186998b
commit b4fa217ab3
+15 -6
View File
@@ -119,7 +119,7 @@ template<typename ValueType, typename BitPolicy = DefaultBitPolicy<ValueType, 16
constexpr ValueType operator*() const {
// Return value for the first set bit
return BitPolicy::from_bit(find_next_set_bit(mask_, 0));
return BitPolicy::from_bit(find_lowest_set_bit(mask_));
}
constexpr Iterator &operator++() {
@@ -151,17 +151,26 @@ template<typename ValueType, typename BitPolicy = DefaultBitPolicy<ValueType, 16
/// Get the first value from a raw bitmask
/// Used for optimizing intersection logic (e.g., "pick first suitable mode")
static constexpr ValueType first_value_from_mask(bitmask_t mask) {
return BitPolicy::from_bit(find_next_set_bit(mask, 0));
return BitPolicy::from_bit(find_lowest_set_bit(mask));
}
/// Find the next set bit in a bitmask starting from a given position
/// Returns the bit position, or MAX_BITS if no more bits are set
static constexpr int find_next_set_bit(bitmask_t mask, int start_bit) {
int bit = start_bit;
/// Find the lowest set bit in a bitmask
/// Returns the bit position, or MAX_BITS if no bits are set
static constexpr int find_lowest_set_bit(bitmask_t mask) {
if (mask == 0)
return BitPolicy::MAX_BITS;
#if defined(__GNUC__) || defined(__clang__)
if constexpr (sizeof(bitmask_t) <= sizeof(unsigned int))
return __builtin_ctz(static_cast<unsigned int>(mask));
else
return __builtin_ctzl(static_cast<unsigned long>(mask));
#else
int bit = 0;
while (bit < BitPolicy::MAX_BITS && !(mask & (static_cast<bitmask_t>(1) << bit))) {
++bit;
}
return bit;
#endif
}
protected: