From dbd48a2af65746eee76b5ea22d31bbbd03f3c942 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Mon, 29 Apr 2019 22:14:02 -0400
Subject: [PATCH 210/217] FIXME: impl-4: call on_assignment for phi nodes

---
 gcc/analyzer/impl-4.cc | 87 ++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 63 insertions(+), 24 deletions(-)

diff --git a/gcc/analyzer/impl-4.cc b/gcc/analyzer/impl-4.cc
index 41195de..9d91553 100644
--- a/gcc/analyzer/impl-4.cc
+++ b/gcc/analyzer/impl-4.cc
@@ -122,14 +122,16 @@ class program_point
 {
 public:
   program_point (const supernode *supernode,
+		 const superedge *from_edge,
 		 unsigned stmt_idx,
 		 enum point_kind kind)
-  : m_supernode (supernode), m_stmt_idx (stmt_idx), m_kind (kind)
+  : m_supernode (supernode), m_from_edge (from_edge),
+    m_stmt_idx (stmt_idx), m_kind (kind)
   {
   }
 
   const supernode *m_supernode;
-  //const superedge *m_from_edge; /* for PK_BEFORE_SUPERNODE.  */
+  const superedge *m_from_edge; /* for PK_BEFORE_SUPERNODE.  */
   unsigned m_stmt_idx;
   enum point_kind m_kind;
 
@@ -143,6 +145,7 @@ public:
   bool operator== (const program_point &other) const
   {
     return (m_supernode == other.m_supernode
+	    && m_from_edge == other.m_from_edge
 	    && m_stmt_idx == other.m_stmt_idx
 	    && m_kind == other.m_kind);
   }
@@ -158,41 +161,48 @@ public:
 
   const gimple *get_stmt () const;
 
+  path_var make_path_var (tree expr) const
+  {
+    return path_var (expr, 0 /* FIXME: stack_depth */);
+  }
+
   static program_point from_function_entry (const supergraph &sg,
 					    function *fun)
   {
-    return before_supernode (sg.get_node_for_function_entry (fun));
+    return before_supernode (sg.get_node_for_function_entry (fun),
+			     NULL);
   }
 
-  static program_point before_supernode (const supernode *supernode)
+  static program_point before_supernode (const supernode *supernode,
+					 const superedge *from_edge)
   {
-    return program_point (supernode, 0, PK_BEFORE_SUPERNODE);
+    return program_point (supernode, from_edge, 0, PK_BEFORE_SUPERNODE);
   }
 
   static program_point before_stmt (const supernode *supernode,
 				    unsigned stmt_idx)
   {
-    return program_point (supernode, stmt_idx, PK_BEFORE_STMT);
+    return program_point (supernode, NULL, stmt_idx, PK_BEFORE_STMT);
   }
 
   static program_point after_stmt (const supernode *supernode,
 				   unsigned stmt_idx)
   {
-    return program_point (supernode, stmt_idx, PK_AFTER_STMT);
+    return program_point (supernode, NULL, stmt_idx, PK_AFTER_STMT);
   }
 
   static program_point after_supernode (const supernode *supernode)
   {
-    return program_point (supernode, 0, PK_AFTER_SUPERNODE);
+    return program_point (supernode, NULL, 0, PK_AFTER_SUPERNODE);
   }
 
   static program_point empty ()
   {
-    return program_point (NULL, 0, PK_EMPTY);
+    return program_point (NULL, NULL, 0, PK_EMPTY);
   }
   static program_point deleted ()
   {
-    return program_point (NULL, 0, PK_DELETED);
+    return program_point (NULL, NULL, 0, PK_DELETED);
   }
 };
 
