diff options
Diffstat (limited to 'gcc/rtl-ssa/changes.cc')
-rw-r--r-- | gcc/rtl-ssa/changes.cc | 54 |
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) |