From fd5e76656d8753694769732d294d5afb7feacf65 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Wed, 15 Jan 2020 21:19:59 -0500
Subject: [PATCH 11/68] FIXME: more WIP on fixing enode bloat

---
 gcc/analyzer/constraint-manager.cc                |  6 ++++--
 gcc/analyzer/region-model.cc                      | 15 +++++++++------
 .../gcc.dg/analyzer/malloc-vs-local-1a.c          |  3 +--
 gcc/testsuite/gcc.dg/analyzer/paths-1.c           |  2 +-
 gcc/testsuite/gcc.dg/analyzer/paths-1a.c          |  2 +-
 gcc/testsuite/gcc.dg/analyzer/paths-3.c           |  4 ++--
 gcc/testsuite/gcc.dg/analyzer/paths-4.c           |  4 ++--
 gcc/testsuite/gcc.dg/analyzer/paths-6.c           |  4 ++--
 8 files changed, 22 insertions(+), 18 deletions(-)

diff --git a/gcc/analyzer/constraint-manager.cc b/gcc/analyzer/constraint-manager.cc
index 7ba10688cd1..6fafef45bf3 100644
--- a/gcc/analyzer/constraint-manager.cc
+++ b/gcc/analyzer/constraint-manager.cc
@@ -1298,12 +1298,14 @@ constraint_manager::purge (const purge_criteria &p, purge_stats *stats)
 	}
     }
 
-  /* Finally, delete any ECs that purely contain constants and aren't
+  /* Finally, delete any ECs that purely contain constants 
+     FIXME: or just one value
+     and aren't
      referenced by any constraints.  */
   for (unsigned ec_idx = 0; ec_idx < m_equiv_classes.length (); )
     {
       equiv_class *ec = m_equiv_classes[ec_idx];
-      if (ec->m_vars.length () == 0)
+      if (ec->m_vars.length () < 2)
 	{
 	  equiv_class_id ec_id (ec_idx);
 	  bool has_constraint = false;
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 16933e0cab7..01ab26e2625 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -7291,12 +7291,12 @@ test_purging_by_criteria ()
     purge_stats stats_for_px;
     purge_one_svalue_id px (model1, x);
     model1.get_constraints ()->purge (px, &stats_for_px);
-    ASSERT_EQ (stats_for_px.m_num_equiv_classes, 0);
+    ASSERT_EQ (stats_for_px.m_num_equiv_classes, 1);
 
     purge_stats stats_for_py;
     purge_one_svalue_id py (model1.get_rvalue (y, NULL));
     model1.get_constraints ()->purge (py, &stats_for_py);
-    ASSERT_EQ (stats_for_py.m_num_equiv_classes, 1);
+    ASSERT_EQ (stats_for_py.m_num_equiv_classes, 0);
 
     ASSERT_EQ (*model0.get_constraints (), *model1.get_constraints ());
   }
@@ -7363,6 +7363,8 @@ test_purging_by_criteria ()
 
     purge_stats stats;
     model1.get_constraints ()->purge (purge_all_svalue_ids (), &stats);
+    ASSERT_EQ (model1.get_constraints ()->m_constraints.length (), 0);
+    ASSERT_EQ (model1.get_constraints ()->m_equiv_classes.length (), 0);
     ASSERT_CONDITION_UNKNOWN (model1, x, NE_EXPR, int_42);
     ASSERT_CONDITION_UNKNOWN (model1, y, NE_EXPR, int_0);
   }
@@ -7401,7 +7403,7 @@ test_purge_unused_svalues ()
 
   /* and the redundant constraint on an old, unknown value for x should
      have been purged.  */
-  ASSERT_EQ (purged.m_num_equiv_classes, 1);
+  ASSERT_EQ (purged.m_num_equiv_classes, 2);
   ASSERT_EQ (purged.m_num_constraints, 2);
   ASSERT_EQ (model.get_constraints ()->m_constraints.length (), 1);
 
@@ -7545,14 +7547,15 @@ test_stack_frames ()
   purge_stats purged;
   model.pop_frame (true, &purged, &ctxt);
 
-  /* We should have purged the unknown values for x and y. */
-  ASSERT_EQ (purged.m_num_svalues, 2);
+  /* We should have purged the values for x and y, and for the constant 5
+     that was constraining y. */
+  ASSERT_EQ (purged.m_num_svalues, 3);
 
   /* We should have purged the frame region and the regions for x and y. */
   ASSERT_EQ (purged.m_num_regions, 3);
 
   /* We should have purged the constraint on y.  */
