[v4] Replace certain uses of TEST_HARD_REG_BIT in loops with better alternatives

Message ID 20260603201348.3974908-1-kevinstefanov15@gmail.com
State New
Headers
Series [v4] Replace certain uses of TEST_HARD_REG_BIT in loops with better alternatives |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gcc_check--master-arm success Test passed
linaro-tcwg-bot/tcwg_simplebootstrap_build--master-aarch64-bootstrap fail Build failed
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 fail Patch failed to apply
linaro-tcwg-bot/tcwg_simplebootstrap_build--master-arm-bootstrap fail Patch failed to apply

Commit Message

Kevin Stefanov June 3, 2026, 8:13 p.m. UTC
  This change takes loops of the form:

  for (int <i> = 0; <i> < FIRST_PSEUDO_REGISTER; <i>++)
    if (TEST_HARD_REG_BIT (<set>, <i>))
      <body that doesn't change i or set>

and carries out the necessary refactoring to rewrite them as:

  hard_reg_set_iterator hrsi; [...]
  EXECUTE_IF_SET_IN_HARD_REG_SET (<set>, 0, <i>, hrsi)
    <body that doesn't change i or set>

in loops where expressing <set> does not involve <i>.

It also replaces the only two call sites of hard_reg_set_size
(which was internally using TEST_HARD_REG_BIT in such a loop)
with a call to hard_reg_set_popcount, as a popcount is all
that it was doing anyway. Thus, the now-unused function
hard_reg_set_size has been removed from the codebase.

Replaced one additional use of TEST_HARD_REG_BIT in such
a loop with a call to hard_reg_set_popcount.

gcc/
	* config/m68k/m68k.cc (m68k_conditional_register_usage): Replace TEST_HARD_REG_BIT
	with EXECUTE_IF_SET_IN_HARD_REG_SET in applicable loops.
	(m68k_zero_call_used_regs): Likewise.
	* config/pdp11/pdp11.cc (pdp11_conditional_register_usage): Likewise.
	* ira-color.cc (create_new_allocno_hard_regs_node): Replace call to hard_reg_set_size
	with hard_reg_set_popcount.
	* ira-int.h (hard_reg_set_size): Remove.
	* ira-lives.cc (process_bb_node_lives): Replace TEST_HARD_REG_BIT
	with EXECUTE_IF_SET_IN_HARD_REG_SET in applicable loops.
	* ira.cc (setup_class_hard_regs): Likewise.
	(update_equiv_regs_prescan): Likewise.
	(build_insn_chain): Likewise.
	(setup_stack_reg_pressure_class): Replace call to hard_reg_set_size
	with hard_reg_set_popcount.
	* lra-eliminations.cc (spill_pseudos): Replace TEST_HARD_REG_BIT
	with EXECUTE_IF_SET_IN_HARD_REG_SET in applicable loops.
	* optabs.cc (expand_asm_reg_clobber_mem_blockage): Replace
	TEST_HARD_REG_BIT with EXECUTE_IF_SET_IN_HARD_REG_SET in one instance
	and with hard_reg_set_popcount in another.
	* postreload.cc (reload_combine): Replace TEST_HARD_REG_BIT
	with EXECUTE_IF_SET_IN_HARD_REG_SET in applicable loops.
	* reginfo.cc (init_reg_sets_1): Likewise.
	* regrename.cc (init_rename_info): Likewise.
	* reload1.cc (maybe_fix_stack_asms): Likewise.
	(update_eliminables_and_spill): Likewise.
	* rtl-ssa/insns.cc (function_info::record_call_clobbers): Likewise.
	* sched-deps.cc (sched_analyze_insn): Likewise.
	* sel-sched-dump.cc (print_hard_reg_set): Likewise.

Signed-off-by: Kevin Stefanov <kevinstefanov15@gmail.com>
---

Hi all,

I have made the improvements suggested by Jeffrey's review.
Thank you for that.

In v4, I remove the function hard_reg_set_size and
replace its only two call sites with calls to
hard_reg_set_popcount as Jeff suggested. Since this
is slightly different from the one recurring mechanical
refactoring I was doing so far everywhere else, but
still related to replacing TEST_HARD_REG_BIT in
loops with better alternatives, I've changed the
patch title to reflect that. The ChangeLog and commit
message have been updated too.

The formatting issues involving commas have been fixed
and I have dropped the gratuitous unrelated change
that Jeff pointed out in the review.

I also spotted some incorrect function names in my previous
ChangeLog. It was an oversight on my side. The git diff
command output shows the function name where the displayed
change dump begins, not the function being changed.
That became a source of confusion for me when the diff dump
begins at the end of the previous function's body as it appears
in the source file. I've corrected these ChangeLog entries.

Synced with trunk as of June 3rd, no merge conflicts.

Regstrapped on x86_64-pc-linux-gnu with enable-languages=c,c++.

This is my first contribution, so if anybody could push it for
me when it's ready, I'd appreciate it. Thanks.

 gcc/config/m68k/m68k.cc   | 64 +++++++++++++++++++--------------------
 gcc/config/pdp11/pdp11.cc |  4 +--
 gcc/ira-color.cc          |  2 +-
 gcc/ira-int.h             | 12 --------
 gcc/ira-lives.cc          | 45 +++++++++++++--------------
 gcc/ira.cc                | 26 ++++++++++------
 gcc/lra-eliminations.cc   |  8 +++--
 gcc/optabs.cc             | 19 ++++++------
 gcc/postreload.cc         | 33 +++++++++++---------
 gcc/reginfo.cc            | 14 ++++-----
 gcc/regrename.cc          | 20 ++++++------
 gcc/reload1.cc            | 47 ++++++++++++++--------------
 gcc/rtl-ssa/insns.cc      |  7 +++--
 gcc/sched-deps.cc         | 50 +++++++++++++++---------------
 gcc/sel-sched-dump.cc     | 12 ++++----
 15 files changed, 185 insertions(+), 178 deletions(-)
  

Comments

