From e055a6b606c49583c82266da7a7d9b4bfde905fd Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Mon, 26 Aug 2019 13:52:54 -0400
Subject: [PATCH 097/124] FIXME: undo "FIXME: WIP on making
 purge_unused_svalues also purge unused regions"

---
 gcc/analyzer/region-model.cc | 177 +++++--------------------------------------
 gcc/analyzer/region-model.h  |   2 +-
 2 files changed, 20 insertions(+), 159 deletions(-)

diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index ba947ed..9562b6f 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -1281,18 +1281,6 @@ PUSH_IGNORE_WFORMAT
 POP_IGNORE_WFORMAT
 }
 
-/* Implementation of region::walk_for_canonicalization vfunc for
-   region.  */
-
-void
-region::walk_for_canonicalization (canonicalization *c) const
-{
-  if (!m_parent_rid.null_p ())
-    c->walk_rid (m_parent_rid);
-  if (!m_sval_id.null_p ())
-    c->walk_sid (m_sval_id);
-}
-
 /* class map_region : public region.  */
 
 /* map_region's copy ctor.  */
@@ -1714,8 +1702,6 @@ map_region::can_merge_p (const map_region *map_region_a,
 void
 map_region::walk_for_canonicalization (canonicalization *c) const
 {
-  region::walk_for_canonicalization (c);
-
   auto_vec<tree> keys (m_map.elements ());
   for (map_t::iterator iter = m_map.begin ();
        iter != m_map.end ();
@@ -2055,8 +2041,6 @@ stack_region::can_merge_p (const stack_region *stack_region_a,
 void
 stack_region::walk_for_canonicalization (canonicalization *c) const
 {
-  region::walk_for_canonicalization (c);
-
   int i;
   region_id *frame_rid;
   FOR_EACH_VEC_ELT (m_frame_rids, i, frame_rid)
@@ -2165,10 +2149,8 @@ heap_region::can_merge_p (const heap_region *heap_a ATTRIBUTE_UNUSED,
    heap_region.  */
 
 void
-heap_region::walk_for_canonicalization (canonicalization *c) const
+heap_region::walk_for_canonicalization (canonicalization *) const
 {
-  region::walk_for_canonicalization (c);
-
   /* Empty.  */
 }
 
@@ -2521,8 +2503,6 @@ root_region::add_to_hash (inchash::hash &hstate) const
 void
 root_region::walk_for_canonicalization (canonicalization *c) const
 {
-  region::walk_for_canonicalization (c);
-
   c->walk_rid (m_stack_rid);
   c->walk_rid (m_globals_rid);
   c->walk_rid (m_heap_rid);
@@ -3189,26 +3169,6 @@ region_model::canonicalize (region_model_context *ctxt)
      rids and sids, generating a rid and sid map.  */
   canonicalization c (*this);
 
-#if 0
-  /* FIXME: (0):
-     Eliminate redundant svalue assignments.  */
-  {
-    unsigned i;
-    region *region;
-    FOR_EACH_VEC_ELT (m_regions, i, region)
-      {
-	svalue_id sid = region->get_value_direct ();
-	if (sid.null_p ())
-	  continue;
-	svalue *sval = get_svalue (sid);
-	if (poisoned_svalue *psval = sval->dyn_cast_poisoned_svalue ())
-	  if (psval->get_poison_kind () == POISON_KIND_UNINIT)
-	    if (region->get_kind () != RK_STACK)
-	      region->set_value (*this, svalue_id::null ());
-      }
-  }
-#endif
-
   /* (1): Walk all svalues, putting poisoned values first, then
      constants, sorting the constants (thus imposing an ordering on any
      constants that are purely referenced by constraints).
@@ -4729,29 +4689,16 @@ region_model::get_region (region_id rid) const
 class restrict_to_used_svalues : public purge_criteria
 {
 public:
-#if 1
-  restrict_to_used_svalues (const svalue_id_map &sid_map)
-  : m_sid_map (sid_map) {}
-#else
   restrict_to_used_svalues (const auto_sbitmap &used) : m_used (used) {}
-#endif
 
   bool should_purge_p (svalue_id sid) const FINAL OVERRIDE
   {
     gcc_assert (!sid.null_p ());
-#if 1
-    return m_sid_map.get_dst_for_src (sid).null_p ();
-#else
     return !bitmap_bit_p (m_used, sid.as_int ());
-#endif
   }
 
 private:
-#if 1
-  const svalue_id_map &m_sid_map;
-#else
   const auto_sbitmap &m_used;
-#endif
 };
 
 /* Remove unused svalues from this model, accumulating stats into STATS.
@@ -4785,46 +4732,14 @@ 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;
 
-  // FIXME:
-  /* Walk the regions, marking rids that we care about, and sids
-     that are used by them.  */
-  /* FIXME:
-     walk stack frames
-     walk globals
-       mark regions within them that have values
-       mark regions that are pointed to
-     purge anything that isn't reached
-        but what about leaked heap regions?
-        presumably we also need to mark svalues that have sm-state
-   */
-  canonicalization c (*this);
-  c.walk_rid (m_root_rid);
+  //svalue_id_set used (*this);
+  auto_sbitmap used (m_svalues.length ());
+  bitmap_clear (used); // FIXME: is this needed?
 
   if (known_used_sid)
     if (!known_used_sid->null_p ())
-      c.walk_sid (*known_used_sid);
-
-#if 0
-  // FIXME: is get_sids_with_sm_state needed?
-  /* Walk the regions, marking those that have a sid with sm-state.  */
-  if (ctxt)
-    {
-      auto_sbitmap sids_with_sm_state (m_svalues.length ());
-      bitmap_clear (sids_with_sm_state); // FIXME: is this needed?
-      ctxt->get_sids_with_sm_state (&sids_with_sm_state);
-      unsigned i;
-      region *r;
-      FOR_EACH_VEC_ELT (m_regions, i, r)
-	{
-	  svalue_id sid = r->get_value_direct ();
-	  if (!sid.null_p ())
-	    if (bitmap_bit_p (sids_with_sm_state, sid.as_int ()))
-	      c.walk_rid (region_id::from_int (i));
-	}
-    }
-#endif
+      bitmap_set_bit (used, known_used_sid->as_int ());
 
-#if 0
   /* Walk the regions, marking sids that are used.  */
   unsigned i;
   region *r;
@@ -4832,27 +4747,15 @@ region_model::purge_unused_svalues (purge_stats *stats,
     {
       svalue_id sid = r->get_value_direct ();
       if (!sid.null_p ())
-	{
-#if 0
-	  /* FIXME: don't preserve uninit values, apart from
-	     the one in the stack?  */
-	  svalue *sval = get_svalue (sid);
-	  if (poisoned_svalue *psval = sval->dyn_cast_poisoned_svalue ())
-	    if (psval->get_poison_kind () == POISON_KIND_UNINIT)
-	      continue;
-#endif
-	  bitmap_set_bit (used_sids, sid.as_int ());
-	}
+	bitmap_set_bit (used, sid.as_int ());
     }
-#endif
 
   /* Now purge any constraints involving svalues we don't care about.  */
-  restrict_to_used_svalues criterion (c.m_sid_map);
+  restrict_to_used_svalues criterion (used);
   m_constraints->purge (criterion, stats);
 
   /* Mark any sids that are in constraints that survived.  */
   {
-  unsigned i;
     equiv_class *ec;
     FOR_EACH_VEC_ELT (m_constraints->m_equiv_classes, i, ec)
       {
@@ -4861,7 +4764,7 @@ region_model::purge_unused_svalues (purge_stats *stats,
 	FOR_EACH_VEC_ELT (ec->m_vars, j, sid)
 	  {
 	    gcc_assert (!sid->null_p ());
-	    c.walk_sid (*sid);
+	    bitmap_set_bit (used, sid->as_int ());
 	  }
 	// FIXME: should we just do this for constants?
 	// is everything else purged?
@@ -4874,13 +4777,12 @@ region_model::purge_unused_svalues (purge_stats *stats,
   if (ctxt)
     for (unsigned i = 0; i < m_svalues.length (); i++)
       {
-	if (!bitmap_bit_p (used_sids, i))
+	if (!bitmap_bit_p (used, i))
 	  if (!ctxt->can_purge_p (svalue_id::from_int (i)))
-	    bitmap_set_bit (used_sids, i);
+	    bitmap_set_bit (used, i);
       }
 #endif
 
-#if 0
   /* Build a mapping from old-sid to new-sid so that we can preserve
      order of the used IDs and move all redundant ones to the end.
      Iterate though svalue IDs, adding used ones to the front of
@@ -4891,7 +4793,7 @@ region_model::purge_unused_svalues (purge_stats *stats,
   for (unsigned i = 0; i < m_svalues.length (); i++)
     {
       svalue_id src (svalue_id::from_int (i));
-      if (bitmap_bit_p (used_sids, i))
+      if (bitmap_bit_p (used, i))
 	{
 	  if (logger)
 	    logger->log ("sv%i is used", i);
@@ -4906,78 +4808,38 @@ region_model::purge_unused_svalues (purge_stats *stats,
     }
   /* The two insertion points should have met.  */
   gcc_assert (next_used_new_sid == after_next_unused_new_sid);
-#endif
-
-  /* We've finished traversing.  Make a note of the limit to which
-     IDs were reached, in the IDs.  */
-  int first_unused_sid = c.m_next_sid_int;
-  int first_unused_rid = c.m_next_rid_int;
 
-  /* Ensure the map is fully populated, moving all unreferenced sids
-     and rids to the end, so that we do the purging later on, and we
-     capture which ones are to be purged.  */
-  for (unsigned i = 0; i < m_svalues.length (); i++)
-    {
-      svalue_id src (svalue_id::from_int (i));
-      c.walk_sid (src);
-    }
-  for (unsigned i = 0; i < m_regions.length (); i++)
-    {
-      region_id src (region_id::from_int (i));
-      c.walk_rid (src);
-    }
-
-  // FIXME:
-  /* Now walk the regions and the constraints, remapping sids and rids,
-     so that all the redundant regions and svalues are at the end.  */
-  remap_region_ids (c.m_rid_map);
-  remap_svalue_ids (c.m_sid_map);
-#if 0
+  /* Now walk the regions and the constraints, remapping sids,
+     so that all the redundant svalues are at the end.  */
+  remap_svalue_ids (map);
   if (logger)
     logger->log ("map: %s", map.to_str ().c_str ());
-#endif
 
   /* Notify any client about the remapping and pending deletion.  */
   // FIXME: potentially this could trigger leak warnings
   if (ctxt)
     {
-      ctxt->remap_svalue_ids (c.m_sid_map);
-      //ctxt->remap_region_ids (c.m_rid_map);
+      ctxt->remap_svalue_ids (map);
       stats->m_num_client_items +=
-	ctxt->on_svalue_purge (svalue_id::from_int (first_unused_sid),
-			       c.m_sid_map);
+	ctxt->on_svalue_purge (svalue_id::from_int (next_used_new_sid), map);
     }
 
   /* Drop the redundant svalues from the end of the vector.  */
-  while ((signed)m_svalues.length () > first_unused_sid)
+  while ((signed)m_svalues.length () > next_used_new_sid)
     {
       if (logger)
 	{
 	  svalue_id victim = svalue_id::from_int (m_svalues.length () - 1);
 	  logger->log ("deleting sv%i (was sv%i)",
 		       victim.as_int (),
-		       c.m_sid_map.get_src_for_dst (victim).as_int ());
+		       map.get_src_for_dst (victim).as_int ());
 	}
       delete m_svalues.pop ();
       stats->m_num_svalues++;
     }
 
-  /* Drop the redundant regions from the end of the vector.  */
-  while ((signed)m_regions.length () > first_unused_rid)
-    {
-      if (logger)
-	{
-	  region_id victim = region_id::from_int (m_regions.length () - 1);
-	  logger->log ("deleting region %i (was region %i)",
-		       victim.as_int (),
-		       c.m_rid_map.get_src_for_dst (victim).as_int ());
-	}
-      delete m_regions.pop ();
-      stats->m_num_regions++;
-    }
-
   if (known_used_sid)
-    c.m_sid_map.update (known_used_sid);
+    map.update (known_used_sid);
 
   validate ();
 }
@@ -5918,7 +5780,6 @@ test_purge_unused_svalues ()
   purge_stats purged;
   model.purge_unused_svalues (&purged, NULL);
   ASSERT_EQ (purged.m_num_svalues, 3);
-  ASSERT_EQ (purged.m_num_regions, 0);
 
   /* and the redundant constraint on an old, unknown value for x should
      have been purged.  */
diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h
index 6d84899..37c06c5 100644
--- a/gcc/analyzer/region-model.h
+++ b/gcc/analyzer/region-model.h
@@ -783,7 +783,7 @@ public:
   void remap_svalue_ids (const svalue_id_map &map);
   virtual void remap_region_ids (const region_id_map &map);
 
-  virtual void walk_for_canonicalization (canonicalization *c) const;
+  virtual void walk_for_canonicalization (canonicalization *c) const = 0;
 
  protected:
   region (region_id parent_rid, svalue_id sval_id, tree type)
-- 
1.8.5.3

