From c9c1e494ec15a5cf8e955119c75d54f2703b27f5 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Thu, 7 Mar 2019 17:16:02 -0500
Subject: [PATCH 081/138] FIXME: more event usage

---
 gcc/analyzer/engine.cc     | 164 ++++++++++++++++++++++++++++++++-------------
 gcc/analyzer/supergraph.cc |  12 ++--
 gcc/analyzer/supergraph.h  |  16 +++++
 3 files changed, 142 insertions(+), 50 deletions(-)

diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index 0734686..c8b8769 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -397,12 +397,35 @@ char *print (const char *fmt, ...)
 enum event_kind
 {
   EK_DEBUG,
+  EK_MESSAGE,
   EK_STATE_CHANGE,
   EK_EDGE,
   EK_CALL_SUMMARY,
   EK_WARNING
 };
 
+static const char *
+event_kind_to_string (enum event_kind ek)
+{
+  switch (ek)
+    {
+    default:
+      gcc_unreachable ();
+    case EK_DEBUG:
+      return "EK_DEBUG";
+    case EK_MESSAGE:
+      return "EK_MESSAGE";
+    case EK_STATE_CHANGE:
+      return "EK_STATE_CHANGE";
+    case EK_EDGE:
+      return "EK_EDGE";
+    case EK_CALL_SUMMARY:
+      return "EK_CALL_SUMMARY";
+    case EK_WARNING:
+      return "EK_WARNING";
+    }
+}
+
 /* FIXME.  */
 
 class checker_event : public diagnostic_event
@@ -422,7 +445,9 @@ public:
   {
     std::string result ("\"");
     result += m_desc;
-    result += "\" (depth ";
+    result += "\" (";
+    result += event_kind_to_string (m_kind);
+    result += ", depth ";
     result += std::to_string (m_depth) + ")";
     return result;
   }
@@ -447,6 +472,23 @@ public:
   // FIXME
 };
 
+class message_event : public checker_event
+{
+public:
+  message_event (location_t loc, tree fndecl, int depth,
+		 const char *desc)
+  : checker_event (EK_MESSAGE, loc, fndecl, depth, desc)
+  {
+  }
+
+  checker_event *clone () const FINAL OVERRIDE
+  {
+    return new message_event (m_loc, m_fndecl, m_depth, m_desc);
+  }
+
+  // FIXME
+};
+
 class state_change_event : public checker_event
 {
 public:
@@ -492,18 +534,21 @@ public:
 class edge_event : public checker_event
 {
 public:
-  edge_event (location_t loc, tree fndecl, int depth,
-	      const char *desc)
-  : checker_event (EK_EDGE, loc, fndecl, depth, desc)
+  edge_event (const superedge *edge,
+	      location_t loc, tree fndecl, int depth, const char *desc)
+  : checker_event (EK_EDGE,
+		   loc, fndecl, depth, desc),
+    m_edge (edge)
   {
   }
 
   checker_event *clone () const FINAL OVERRIDE
   {
-    return new edge_event (m_loc, m_fndecl, m_depth, m_desc);
+    return new edge_event (m_edge, m_loc, m_fndecl, m_depth, m_desc);
   }
 
   // FIXME
+  const superedge *m_edge;
 };
 
 class call_summary : public checker_event
@@ -741,6 +786,9 @@ public:
   {
   }
 
+  void add_events_for_node (checker_path *path, const supernode *node,
+			    int stack_depth);
+
   void prune_active_vars_to_cache_misses (sm_instance *sm_inst,
 					  const supernode *node);
 
@@ -891,6 +939,27 @@ struct sm_instance
   set_of_vars m_active_vars;
 };
 
+void
+engine::add_events_for_node (checker_path *path, const supernode *node,
+			     int stack_depth)
+{
+  if (m_verbosity > 1)
+    {
+      path->add_event (new debug_event (node->get_start_location (),
+					node->m_fun->decl,
+					stack_depth,
+					print ("SN: %i", node->m_index)));
+    }
+  if (m_verbosity > 0 && node->entry_p ())
+    {
+      path->add_event (new message_event (node->get_start_location (),
+					  node->m_fun->decl,
+					  stack_depth,
+					  print ("entry to %qE", node->m_fun->decl)));
+    }
+}
+
+
 /* Remove any active vars that are on the "start" of a blk_transition
    within NODE.  */
 
@@ -1183,11 +1252,7 @@ engine::dfs_traverse (sm_instance sm_inst, backtrace b,
       log ("path_state: %s", ps.to_str ().c_str ());
     }
 
