diff options
author | David Malcolm <dmalcolm@redhat.com> | 2021-07-15 15:01:57 -0400 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2021-07-15 15:01:57 -0400 |
commit | a9241df96e1950c630550ada9371c0b4a03496cf (patch) | |
tree | 8223a597e534cc582599264829b4c0bb2e7f7ac6 /gcc/analyzer | |
parent | 797358f42fab5ee58a893b68ed18f6ea05eff634 (diff) | |
download | gcc-a9241df96e1950c630550ada9371c0b4a03496cf.zip gcc-a9241df96e1950c630550ada9371c0b4a03496cf.tar.gz gcc-a9241df96e1950c630550ada9371c0b4a03496cf.tar.bz2 |
analyzer: handle self-referential phis
gcc/analyzer/ChangeLog:
* state-purge.cc (self_referential_phi_p): New.
(state_purge_per_ssa_name::process_point): Don't purge an SSA name
at its def-stmt if the def-stmt is self-referential.
gcc/testsuite/ChangeLog:
* gcc.dg/analyzer/phi-1.c: New test.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Diffstat (limited to 'gcc/analyzer')
-rw-r--r-- | gcc/analyzer/state-purge.cc | 37 |
1 files changed, 34 insertions, 3 deletions
diff --git a/gcc/analyzer/state-purge.cc b/gcc/analyzer/state-purge.cc index 70a09ed..e82ea87 100644 --- a/gcc/analyzer/state-purge.cc +++ b/gcc/analyzer/state-purge.cc @@ -288,6 +288,20 @@ state_purge_per_ssa_name::add_to_worklist (const function_point &point, } } +/* Does this phi depend on itself? + e.g. in: + added_2 = PHI <added_6(2), added_2(3), added_11(4)> + the middle defn (from edge 3) requires added_2 itself. */ + +static bool +self_referential_phi_p (const gphi *phi) +{ + for (unsigned i = 0; i < gimple_phi_num_args (phi); i++) + if (gimple_phi_arg_def (phi, i) == gimple_phi_result (phi)) + return true; + return false; +} + /* Process POINT, popped from WORKLIST. Iterate over predecessors of POINT, adding to WORKLIST. */ @@ -326,11 +340,28 @@ state_purge_per_ssa_name::process_point (const function_point &point, !gsi_end_p (gpi); gsi_next (&gpi)) { gphi *phi = gpi.phi (); + /* Are we at the def-stmt for m_name? */ if (phi == def_stmt) { - if (logger) - logger->log ("def stmt within phis; terminating"); - return; + /* Does this phi depend on itself? + e.g. in: + added_2 = PHI <added_6(2), added_2(3), added_11(4)> + the middle defn (from edge 3) requires added_2 itself + so we can't purge it here. */ + if (self_referential_phi_p (phi)) + { + if (logger) + logger->log ("self-referential def stmt within phis;" + " continuing"); + } + else + { + /* Otherwise, we can stop here, so that m_name + can be purged. */ + if (logger) + logger->log ("def stmt within phis; terminating"); + return; + } } } |