On Tue, Jun 24, 2025 at 5:40 PM Richard Sandiford
<richard.sandif...@arm.com> wrote:
>
> process_uses_of_deleted_def seems to have been written on the assumption
> that non-degenerate phis would be explicitly deleted by an insn_change,
> and that the function therefore only needed to delete degenerate phis.
> But that was inconsistent with the rest of the code, and wouldn't be
> very convenient in any case.
>
> This patch therefore rewrites process_uses_of_deleted_def to handle
> general phis.
>
> I'm not aware that this fixes an issues in current code, but it is
> needed to enable the rtl-ssa dce work that Ondřej and Honza are
> working on.
>
> Tested on aarch64-linux-gnu.  OK to install?

OK.

> Richard
>
>
> gcc/
>         PR rtl-optimization/120745
>         * rtl-ssa/changes.cc (process_uses_of_deleted_def): Rewrite to
>         handle deletions of non-degenerate phis.
> ---
>  gcc/rtl-ssa/changes.cc | 36 ++++++++++++++++++++++++------------
>  1 file changed, 24 insertions(+), 12 deletions(-)
>
> diff --git a/gcc/rtl-ssa/changes.cc b/gcc/rtl-ssa/changes.cc
> index f7aa6a66cdf..01f9c383b23 100644
> --- a/gcc/rtl-ssa/changes.cc
> +++ b/gcc/rtl-ssa/changes.cc
> @@ -258,28 +258,40 @@ rtl_ssa::changes_are_worthwhile 
> (array_slice<insn_change *const> changes,
>  void
>  function_info::process_uses_of_deleted_def (set_info *set)
>  {
> -  if (!set->has_any_uses ())
> -    return;
> -
> -  auto *use = *set->all_uses ().begin ();
> -  do
> +  // Each member of the worklist is either SET or a dead phi.
> +  auto_vec<set_info *, 16> worklist;
> +  worklist.quick_push (set);
> +  while (!worklist.is_empty ())
>      {
> -      auto *next_use = use->next_use ();
> +      auto *this_set = worklist.pop ();
> +      auto *use = this_set->first_use ();
> +      if (!use)
> +       {
> +         if (this_set != set)
> +           delete_phi (as_a<phi_info *> (this_set));
> +         continue;
> +       }
>        if (use->is_in_phi ())
>         {
> -         // This call will not recurse.
> -         process_uses_of_deleted_def (use->phi ());
> -         delete_phi (use->phi ());
> +         // Removing all uses from the phi ensures that we'll only add
> +         // it to the worklist once.
> +         auto *phi = use->phi ();
> +         for (auto *input : phi->inputs ())
> +           {
> +             remove_use (input);
> +             input->set_def (nullptr);
> +           }
> +         worklist.safe_push (phi);
>         }
>        else
>         {
>           gcc_assert (use->is_live_out_use ());
>           remove_use (use);
>         }
> -      use = next_use;
> +      // The phi handling above might have removed multiple uses of this_set.
> +      if (this_set->has_any_uses ())
> +       worklist.safe_push (this_set);
>      }
> -  while (use);
> -  gcc_assert (!set->has_any_uses ());
>  }
>
>  // Update the REG_NOTES of INSN, whose pattern has just been changed.
> --
> 2.43.0
>

Reply via email to