]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
rtl-ssa: Rewrite process_uses_of_deleted_def [PR120745]
authorRichard Sandiford <richard.sandiford@arm.com>
Wed, 25 Jun 2025 09:44:34 +0000 (10:44 +0100)
committerRichard Sandiford <richard.sandiford@arm.com>
Wed, 25 Jun 2025 09:44:34 +0000 (10:44 +0100)
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 any issues in current code, but it is
needed to enable the rtl-ssa dce work that OndÅ™ej and Honza are
working on.

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

index f7aa6a66cdf5c477bad660e445494d447efa3055..00e6c3185644c7af11daefca8e82babd944d4ad1 100644 (file)
@@ -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
+         // the phi 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.