[committed] analyzer: record per-enode saved_diagnostics

David Malcolm dmalcolm@redhat.com
Thu Apr 1 22:28:00 GMT 2021


Various places iterate through all of the saved_diagnostics to find
just the ones that are at a given enode.  This patch adds a per-enode
record of the diagnostics that are at each node, to save iterating
through all of the diagnostics each time.

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as 6e943d5a2e3c581e40ccab46bec986a1f22c70c2.

gcc/analyzer/ChangeLog:
	* diagnostic-manager.cc (diagnostic_manager::add_diagnostic): Make
	enode param non-constant, and call add_diagnostic on it.  Add
	enode index to log message.
	(diagnostic_manager::add_diagnostic): Make enode param
	non-constant.
	* diagnostic-manager.h (diagnostic_manager::add_diagnostic):
	Likewise for both decls.
	* engine.cc
	(impl_region_model_context::impl_region_model_context): Likewise
	for enode_for_diag.
	(impl_sm_context::impl_sm_context): Likewise.
	(impl_sm_context::m_enode_for_diag): Likewise.
	(exploded_node::dump_dot): Don't pass the diagnostic manager
	to dump_saved_diagnostics.
	(exploded_node::dump_saved_diagnostics): Drop param.  Iterate
	directly through all saved diagnostics for the enode, rather
	than all saved diagnostics in the diagnostic_manager and
	filtering.
	(exploded_node::on_stmt): Make non-const.
	(exploded_node::on_edge): Likewise.
	(exploded_node::on_longjmp): Likewise.
	(exploded_node::detect_leaks): Likewise.
	(exploded_graph::get_or_create_node): Make enode_for_diag param
	non-const.
	(exploded_graph_annotator::print_enode): Iterate
	directly through all saved diagnostics for the enode, rather
	than all saved diagnostics in the diagnostic_manager and
	filtering.
	* exploded-graph.h
	(impl_region_model_context::impl_region_model_context): Make
	enode_for_diag param non-constant.
	(impl_region_model_context::m_enode_for_diag): Likewise.
	(exploded_node::dump_saved_diagnostics): Drop param.
	(exploded_node::on_stmt): Make non-const.
	(exploded_node::on_edge): Likewise.
	(exploded_node::on_longjmp): Likewise.
	(exploded_node::detect_leaks): Likewise.
	(exploded_node::add_diagnostic): New.
	(exploded_node::get_num_diagnostics): New.
	(exploded_node::get_saved_diagnostic): New.
	(exploded_node::m_saved_diagnostics): New.
	(exploded_graph::get_or_create_node): Make enode_for_diag param
	non-constant.
	* feasible-graph.cc (feasible_node::dump_dot): Drop
	diagnostic_manager from call to dump_saved_diagnostics.
	* program-state.cc (program_state::on_edge): Convert enode param
	to non-const pointer.
	(program_state::prune_for_point): Likewise for enode_for_diag
	param.
	* program-state.h (program_state::on_edge): Convert enode param
	to non-const pointer.
	(program_state::prune_for_point): Likewise for enode_for_diag
	param.
---
 gcc/analyzer/diagnostic-manager.cc |  9 +++---
 gcc/analyzer/diagnostic-manager.h  |  4 +--
 gcc/analyzer/engine.cc             | 52 +++++++++++++-----------------
 gcc/analyzer/exploded-graph.h      | 34 +++++++++++++------
 gcc/analyzer/feasible-graph.cc     |  5 ++-
 gcc/analyzer/program-state.cc      | 12 +++----
 gcc/analyzer/program-state.h       |  4 +--
 7 files changed, 65 insertions(+), 55 deletions(-)