Jeffrey Law June 4, 2026, 4:48 a.m. UTC | #1
On 6/3/2026 2:13 PM, Kevin Stefanov wrote:
> This change takes loops of the form:
>
>    for (int <i> = 0; <i> < FIRST_PSEUDO_REGISTER; <i>++)
>      if (TEST_HARD_REG_BIT (<set>, <i>))
>        <body that doesn't change i or set>
>
> and carries out the necessary refactoring to rewrite them as:
>
>    hard_reg_set_iterator hrsi; [...]
>    EXECUTE_IF_SET_IN_HARD_REG_SET (<set>, 0, <i>, hrsi)
>      <body that doesn't change i or set>
>
> in loops where expressing <set> does not involve <i>.
>
> It also replaces the only two call sites of hard_reg_set_size
> (which was internally using TEST_HARD_REG_BIT in such a loop)
> with a call to hard_reg_set_popcount, as a popcount is all
> that it was doing anyway. Thus, the now-unused function
> hard_reg_set_size has been removed from the codebase.
>
> Replaced one additional use of TEST_HARD_REG_BIT in such
> a loop with a call to hard_reg_set_popcount.
>
> gcc/
> 	* config/m68k/m68k.cc (m68k_conditional_register_usage): Replace TEST_HARD_REG_BIT
> 	with EXECUTE_IF_SET_IN_HARD_REG_SET in applicable loops.
> 	(m68k_zero_call_used_regs): Likewise.
> 	* config/pdp11/pdp11.cc (pdp11_conditional_register_usage): Likewise.
> 	* ira-color.cc (create_new_allocno_hard_regs_node): Replace call to hard_reg_set_size
> 	with hard_reg_set_popcount.
> 	* ira-int.h (hard_reg_set_size): Remove.
> 	* ira-lives.cc (process_bb_node_lives): Replace TEST_HARD_REG_BIT
> 	with EXECUTE_IF_SET_IN_HARD_REG_SET in applicable loops.
> 	* ira.cc (setup_class_hard_regs): Likewise.
> 	(update_equiv_regs_prescan): Likewise.
> 	(build_insn_chain): Likewise.
> 	(setup_stack_reg_pressure_class): Replace call to hard_reg_set_size
> 	with hard_reg_set_popcount.
> 	* lra-eliminations.cc (spill_pseudos): Replace TEST_HARD_REG_BIT
> 	with EXECUTE_IF_SET_IN_HARD_REG_SET in applicable loops.
> 	* optabs.cc (expand_asm_reg_clobber_mem_blockage): Replace
> 	TEST_HARD_REG_BIT with EXECUTE_IF_SET_IN_HARD_REG_SET in one instance
> 	and with hard_reg_set_popcount in another.
> 	* postreload.cc (reload_combine): Replace TEST_HARD_REG_BIT
> 	with EXECUTE_IF_SET_IN_HARD_REG_SET in applicable loops.
> 	* reginfo.cc (init_reg_sets_1): Likewise.
> 	* regrename.cc (init_rename_info): Likewise.
> 	* reload1.cc (maybe_fix_stack_asms): Likewise.
> 	(update_eliminables_and_spill): Likewise.
> 	* rtl-ssa/insns.cc (function_info::record_call_clobbers): Likewise.
> 	* sched-deps.cc (sched_analyze_insn): Likewise.
> 	* sel-sched-dump.cc (print_hard_reg_set): Likewise.
Thanks!  I pushed this to the trunk.

Jeff
  
Andreas Schwab June 5, 2026, 8:24 a.m. UTC | #2
In file included from ../../gcc/rtl.h:37:0,
                 from ../../gcc/config/m68k/m68k.cc:31:
