Make EVRP release unused value-ranges, cleanup lattice swapping

Message ID alpine.LSU.2.20.1907311252360.19626@zhemvz.fhfr.qr
State New
Headers show
Series
  • Make EVRP release unused value-ranges, cleanup lattice swapping
Related show

Commit Message

Richard Biener July 31, 2019, 10:54 a.m.
This is the last bit I had in my tree - as seen elsewhere you
eventually run into testcases triggering issues, so this fixes
EVRP not releasing any of its temporary ranges it pushes to
the lattice.  It also cleans up the lattice entry swapping
"const correctness" issue by adding a new swap_vr_value
method to the lattice.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

2019-07-31  Richard Biener  <rguenther@suse.de>

	* vr-values.h (vr_values::swap_vr_value): New.
	(vr_values::free_value_range): likewise.
	* vr-values.c (vr_values::swap_vr_value): Implement.
	* gimple-ssa-evrp-analyze.h (evrp_range_analyzer::pop_value_range):
	Do not return a range or take a var.
	(evrp_range_analyzer::stack): Change back to recording a non-const
	value_range *.
	* gimple-ssa-evrp-analyze.c
	(evrp_range_analyzer::record_ranges_from_stmt): Free unused
	value-range.
	(evrp_range_analyzer::pop_to_marker): Adjust.
	(evrp_range_analyzer::push_value_range): Use new swap_vr_value.
	(evrp_range_analyzer::pop_value_range): Likewise.  Free the
	no longer needed value-range.

Patch

Index: gcc/vr-values.c
===================================================================
--- gcc/vr-values.c	(revision 273923)
+++ gcc/vr-values.c	(working copy)
@@ -4315,6 +4315,8 @@  vr_values::simplify_stmt_using_ranges (g
   return false;
 }
 
+/* Set the lattice entry for VAR to VR.  */
+
 void
 vr_values::set_vr_value (tree var, value_range *vr)
 {
@@ -4323,3 +4325,13 @@  vr_values::set_vr_value (tree var, value
   vr_value[SSA_NAME_VERSION (var)] = vr;
 }
 
+/* Swap the lattice entry for VAR with VR and return the old entry.  */
+
+value_range *
+vr_values::swap_vr_value (tree var, value_range *vr)
+{
+  if (SSA_NAME_VERSION (var) >= num_vr_values)
+    return NULL;
+  std::swap (vr_value[SSA_NAME_VERSION (var)], vr);
+  return vr;
+}
Index: gcc/vr-values.h
===================================================================
--- gcc/vr-values.h	(revision 273923)
+++ gcc/vr-values.h	(working copy)
@@ -41,8 +41,9 @@  class vr_values
   ~vr_values (void);
 
   const value_range *get_value_range (const_tree);
-
   void set_vr_value (tree, value_range *);
+  value_range *swap_vr_value (tree, value_range *);
+
   void set_def_to_varying (const_tree);
   void set_defs_to_varying (gimple *);
   bool update_value_range (const_tree, value_range *);
@@ -68,6 +69,8 @@  class vr_values
   /* Allocate a new value_range object.  */
   value_range *allocate_value_range (void)
     { return vrp_value_range_pool.allocate (); }
+  void free_value_range (value_range *vr)
+    { vrp_value_range_pool.remove (vr); }
 
   /* */
   void cleanup_edges_and_switches (void);
Index: gcc/gimple-ssa-evrp-analyze.c
===================================================================
--- gcc/gimple-ssa-evrp-analyze.c	(revision 273923)
+++ gcc/gimple-ssa-evrp-analyze.c	(working copy)
@@ -214,7 +214,10 @@  evrp_range_analyzer::record_ranges_from_
 				    old_vr->max ());
 	      tem.intersect (vrs[i].second);
 	      if (tem.equal_p (*old_vr))
-		continue;
+		{
+		  vr_values->free_value_range (vrs[i].second);
+		  continue;
+		}
 	      push_value_range (vrs[i].first, vrs[i].second);
 	      if (is_fallthru
 		  && m_update_global_ranges
@@ -393,7 +396,7 @@  evrp_range_analyzer::pop_to_marker (void
 {
   gcc_checking_assert (!stack.is_empty ());
   while (stack.last ().first != NULL_TREE)
-    pop_value_range (stack.last ().first);
+    pop_value_range ();
   stack.pop ();
 }
 
@@ -421,17 +424,18 @@  evrp_range_analyzer::push_value_range (t
       dump_value_range (dump_file, vr);
       fprintf (dump_file, "\n");
     }
-  stack.safe_push (std::make_pair (var, get_value_range (var)));
-  vr_values->set_vr_value (var, vr);
+  value_range *old_vr = vr_values->swap_vr_value (var, vr);
+  stack.safe_push (std::make_pair (var, old_vr));
 }
 
-/* Pop the Value Range from the vrp_stack and update VAR with it.  */
+/* Pop a Value Range from the vrp_stack.  */
 
-const value_range *
-evrp_range_analyzer::pop_value_range (tree var)
+void
+evrp_range_analyzer::pop_value_range ()
 {
-  const value_range *vr = stack.last ().second;
-  gcc_checking_assert (var == stack.last ().first);
+  std::pair<tree, value_range *> e = stack.pop ();
+  tree var = e.first;
+  value_range *vr = e.second;
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
       fprintf (dump_file, "popping range for ");
@@ -440,9 +444,9 @@  evrp_range_analyzer::pop_value_range (tr
       dump_value_range (dump_file, vr);
       fprintf (dump_file, "\n");
     }
-  /* We saved off a lattice entry, now give it back - it can now
-     be modified again, thus the const casting.  */
-  vr_values->set_vr_value (var, const_cast <value_range *> (vr));
-  stack.pop ();
-  return vr;
+  /* We saved off a lattice entry, now give it back and release
+     the one we popped.  */
+  value_range *popped_vr = vr_values->swap_vr_value (var, vr);
+  if (popped_vr)
+    vr_values->free_value_range (popped_vr);
 }
Index: gcc/gimple-ssa-evrp-analyze.h
===================================================================
--- gcc/gimple-ssa-evrp-analyze.h	(revision 273923)
+++ gcc/gimple-ssa-evrp-analyze.h	(working copy)
@@ -62,14 +62,14 @@  class evrp_range_analyzer
   DISABLE_COPY_AND_ASSIGN (evrp_range_analyzer);
   class vr_values *vr_values;
 
-  const value_range *pop_value_range (tree var);
+  void pop_value_range ();
   value_range *try_find_new_range (tree, tree op, tree_code code, tree limit);
   void record_ranges_from_incoming_edge (basic_block);
   void record_ranges_from_phis (basic_block);
   void set_ssa_range_info (tree, value_range *);
 
   /* STACK holds the old VR.  */
-  auto_vec<std::pair <tree, const value_range*> > stack;
+  auto_vec<std::pair <tree, value_range *> > stack;
 
   /* True if we are updating global ranges, false otherwise.  */
   bool m_update_global_ranges;