https://gcc.gnu.org/g:cdb482ccf2c0981e66e243fa97fea1d64fec9f40

commit cdb482ccf2c0981e66e243fa97fea1d64fec9f40
Author: Alexandre Oliva <[email protected]>
Date:   Fri Nov 21 16:13:47 2025 -0300

    hard-reg-set: use first_diff for iteration
    
    Use the newly-added first_diff API for iteration.  This hugely
    simplifies the iterator type, that no longer saves internal state, and
    largely simplifies and likely speeds up iteration, thanks to the use
    of ctz.
    
    
    for  gcc/ChangeLog
    
            PR rtl-optimization/122767
            * hard-reg-set.h (hard_reg_set_iterator): Simplify.
            (hard_reg_set_iter_init): Likewise.
            (hard_reg_set_iter_set): Likewise.  Use first_diff.
            (hard_reg_set_iter_next): Likewise.

Diff:
---
 gcc/hard-reg-set.h | 77 +++++++++++-------------------------------------------
 1 file changed, 15 insertions(+), 62 deletions(-)

diff --git a/gcc/hard-reg-set.h b/gcc/hard-reg-set.h
index e33c8e334d39..5eb3c671aa25 100644
--- a/gcc/hard-reg-set.h
+++ b/gcc/hard-reg-set.h
@@ -321,23 +321,13 @@ hard_reg_set_first_diff (const_hard_reg_set x, 
const_hard_reg_set y,
 }
 #endif
 
-/* Iterator for hard register sets.  */
+/* Iterator for hard register sets.  This is not an iterator proper, the bulk
+   of the iterator state is held in the REGNO passed to the iterator
+   functions.  */
 
 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 +338,27 @@ 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 const HARD_REG_SET hard_reg_set_empty;
+  *regno = std::abs (hard_reg_set_first_diff (*iter->set,
+                                             hard_reg_set_empty,
+                                             *regno)) - 1;
+  /* If hard_reg_set_first_diff returns zero, we'll have set *regno to
+     (unsigned)-1 above, so the test below will yield FALSE, and iteration will
+     stop.  Also stop iteration if it finds a nonzero bit at
+     FIRST_PSEUDO_REGISTER or greater.  */
+  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;
 }

Reply via email to