../../gcc/config/m68k/m68k.cc: In function 'void m68k_conditional_register_usage()':
../../gcc/hard-reg-set.h:407:55: error: invalid conversion from 'int*' to 'unsigned int*' [-fpermissive]
   for (hard_reg_set_iter_init (&(ITER), (SET), (MIN), &(REGNUM));       \
                                                       ^~~~~~~~~
../../gcc/config/m68k/m68k.cc:7122:7: note: in expansion of macro 'EXECUTE_IF_SET_IN_HARD_REG_SET'
       EXECUTE_IF_SET_IN_HARD_REG_SET (x, 0, i, hrsi)
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../gcc/hard-reg-set.h:348:1: note:   initializing argument 4 of 'void hard_reg_set_iter_init(hard_reg_set_iterator*, const_hard_reg_set, unsigned int, unsigned int*)'
 hard_reg_set_iter_init (hard_reg_set_iterator *iter, const_hard_reg_set set,
 ^~~~~~~~~~~~~~~~~~~~~~
../../gcc/hard-reg-set.h:408:40: error: invalid conversion from 'int*' to 'unsigned int*' [-fpermissive]
        hard_reg_set_iter_set (&(ITER), &(REGNUM));                      \
                                        ^~~~~~~~~
../../gcc/config/m68k/m68k.cc:7122:7: note: in expansion of macro 'EXECUTE_IF_SET_IN_HARD_REG_SET'
       EXECUTE_IF_SET_IN_HARD_REG_SET (x, 0, i, hrsi)
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../gcc/hard-reg-set.h:368:1: note:   initializing argument 2 of 'bool hard_reg_set_iter_set(hard_reg_set_iterator*, unsigned int*)'
 hard_reg_set_iter_set (hard_reg_set_iterator *iter, unsigned *regno)
../../gcc/config/m68k/m68k.cc: In function 'HARD_REG_SET m68k_zero_call_used_regs(HARD_REG_SET)':
../../gcc/config/m68k/m68k.cc:7215:60: error: 'regno' was not declared in this \
scope
   EXECUTE_IF_SET_IN_HARD_REG_SET (need_zeroed_hardregs, 0, regno, hrsi)
                                                            ^
../../gcc/hard-reg-set.h:407:57: note: in definition of macro 'EXECUTE_IF_SET_IN_HARD_REG_SET'
   for (hard_reg_set_iter_init (&(ITER), (SET), (MIN), &(REGNUM));       \
                                                         ^~~~~~
../../gcc/config/m68k/m68k.cc:7215:60: note: suggested alternative: 'region'
   EXECUTE_IF_SET_IN_HARD_REG_SET (need_zeroed_hardregs, 0, regno, hrsi)
                                                            ^
../../gcc/hard-reg-set.h:407:57: note: in definition of macro 'EXECUTE_IF_SET_IN_HARD_REG_SET'
   for (hard_reg_set_iter_init (&(ITER), (SET), (MIN), &(REGNUM));       \
                                                         ^~~~~~
make[2]: *** [Makefile:2798: m68k.o] Error 1
  
Kevin Stefanov June 5, 2026, 10:02 a.m. UTC | #3
Sorry, I didn't know what m68k was and that it's an architecture I was
supposed to build a cross compiler for as my bootstrap testing for
this patch. Does that mean I have to submit a new patch now that fixes
these, or go back to this patch and call the fixed version PATCH v5
and send that for review after verifying it successfully bootstraps a
cross compiler targeting the m68k architecture?

On Fri, Jun 5, 2026 at 11:24 AM Andreas Schwab <schwab@linux-m68k.org> wrote:
>
> In file included from ../../gcc/rtl.h:37:0,
>                  from ../../gcc/config/m68k/m68k.cc:31:
> ../../gcc/config/m68k/m68k.cc: In function 'void m68k_conditional_register_usage()':
> ../../gcc/hard-reg-set.h:407:55: error: invalid conversion from 'int*' to 'unsigned int*' [-fpermissive]
>    for (hard_reg_set_iter_init (&(ITER), (SET), (MIN), &(REGNUM));       \
>                                                        ^~~~~~~~~
> ../../gcc/config/m68k/m68k.cc:7122:7: note: in expansion of macro 'EXECUTE_IF_SET_IN_HARD_REG_SET'
>        EXECUTE_IF_SET_IN_HARD_REG_SET (x, 0, i, hrsi)
>        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> ../../gcc/hard-reg-set.h:348:1: note:   initializing argument 4 of 'void hard_reg_set_iter_init(hard_reg_set_iterator*, const_hard_reg_set, unsigned int, unsigned int*)'
>  hard_reg_set_iter_init (hard_reg_set_iterator *iter, const_hard_reg_set set,
>  ^~~~~~~~~~~~~~~~~~~~~~
> ../../gcc/hard-reg-set.h:408:40: error: invalid conversion from 'int*' to 'unsigned int*' [-fpermissive]
>         hard_reg_set_iter_set (&(ITER), &(REGNUM));                      \
>                                         ^~~~~~~~~
> ../../gcc/config/m68k/m68k.cc:7122:7: note: in expansion of macro 'EXECUTE_IF_SET_IN_HARD_REG_SET'
>        EXECUTE_IF_SET_IN_HARD_REG_SET (x, 0, i, hrsi)
>        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> ../../gcc/hard-reg-set.h:368:1: note:   initializing argument 2 of 'bool hard_reg_set_iter_set(hard_reg_set_iterator*, unsigned int*)'
>  hard_reg_set_iter_set (hard_reg_set_iterator *iter, unsigned *regno)
> ../../gcc/config/m68k/m68k.cc: In function 'HARD_REG_SET m68k_zero_call_used_regs(HARD_REG_SET)':
> ../../gcc/config/m68k/m68k.cc:7215:60: error: 'regno' was not declared in this \
> scope
>    EXECUTE_IF_SET_IN_HARD_REG_SET (need_zeroed_hardregs, 0, regno, hrsi)
>                                                             ^
> ../../gcc/hard-reg-set.h:407:57: note: in definition of macro 'EXECUTE_IF_SET_IN_HARD_REG_SET'
>    for (hard_reg_set_iter_init (&(ITER), (SET), (MIN), &(REGNUM));       \
>                                                          ^~~~~~
> ../../gcc/config/m68k/m68k.cc:7215:60: note: suggested alternative: 'region'
>    EXECUTE_IF_SET_IN_HARD_REG_SET (need_zeroed_hardregs, 0, regno, hrsi)
>                                                             ^
> ../../gcc/hard-reg-set.h:407:57: note: in definition of macro 'EXECUTE_IF_SET_IN_HARD_REG_SET'
>    for (hard_reg_set_iter_init (&(ITER), (SET), (MIN), &(REGNUM));       \
>                                                          ^~~~~~
> make[2]: *** [Makefile:2798: m68k.o] Error 1
>
> --
> Andreas Schwab, schwab@linux-m68k.org
> GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
> "And now for something completely different."
  
Sam James June 5, 2026, 10:15 a.m. UTC | #4
Kevin Stefanov <kevinstefanov15@gmail.com> writes:

> Sorry, I didn't know what m68k was and that it's an architecture I was
> supposed to build a cross compiler for as my bootstrap testing for
> this patch. Does that mean I have to submit a new patch now that fixes
> these, or go back to this patch and call the fixed version PATCH v5
> and send that for review after verifying it successfully bootstraps a
> cross compiler targeting the m68k architecture?

Drea has fixed it in r17-1365-g5958e61d12f21c. That was applied on top
of your patch and your patch has not been reverted, so there's no need
to submit a new version. It's all done.

Now, as for cross and testing: it depends. Your change touched code for
some targets like m68k, so in future, it's a good idea to at least test
a cross compile there to make sure it didn't break anything. But if your
patch hadn't touched m68k/, it can still be useful for "tree-wide"
changes like this (porting all over the place) to test on some
alternative targets (just a couple) to see if you made an assumption
that was bad.

But it happens, don't feel bad about it. Just learn from it and ask if
you have any more questions.

>
> On Fri, Jun 5, 2026 at 11:24 AM Andreas Schwab <schwab@linux-m68k.org> wrote:
>>
>> In file included from ../../gcc/rtl.h:37:0,
>>                  from ../../gcc/config/m68k/m68k.cc:31:
>> ../../gcc/config/m68k/m68k.cc: In function 'void m68k_conditional_register_usage()':
>> ../../gcc/hard-reg-set.h:407:55: error: invalid conversion from 'int*' to 'unsigned int*' [-fpermissive]
>>    for (hard_reg_set_iter_init (&(ITER), (SET), (MIN), &(REGNUM));       \
>>                                                        ^~~~~~~~~
>> ../../gcc/config/m68k/m68k.cc:7122:7: note: in expansion of macro 'EXECUTE_IF_SET_IN_HARD_REG_SET'
>>        EXECUTE_IF_SET_IN_HARD_REG_SET (x, 0, i, hrsi)
>>        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> ../../gcc/hard-reg-set.h:348:1: note:   initializing argument 4 of 'void hard_reg_set_iter_init(hard_reg_set_iterator*, const_hard_reg_set, unsigned int, unsigned int*)'
>>  hard_reg_set_iter_init (hard_reg_set_iterator *iter, const_hard_reg_set set,
>>  ^~~~~~~~~~~~~~~~~~~~~~
>> ../../gcc/hard-reg-set.h:408:40: error: invalid conversion from 'int*' to 'unsigned int*' [-fpermissive]
>>         hard_reg_set_iter_set (&(ITER), &(REGNUM));                      \
>>                                         ^~~~~~~~~
>> ../../gcc/config/m68k/m68k.cc:7122:7: note: in expansion of macro 'EXECUTE_IF_SET_IN_HARD_REG_SET'
>>        EXECUTE_IF_SET_IN_HARD_REG_SET (x, 0, i, hrsi)
>>        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> ../../gcc/hard-reg-set.h:368:1: note:   initializing argument 2 of 'bool hard_reg_set_iter_set(hard_reg_set_iterator*, unsigned int*)'
>>  hard_reg_set_iter_set (hard_reg_set_iterator *iter, unsigned *regno)
>> ../../gcc/config/m68k/m68k.cc: In function 'HARD_REG_SET m68k_zero_call_used_regs(HARD_REG_SET)':
>> ../../gcc/config/m68k/m68k.cc:7215:60: error: 'regno' was not declared in this \
>> scope
>>    EXECUTE_IF_SET_IN_HARD_REG_SET (need_zeroed_hardregs, 0, regno, hrsi)
>>                                                             ^
>> ../../gcc/hard-reg-set.h:407:57: note: in definition of macro 'EXECUTE_IF_SET_IN_HARD_REG_SET'
>>    for (hard_reg_set_iter_init (&(ITER), (SET), (MIN), &(REGNUM));       \
>>                                                          ^~~~~~
>> ../../gcc/config/m68k/m68k.cc:7215:60: note: suggested alternative: 'region'
>>    EXECUTE_IF_SET_IN_HARD_REG_SET (need_zeroed_hardregs, 0, regno, hrsi)
>>                                                             ^
>> ../../gcc/hard-reg-set.h:407:57: note: in definition of macro 'EXECUTE_IF_SET_IN_HARD_REG_SET'
>>    for (hard_reg_set_iter_init (&(ITER), (SET), (MIN), &(REGNUM));       \
>>                                                          ^~~~~~
>> make[2]: *** [Makefile:2798: m68k.o] Error 1
>>
>> --
>> Andreas Schwab, schwab@linux-m68k.org
>> GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
>> "And now for something completely different."
  
Kevin Stefanov June 9, 2026, 11:30 a.m. UTC | #5
Thanks Sam and everyone for the help with my first patch.

I do want to grow in the compiler space and in GCC specifically,
as I'm a fan of the GNU project and have always enjoyed
low-level programming. Lately I've been learning CPU microarchitecture,
measuring how optimally a given system is using it with tools like
Perf, TMA methodology and LLVM Machine Code Analyzer,
and the performance implications of what compilers are (and aren't yet)
capable of doing to our source code.

My question is - how should I go about growing in GCC, specifically toward
areas that have to do with hardware architecture-aware optimizations? I suppose
I'd need to familiarize myself with one or more parts of GCC that are
responsible
for operations like register allocation, instruction selection and
scheduling and
optimizations like auto-vectorization? Should I pick and complete a
few more items
on the EasyHacks list and then find a way to get involved in a larger
contribution,
or is there a better next step for me?

On Fri, Jun 5, 2026 at 1:15 PM Sam James <sam@gentoo.org> wrote:
>
> Kevin Stefanov <kevinstefanov15@gmail.com> writes:
>
> > Sorry, I didn't know what m68k was and that it's an architecture I was
> > supposed to build a cross compiler for as my bootstrap testing for
> > this patch. Does that mean I have to submit a new patch now that fixes
> > these, or go back to this patch and call the fixed version PATCH v5
> > and send that for review after verifying it successfully bootstraps a
> > cross compiler targeting the m68k architecture?
>
> Drea has fixed it in r17-1365-g5958e61d12f21c. That was applied on top
> of your patch and your patch has not been reverted, so there's no need
> to submit a new version. It's all done.
>
> Now, as for cross and testing: it depends. Your change touched code for
> some targets like m68k, so in future, it's a good idea to at least test
> a cross compile there to make sure it didn't break anything. But if your
> patch hadn't touched m68k/, it can still be useful for "tree-wide"
> changes like this (porting all over the place) to test on some
> alternative targets (just a couple) to see if you made an assumption
> that was bad.
>
> But it happens, don't feel bad about it. Just learn from it and ask if
> you have any more questions.
>
> >
> > On Fri, Jun 5, 2026 at 11:24 AM Andreas Schwab <schwab@linux-m68k.org> wrote:
> >>
> >> In file included from ../../gcc/rtl.h:37:0,
> >>                  from ../../gcc/config/m68k/m68k.cc:31:
> >> ../../gcc/config/m68k/m68k.cc: In function 'void m68k_conditional_register_usage()':
> >> ../../gcc/hard-reg-set.h:407:55: error: invalid conversion from 'int*' to 'unsigned int*' [-fpermissive]
> >>    for (hard_reg_set_iter_init (&(ITER), (SET), (MIN), &(REGNUM));       \
> >>                                                        ^~~~~~~~~
> >> ../../gcc/config/m68k/m68k.cc:7122:7: note: in expansion of macro 'EXECUTE_IF_SET_IN_HARD_REG_SET'
> >>        EXECUTE_IF_SET_IN_HARD_REG_SET (x, 0, i, hrsi)
> >>        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> >> ../../gcc/hard-reg-set.h:348:1: note:   initializing argument 4 of 'void hard_reg_set_iter_init(hard_reg_set_iterator*, const_hard_reg_set, unsigned int, unsigned int*)'
> >>  hard_reg_set_iter_init (hard_reg_set_iterator *iter, const_hard_reg_set set,
> >>  ^~~~~~~~~~~~~~~~~~~~~~
> >> ../../gcc/hard-reg-set.h:408:40: error: invalid conversion from 'int*' to 'unsigned int*' [-fpermissive]
> >>         hard_reg_set_iter_set (&(ITER), &(REGNUM));                      \
> >>                                         ^~~~~~~~~
> >> ../../gcc/config/m68k/m68k.cc:7122:7: note: in expansion of macro 'EXECUTE_IF_SET_IN_HARD_REG_SET'
> >>        EXECUTE_IF_SET_IN_HARD_REG_SET (x, 0, i, hrsi)
> >>        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> >> ../../gcc/hard-reg-set.h:368:1: note:   initializing argument 2 of 'bool hard_reg_set_iter_set(hard_reg_set_iterator*, unsigned int*)'
> >>  hard_reg_set_iter_set (hard_reg_set_iterator *iter, unsigned *regno)
> >> ../../gcc/config/m68k/m68k.cc: In function 'HARD_REG_SET m68k_zero_call_used_regs(HARD_REG_SET)':
> >> ../../gcc/config/m68k/m68k.cc:7215:60: error: 'regno' was not declared in this \
> >> scope
> >>    EXECUTE_IF_SET_IN_HARD_REG_SET (need_zeroed_hardregs, 0, regno, hrsi)
> >>                                                             ^
> >> ../../gcc/hard-reg-set.h:407:57: note: in definition of macro 'EXECUTE_IF_SET_IN_HARD_REG_SET'
> >>    for (hard_reg_set_iter_init (&(ITER), (SET), (MIN), &(REGNUM));       \
> >>                                                          ^~~~~~
> >> ../../gcc/config/m68k/m68k.cc:7215:60: note: suggested alternative: 'region'
> >>    EXECUTE_IF_SET_IN_HARD_REG_SET (need_zeroed_hardregs, 0, regno, hrsi)
> >>                                                             ^
> >> ../../gcc/hard-reg-set.h:407:57: note: in definition of macro 'EXECUTE_IF_SET_IN_HARD_REG_SET'
> >>    for (hard_reg_set_iter_init (&(ITER), (SET), (MIN), &(REGNUM));       \
> >>                                                          ^~~~~~
> >> make[2]: *** [Makefile:2798: m68k.o] Error 1
> >>
> >> --
> >> Andreas Schwab, schwab@linux-m68k.org
> >> GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
> >> "And now for something completely different."
  
Jeffrey Law June 9, 2026, 1:28 p.m. UTC | #6
On 6/9/2026 5:30 AM, Kevin Stefanov wrote:
> Thanks Sam and everyone for the help with my first patch.
We're happy to help.  And just to be 100% clear, for a patch of that 
nature there is often fallout on obscure targets like we saw on m68k, 
pdp11 and perhaps others.  While we always strive to avoid that kind of 
problem we understand testing everything is impossible.  Point being, 
don't worry about the minor fallout.
>
> My question is - how should I go about growing in GCC, specifically toward
> areas that have to do with hardware architecture-aware optimizations? I suppose
> I'd need to familiarize myself with one or more parts of GCC that are
> responsible for operations like register allocation, instruction selection and
> scheduling and optimizations like auto-vectorization? Should I pick and complete a
> few more items on the EasyHacks list and then find a way to get involved in a larger
> contribution, or is there a better next step for me?
The best advice I can give is to find an area of particular interest.  
That might be a phase of the compiler like you've mentioned above, or a 
specific target you want to improve, etc and spend time making those 
things better.

I would recommend getting more familiar with the basics before starting 
to tackle something like register allocation or vectorization.  You 
mentioned the easyhacks which are often good places to start.  SImilarly 
Andrea has an easy bug of the week in her GCC weekly report.  I've been 
meaning to add a second bug to that report under my supervision.  Those 
will often be things like match.pd patterns or simplify-rtx.cc 
improvements.  They tend to be localized and easier to wrap your head 
around to get more familiar with how the two internal formats (gimple & 
RTL) work.

Jeff
  

Patch

diff --git a/gcc/config/m68k/m68k.cc b/gcc/config/m68k/m68k.cc
index ee5210afedc..494f4b76924 100644
--- a/gcc/config/m68k/m68k.cc
+++ b/gcc/config/m68k/m68k.cc
@@ -7118,9 +7118,9 @@  m68k_conditional_register_usage (void)
   if (!TARGET_HARD_FLOAT)
     {
       x = reg_class_contents[FP_REGS];
-      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-        if (TEST_HARD_REG_BIT (x, i))
-	  fixed_regs[i] = call_used_regs[i] = 1;
+      hard_reg_set_iterator hrsi;
+      EXECUTE_IF_SET_IN_HARD_REG_SET (x, 0, i, hrsi)
+	fixed_regs[i] = call_used_regs[i] = 1;
     }
   if (flag_pic)
     fixed_regs[PIC_REG] = call_used_regs[PIC_REG] = 1;
@@ -7211,37 +7211,37 @@  m68k_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs)
 {
   rtx zero_fpreg = NULL_RTX;
 
-  for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
-    if (TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
-      {
-	rtx reg, zero;
+  hard_reg_set_iterator hrsi;
+  EXECUTE_IF_SET_IN_HARD_REG_SET (need_zeroed_hardregs, 0, regno, hrsi)
+    {
+      rtx reg, zero;
 
-	if (INT_REGNO_P (regno))
-	  {
-	    reg = regno_reg_rtx[regno];
-	    zero = CONST0_RTX (SImode);
-	  }
-	else if (FP_REGNO_P (regno))
-	  {
-	    reg = gen_raw_REG (SFmode, regno);
-	    if (zero_fpreg == NULL_RTX)
-	      {
-		/* On the 040/060 clearing an FP reg loads a large
-		   immediate.  To reduce code size use the first
-		   cleared FP reg to clear remaining ones.  Don't do
-		   this on cores which use fmovecr.  */
-		zero = CONST0_RTX (SFmode);
-		if (TUNE_68040_60)
-		  zero_fpreg = reg;
-	      }
-	    else
-	      zero = zero_fpreg;
-	  }
-	else
-	  gcc_unreachable ();
+      if (INT_REGNO_P (regno))
+	{
+	  reg = regno_reg_rtx[regno];
+	  zero = CONST0_RTX (SImode);
+	}
+      else if (FP_REGNO_P (regno))
+	{
+	  reg = gen_raw_REG (SFmode, regno);
+	  if (zero_fpreg == NULL_RTX)
+	    {
+	      /* On the 040/060 clearing an FP reg loads a large
+		 immediate.  To reduce code size use the first
+		 cleared FP reg to clear remaining ones.  Don't do
+		 this on cores which use fmovecr.  */
+	      zero = CONST0_RTX (SFmode);
+	      if (TUNE_68040_60)
+		zero_fpreg = reg;
+	    }
+	  else
+	    zero = zero_fpreg;
+	}
+      else
+	gcc_unreachable ();
 
-	emit_move_insn (reg, zero);
-      }
+      emit_move_insn (reg, zero);
+    }
 
   return need_zeroed_hardregs;
 }
diff --git a/gcc/config/pdp11/pdp11.cc b/gcc/config/pdp11/pdp11.cc
index 2824860a9b3..7aee804439d 100644
--- a/gcc/config/pdp11/pdp11.cc
+++ b/gcc/config/pdp11/pdp11.cc
@@ -2214,8 +2214,8 @@  pdp11_conditional_register_usage (void)
   if (!TARGET_FPU)
     {
       x = reg_class_contents[FPU_REGS];
-      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++ )
-       if (TEST_HARD_REG_BIT (x, i))
+      hard_reg_set_iterator hrsi;
+      EXECUTE_IF_SET_IN_HARD_REG_SET (x, 0, i, hrsi)
 	fixed_regs[i] = call_used_regs[i] = 1;
     }
 
diff --git a/gcc/ira-color.cc b/gcc/ira-color.cc
index 447ea31f4a3..b48e3821e6b 100644
--- a/gcc/ira-color.cc
+++ b/gcc/ira-color.cc
@@ -349,7 +349,7 @@  create_new_allocno_hard_regs_node (allocno_hard_regs_t hv)
 	      ira_allocate (sizeof (struct allocno_hard_regs_node)));
   new_node->check = 0;
   new_node->hard_regs = hv;
-  new_node->hard_regs_num = hard_reg_set_size (hv->set);
+  new_node->hard_regs_num = hard_reg_set_popcount (hv->set);
   new_node->first = NULL;
   new_node->used_p = false;
   return new_node;
diff --git a/gcc/ira-int.h b/gcc/ira-int.h
index 778c7afe694..0b7bd4e9f02 100644
--- a/gcc/ira-int.h
+++ b/gcc/ira-int.h
@@ -1437,18 +1437,6 @@  ira_hard_reg_set_intersection_p (int hard_regno, machine_mode mode,
   return false;
 }
 
-/* Return number of hard registers in hard register SET.  */
-inline int
-hard_reg_set_size (HARD_REG_SET set)
-{
-  int i, size;
-
-  for (size = i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-    if (TEST_HARD_REG_BIT (set, i))
-      size++;
-  return size;
-}
-
 /* The function returns TRUE if hard registers starting with
    HARD_REGNO and containing value of MODE are fully in set
    HARD_REGSET.  */
diff --git a/gcc/ira-lives.cc b/gcc/ira-lives.cc
index a6b3eff1ab8..031b6412737 100644
--- a/gcc/ira-lives.cc
+++ b/gcc/ira-lives.cc
@@ -1311,7 +1311,7 @@  static void
 process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
 {
   int i, freq;
-  unsigned int j;
+  unsigned int j, k;
   basic_block bb;
   rtx_insn *insn;
   bitmap_iterator bi;
@@ -1332,27 +1332,28 @@  process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
       sparseset_clear (objects_live);
       REG_SET_TO_HARD_REG_SET (hard_regs_live, reg_live_out);
       hard_regs_live &= ~(eliminable_regset | ira_no_alloc_regs);
-      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-	if (TEST_HARD_REG_BIT (hard_regs_live, i))
-	  {
-	    enum reg_class aclass, pclass, cl;
-
-	    aclass = ira_allocno_class_translate[REGNO_REG_CLASS (i)];
-	    pclass = ira_pressure_class_translate[aclass];
-	    for (j = 0;
-		 (cl = ira_reg_class_super_classes[pclass][j])
-		   != LIM_REG_CLASSES;
-		 j++)
-	      {
-		if (! ira_reg_pressure_class_p[cl])
-		  continue;
-		curr_reg_pressure[cl]++;
-		if (curr_bb_node->reg_pressure[cl] < curr_reg_pressure[cl])
-		  curr_bb_node->reg_pressure[cl] = curr_reg_pressure[cl];
-		ira_assert (curr_reg_pressure[cl]
-			    <= ira_class_hard_regs_num[cl]);
-	      }
-	  }
+      hard_reg_set_iterator hrsi;
+      k = 0;
+      EXECUTE_IF_SET_IN_HARD_REG_SET (hard_regs_live, 0, k, hrsi)
+	{
+	  enum reg_class aclass, pclass, cl;
+
+	  aclass = ira_allocno_class_translate[REGNO_REG_CLASS (k)];
+	  pclass = ira_pressure_class_translate[aclass];
+	  for (j = 0;
+	       (cl = ira_reg_class_super_classes[pclass][j])
+		 != LIM_REG_CLASSES;
+	       j++)
+	    {
+	      if (! ira_reg_pressure_class_p[cl])
+		continue;
+	      curr_reg_pressure[cl]++;
+	      if (curr_bb_node->reg_pressure[cl] < curr_reg_pressure[cl])
+		curr_bb_node->reg_pressure[cl] = curr_reg_pressure[cl];
+	      ira_assert (curr_reg_pressure[cl]
+			  <= ira_class_hard_regs_num[cl]);
+	    }
+	}
       EXECUTE_IF_SET_IN_BITMAP (reg_live_out, FIRST_PSEUDO_REGISTER, j, bi)
 	mark_pseudo_regno_live (j);
 
diff --git a/gcc/ira.cc b/gcc/ira.cc
index f1beb7b300f..e101c6f6664 100644
--- a/gcc/ira.cc
+++ b/gcc/ira.cc
@@ -466,6 +466,7 @@  static void
 setup_class_hard_regs (void)
 {
   int cl, i, hard_regno, n;
+  unsigned int j;
   HARD_REG_SET processed_hard_reg_set;
 
   ira_assert (SHRT_MAX >= FIRST_PSEUDO_REGISTER);
@@ -497,9 +498,12 @@  setup_class_hard_regs (void)
 	    }
 	}
       ira_class_hard_regs_num[cl] = n;
-      for (n = 0, i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-	if (TEST_HARD_REG_BIT (temp_hard_regset, i))
-	  ira_non_ordered_class_hard_regs[cl][n++] = i;
+      n = 0;
+      j = 0;
+      hard_reg_set_iterator hrsi;
+      EXECUTE_IF_SET_IN_HARD_REG_SET (temp_hard_regset, 0, j, hrsi)
+	ira_non_ordered_class_hard_regs[cl][n++] = j;
+
       ira_assert (ira_class_hard_regs_num[cl] == n);
     }
 }
@@ -758,7 +762,7 @@  setup_stack_reg_pressure_class (void)
       {
 	cl = ira_pressure_classes[i];
 	temp_hard_regset2 = temp_hard_regset & reg_class_contents[cl];
-	size = hard_reg_set_size (temp_hard_regset2);
+	size = hard_reg_set_popcount (temp_hard_regset2);
 	if (best < size)
 	  {
 	    best = size;
@@ -3610,10 +3614,14 @@  update_equiv_regs_prescan (void)
 	}
 
   HARD_REG_SET extra_caller_saves = callee_abis.caller_save_regs (*crtl->abi);
+
+  hard_reg_set_iterator hrsi;
+  unsigned int regno = 0;
   if (!hard_reg_set_empty_p (extra_caller_saves))
-    for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
-      if (TEST_HARD_REG_BIT (extra_caller_saves, regno))
+    {
+      EXECUTE_IF_SET_IN_HARD_REG_SET (extra_caller_saves, 0, regno, hrsi)
 	df_set_regs_ever_live (regno, true);
+    }
 }
 
 /* Find registers that are equivalent to a single value throughout the
@@ -4387,9 +4395,9 @@  build_insn_chain (void)
   sbitmap *live_subregs = XCNEWVEC (sbitmap, max_regno);
   auto_bitmap live_subregs_used;
 
-  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-    if (TEST_HARD_REG_BIT (eliminable_regset, i))
-      bitmap_set_bit (elim_regset, i);
+  hard_reg_set_iterator hrsi;
+  EXECUTE_IF_SET_IN_HARD_REG_SET (eliminable_regset, 0, i, hrsi)
+    bitmap_set_bit (elim_regset, i);
   FOR_EACH_BB_REVERSE_FN (bb, cfun)
     {
       bitmap_iterator bi;
diff --git a/gcc/lra-eliminations.cc b/gcc/lra-eliminations.cc
index 571c17cf648..40f05563566 100644
--- a/gcc/lra-eliminations.cc
+++ b/gcc/lra-eliminations.cc
@@ -1132,6 +1132,7 @@  static int
 spill_pseudos (HARD_REG_SET set, int *spilled_pseudos)
 {
   int i, n;
+  unsigned int j;
   bitmap_head to_process;
   rtx_insn *insn;
 
@@ -1140,9 +1141,10 @@  spill_pseudos (HARD_REG_SET set, int *spilled_pseudos)
   if (lra_dump_file != NULL)
     {
       fprintf (lra_dump_file, "	   Spilling non-eliminable hard regs:");
-      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-	if (TEST_HARD_REG_BIT (set, i))
-	  fprintf (lra_dump_file, " %d", i);
+      j = 0;
+      hard_reg_set_iterator hrsi;
+      EXECUTE_IF_SET_IN_HARD_REG_SET (set, 0, j, hrsi)
+	fprintf (lra_dump_file, " %d", j);
       fprintf (lra_dump_file, "\n");
     }
   bitmap_initialize (&to_process, &reg_obstack);
diff --git a/gcc/optabs.cc b/gcc/optabs.cc
index 80a78d6e80c..57fc9d3306e 100644
--- a/gcc/optabs.cc
+++ b/gcc/optabs.cc
@@ -7686,9 +7686,9 @@  expand_asm_reg_clobber_mem_blockage (HARD_REG_SET regs)
   rtx asm_op, clob_mem;
 
   unsigned int num_of_regs = 0;
-  for (unsigned int i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-    if (TEST_HARD_REG_BIT (regs, i))
-      num_of_regs++;
+  unsigned int i;
+
+  num_of_regs = hard_reg_set_popcount (regs);
 
   asm_op = gen_rtx_ASM_OPERANDS (VOIDmode, "", "", 0,
 				 rtvec_alloc (0), rtvec_alloc (0),
@@ -7707,12 +7707,13 @@  expand_asm_reg_clobber_mem_blockage (HARD_REG_SET regs)
   if (num_of_regs > 0)
     {
       unsigned int j = 2;
-      for (unsigned int i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-	if (TEST_HARD_REG_BIT (regs, i))
-	  {
-	    RTVEC_ELT (v, j) = gen_rtx_CLOBBER (VOIDmode, regno_reg_rtx[i]);
- 	    j++;
-	  }
+      hard_reg_set_iterator hrsi2;
+      i = 0;
+      EXECUTE_IF_SET_IN_HARD_REG_SET (regs, 0, i, hrsi2)
+	{
+	  RTVEC_ELT (v, j) = gen_rtx_CLOBBER (VOIDmode, regno_reg_rtx[i]);
+	  j++;
+	}
       gcc_assert (j == (num_of_regs + 2));
     }
 
diff --git a/gcc/postreload.cc b/gcc/postreload.cc
index 117e449fedd..576456c79d5 100644
--- a/gcc/postreload.cc
+++ b/gcc/postreload.cc
@@ -1338,14 +1338,15 @@  reload_combine (void)
     last_index_reg = -1;
   else if (first_index_reg == -1 && last_index_reg == 0)
     {
-      for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
-	if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], r))
-	  {
-	    if (first_index_reg == -1)
-	      first_index_reg = r;
+      hard_reg_set_iterator hrsi1;
+      EXECUTE_IF_SET_IN_HARD_REG_SET
+	(reg_class_contents[INDEX_REG_CLASS], 0, r, hrsi1)
+	{
+	  if (first_index_reg == -1)
+	    first_index_reg = r;
 
-	    last_index_reg = r;
-	  }
+	  last_index_reg = r;
+	}
 
       /* If no index register is available, we can quit now.  Set LAST_INDEX_REG
 	 to -1 so we'll know to quit early the next time we get here.  */
@@ -1440,12 +1441,12 @@  reload_combine (void)
 	  rtx link;
 	  HARD_REG_SET used_regs = insn_callee_abi (insn).full_reg_clobbers ();
 
-	  for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
-	    if (TEST_HARD_REG_BIT (used_regs, r))
-	      {
-		reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
-		reg_state[r].store_ruid = reload_combine_ruid;
-	      }
+	  hard_reg_set_iterator hrsi2;
+	  EXECUTE_IF_SET_IN_HARD_REG_SET (used_regs, 0, r, hrsi2)
+	    {
+	      reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
+	      reg_state[r].store_ruid = reload_combine_ruid;
+	    }
 
 	  for (link = CALL_INSN_FUNCTION_USAGE (insn); link;
 	       link = XEXP (link, 1))
@@ -1480,9 +1481,11 @@  reload_combine (void)
 	    live = &ever_live_at_start;
 
 	  if (live)
-	    for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
-	      if (TEST_HARD_REG_BIT (*live, r))
+	    {
+	      hard_reg_set_iterator hrsi3;
+	      EXECUTE_IF_SET_IN_HARD_REG_SET (*live, 0, r, hrsi3)
 		reg_state[r].use_index = -1;
+	    }
 	}
 
       reload_combine_note_use (&PATTERN (insn), insn, reload_combine_ruid,
diff --git a/gcc/reginfo.cc b/gcc/reginfo.cc
index 3dbb4b3f7d0..da0c65c924d 100644
--- a/gcc/reginfo.cc
+++ b/gcc/reginfo.cc
@@ -269,13 +269,13 @@  init_reg_sets_1 (void)
   for (i = 0; i < N_REG_CLASSES; i++)
     {
       bool any_nonfixed = false;
-      for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
-	if (TEST_HARD_REG_BIT (reg_class_contents[i], j))
-	  {
-	    reg_class_size[i]++;
-	    if (!fixed_regs[j])
-	      any_nonfixed = true;
-	  }
+      hard_reg_set_iterator hrsi;
+      EXECUTE_IF_SET_IN_HARD_REG_SET (reg_class_contents[i], 0, j, hrsi)
+	{
+	  reg_class_size[i]++;
+	  if (!fixed_regs[j])
+	    any_nonfixed = true;
+	}
       class_only_fixed_regs[i] = !any_nonfixed;
     }
 
diff --git a/gcc/regrename.cc b/gcc/regrename.cc
index b0021019c69..5b625cd27df 100644
--- a/gcc/regrename.cc
+++ b/gcc/regrename.cc
@@ -630,17 +630,17 @@  init_rename_info (class bb_rename_info *p, basic_block bb)
 	  remove_range_from_hard_reg_set (&live_hard_regs, i, iri->nregs);
 	}
     }
-  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+  struct incoming_reg_info *iri;
+  unsigned int j = 0;
+  hard_reg_set_iterator hrsi;
+  EXECUTE_IF_SET_IN_HARD_REG_SET (start_chains_set, 0, j, hrsi)
     {
-      struct incoming_reg_info *iri = p->incoming + i;
-      if (TEST_HARD_REG_BIT (start_chains_set, i))
-	{
-	  du_head_p chain;
-	  if (dump_file)
-	    fprintf (dump_file, "opening incoming chain\n");
-	  chain = create_new_chain (i, iri->nregs, NULL, NULL, NO_REGS);
-	  bitmap_set_bit (&p->incoming_open_chains_set, chain->id);
-	}
+      du_head_p chain;
+      if (dump_file)
+	fprintf (dump_file, "opening incoming chain\n");
+      iri = p->incoming + j;
+      chain = create_new_chain (j, iri->nregs, NULL, NULL, NO_REGS);
+      bitmap_set_bit (&p->incoming_open_chains_set, chain->id);
     }
 }
 
diff --git a/gcc/reload1.cc b/gcc/reload1.cc
index 3cc1bff0928..638aca6acee 100644
--- a/gcc/reload1.cc
+++ b/gcc/reload1.cc
@@ -1403,12 +1403,13 @@  maybe_fix_stack_asms (void)
 	 constraints, must be usable as reload registers.  So clear them
 	 out of the life information.  */
       allowed &= clobbered;
-      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-	if (TEST_HARD_REG_BIT (allowed, i))
-	  {
-	    CLEAR_REGNO_REG_SET (&chain->live_throughout, i);
-	    CLEAR_REGNO_REG_SET (&chain->dead_or_set, i);
-	  }
+      hard_reg_set_iterator hrsi;
+      unsigned int j = 0;
+      EXECUTE_IF_SET_IN_HARD_REG_SET (allowed, 0, j, hrsi)
+	{
+	  CLEAR_REGNO_REG_SET (&chain->live_throughout, j);
+	  CLEAR_REGNO_REG_SET (&chain->dead_or_set, j);
+	}
     }
 
 #endif
@@ -3919,29 +3920,29 @@  update_eliminables (HARD_REG_SET *pset)
 static bool
 update_eliminables_and_spill (void)
 {
-  int i;
+  unsigned int i;
   bool did_spill = false;
   HARD_REG_SET to_spill;
   CLEAR_HARD_REG_SET (to_spill);
   update_eliminables (&to_spill);
   used_spill_regs &= ~to_spill;
 
-  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-    if (TEST_HARD_REG_BIT (to_spill, i))
-      {
-	spill_hard_reg (i, 1);
-	did_spill = true;
-
-	/* Regardless of the state of spills, if we previously had
-	   a register that we thought we could eliminate, but now
-	   cannot eliminate, we must run another pass.
-
-	   Consider pseudos which have an entry in reg_equiv_* which
-	   reference an eliminable register.  We must make another pass
-	   to update reg_equiv_* so that we do not substitute in the
-	   old value from when we thought the elimination could be
-	   performed.  */
-      }
+  hard_reg_set_iterator hrsi;
+  EXECUTE_IF_SET_IN_HARD_REG_SET (to_spill, 0, i, hrsi)
+    {
+      spill_hard_reg (i, 1);
+      did_spill = true;
+
+      /* Regardless of the state of spills, if we previously had
+	 a register that we thought we could eliminate, but now
+	 cannot eliminate, we must run another pass.
+
+	 Consider pseudos which have an entry in reg_equiv_* which
+	 reference an eliminable register.  We must make another pass
+	 to update reg_equiv_* so that we do not substitute in the
+	 old value from when we thought the elimination could be
+	 performed.  */
+    }
   return did_spill;
 }
 
diff --git a/gcc/rtl-ssa/insns.cc b/gcc/rtl-ssa/insns.cc
index c332119f11e..fbd1fd9634a 100644
--- a/gcc/rtl-ssa/insns.cc
+++ b/gcc/rtl-ssa/insns.cc
@@ -628,8 +628,10 @@  function_info::record_call_clobbers (build_info &bi, insn_info *insn,
       m_clobbered_by_calls |= abi.full_and_partial_reg_clobbers ();
     }
   else
-    for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
-      if (TEST_HARD_REG_BIT (abi.full_reg_clobbers (), regno))
+    {
+      hard_reg_set_iterator hrsi;
+      unsigned int regno = 0;
+      EXECUTE_IF_SET_IN_HARD_REG_SET (abi.full_reg_clobbers (), 0, regno, hrsi)
 	{
 	  def_info *def = m_defs[regno + 1];
 	  if (!def || def->last_def ()->insn () != insn)
@@ -641,6 +643,7 @@  function_info::record_call_clobbers (build_info &bi, insn_info *insn,
 	      bi.record_reg_def (def);
 	    }
 	}
+    }
 }
 
 // Called while building SSA form using BI.  Record that INSN contains
diff --git a/gcc/sched-deps.cc b/gcc/sched-deps.cc
index e72b53ccf79..b2da11c7900 100644
--- a/gcc/sched-deps.cc
+++ b/gcc/sched-deps.cc
@@ -3149,22 +3149,22 @@  sched_analyze_insn (class deps_desc *deps, rtx x, rtx_insn *insn)
 	    }
 	}
 
-      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-	if (TEST_HARD_REG_BIT (implicit_reg_pending_uses, i))
-	  {
-	    struct deps_reg *reg_last = &deps->reg_last[i];
-	    add_dependence_list (insn, reg_last->sets, 0, REG_DEP_TRUE, false);
-	    add_dependence_list (insn, reg_last->implicit_sets, 0,
-				 REG_DEP_ANTI, false);
-	    add_dependence_list (insn, reg_last->clobbers, 0, REG_DEP_TRUE,
-				 false);
+      hard_reg_set_iterator hrsi;
+      EXECUTE_IF_SET_IN_HARD_REG_SET (implicit_reg_pending_uses, 0, i, hrsi)
+	{
+	  struct deps_reg *reg_last = &deps->reg_last[i];
+	  add_dependence_list (insn, reg_last->sets, 0, REG_DEP_TRUE, false);
+	  add_dependence_list (insn, reg_last->implicit_sets, 0,
+			       REG_DEP_ANTI, false);
+	  add_dependence_list (insn, reg_last->clobbers, 0, REG_DEP_TRUE,
+			       false);
 
-	    if (!deps->readonly)
-	      {
-		reg_last->uses = alloc_INSN_LIST (insn, reg_last->uses);
-		reg_last->uses_length++;
-	      }
-	  }
+	  if (!deps->readonly)
+	    {
+	      reg_last->uses = alloc_INSN_LIST (insn, reg_last->uses);
+	      reg_last->uses_length++;
+	    }
+	}
 
       if (targetm.sched.exposed_pipeline)
 	{
@@ -3309,20 +3309,20 @@  sched_analyze_insn (class deps_desc *deps, rtx x, rtx_insn *insn)
 	}
     }
 
-  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-    if (TEST_HARD_REG_BIT (implicit_reg_pending_clobbers, i))
-      {
-	struct deps_reg *reg_last = &deps->reg_last[i];
-	add_dependence_list (insn, reg_last->sets, 0, REG_DEP_ANTI, false);
-	add_dependence_list (insn, reg_last->clobbers, 0, REG_DEP_ANTI, false);
-	add_dependence_list (insn, reg_last->uses, 0, REG_DEP_ANTI, false);
-	add_dependence_list (insn, reg_last->control_uses, 0, REG_DEP_ANTI,
-			     false);
+  hard_reg_set_iterator hrsi;
+  EXECUTE_IF_SET_IN_HARD_REG_SET (implicit_reg_pending_clobbers, 0, i, hrsi)
+    {
+      struct deps_reg *reg_last = &deps->reg_last[i];
+      add_dependence_list (insn, reg_last->sets, 0, REG_DEP_ANTI, false);
+      add_dependence_list (insn, reg_last->clobbers, 0, REG_DEP_ANTI, false);
+      add_dependence_list (insn, reg_last->uses, 0, REG_DEP_ANTI, false);
+      add_dependence_list (insn, reg_last->control_uses, 0, REG_DEP_ANTI,
+			   false);
 
 	if (!deps->readonly)
 	  reg_last->implicit_sets
 	    = alloc_INSN_LIST (insn, reg_last->implicit_sets);
-      }
+    }
 
   if (!deps->readonly)
     {
diff --git a/gcc/sel-sched-dump.cc b/gcc/sel-sched-dump.cc
index 146e819bc6b..e0f20801fa6 100644
--- a/gcc/sel-sched-dump.cc
+++ b/gcc/sel-sched-dump.cc
@@ -539,14 +539,14 @@  dump_insn_vector (rtx_vec_t succs)
 static void
 print_hard_reg_set (FILE *file, const char *prefix, HARD_REG_SET set)
 {
-  int i;
+  unsigned int i;
 
   fprintf (file, "%s{ ", prefix);
-  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-    {
-      if (TEST_HARD_REG_BIT (set, i))
-	fprintf (file, "%d ", i);
-    }
+
+  hard_reg_set_iterator hrsi;
+  EXECUTE_IF_SET_IN_HARD_REG_SET (set, 0, i, hrsi)
+    fprintf (file, "%d ", i);
+
   fprintf (file, "}\n");
 }