Fix PR56113

Submitted by Richard Guenther on Jan. 29, 2013, 1:13 p.m.

Details

Message ID alpine.LNX.2.00.1301291408300.6889@zhemvz.fhfr.qr
State New
Headers show

Commit Message

Richard Guenther Jan. 29, 2013, 1:13 p.m.
This reduces the amount of memory needed by PTA pointer unification
which has quadratic memory requirements.  It's very easy to improve
the situation where a lot of pointer equivalences are present
by not keeping duplicate bitmaps we unify using a hashtable already.
This reduces the overhead of the testcase in the PR from requiring
peak 2.5GB to 1.4MB instead.  This doesn't change the fact that
the algorithm is quadratic in its memory requirements (worst memory
requirements when it doesn't produce anything useful in the end).

Bootstrap and regtest running on x86_64-unknown-linux-gnu.  I plan
to install this on trunk and the 4.7 branch for the general
memory-hog regressions.

Richard.

2013-01-29  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/56113
	* tree-ssa-structalias.c (equiv_class_lookup): Also return
	the bitmap leader.
	(label_visit): Free duplicate bitmaps and record the leader instead.
	(perform_var_substitution): Adjust.

Patch hide | download patch | download mbox

Index: gcc/tree-ssa-structalias.c
===================================================================
--- gcc/tree-ssa-structalias.c	(revision 195532)
+++ gcc/tree-ssa-structalias.c	(working copy)
@@ -1907,10 +1908,10 @@  equiv_class_label_eq (const void *p1, co
 }
 
 /* Lookup a equivalence class in TABLE by the bitmap of LABELS it
-   contains.  */
+   contains.  Sets *REF_LABELS to the bitmap LABELS is equivalent to.  */
 
 static unsigned int
-equiv_class_lookup (htab_t table, bitmap labels)
+equiv_class_lookup (htab_t table, bitmap labels, bitmap *ref_labels)
 {
   void **slot;
   struct equiv_class_label ecl;
@@ -1921,9 +1922,18 @@  equiv_class_lookup (htab_t table, bitmap
   slot = htab_find_slot_with_hash (table, &ecl,
 				   ecl.hashcode, NO_INSERT);
   if (!slot)
-    return 0;
+    {
+      if (ref_labels)
+	*ref_labels = NULL;
+      return 0;
+    }
   else
-    return ((equiv_class_label_t) *slot)->equivalence_class;
+    {
+      equiv_class_label_t ec = (equiv_class_label_t) *slot;
+      if (ref_labels)
+	*ref_labels = ec->labels;
+      return ec->equivalence_class;
+    }
 }
 
 
@@ -2123,14 +2133,21 @@  label_visit (constraint_graph_t graph, s
 
   if (!bitmap_empty_p (graph->points_to[n]))
     {
+      bitmap ref_points_to;
       unsigned int label = equiv_class_lookup (pointer_equiv_class_table,
-					       graph->points_to[n]);
+					       graph->points_to[n],
+					       &ref_points_to);
       if (!label)
 	{
 	  label = pointer_equiv_class++;
 	  equiv_class_add (pointer_equiv_class_table,
 			   label, graph->points_to[n]);
 	}
+      else
+	{
+	  BITMAP_FREE (graph->points_to[n]);
+	  graph->points_to[n] = ref_points_to;
+	}
       graph->pointer_label[n] = label;
     }
 }
@@ -2190,7 +2223,7 @@  perform_var_substitution (constraint_gra
       /* Look up the location equivalence label if one exists, or make
 	 one otherwise.  */
       label = equiv_class_lookup (location_equiv_class_table,
-				  pointed_by);
+				  pointed_by, NULL);
       if (label == 0)
 	{
 	  label = location_equiv_class++;