@@ -1057,9 +1067,13 @@ program_point::print (pretty_printer *pp) const
 
     case PK_BEFORE_SUPERNODE:
       {
-	pp_printf (pp, "before SN: %i", m_supernode->m_index);
+	if (m_from_edge)
+	  pp_printf (pp, "before SN: %i (from SN: %i)",
+		     m_supernode->m_index, m_from_edge->m_src->m_index);
+	else
+	  pp_printf (pp, "before SN: %i (NULL from-edge)",
+		     m_supernode->m_index);
 	pp_newline (pp);
-	// TODO: print in-edge info
 	for (gphi_iterator gpi
 	       = const_cast<supernode *>(get_supernode ())->start_phis ();
 	     !gsi_end_p (gpi); gsi_next (&gpi))
@@ -1212,7 +1226,8 @@ public:
   {
   }
 
-  void on_transition (const supernode *node, const gimple *stmt,
+  void on_transition (const supernode *node  ATTRIBUTE_UNUSED,
+		      const gimple *stmt  ATTRIBUTE_UNUSED,
 		      tree var,
 		      state_machine::state_t from,
 		      state_machine::state_t to,
@@ -1449,7 +1464,7 @@ exploded_node::on_stmt (const exploded_graph &eg) const
 {
   const program_point &point = m_ps.m_point;
   const program_state &old_state = m_ps.m_state;
-  const path_state &old_ps = old_state.m_path_state;
+  //const path_state &old_ps = old_state.m_path_state;
 
   program_state new_state (old_state);
   path_state *new_ps = &new_state.m_path_state;
@@ -1670,18 +1685,18 @@ exploded_edge::dump_dot (graphviz_out *gv) const
 	break;
       }
 
-  m_src->dump_dot_id (gv->m_pp);
-  pp_string (gv->m_pp, " -> ");
-  m_dest->dump_dot_id (gv->m_pp);
-  pp_printf (gv->m_pp,
+  m_src->dump_dot_id (pp);
+  pp_string (pp, " -> ");
+  m_dest->dump_dot_id (pp);
+  pp_printf (pp,
 	     (" [style=%s, color=%s, weight=%d, constraint=%s,"
 	      " headlabel=\""),
 	     style, color, weight, constraint);
 
   if (m_sedge)
-    m_sedge->dump_label_to_pp (gv->m_pp);
+    m_sedge->dump_label_to_pp (pp);
 
-  pp_printf (gv->m_pp, "\"];\n");
+  pp_printf (pp, "\"];\n");
 }
 
 
@@ -1694,7 +1709,7 @@ exploded_graph::exploded_graph (const supergraph &sg, logger *logger,
 				int verbosity)
 : log_user (logger), m_sg (sg), m_ext_state (ext_state), m_verbosity (verbosity)
 {
-  m_entrypoint = get_or_create_node (program_point (NULL, 0, PK_ORIGIN),
+  m_entrypoint = get_or_create_node (program_point (NULL, NULL, 0, PK_ORIGIN),
 				     program_state (ext_state));
 }
 
@@ -1793,19 +1808,43 @@ exploded_graph::process_node (exploded_node *node)
 
     case PK_BEFORE_SUPERNODE:
       {
+	program_state next_state (state);
+
+	for (gphi_iterator gpi
+	       = const_cast<supernode *>(node->get_supernode ())->start_phis ();
+	     !gsi_end_p (gpi); gsi_next (&gpi))
+	  {
+	    gphi *phi = gpi.phi ();
+
+	    const cfg_superedge *last_cfg_superedge
+	      = point.m_from_edge->dyn_cast_cfg_superedge ();
+	    gcc_assert (last_cfg_superedge);
+	    // FIXME: this ought to be an as_a<>
+
+	    tree src = last_cfg_superedge->get_phi_arg (phi);
+	    tree lhs = gimple_phi_result (phi);
+
+	    /* Update next_state based on phi.  */
+	    node->on_assignment (*this,
+				 point.make_path_var (lhs),
+				 point.make_path_var (src),
+				 state,
+				 &next_state);
+	  }
+
 	if (point.m_supernode->m_stmts.length () > 0)
 	  {
 	    program_point next_point
 	      = program_point::before_stmt (point.m_supernode, 0);
 	    exploded_node *next
-	      = get_or_create_node (next_point, state);
+	      = get_or_create_node (next_point, next_state);
 	    add_edge (node, next, NULL);
 	  }
 	else
 	  {
 	    program_point next_point
 	      = program_point::after_supernode (point.m_supernode);
-	    exploded_node *next = get_or_create_node (next_point, state);
+	    exploded_node *next = get_or_create_node (next_point, next_state);
 	    add_edge (node, next, NULL);
 	  }
       }
@@ -1874,7 +1913,7 @@ exploded_graph::process_node (exploded_node *node)
 	     }
 #endif
 	    program_point next_point
-	      = program_point::before_supernode (succ->m_dest);
+	      = program_point::before_supernode (succ->m_dest, succ);
 	    exploded_node *next = get_or_create_node (next_point, next_state);
 	    add_edge (node, next, succ);
 	  }
-- 
1.8.5.3

