From 9c6a907bf4fa600b781ebf3a6d473a7f08d355d2 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Thu, 7 Nov 2019 13:16:19 -0500
Subject: [PATCH 116/119] FIXME: fixup state_change; use it to avoid purging
 svalues needed for state_change_event generation; fix state purging

---
 gcc/analyzer/engine.cc        |  32 +++++----
 gcc/analyzer/exploded-graph.h |   3 +-
 gcc/analyzer/program-point.h  |  19 +++---
 gcc/analyzer/program-state.cc | 147 +++++++++++++++++++++++++++++++++++++-----
 gcc/analyzer/program-state.h  |  39 +++++++++--
 gcc/analyzer/region-model.cc  |   2 +
 gcc/analyzer/state-purge.cc   |  44 ++++++++-----
 gcc/analyzer/state-purge.h    |   2 +-
 gcc/analyzer/supergraph.cc    |   1 +
 gcc/analyzer/supergraph.h     |  10 +++
 10 files changed, 241 insertions(+), 58 deletions(-)

diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index 5b00c8f..dad96b9 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -131,6 +131,8 @@ void
 impl_region_model_context::remap_svalue_ids (const svalue_id_map &map)
 {
   m_new_state->remap_svalue_ids (map);
+  if (m_change)
+    m_change->remap_svalue_ids (map);
 }
 
 #if 0
@@ -164,6 +166,8 @@ impl_region_model_context::on_svalue_purge (svalue_id first_unused_sid,
       total += smap->on_svalue_purge (sm, sm_idx, first_unused_sid,
 				      map, this);
     }
+  if (m_change)
+    total += m_change->on_svalue_purge (first_unused_sid);
   return total;
 }
 
@@ -1178,8 +1182,8 @@ exploded_node::on_longjmp (exploded_graph &eg,
     = program_point::after_supernode (setjmp_point.get_supernode (),
 				      setjmp_point.get_call_string ());
 
-  exploded_node *next = eg.get_or_create_node (next_point, *new_state);
   state_change change; // FIXME
+  exploded_node *next = eg.get_or_create_node (next_point, *new_state, &change);
 
   /* Create custom exploded_edge for a longjmp.  */
   if (next)
@@ -1269,6 +1273,7 @@ exploded_edge::exploded_edge (exploded_node *src, exploded_node *dest,
 : dedge (src, dest), m_sedge (sedge), m_change (change),
   m_rewind_info (rewind_info)
 {
+  change.validate (src->get_state (), dest->get_state ());
 }
 
 /* exploded_edge's dtor.  */
@@ -1659,7 +1664,7 @@ exploded_graph::exploded_graph (const supergraph &sg, logger *logger,
   m_origin = get_or_create_node (program_point (function_point (NULL, NULL,
 								0, PK_ORIGIN),
 						call_string ()),
-				 program_state (ext_state));
+				 program_state (ext_state), NULL);
   for (int i = 0; i < m_sg.num_nodes (); i++)
     m_PK_AFTER_SUPERNODE_per_snode.quick_push (i);
 }
@@ -1694,7 +1699,7 @@ exploded_graph::add_function_entry (function *fun)
   program_state state (m_ext_state);
   state.m_region_model->push_frame (fun, NULL, NULL);
 
-  exploded_node *enode = get_or_create_node (point, state);
+  exploded_node *enode = get_or_create_node (point, state, NULL);
   /* We should never fail to add such a node.  */
   gcc_assert (enode);
   state_change change;
@@ -1703,11 +1708,14 @@ exploded_graph::add_function_entry (function *fun)
 }
 
 /* Get or create an exploded_node for (POINT, STATE).
-   If a new node is created, it is added to the worklist.  */
+   If a new node is created, it is added to the worklist.
+   If CHANGE is non-NULL, use it to suppress some purging of state,
+   to make generation of state_change_event instances easier.  */
 
 exploded_node *
 exploded_graph::get_or_create_node (const program_point &point,
-				    const program_state &state)
+				    const program_state &state,
+				    state_change *change)
 {
   LOG_FUNC (get_logger ());
   if (get_logger ())
@@ -1732,7 +1740,7 @@ exploded_graph::get_or_create_node (const program_point &point,
 
   /* Prune state to try to improve the chances of a cache hit,
      avoiding generating redundant nodes.  */
-  program_state pruned_state = state.prune_for_point (*this, point);
+  program_state pruned_state = state.prune_for_point (*this, point, change);
 
   pruned_state.validate (get_ext_state ());
 
@@ -2086,7 +2094,7 @@ exploded_graph::process_worklist ()
 			   states, adding to the worklist.  */
 			exploded_node *merged_enode
 			  = get_or_create_node (node->get_point (),
-						merged_state);
+						merged_state, &change);
 			if (merged_enode == NULL)
 			  continue;
 
@@ -2333,7 +2341,7 @@ exploded_graph::process_node (exploded_node *node)
 	      = program_point::before_stmt (point.get_supernode (), 0,
 					    point.get_call_string ());
 	    exploded_node *next
-	      = get_or_create_node (next_point, next_state);
+	      = get_or_create_node (next_point, next_state, &change);
 	    if (next)
 	      add_edge (node, next, NULL, change);
 	  }