-  ASSERT_EQ (purged.m_num_equiv_classes, 1);
+  ASSERT_EQ (purged.m_num_equiv_classes, 2);
   ASSERT_EQ (purged.m_num_constraints, 2);
 
   /* Verify that p (which was pointing at the local "x" in the popped
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-1a.c b/gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-1a.c
index 72360c2f9fa..e1b4ba461c9 100644
--- a/gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-1a.c
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-1a.c
@@ -171,8 +171,7 @@ int test_initial_flag (int n)
 
   result = do_stuff (ptr, n);
 
-  __analyzer_dump_exploded_nodes (0); /* { dg-warning "5 exploded nodes" } */
-  // FIXME: why 5 here?
+  __analyzer_dump_exploded_nodes (0); /* { dg-warning "4 exploded nodes" } */
 
   if (n > 10)
     free (ptr); /* { dg-bogus "not on the heap" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/paths-1.c b/gcc/testsuite/gcc.dg/analyzer/paths-1.c
index 06468774472..20fe99371c7 100644
--- a/gcc/testsuite/gcc.dg/analyzer/paths-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/paths-1.c
@@ -13,6 +13,6 @@ void test (struct foo *pf)
     bar (0);
   else
     bar (1);
-  __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 exploded nodes" } */
+  __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */
   __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */
 }
diff --git a/gcc/testsuite/gcc.dg/analyzer/paths-1a.c b/gcc/testsuite/gcc.dg/analyzer/paths-1a.c
index 8760de93499..d1c650c2110 100644
--- a/gcc/testsuite/gcc.dg/analyzer/paths-1a.c
+++ b/gcc/testsuite/gcc.dg/analyzer/paths-1a.c
@@ -13,6 +13,6 @@ void test (union foo *pf)
     bar (0);
   else
     bar (1);
-  __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 exploded nodes" } */
+  __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */
   __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */
 }
diff --git a/gcc/testsuite/gcc.dg/analyzer/paths-3.c b/gcc/testsuite/gcc.dg/analyzer/paths-3.c
index 440213b7991..f69f49f25c9 100644
--- a/gcc/testsuite/gcc.dg/analyzer/paths-3.c
+++ b/gcc/testsuite/gcc.dg/analyzer/paths-3.c
@@ -13,7 +13,7 @@ int test_1 (int a, int b)
     else
       p = malloc (32);
 
-  __analyzer_dump_exploded_nodes (0); /* { dg-warning "4 exploded nodes" } */
+  __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 exploded nodes" } */
   __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */
 
   if (a > 5)
@@ -35,7 +35,7 @@ int test_2 (int a, int b)
     else
       p = malloc (32);
 
-  __analyzer_dump_exploded_nodes (0); /* { dg-warning "4 exploded nodes" } */
+  __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 exploded nodes" } */
   __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */
 
   if (a > 6) /* different condition */
diff --git a/gcc/testsuite/gcc.dg/analyzer/paths-4.c b/gcc/testsuite/gcc.dg/analyzer/paths-4.c
index 34bd09eee05..0d84f4ce991 100644
--- a/gcc/testsuite/gcc.dg/analyzer/paths-4.c
+++ b/gcc/testsuite/gcc.dg/analyzer/paths-4.c
@@ -13,7 +13,7 @@ int test_1 (struct state *s)
   __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */
   while (1)
     {
-      __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */
+      __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */
       __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */
       do_stuff (s, s->mode);
     }
@@ -24,7 +24,7 @@ int test_2 (struct state *s)
   __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */
   while (1)
     {
-      __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 exploded nodes" } */
+      __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */
       __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */
       switch (s->mode)
 	{
diff --git a/gcc/testsuite/gcc.dg/analyzer/paths-6.c b/gcc/testsuite/gcc.dg/analyzer/paths-6.c
index 428d8748731..cb87cde2274 100644
--- a/gcc/testsuite/gcc.dg/analyzer/paths-6.c
+++ b/gcc/testsuite/gcc.dg/analyzer/paths-6.c
@@ -92,8 +92,8 @@ void test_3 (int i)
       break;
     }
 
-  __analyzer_dump_exploded_nodes (0); /* { dg-warning "6 exploded nodes" } */
-  __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 exploded node" } */
+  __analyzer_dump_exploded_nodes (0); /* { dg-warning "5 exploded nodes" } */
+  __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */
   __analyzer_eval (f == 3); /* { dg-warning "TRUE" } */
   __analyzer_eval (g == 4); /* { dg-warning "TRUE" } */
   __analyzer_eval (h == 5); /* { dg-warning "TRUE" } */
-- 
2.21.0

