diff options
-rw-r--r-- | gcc/rtl-ssa/changes.cc | 35 | ||||
-rw-r--r-- | gcc/rtl-ssa/functions.h | 1 |
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 *); |