@@ -2342,7 +2350,8 @@ exploded_graph::process_node (exploded_node *node)
 	    program_point next_point
 	      = program_point::after_supernode (point.get_supernode (),
 						point.get_call_string ());
-	    exploded_node *next = get_or_create_node (next_point, next_state);
+	    exploded_node *next = get_or_create_node (next_point, next_state,
+						      &change);
 	    if (next)
 	      add_edge (node, next, NULL, change);
 	  }
@@ -2397,7 +2406,7 @@ exploded_graph::process_node (exploded_node *node)
 	     : program_point::after_supernode (point.get_supernode (),
 					       point.get_call_string ()));
 	exploded_node *next = get_or_create_node (next_point,
-						  next_state);
+						  next_state, &change);
 	if (next)
 	  add_edge (node, next, NULL, change);
       }
@@ -2452,7 +2461,8 @@ exploded_graph::process_node (exploded_node *node)
 		continue;
 	      }
 
-	    exploded_node *next = get_or_create_node (next_point, next_state);
+	    exploded_node *next = get_or_create_node (next_point, next_state,
+						      &change);
 	    if (next)
 	      add_edge (node, next, succ, change);
 	  }
diff --git a/gcc/analyzer/exploded-graph.h b/gcc/analyzer/exploded-graph.h
index de3ec4b..2c72c1d 100644
--- a/gcc/analyzer/exploded-graph.h
+++ b/gcc/analyzer/exploded-graph.h
@@ -648,7 +648,8 @@ public:
   void process_node (exploded_node *node);
 
   exploded_node *get_or_create_node (const program_point &point,
-				     const program_state &state);
+				     const program_state &state,
+				     state_change *change);
   void add_edge (exploded_node *src, exploded_node *dest,
 		 const superedge *sedge,
 		 const state_change &change,
diff --git a/gcc/analyzer/program-point.h b/gcc/analyzer/program-point.h
index f657edf..49f6c05 100644
--- a/gcc/analyzer/program-point.h
+++ b/gcc/analyzer/program-point.h
@@ -83,13 +83,11 @@ public:
   {
     if (from_edge)
       {
-	gcc_assert (m_kind == PK_BEFORE_SUPERNODE);
-#if 0
-	gcc_assert (from_edge->get_kind () == SUPEREDGE_CFG_EDGE);
-#endif
+	gcc_checking_assert (m_kind == PK_BEFORE_SUPERNODE);
+	gcc_checking_assert (from_edge->get_kind () == SUPEREDGE_CFG_EDGE);
       }
     if (stmt_idx)
-      gcc_assert (m_kind == PK_BEFORE_STMT);
+      gcc_checking_assert (m_kind == PK_BEFORE_STMT);
   }
 
   void print (pretty_printer *pp, const format &f) const;
@@ -140,10 +138,8 @@ public:
   static function_point before_supernode (const supernode *supernode,
 					  const superedge *from_edge)
   {
-#if 0
     if (from_edge && from_edge->get_kind () != SUPEREDGE_CFG_EDGE)
       from_edge = NULL;
-#endif
     return function_point (supernode, from_edge, 0, PK_BEFORE_SUPERNODE);
   }
 
@@ -174,10 +170,15 @@ public:
   static int cmp_within_supernode (const function_point &point_a,
 				   const function_point &point_b);
 
-//private:
+ private:
   const supernode *m_supernode;
-  const superedge *m_from_edge; /* for PK_BEFORE_SUPERNODE.  */
+
+  /* For PK_BEFORE_SUPERNODE, and only for CFG edges.  */
+  const superedge *m_from_edge;
+
+  /* Only for PK_BEFORE_STMT.  */
   unsigned m_stmt_idx;
+
   enum point_kind m_kind;
 };
 
