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!

Reply via email to