Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu. Pushed to trunk as 6bbad96cd44774bc199b256dbf4260b25b87c7db.
gcc/analyzer/ChangeLog: * state-purge.cc (state_purge_annotator::add_node_annotations): Rather than erroneously always using the NULL in-edge, determine each relevant in-edge, and print the appropriate data for each in-edge. Use print_needed to print the data as comma-separated lists of SSA names. (print_vec_of_names): Add "within_table" param and use it. (state_purge_annotator::add_stmt_annotations): Factor out collation and printing code into... (state_purge_annotator::print_needed): ...this new function. * state-purge.h (state_purge_annotator::print_needed): New decl. Signed-off-by: David Malcolm <dmalc...@redhat.com> --- gcc/analyzer/state-purge.cc | 66 ++++++++++++++++++++++--------------- gcc/analyzer/state-purge.h | 4 +++ 2 files changed, 43 insertions(+), 27 deletions(-) diff --git a/gcc/analyzer/state-purge.cc b/gcc/analyzer/state-purge.cc index e82ea87e735..3c3b77500a6 100644 --- a/gcc/analyzer/state-purge.cc +++ b/gcc/analyzer/state-purge.cc @@ -477,23 +477,20 @@ state_purge_annotator::add_node_annotations (graphviz_out *gv, "lightblue"); pp_write_text_to_stream (pp); - // FIXME: passing in a NULL in-edge means we get no hits - function_point before_supernode - (function_point::before_supernode (&n, NULL)); - - for (state_purge_map::iterator iter = m_map->begin (); - iter != m_map->end (); - ++iter) + /* Different in-edges mean different names need purging. + Determine which points to dump. */ + auto_vec<function_point> points; + if (n.entry_p ()) + points.safe_push (function_point::before_supernode (&n, NULL)); + else + for (auto inedge : n.m_preds) + points.safe_push (function_point::before_supernode (&n, inedge)); + + for (auto & point : points) { - tree name = (*iter).first; - state_purge_per_ssa_name *per_name_data = (*iter).second; - if (per_name_data->get_function () == n.m_fun) - { - if (per_name_data->needed_at_point_p (before_supernode)) - pp_printf (pp, "%qE needed here", name); - else - pp_printf (pp, "%qE not needed here", name); - } + point.print (pp, format (true)); + pp_newline (pp); + print_needed (gv, point, false); pp_newline (pp); } @@ -502,19 +499,20 @@ state_purge_annotator::add_node_annotations (graphviz_out *gv, return false; } -/* Print V to GV as a comma-separated list in braces within a <TR>, - titling it with TITLE. +/* Print V to GV as a comma-separated list in braces, titling it with TITLE. + If WITHIN_TABLE is true, print it within a <TR> - Subroutine of state_purge_annotator::add_stmt_annotations. */ + Subroutine of state_purge_annotator::print_needed. */ static void print_vec_of_names (graphviz_out *gv, const char *title, - const auto_vec<tree> &v) + const auto_vec<tree> &v, bool within_table) { pretty_printer *pp = gv->get_pp (); tree name; unsigned i; - gv->begin_trtd (); + if (within_table) + gv->begin_trtd (); pp_printf (pp, "%s: {", title); FOR_EACH_VEC_ELT (v, i, name) { @@ -523,8 +521,11 @@ print_vec_of_names (graphviz_out *gv, const char *title, pp_printf (pp, "%qE", name); } pp_printf (pp, "}"); - pp_write_text_as_html_like_dot_to_stream (pp); - gv->end_tdtr (); + if (within_table) + { + pp_write_text_as_html_like_dot_to_stream (pp); + gv->end_tdtr (); + } pp_newline (pp); } @@ -556,6 +557,17 @@ state_purge_annotator::add_stmt_annotations (graphviz_out *gv, function_point before_stmt (function_point::before_stmt (supernode, stmt_idx)); + print_needed (gv, before_stmt, true); +} + +/* Get the ssa names needed and not-needed at POINT, and print them to GV. + If WITHIN_TABLE is true, print them within <TR> elements. */ + +void +state_purge_annotator::print_needed (graphviz_out *gv, + const function_point &point, + bool within_table) const +{ auto_vec<tree> needed; auto_vec<tree> not_needed; for (state_purge_map::iterator iter = m_map->begin (); @@ -564,17 +576,17 @@ state_purge_annotator::add_stmt_annotations (graphviz_out *gv, { tree name = (*iter).first; state_purge_per_ssa_name *per_name_data = (*iter).second; - if (per_name_data->get_function () == supernode->m_fun) + if (per_name_data->get_function () == point.get_function ()) { - if (per_name_data->needed_at_point_p (before_stmt)) + if (per_name_data->needed_at_point_p (point)) needed.safe_push (name); else not_needed.safe_push (name); } } - print_vec_of_names (gv, "needed here", needed); - print_vec_of_names (gv, "not needed here", not_needed); + print_vec_of_names (gv, "needed here", needed, within_table); + print_vec_of_names (gv, "not needed here", not_needed, within_table); } #endif /* #if ENABLE_ANALYZER */ diff --git a/gcc/analyzer/state-purge.h b/gcc/analyzer/state-purge.h index 879013dbc17..409490e6761 100644 --- a/gcc/analyzer/state-purge.h +++ b/gcc/analyzer/state-purge.h @@ -159,6 +159,10 @@ public: const FINAL OVERRIDE; private: + void print_needed (graphviz_out *gv, + const function_point &point, + bool within_table) const; + const state_purge_map *m_map; }; -- 2.26.3