-  if (m_verbosity > 0)
-    b.m_path.add_event (new debug_event (node->get_start_location (),
-					 node->m_fun->decl,
-					 b.m_path.m_stack_depth,
-					 print ("SN: %i", node->m_index)));
+  add_events_for_node (&b.m_path, node, b.m_path.m_stack_depth);
 
   /* Look up to see if we've visited this node in these states before.  */
   prune_active_vars_to_cache_misses (&sm_inst, node);
@@ -1285,7 +1350,8 @@ engine::dfs_traverse (sm_instance sm_inst, backtrace b,
 	   backtrace new_b (b);
 
 	   checker_event *event
-	     = new edge_event ((last_stmt
+	     = new edge_event (succ,
+			       (last_stmt
 				? last_stmt->location
 				: UNKNOWN_LOCATION),
 			       node->m_fun->decl,
@@ -1793,13 +1859,17 @@ engine::follow_call (sm_instance sm_inst, backtrace b, path_state ps,
   b_in_callee.m_path = b.m_path;
 
   if (m_verbosity > 0)
-    b_in_callee.m_path.add_event
-      (new edge_event (edge->call_stmt->location,
-		       caller_node->m_fun->decl,
-		       b_in_callee.m_path.m_stack_depth,
-		       print ("calling %qE from %qE",
-			      callee_node->m_fun->decl,
-			      caller_node->m_fun->decl)));
+    {
+      const superedge *sedge = m_sg.get_edge_for_call (edge);
+      b_in_callee.m_path.add_event
+	(new edge_event (sedge,
+			 edge->call_stmt->location,
+			 caller_node->m_fun->decl,
+			 b_in_callee.m_path.m_stack_depth,
+			 print ("calling %qE from %qE",
+				callee_node->m_fun->decl,
+				caller_node->m_fun->decl)));
+    }
   b_in_callee.m_path.m_stack_depth++;
 
   dfs_traverse (callee_sm_inst, b_in_callee, ps, callee_node,
@@ -2115,6 +2185,8 @@ engine::expand_call_summary (const call_summary *summary_event,
       log ("state: %s", m_sm.get_state_name (state));
     }
 
+  const int caller_stack_depth = summary_event->m_depth;
+
   const supernode *callee_node
     = m_sg.get_node_for_function_entry (summary_event->m_edge->callee->get_fun ());
   const supernode *caller_node
@@ -2123,12 +2195,14 @@ engine::expand_call_summary (const call_summary *summary_event,
   checker_path *result = new checker_path ();
 
   // TODO:
-  result->add_event (new debug_event (summary_event->m_loc,
-				      summary_event->m_fndecl,
-				      summary_event->m_depth,
-				      print ("calling %qE from %qE",
-					     callee_node->m_fun->decl,
-					     caller_node->m_fun->decl)));
+  const superedge *sedge_call = m_sg.get_edge_for_call (summary_event->m_edge);
+  result->add_event (new edge_event (sedge_call,
+				     summary_event->m_loc,
+				     caller_node->m_fun->decl,
+				     caller_stack_depth,
+				     print ("calling %qE from %qE",
+					    callee_node->m_fun->decl,
+					    caller_node->m_fun->decl)));
 
   // TODO: body of function
 
@@ -2136,23 +2210,20 @@ engine::expand_call_summary (const call_summary *summary_event,
      the state change happen.  We can probably figure that out from
      the suffix summaries.  */
   {
-    const int callee_stack_depth = summary_event->m_depth + 1;
+    const int callee_stack_depth = caller_stack_depth + 1;
     const supernode *node = callee_node;
     while (node)
       {
 	/* FIXME: look in sfx_add/sfx_transition.  */
 
-	result->add_event (new debug_event (node->get_start_location (),
-					    node->m_fun->decl,
-					    callee_stack_depth,
-					    print ("SN: %i", node->m_index)));
+	add_events_for_node (result, node, callee_stack_depth);
 
 	/* Stmts.  */
 	int i;
 	gimple *stmt;
 	FOR_EACH_VEC_ELT (node->m_stmts, i, stmt)
 	  {
-	    if (m_verbosity >= 2)
+	    if (m_verbosity >= 1)
 	      {
 		pretty_printer pp;
 		pp_string (&pp, "stmt: ");
@@ -2238,20 +2309,15 @@ engine::expand_call_summary (const call_summary *summary_event,
       }
   }
 
-#if 0
-  result->add_event (new debug_event (callee_node->get_start_location (),
-				      callee_node->m_fun->decl,
-				      summary_event->m_depth + 1,
-				      print ("within %qE",
-					     callee_node->m_fun->decl)));
-#endif
-
-  result->add_event (new debug_event (summary_event->m_loc, // FIXME
-				      caller_node->m_fun->decl,
-				      summary_event->m_depth,
-				      print ("returning to %qE from %qE",
-					     caller_node->m_fun->decl,
-					     callee_node->m_fun->decl)));
+  const superedge *sedge_return
+    = m_sg.get_edge_for_return (summary_event->m_edge);
+  result->add_event (new edge_event (sedge_return,
+				     summary_event->m_loc,
+				     caller_node->m_fun->decl,
+				     caller_stack_depth,
+				     print ("returning to %qE from %qE",
+					    caller_node->m_fun->decl,
+					    callee_node->m_fun->decl)));
   return result;
 }
 
@@ -2328,6 +2394,11 @@ engine::prune_path (checker_path *path, tree var, state_machine::state_t state)
 	    path->delete_event (idx);
 	  break;
 
+	case EK_MESSAGE:
+	  if (m_verbosity < 1)
+	    path->delete_event (idx);
+	  break;
+
 	case EK_STATE_CHANGE:
 	  {
 	    state_change_event *state_change = (state_change_event *)base_event;
@@ -2352,8 +2423,9 @@ engine::prune_path (checker_path *path, tree var, state_machine::state_t state)
 	    inform (base_event->m_loc, "considering edge_event %i: %s",
 		    idx, base_event->m_desc);
 #endif
-	    // TODO: for now, filter them all:
-	    if (m_verbosity < 2)
+	    // TODO: for now, filter all intraprodcural edges:
+	    if (m_verbosity < 2
+		&& event->m_edge->m_kind == SUPEREDGE_CFG_EDGE)
 	      path->delete_event (idx);
 
 	    /* TODO: is this edge significant to var?
diff --git a/gcc/analyzer/supergraph.cc b/gcc/analyzer/supergraph.cc
index ab485b2..4dfabe6 100644
--- a/gcc/analyzer/supergraph.cc
+++ b/gcc/analyzer/supergraph.cc
@@ -152,8 +152,10 @@ supergraph::supergraph ()
 	    = ENTRY_BLOCK_PTR_FOR_FN (edge->callee->get_fun ());
 	  supernode *callee_supernode
 	    = *m_bb_to_initial_node.get (callee_cfg_block);
-	  add_callgraph_edge (caller_prev_supernode, callee_supernode,
-			      SUPEREDGE_CALL, edge);
+	  superedge *sedge
+	    = add_callgraph_edge (caller_prev_supernode, callee_supernode,
+				  SUPEREDGE_CALL, edge);
+	  m_cgraph_edge_to_call_superedge.put (edge, sedge);
 	}
     }
 
@@ -170,8 +172,10 @@ supergraph::supergraph ()
 	    = EXIT_BLOCK_PTR_FOR_FN (edge->callee->get_fun ());
 	  supernode *callee_supernode
 	    = *m_bb_to_initial_node.get (callee_cfg_block);
-	  add_callgraph_edge (callee_supernode, caller_next_supernode,
-			      SUPEREDGE_RETURN, edge);
+	  superedge *sedge
+	    = add_callgraph_edge (callee_supernode, caller_next_supernode,
+				  SUPEREDGE_RETURN, edge);
+	  m_cgraph_edge_to_return_superedge.put (edge, sedge);
 	}
     }
 
diff --git a/gcc/analyzer/supergraph.h b/gcc/analyzer/supergraph.h
index 52f86d2..c2c5aca 100644
--- a/gcc/analyzer/supergraph.h
+++ b/gcc/analyzer/supergraph.h
@@ -98,6 +98,18 @@ public:
 	      (m_cgraph_edge_to_caller_next_node).get (edge));
   }
 
+  superedge *get_edge_for_call (cgraph_edge *edge) const
+  {
+    return (*const_cast <cgraph_edge_to_superedge_t &>
+	      (m_cgraph_edge_to_call_superedge).get (edge));
+  }
+
+  superedge *get_edge_for_return (cgraph_edge *edge) const
+  {
+    return (*const_cast <cgraph_edge_to_superedge_t &>
+	      (m_cgraph_edge_to_return_superedge).get (edge));
+  }
+
   void dump_dot_to_pp (pretty_printer *pp, enum supergraph_dot_flags flags,
 		       const dot_annotator *a = NULL) const;
   void dump_dot_to_file (FILE *fp, enum supergraph_dot_flags flags,
@@ -128,6 +140,10 @@ private:
   typedef hash_map<cgraph_edge *, supernode *> cgraph_edge_to_node_t;
   cgraph_edge_to_node_t m_cgraph_edge_to_caller_prev_node;
   cgraph_edge_to_node_t m_cgraph_edge_to_caller_next_node;
+
+  typedef hash_map<cgraph_edge *, superedge *> cgraph_edge_to_superedge_t;
+  cgraph_edge_to_superedge_t m_cgraph_edge_to_call_superedge;
+  cgraph_edge_to_superedge_t m_cgraph_edge_to_return_superedge;
 };
 
 /* FIXME.  */
-- 
1.8.5.3