diff --git a/gcc/analyzer/program-state.cc b/gcc/analyzer/program-state.cc
index 364bfc7..b299f23 100644
--- a/gcc/analyzer/program-state.cc
+++ b/gcc/analyzer/program-state.cc
@@ -694,8 +694,11 @@ program_state::on_edge (exploded_graph &eg,
 
 program_state
 program_state::prune_for_point (exploded_graph &eg,
-				const program_point &point) const
+				const program_point &point,
+				state_change *change) const
 {
+  LOG_SCOPE (eg.get_logger ());
+
   function *fun = point.get_function ();
   if (!fun)
     return *this;
@@ -733,15 +736,29 @@ program_state::prune_for_point (exploded_graph &eg,
 		    = new_state.m_region_model->get_region (rid);
 		  svalue_id sid = region->get_value_direct ();
 		  if (!sid.null_p ())
-		    if (!new_state.can_purge_p (eg.get_ext_state (), sid))
-		      {
-			/* (currently only state maps can keep things
-			   alive).  */
-			eg.log ("not purging RID: %i for %qE"
-				" (used by state map)",
-				rid.as_int (), var);
-			continue;
-		      }
+		    {
+		      if (!new_state.can_purge_p (eg.get_ext_state (), sid))
+			{
+			  /* (currently only state maps can keep things
+			     alive).  */
+			  eg.log ("not purging RID: %i for %qE"
+				  " (used by state map)",
+				  rid.as_int (), var);
+			  continue;
+			}
+
+		      /* Don't purge regions containing svalues that
+			 have a change of sm-state, to make it easier to
+			 generate state_change_event messages.  */
+		      if (change)
+			if (change->affects_p (sid))
+			  {
+			    eg.log ("not purging RID: %i for %qE"
+				    " (affected by change)",
+				    rid.as_int (), var);
+			    continue;
+			  }
+		    }
 		  purgeable_ssa_regions.add_region (rid);
 		  ssa_names_to_purge.safe_push (var);
 		  eg.log ("purging RID: %i for %qE", rid.as_int (), var);
@@ -770,7 +787,7 @@ program_state::prune_for_point (exploded_graph &eg,
   impl_region_model_context ctxt (eg, NULL,
 				  this,
 				  &new_state,
-				  NULL, // FIXME: state_change
+				  change,
 				  NULL);
   new_state.m_region_model->purge_unused_svalues (&stats, &ctxt);
   eg.log ("num svalues purged: %i", stats.m_num_svalues);
@@ -920,24 +937,65 @@ state_change::sm_change::dump (pretty_printer *pp,
 {
   const state_machine &sm = get_sm (ext_state);
   pp_string (pp, "(");
+#if 0
   m_old_sid.print (pp);
   pp_string (pp, "/");
+#endif
   m_new_sid.print (pp);
+#if 0
   pp_string (pp, "/origin: ");
   m_old_origin_sid.print (pp);
+#endif
   pp_printf (pp, ": %s: %qs -> %qs)",
 	     sm.get_name (),
 	     sm.get_state_name (m_old_state),
 	     sm.get_state_name (m_new_state));
 }
 
-/* FIXME.  */
+/* Remap all svalue_ids in this change according to MAP.  */
+
+void
+state_change::sm_change::remap_svalue_ids (const svalue_id_map &map)
+{
+  // FIXME: we only update the "new" sids, not the "old" ones.
+  map.update (&m_new_sid);
+}
+
+/* Purge any svalue_ids >= FIRST_UNUSED_SID.
+   Return the number of states that were purged.  */
+
+int
+state_change::sm_change::on_svalue_purge (svalue_id first_unused_sid)
+{
+  if (m_new_sid.as_int () >= first_unused_sid.as_int ())
+    {
+      m_new_sid = svalue_id::null ();
+      return 1;
+    }
+
+  return 0;
+}
+
+/* Assert that this object is sane.  */
+
+void
+state_change::sm_change::validate (const program_state &old_state,
+				   const program_state &new_state) const
+{
+#if 0
+  m_old_sid.validate (*old_state.m_region_model);
+  m_old_origin_sid.validate (*old_state.m_region_model);
+#endif
+  m_new_sid.validate (*new_state.m_region_model);
+}
+
+/* state_change's ctor.  */
 
 state_change::state_change ()
 {
 }
 
-/* FIXME.  */
+/* state_change's copy ctor.  */
 
 state_change::state_change (const state_change &other)
 : m_sm_changes (other.m_sm_changes.length ())
@@ -948,7 +1006,7 @@ state_change::state_change (const state_change &other)
     m_sm_changes.quick_push (*change);
 }
 
-/* FIXME.  */
+/* Record a state-machine state change.  */
 
 void
 state_change::add_sm_change (int sm_idx,
@@ -963,7 +1021,23 @@ state_change::add_sm_change (int sm_idx,
 				     old_state, new_state));
 }
 
-/* FIXME.  */
+/* Return true if SID (in the new state) was affected by any
+   sm-state changes.  */
+
+bool
+state_change::affects_p (svalue_id sid) const
+{
+  unsigned i;
+  sm_change *change;
+  FOR_EACH_VEC_ELT (m_sm_changes, i, change)
+    {
+      if (sid == change->m_new_sid)
+	return true;
+    }
+  return false;
+}
+
+/* Dump this state_change to PP.  */
 
 void
 state_change::dump (pretty_printer *pp,
@@ -979,7 +1053,7 @@ state_change::dump (pretty_printer *pp,
     }
 }
 
-/* FIXME.  */
+/* Dump this state_change to stderr.  */
 
 void
 state_change::dump (const extrinsic_state &ext_state) const
@@ -992,6 +1066,47 @@ state_change::dump (const extrinsic_state &ext_state) const
   pp_flush (&pp);
 }
 
+/* Remap all svalue_ids in this state_change according to MAP.  */
+
+void
+state_change::remap_svalue_ids (const svalue_id_map &map)
+{
+  unsigned i;
+  sm_change *change;
+  FOR_EACH_VEC_ELT (m_sm_changes, i, change)
+    change->remap_svalue_ids (map);
+}
+
+/* Purge any svalue_ids >= FIRST_UNUSED_SID.
+   Return the number of states that were purged.  */
+
+int
+state_change::on_svalue_purge (svalue_id first_unused_sid)
+{
+  int result = 0;
+  unsigned i;
+  sm_change *change;
+  FOR_EACH_VEC_ELT (m_sm_changes, i, change)
+    result += change->on_svalue_purge (first_unused_sid);
+  return result;
+}
+
+/* Assert that this object is sane.  */
+
+void
+state_change::validate (const program_state &old_state,
+			const program_state &new_state) const
+{
+  /* Skip this in a release build.  */
+#if !CHECKING_P
+  return;
+#endif
+  unsigned i;
+  sm_change *change;
+  FOR_EACH_VEC_ELT (m_sm_changes, i, change)
+    change->validate (old_state, new_state);
+}
+
 #if CHECKING_P
 
 namespace selftest {
diff --git a/gcc/analyzer/program-state.h b/gcc/analyzer/program-state.h
index 27c129a..a522789 100644
--- a/gcc/analyzer/program-state.h
+++ b/gcc/analyzer/program-state.h
@@ -243,7 +243,8 @@ public:
 		state_change *change);
 
   program_state prune_for_point (exploded_graph &eg,
-				 const program_point &point) const;
+				 const program_point &point,
+				 state_change *change) const;
 
   void remap_svalue_ids (const svalue_id_map &map);
 
