https://gcc.gnu.org/g:9f3f2a809e771ab43dfa31d55762436c989f5e85

commit 9f3f2a809e771ab43dfa31d55762436c989f5e85
Author: Richard Sandiford <richard.sandif...@arm.com>
Date:   Mon Jun 23 16:18:56 2025 +0100

    rtl-ssa: Rewrite process_uses_of_deleted_def
    
    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.
    
    gcc/
            * rtl-ssa/changes.cc (process_uses_of_deleted_def): Rewrite to
            handle deletions of non-degenerate phis.

Diff:
---
 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 eb89eb664de0..3c0fb51cc866 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.

Reply via email to