aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2025-06-25 10:44:34 +0100
committerRichard Sandiford <richard.sandiford@arm.com>2025-06-25 10:44:34 +0100
commit76f7f91de08de49f39c612bdc9a44a6a8b45325f (patch)
tree6e90910e673e8222caeea8f1ba5cb498d4dc5a06
parent190aaaaf077fe5f318e168a7a1e1aa57058f377e (diff)
downloadgcc-76f7f91de08de49f39c612bdc9a44a6a8b45325f.zip
gcc-76f7f91de08de49f39c612bdc9a44a6a8b45325f.tar.gz
gcc-76f7f91de08de49f39c612bdc9a44a6a8b45325f.tar.bz2
rtl-ssa: Rewrite process_uses_of_deleted_def [PR120745]
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.
-rw-r--r--gcc/rtl-ssa/changes.cc36
1 files changed, 24 insertions, 12 deletions
diff --git a/gcc/rtl-ssa/changes.cc b/gcc/rtl-ssa/changes.cc
index f7aa6a6..00e6c31 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
+ // 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.