@@ -277,7 +278,11 @@ public:
   auto_delete_vec<sm_state_map> m_checker_states;
 };
 
-/* FIXME.  */
+/* A class for recording "interesting" state changes.
+   This is used for annotating edges in the GraphViz output of the
+   exploded_graph, and for recording sm-state-changes, so that
+   values that change aren't purged (to make it easier to generate
+   state_change_event instances in the diagnostic_path).  */
 
 class state_change
 {
@@ -285,13 +290,19 @@ class state_change
   struct sm_change
   {
     sm_change (int sm_idx,
-	       svalue_id old_sid, svalue_id new_sid,
-	       svalue_id old_origin_sid,
+	       svalue_id old_sid ATTRIBUTE_UNUSED,
+	       svalue_id new_sid,
+	       svalue_id old_origin_sid ATTRIBUTE_UNUSED,
 	       state_machine::state_t old_state,
 	       state_machine::state_t new_state)
     : m_sm_idx (sm_idx),
-      m_old_sid (old_sid), m_new_sid (new_sid),
+#if 0
+      m_old_sid (old_sid),
+#endif
+      m_new_sid (new_sid),
+#if 0
       m_old_origin_sid (old_origin_sid),
+#endif
       m_old_state (old_state), m_new_state (new_state)
     {}
 
@@ -302,10 +313,20 @@ class state_change
 
     void dump (pretty_printer *pp, const extrinsic_state &ext_state) const;
 
+    void remap_svalue_ids (const svalue_id_map &map);
+    int on_svalue_purge (svalue_id first_unused_sid);
+
+    void validate (const program_state &old_state,
+		   const program_state &new_state) const;
+
     int m_sm_idx;
+#if 0
     svalue_id m_old_sid;
+#endif
     svalue_id m_new_sid;
+#if 0
     svalue_id m_old_origin_sid;
+#endif
     state_machine::state_t m_old_state;
     state_machine::state_t m_new_state;
   };
@@ -319,9 +340,17 @@ class state_change
 		      state_machine::state_t old_state,
 		      state_machine::state_t new_state);
 
