aboutsummaryrefslogtreecommitdiff
path: root/gcc/rtl-ssa/changes.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rtl-ssa/changes.cc')
-rw-r--r--gcc/rtl-ssa/changes.cc54
1 files changed, 42 insertions, 12 deletions
diff --git a/gcc/rtl-ssa/changes.cc b/gcc/rtl-ssa/changes.cc
index eb579ad..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.
@@ -1106,6 +1118,24 @@ recog_level2 (insn_change &change, add_regno_clobber_fn add_regno_clobber)
}
}
+ // Per rtl.texi, registers that are modified using RTX_AUTOINC operations
+ // cannot also appear outside an address.
+ vec_rtx_properties properties;
+ properties.add_pattern (pat);
+ for (rtx_obj_reference def : properties.refs ())
+ if (def.is_pre_post_modify ())
+ for (rtx_obj_reference use : properties.refs ())
+ if (def.regno == use.regno && !use.in_address ())
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "register %d is both auto-modified"
+ " and used outside an address:\n", def.regno);
+ print_rtl_single (dump_file, pat);
+ }
+ return false;
+ }
+
// check_asm_operands checks the constraints after RA, so we don't
// need to do it again.
if (reload_completed && !asm_p)