On Nov 24, 2025, Vladimir Makarov <[email protected]> wrote:
> I am also agree using ctz should be faster.
My secret evil plan ;-) was to use the newly-added API for
EXECUTE_IF_SET_IN_HARD_REG_SET, as in the working patchlet below, but
the existing iterators with ctz or ffs would be more efficient, so the
SKIP parameter I put in end up useless. It's not so important, because
the single use is inlined with skip == 0, but we could drop the
infrastructure for skipping, and switch to a ctz or ffs in the iterator
loop in a followup. WDYT?
I suppose where ctz or ffs are not directly supported in hardware,
testing a few of the least significant bits to use the current loop
instead of the ctz/ffs call might be profitable, but I'm not sure that's
worth the trouble.
--- a/gcc/hard-reg-set.h
+++ b/gcc/hard-reg-set.h
@@ -325,19 +325,7 @@ hard_reg_set_first_diff (const_hard_reg_set x,
const_hard_reg_set y,
struct hard_reg_set_iterator
{
- /* Pointer to the current element. */
- const HARD_REG_ELT_TYPE *pelt;
-
- /* The length of the set. */
- unsigned short length;
-
- /* Word within the current element. */
- unsigned short word_no;
-
- /* Contents of the actually processed word. When finding next bit
- it is shifted right, so that the actual bit is always the least
- significant bit of ACTUAL. */
- HARD_REG_ELT_TYPE bits;
+ const HARD_REG_SET *set;
};
#define HARD_REG_ELT_BITS UHOST_BITS_PER_WIDE_INT
@@ -348,64 +336,23 @@ inline void
hard_reg_set_iter_init (hard_reg_set_iterator *iter, const_hard_reg_set set,
unsigned min, unsigned *regno)
{
-#ifdef HARD_REG_SET_LONGS
- iter->pelt = set.elts;
- iter->length = HARD_REG_SET_LONGS;
-#else
- iter->pelt = &set;
- iter->length = 1;
-#endif
- iter->word_no = min / HARD_REG_ELT_BITS;
- if (iter->word_no < iter->length)
- {
- iter->bits = iter->pelt[iter->word_no];
- iter->bits >>= min % HARD_REG_ELT_BITS;
-
- /* This is required for correct search of the next bit. */
- min += !iter->bits;
- }
+ iter->set = &set;
*regno = min;
}
inline bool
hard_reg_set_iter_set (hard_reg_set_iterator *iter, unsigned *regno)
{
- while (1)
- {
- /* Return false when we're advanced past the end of the set. */
- if (iter->word_no >= iter->length)
- return false;
-
- if (iter->bits)
- {
- /* Find the correct bit and return it. */
- while (!(iter->bits & 1))
- {
- iter->bits >>= 1;
- *regno += 1;
- }
- return (*regno < FIRST_PSEUDO_REGISTER);
- }
-
- /* Round to the beginning of the next word. */
- *regno = (*regno + HARD_REG_ELT_BITS - 1);
- *regno -= *regno % HARD_REG_ELT_BITS;
-
- /* Find the next non-zero word. */
- while (++iter->word_no < iter->length)
- {
- iter->bits = iter->pelt[iter->word_no];
- if (iter->bits)
- break;
- *regno += HARD_REG_ELT_BITS;
- }
- }
+ static HARD_REG_SET hard_reg_set_empty;
+ *regno = std::abs (hard_reg_set_first_diff (*iter->set,
+ hard_reg_set_empty,
+ *regno)) - 1;
+ return *regno < FIRST_PSEUDO_REGISTER;
}
inline void
-hard_reg_set_iter_next (hard_reg_set_iterator *iter, unsigned *regno)
+hard_reg_set_iter_next (hard_reg_set_iterator *, unsigned *regno)
{
- iter->bits >>= 1;
*regno += 1;
}
--
Alexandre Oliva, happy hacker https://blog.lx.oliva.nom.br/
Free Software Activist FSFLA co-founder GNU Toolchain Engineer
More tolerance and less prejudice are key for inclusion and diversity.
Excluding neuro-others for not behaving ""normal"" is *not* inclusive!