+  bool affects_p (svalue_id sid) const;
+
   void dump (pretty_printer *pp, const extrinsic_state &ext_state) const;
   void dump (const extrinsic_state &ext_state) const;
 
+  void remap_svalue_ids (const svalue_id_map &map);
+  int on_svalue_purge (svalue_id first_unused_sid);
+
+  void validate (const program_state &old_state,
+		 const program_state &new_state) const;
+
  private:
   auto_vec<sm_change> m_sm_changes;
 };
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 2f7e521..f375978 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -6130,6 +6130,8 @@ region_model::purge_unused_svalues (purge_stats *stats,
   // FIXME: might want to avoid a vfunc call just to do logging here:
   logger *logger = ctxt ? ctxt->get_logger () : NULL;
 
+  LOG_SCOPE (logger);
+
   //svalue_id_set used (*this);
   auto_sbitmap used (m_svalues.length ());
   bitmap_clear (used); // FIXME: is this needed?
diff --git a/gcc/analyzer/state-purge.cc b/gcc/analyzer/state-purge.cc
index ab929b4..3428d39 100644
--- a/gcc/analyzer/state-purge.cc
+++ b/gcc/analyzer/state-purge.cc
@@ -187,7 +187,7 @@ state_purge_per_ssa_name::state_purge_per_ssa_name (const state_purge_map &map,
     while (worklist.length () > 0)
       {
 	function_point point = worklist.pop ();
-	process_point (point, &worklist, map.get_logger ());
+	process_point (point, &worklist, map);
     }
   }
 
@@ -247,11 +247,9 @@ state_purge_per_ssa_name::add_to_worklist (const function_point &point,
       logger->end_log_line ();
     }
 
-#if 0
   gcc_assert (point.get_function () == m_fun);
   if (point.get_from_edge ())
     gcc_assert (point.get_from_edge ()->get_kind () == SUPEREDGE_CFG_EDGE);
-#endif
 
   if (m_points_needing_name.contains (point))
     {
@@ -273,8 +271,9 @@ state_purge_per_ssa_name::add_to_worklist (const function_point &point,
 void
 state_purge_per_ssa_name::process_point (const function_point &point,
 					 auto_vec<function_point> *worklist,
-					 logger *logger)
+					 const state_purge_map &map)
 {
+  logger *logger = map.get_logger ();
   LOG_FUNC (logger);
   if (logger)
     {
@@ -313,15 +312,29 @@ state_purge_per_ssa_name::process_point (const function_point &point,
 	  }
 
 	/* Add given pred to worklist.  */
-	if (point.m_from_edge)
+	if (point.get_from_edge ())
 	  {
-	    if (/*(point.m_from_edge->get_kind () == SUPEREDGE_CFG_EDGE
-		 || (point.m_from_edge->get_kind ()
-		     == SUPEREDGE_INTRAPROCEDURAL_CALL))
-		     && */point.m_from_edge->m_src)
-	      add_to_worklist
-		(function_point::after_supernode (point.m_from_edge->m_src),
-		 worklist, logger);
+	    gcc_assert (point.get_from_edge ()->m_src);
+	    add_to_worklist
+	      (function_point::after_supernode (point.get_from_edge ()->m_src),
+	       worklist, logger);
+	  }
+	else
+	  {
+	    /* Add any intraprocedually edge for a call.  */
+	    if (snode->m_returning_call)
+	      {
+		cgraph_edge *cedge
+		  = supergraph_call_edge (snode->m_fun,
+					  snode->m_returning_call);
+		gcc_assert (cedge);
+		superedge *sedge
+		  = map.get_sg ().get_intraprocedural_edge_for_call (cedge);
+		gcc_assert (sedge);
+		add_to_worklist
+		  (function_point::after_supernode (sedge->m_src),
+		   worklist, logger);
+	      }
 	  }
       }
       break;
@@ -334,9 +347,9 @@ state_purge_per_ssa_name::process_point (const function_point &point,
 	      logger->log ("def stmt; terminating");
 	    return;
 	  }
-	if (point.m_stmt_idx > 0)
-	  add_to_worklist (function_point::before_stmt (snode,
-							point.m_stmt_idx - 1),
+	if (point.get_stmt_idx () > 0)
+	  add_to_worklist (function_point::before_stmt
+			     (snode, point.get_stmt_idx () - 1),
 			   worklist, logger);
 	else
 	{
@@ -403,6 +416,7 @@ state_purge_annotator::add_node_annotations (pretty_printer *pp,
    pp_left_brace (pp);
    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));
 
diff --git a/gcc/analyzer/state-purge.h b/gcc/analyzer/state-purge.h
index a1d73d1..a86afc2 100644
--- a/gcc/analyzer/state-purge.h
+++ b/gcc/analyzer/state-purge.h
@@ -139,7 +139,7 @@ private:
 
   void process_point (const function_point &point,
 		      auto_vec<function_point> *worklist,
-		      logger *logger);
+		      const state_purge_map &map);
 
   typedef hash_set<function_point> point_set_t;
   point_set_t m_points_needing_name;
diff --git a/gcc/analyzer/supergraph.cc b/gcc/analyzer/supergraph.cc
index d821e10..da5b13a 100644
--- a/gcc/analyzer/supergraph.cc
+++ b/gcc/analyzer/supergraph.cc
@@ -217,6 +217,7 @@ supergraph::supergraph (logger *logger)
 				       SUPEREDGE_INTRAPROCEDURAL_CALL,
 				       edge);
 	  add_edge (sedge);
+	  m_cgraph_edge_to_intraproc_superedge.put (edge, sedge);
 	}
 
     }