diff --git a/gcc/analyzer/diagnostic-manager.cc b/gcc/analyzer/diagnostic-manager.cc
index a376755b7ee..9ec3e899e85 100644
--- a/gcc/analyzer/diagnostic-manager.cc
+++ b/gcc/analyzer/diagnostic-manager.cc
@@ -791,7 +791,7 @@ diagnostic_manager::diagnostic_manager (logger *logger, engine *eng,
 
 void
 diagnostic_manager::add_diagnostic (const state_machine *sm,
-				    const exploded_node *enode,
+				    exploded_node *enode,
 				    const supernode *snode, const gimple *stmt,
 				    stmt_finder *finder,
 				    tree var,
@@ -809,16 +809,17 @@ diagnostic_manager::add_diagnostic (const state_machine *sm,
     = new saved_diagnostic (sm, enode, snode, stmt, finder, var, sval,
 			    state, d, m_saved_diagnostics.length ());
   m_saved_diagnostics.safe_push (sd);
+  enode->add_diagnostic (sd);
   if (get_logger ())
-    log ("adding saved diagnostic %i at SN %i: %qs",
+    log ("adding saved diagnostic %i at SN %i to EN %i: %qs",
 	 sd->get_index (),
-	 snode->m_index, d->get_kind ());
+	 snode->m_index, enode->m_index, d->get_kind ());
 }
 
 /* Queue pending_diagnostic D at ENODE for later emission.  */
 
 void
-diagnostic_manager::add_diagnostic (const exploded_node *enode,
+diagnostic_manager::add_diagnostic (exploded_node *enode,
 				    const supernode *snode, const gimple *stmt,
 				    stmt_finder *finder,
 				    pending_diagnostic *d)
diff --git a/gcc/analyzer/diagnostic-manager.h b/gcc/analyzer/diagnostic-manager.h
index 14549779549..fc8ac2650c2 100644
--- a/gcc/analyzer/diagnostic-manager.h
+++ b/gcc/analyzer/diagnostic-manager.h
@@ -101,7 +101,7 @@ public:
   json::object *to_json () const;
 
   void add_diagnostic (const state_machine *sm,
-		       const exploded_node *enode,
+		       exploded_node *enode,
 		       const supernode *snode, const gimple *stmt,
 		       stmt_finder *finder,
 		       tree var,
@@ -109,7 +109,7 @@ public:
 		       state_machine::state_t state,
 		       pending_diagnostic *d);
 
-  void add_diagnostic (const exploded_node *enode,
+  void add_diagnostic (exploded_node *enode,
 		       const supernode *snode, const gimple *stmt,
 		       stmt_finder *finder,
 		       pending_diagnostic *d);
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index 1fb96de6082..857d43450d1 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -75,7 +75,7 @@ namespace ana {
 
 impl_region_model_context::
 impl_region_model_context (exploded_graph &eg,
-			   const exploded_node *enode_for_diag,
+			   exploded_node *enode_for_diag,
 			   const program_state *old_state,
 			   program_state *new_state,
 			   const gimple *stmt,
@@ -199,7 +199,7 @@ public:
   impl_sm_context (exploded_graph &eg,
 		   int sm_idx,
 		   const state_machine &sm,
-		   const exploded_node *enode_for_diag,
+		   exploded_node *enode_for_diag,
 		   const program_state *old_state,
 		   program_state *new_state,
 		   const sm_state_map *old_smap,
@@ -352,7 +352,7 @@ public:
 
   log_user m_logger;
   exploded_graph &m_eg;
-  const exploded_node *m_enode_for_diag;
+  exploded_node *m_enode_for_diag;
   const program_state *m_old_state;
   program_state *m_new_state;
   const sm_state_map *m_old_smap;
@@ -950,7 +950,7 @@ exploded_node::dump_dot (graphviz_out *gv, const dump_args_t &args) const
       dump_processed_stmts (pp);
     }
 
-  dump_saved_diagnostics (pp, args.m_eg.get_diagnostic_manager ());
+  dump_saved_diagnostics (pp);
 
   args.dump_extra_info (this, pp);
 
@@ -988,18 +988,15 @@ exploded_node::dump_processed_stmts (pretty_printer *pp) const
 /* Dump any saved_diagnostics at this enode to PP.  */
 
 void
-exploded_node::dump_saved_diagnostics (pretty_printer *pp,
-				       const diagnostic_manager &dm) const
+exploded_node::dump_saved_diagnostics (pretty_printer *pp) const
 {
-  for (unsigned i = 0; i < dm.get_num_diagnostics (); i++)
+  unsigned i;
+  const saved_diagnostic *sd;
+  FOR_EACH_VEC_ELT (m_saved_diagnostics, i, sd)
     {
-      const saved_diagnostic *sd = dm.get_saved_diagnostic (i);
-      if (sd->m_enode == this)
-	{
-	  pp_printf (pp, "DIAGNOSTIC: %s (sd: %i)",
-		     sd->m_d->get_kind (), sd->get_index ());
-	  pp_newline (pp);
-	}
+      pp_printf (pp, "DIAGNOSTIC: %s (sd: %i)",
+		 sd->m_d->get_kind (), sd->get_index ());
+      pp_newline (pp);
     }
 }
 
@@ -1119,7 +1116,7 @@ exploded_node::on_stmt_flags
 exploded_node::on_stmt (exploded_graph &eg,
 			const supernode *snode,
 			const gimple *stmt,
-			program_state *state) const
+			program_state *state)
 {
   logger *logger = eg.get_logger ();
   LOG_SCOPE (logger);
@@ -1303,14 +1300,14 @@ bool
 exploded_node::on_edge (exploded_graph &eg,
 			const superedge *succ,
 			program_point *next_point,
-			program_state *next_state) const
+			program_state *next_state)
 {
   LOG_FUNC (eg.get_logger ());
 
   if (!next_point->on_edge (eg, succ))
     return false;
 
-  if (!next_state->on_edge (eg, *this, succ))
+  if (!next_state->on_edge (eg, this, succ))
     return false;
 
   return true;
@@ -1435,7 +1432,7 @@ void
 exploded_node::on_longjmp (exploded_graph &eg,
 			   const gcall *longjmp_call,
 			   program_state *new_state,
-			   region_model_context *ctxt) const
+			   region_model_context *ctxt)
 {
   tree buf_ptr = gimple_call_arg (longjmp_call, 0);
   gcc_assert (POINTER_TYPE_P (TREE_TYPE (buf_ptr)));
@@ -1544,7 +1541,7 @@ exploded_node::on_longjmp (exploded_graph &eg,
    leaks.  */
 
 void
-exploded_node::detect_leaks (exploded_graph &eg) const
+exploded_node::detect_leaks (exploded_graph &eg)
 {
   LOG_FUNC_1 (eg.get_logger (), "EN: %i", m_index);
 
@@ -2163,7 +2160,7 @@ exploded_graph::add_function_entry (function *fun)
 exploded_node *
 exploded_graph::get_or_create_node (const program_point &point,
 				    const program_state &state,
-				    const exploded_node *enode_for_diag)
+				    exploded_node *enode_for_diag)
 {
   logger * const logger = get_logger ();
   LOG_FUNC (logger);
@@ -4664,16 +4661,13 @@ private:
 	break;
       }
     gv->end_tdtr ();
+
     /* Dump any saved_diagnostics at this enode.  */
-    {
-      const diagnostic_manager &dm = m_eg.get_diagnostic_manager ();
-      for (unsigned i = 0; i < dm.get_num_diagnostics (); i++)
-	{
-	  const saved_diagnostic *sd = dm.get_saved_diagnostic (i);
-	  if (sd->m_enode == enode)
-	    print_saved_diagnostic (gv, sd);
-	}
-    }
+    for (unsigned i = 0; i < enode->get_num_diagnostics (); i++)
+      {
+	const saved_diagnostic *sd = enode->get_saved_diagnostic (i);
+	print_saved_diagnostic (gv, sd);
+      }
     pp_printf (pp, "</TABLE>");
     pp_printf (pp, "</TD>");
   }
diff --git a/gcc/analyzer/exploded-graph.h b/gcc/analyzer/exploded-graph.h
index deb739f5572..25666411480 100644
--- a/gcc/analyzer/exploded-graph.h
+++ b/gcc/analyzer/exploded-graph.h
@@ -30,7 +30,7 @@ class impl_region_model_context : public region_model_context
 {
  public:
   impl_region_model_context (exploded_graph &eg,
-			     const exploded_node *enode_for_diag,
+			     exploded_node *enode_for_diag,
 
 			     /* TODO: should we be getting the ECs from the
 				old state, rather than the new?  */
@@ -70,7 +70,7 @@ class impl_region_model_context : public region_model_context
 
   exploded_graph *m_eg;
   log_user m_logger;
-  const exploded_node *m_enode_for_diag;
+  exploded_node *m_enode_for_diag;
   const program_state *m_old_state;
   program_state *m_new_state;
   const gimple *m_stmt;
@@ -186,8 +186,7 @@ class exploded_node : public dnode<eg_traits>
   void dump (const extrinsic_state &ext_state) const;
 
   void dump_processed_stmts (pretty_printer *pp) const;
-  void dump_saved_diagnostics (pretty_printer *pp,
-			       const diagnostic_manager &dm) const;
+  void dump_saved_diagnostics (pretty_printer *pp) const;
 
   json::object *to_json (const extrinsic_state &ext_state) const;
 
@@ -227,17 +226,17 @@ class exploded_node : public dnode<eg_traits>
   on_stmt_flags on_stmt (exploded_graph &eg,
 			 const supernode *snode,
 			 const gimple *stmt,
-			 program_state *state) const;
+			 program_state *state);
   bool on_edge (exploded_graph &eg,
 		const superedge *succ,
 		program_point *next_point,
-		program_state *next_state) const;
+		program_state *next_state);
   void on_longjmp (exploded_graph &eg,
 		   const gcall *call,
 		   program_state *new_state,
-		   region_model_context *ctxt) const;
+		   region_model_context *ctxt);
 
-  void detect_leaks (exploded_graph &eg) const;
+  void detect_leaks (exploded_graph &eg);
 
   const program_point &get_point () const { return m_ps.get_point (); }
   const supernode *get_supernode () const
@@ -269,6 +268,19 @@ class exploded_node : public dnode<eg_traits>
     m_status = status;
   }
 
+  void add_diagnostic (const saved_diagnostic *sd)
+  {
+    m_saved_diagnostics.safe_push (sd);
+  }
+  unsigned get_num_diagnostics () const
+  {
+    return m_saved_diagnostics.length ();
+  }
+  const saved_diagnostic *get_saved_diagnostic (unsigned idx) const
+  {
+    return m_saved_diagnostics[idx];
+  }
+
 private:
   DISABLE_COPY_AND_ASSIGN (exploded_node);
 
@@ -278,6 +290,10 @@ private:
 
   enum status m_status;
 
+  /* The saved_diagnostics at this enode, borrowed from the
+     diagnostic_manager.  */
+  auto_vec <const saved_diagnostic *> m_saved_diagnostics;
+
 public:
   /* The index of this exploded_node.  */
   const int m_index;
@@ -761,7 +777,7 @@ public:
 
   exploded_node *get_or_create_node (const program_point &point,
 				     const program_state &state,
-				     const exploded_node *enode_for_diag);
+				     exploded_node *enode_for_diag);
   exploded_edge *add_edge (exploded_node *src, exploded_node *dest,
 			   const superedge *sedge,
 			   exploded_edge::custom_info_t *custom = NULL);
diff --git a/gcc/analyzer/feasible-graph.cc b/gcc/analyzer/feasible-graph.cc
index bb409d61dd2..675bda9e7e5 100644
--- a/gcc/analyzer/feasible-graph.cc
+++ b/gcc/analyzer/feasible-graph.cc
@@ -79,7 +79,7 @@ base_feasible_node::dump_dot_id (pretty_printer *pp) const
 
 void
 feasible_node::dump_dot (graphviz_out *gv,
-			const dump_args_t &args) const
+			const dump_args_t &) const
 {
   pretty_printer *pp = gv->get_pp ();
 
@@ -102,8 +102,7 @@ feasible_node::dump_dot (graphviz_out *gv,
   pp_newline (pp);
 
   m_inner_node->dump_processed_stmts (pp);
-  m_inner_node->dump_saved_diagnostics
-    (pp, args.m_inner_args.m_eg.get_diagnostic_manager ());
+  m_inner_node->dump_saved_diagnostics (pp);
 
   pp_write_text_as_dot_label_to_stream (pp, /*for_record=*/true);
 
diff --git a/gcc/analyzer/program-state.cc b/gcc/analyzer/program-state.cc
index fcea5ce436d..347cb290d10 100644
--- a/gcc/analyzer/program-state.cc
+++ b/gcc/analyzer/program-state.cc
@@ -959,11 +959,11 @@ program_state::get_current_function () const
 
 bool
 program_state::on_edge (exploded_graph &eg,
-			const exploded_node &enode,
+			exploded_node *enode,
 			const superedge *succ)
 {
   /* Update state.  */
-  const program_point &point = enode.get_point ();
+  const program_point &point = enode->get_point ();
   const gimple *last_stmt = point.get_supernode ()->get_last_stmt ();
 
   /* For conditionals and switch statements, add the
@@ -975,8 +975,8 @@ program_state::on_edge (exploded_graph &eg,
      sm-state transitions (e.g. transitions due to ptrs becoming known
      to be NULL or non-NULL) */
 
-  impl_region_model_context ctxt (eg, &enode,
-				  &enode.get_state (),
+  impl_region_model_context ctxt (eg, enode,
+				  &enode->get_state (),
 				  this,
 				  last_stmt);
   if (!m_region_model->maybe_update_for_edge (*succ,
@@ -991,7 +991,7 @@ program_state::on_edge (exploded_graph &eg,
       return false;
     }
 
-  program_state::detect_leaks (enode.get_state (), *this,
+  program_state::detect_leaks (enode->get_state (), *this,
 				NULL, eg.get_ext_state (),
 				&ctxt);
 
@@ -1007,7 +1007,7 @@ program_state::on_edge (exploded_graph &eg,
 program_state
 program_state::prune_for_point (exploded_graph &eg,
 				const program_point &point,
-				const exploded_node *enode_for_diag) const
+				exploded_node *enode_for_diag) const
 {
   logger * const logger = eg.get_logger ();
   LOG_SCOPE (logger);
diff --git a/gcc/analyzer/program-state.h b/gcc/analyzer/program-state.h
index 54fdb5b167c..71b6f0187a4 100644
--- a/gcc/analyzer/program-state.h
+++ b/gcc/analyzer/program-state.h
@@ -221,12 +221,12 @@ public:
   function * get_current_function () const;
 
   bool on_edge (exploded_graph &eg,
-		const exploded_node &enode,
+		exploded_node *enode,
 		const superedge *succ);
 
   program_state prune_for_point (exploded_graph &eg,
 				 const program_point &point,
-				 const exploded_node *enode_for_diag) const;
+				 exploded_node *enode_for_diag) const;
 
   tree get_representative_tree (const svalue *sval) const;
 
-- 
2.26.2



More information about the Gcc-patches mailing list