aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2023-10-25 10:39:51 +0100
committerRichard Sandiford <richard.sandiford@arm.com>2023-10-25 10:39:51 +0100
commitadf1b369c5321ffc213e080f8aa9d0cc8d7f9eca (patch)
treec446e8b86c6cdc12996f6365543dc8d4cd758e2d
parent60ef0d2cdc97b4325947941834f5d3590f0af062 (diff)
downloadgcc-adf1b369c5321ffc213e080f8aa9d0cc8d7f9eca.zip
gcc-adf1b369c5321ffc213e080f8aa9d0cc8d7f9eca.tar.gz
gcc-adf1b369c5321ffc213e080f8aa9d0cc8d7f9eca.tar.bz2
rtl-ssa: Handle artifical uses of deleted defs
If an optimisation removes the last real use of a definition, there can still be artificial uses left. This patch removes those uses too. These artificial uses exist because RTL-SSA is only an SSA-like view of the existing RTL IL, rather than a native SSA representation. It effectively treats RTL registers like gimple vops, but with the addition of an RPO view of the register's lifetime(s). Things are structured to allow most operations to update this RPO view in amortised sublinear time. gcc/ * rtl-ssa/functions.h (function_info::process_uses_of_deleted_def): New member function. * rtl-ssa/changes.cc (function_info::process_uses_of_deleted_def): Likewise. (function_info::change_insns): Use it.
-rw-r--r--gcc/rtl-ssa/changes.cc35
-rw-r--r--gcc/rtl-ssa/functions.h1
2 files changed, 34 insertions, 2 deletions
diff --git a/gcc/rtl-ssa/changes.cc b/gcc/rtl-ssa/changes.cc
index 5800f9d..3e14069 100644
--- a/gcc/rtl-ssa/changes.cc
+++ b/gcc/rtl-ssa/changes.cc
@@ -209,6 +209,35 @@ rtl_ssa::changes_are_worthwhile (array_slice<insn_change *const> changes,
return true;
}
+// SET has been deleted. Clean up all remaining uses. Such uses are
+// either dead phis or now-redundant live-out uses.
+void
+function_info::process_uses_of_deleted_def (set_info *set)
+{
+ if (!set->has_any_uses ())
+ return;
+
+ auto *use = *set->all_uses ().begin ();
+ do
+ {
+ auto *next_use = use->next_use ();
+ if (use->is_in_phi ())
+ {
+ // This call will not recurse.
+ process_uses_of_deleted_def (use->phi ());
+ delete_phi (use->phi ());
+ }
+ else
+ {
+ gcc_assert (use->is_live_out_use ());
+ remove_use (use);
+ }
+ use = next_use;
+ }
+ while (use);
+ gcc_assert (!set->has_any_uses ());
+}
+
// Update the REG_NOTES of INSN, whose pattern has just been changed.
static void
update_notes (rtx_insn *insn)
@@ -695,7 +724,8 @@ function_info::change_insns (array_slice<insn_change *> changes)
}
// Remove all definitions that are no longer needed. After the above,
- // such definitions should no longer have any registered users.
+ // the only uses of such definitions should be dead phis and now-redundant
+ // live-out uses.
//
// In particular, this means that consumers must handle debug
// instructions before removing a set.
@@ -704,7 +734,8 @@ function_info::change_insns (array_slice<insn_change *> changes)
if (def->m_has_been_superceded)
{
auto *set = dyn_cast<set_info *> (def);
- gcc_assert (!set || !set->has_any_uses ());
+ if (set && set->has_any_uses ())
+ process_uses_of_deleted_def (set);
remove_def (def);
}
diff --git a/gcc/rtl-ssa/functions.h b/gcc/rtl-ssa/functions.h
index 73690a0..cd90b6a 100644
--- a/gcc/rtl-ssa/functions.h
+++ b/gcc/rtl-ssa/functions.h
@@ -263,6 +263,7 @@ private:
bb_info *create_bb_info (basic_block);
void append_bb (bb_info *);
+ void process_uses_of_deleted_def (set_info *);
insn_info *add_placeholder_after (insn_info *);
void possibly_queue_changes (insn_change &);
void finalize_new_accesses (insn_change &, insn_info *);