diff --git a/gcc/analyzer/supergraph.h b/gcc/analyzer/supergraph.h
index 779a33e..78ae93a 100644
--- a/gcc/analyzer/supergraph.h
+++ b/gcc/analyzer/supergraph.h
@@ -128,6 +128,12 @@ public:
 	      (m_cgraph_edge_to_return_superedge).get (edge));
   }
 
+  superedge *get_intraprocedural_edge_for_call (cgraph_edge *edge) const
+  {
+    return (*const_cast <cgraph_edge_to_intraproc_superedge_t &>
+	      (m_cgraph_edge_to_intraproc_superedge).get (edge));
+  }
+
   cfg_superedge *get_edge_for_cfg_edge (edge e) const
   {
     return (*const_cast <cfg_edge_to_cfg_superedge_t &>
@@ -190,6 +196,10 @@ private:
     cgraph_edge_to_return_superedge_t;
   cgraph_edge_to_return_superedge_t m_cgraph_edge_to_return_superedge;
 
+  typedef ordered_hash_map<cgraph_edge *, superedge *>
+    cgraph_edge_to_intraproc_superedge_t;
+  cgraph_edge_to_intraproc_superedge_t m_cgraph_edge_to_intraproc_superedge;
+
   typedef ordered_hash_map<gimple *, supernode *> stmt_to_node_t;
   stmt_to_node_t m_stmt_to_node_t;
 
-- 
1.8.5.3

