public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Improve memory usage on PR64928
@ 2015-03-05 16:04 Richard Biener
  2015-03-06 12:33 ` Richard Biener
  0 siblings, 1 reply; 2+ messages in thread
From: Richard Biener @ 2015-03-05 16:04 UTC (permalink / raw)
  To: gcc-patches


I am currently testing the following patch to reduce peak memory
usage of the out-of-SSA phase for the testcase in the PR.  The
issue is (as usual) big live and SSA conflict graph memory use.
This side tackles live info and frees livein before computing
the conflict graph (which only needs liveout).

Bootstrap and regtest ongoing on x86_64-unknown-linux-gnu.

Richard.

2015-03-05  Richard Biener  <rguenther@suse.de>

	PR middle-end/64928
	* tree-ssa-live.h (struct tree_live_info_d): Add livein_obstack
	and liveout_obstack members.
	(calculate_live_on_exit): Remove.
	(delete_tree_live_info_livein): Declare.
	(delete_tree_live_info_liveout): Likewise.
	* tree-ssa-live.c (liveness_bitmap_obstack): Remove global var.
	(new_tree_live_info): Adjust.
	(delete_tree_live_info_livein): New function.
	(delete_tree_live_info_liveout): Likewise.
	(delete_tree_live_info): Deal with partly deleted live info.
	(loe_visit_block): Remove temporary bitmap by using
	bitmap_ior_and_compl_into.
	(live_worklist): Adjust accordingly.
	(calculate_live_on_exit): Make static.
	(calculate_live_ranges): Do not initialize liveness_bitmap_obstack.

Index: gcc/tree-ssa-coalesce.c
===================================================================
--- gcc/tree-ssa-coalesce.c	(revision 221205)
+++ gcc/tree-ssa-coalesce.c	(working copy)
@@ -1345,6 +1345,7 @@ coalesce_ssa_name (void)
     dump_var_map (dump_file, map);
 
   liveinfo = calculate_live_ranges (map);
+  delete_tree_live_info_livein (liveinfo);
 
   if (dump_file && (dump_flags & TDF_DETAILS))
     dump_live_info (dump_file, liveinfo, LIVEDUMP_ENTRY);
Index: gcc/tree-ssa-live.c
===================================================================
--- gcc/tree-ssa-live.c	(revision 221205)
+++ gcc/tree-ssa-live.c	(working copy)
@@ -973,13 +973,6 @@ remove_unused_locals (void)
   timevar_pop (TV_REMOVE_UNUSED);
 }
 
-/* Obstack for globale liveness info bitmaps.  We don't want to put these
-   on the default obstack because these bitmaps can grow quite large and
-   we'll hold on to all that memory until the end of the compiler run.
-   As a bonus, delete_tree_live_info can destroy all the bitmaps by just
-   releasing the whole obstack.  */
-static bitmap_obstack liveness_bitmap_obstack;
-
 /* Allocate and return a new live range information object base on MAP.  */
 
 static tree_live_info_p
@@ -992,31 +985,61 @@ new_tree_live_info (var_map map)
   live->map = map;
   live->num_blocks = last_basic_block_for_fn (cfun);
 
+  bitmap_obstack_initialize (&live->livein_obstack);
+  bitmap_obstack_initialize (&live->liveout_obstack);
   live->livein = XNEWVEC (bitmap_head, last_basic_block_for_fn (cfun));
   FOR_EACH_BB_FN (bb, cfun)
-    bitmap_initialize (&live->livein[bb->index], &liveness_bitmap_obstack);
+    bitmap_initialize (&live->livein[bb->index], &live->livein_obstack);
 
   live->liveout = XNEWVEC (bitmap_head, last_basic_block_for_fn (cfun));
   FOR_EACH_BB_FN (bb, cfun)
-    bitmap_initialize (&live->liveout[bb->index], &liveness_bitmap_obstack);
+    bitmap_initialize (&live->liveout[bb->index], &live->liveout_obstack);
 
   live->work_stack = XNEWVEC (int, last_basic_block_for_fn (cfun));
   live->stack_top = live->work_stack;
 
-  live->global = BITMAP_ALLOC (&liveness_bitmap_obstack);
+  live->global = BITMAP_ALLOC (NULL);
   return live;
 }
 
 
+/* Free storage for livein of the live range info object LIVE.  */
+
+void
+delete_tree_live_info_livein (tree_live_info_p live)
+{
+  bitmap_obstack_release (&live->livein_obstack);
+  free (live->livein);
+  live->livein = NULL;
+}
+
+/* Free storage for liveout of the live range info object LIVE.  */
+
+void
+delete_tree_live_info_liveout (tree_live_info_p live)
+{
+  bitmap_obstack_release (&live->liveout_obstack);
+  free (live->liveout);
+  live->liveout = NULL;
+}
+
 /* Free storage for live range info object LIVE.  */
 
 void
 delete_tree_live_info (tree_live_info_p live)
 {
-  bitmap_obstack_release (&liveness_bitmap_obstack);
+  if (live->livein)
+    {
+      bitmap_obstack_release (&live->livein_obstack);
+      free (live->livein);
+    }
+  if (live->liveout)
+    {
+      bitmap_obstack_release (&live->liveout_obstack);
+      free (live->liveout);
+    }
+  BITMAP_FREE (live->global);
   free (live->work_stack);
-  free (live->liveout);
-  free (live->livein);
   free (live);
 }
 
@@ -1027,8 +1050,7 @@ delete_tree_live_info (tree_live_info_p
    it each time.  */
 
 static void
-loe_visit_block (tree_live_info_p live, basic_block bb, sbitmap visited,
-		 bitmap tmp)
+loe_visit_block (tree_live_info_p live, basic_block bb, sbitmap visited)
 {
   edge e;
   bool change;
@@ -1046,17 +1068,17 @@ loe_visit_block (tree_live_info_p live,
       pred_bb = e->src;
       if (pred_bb == ENTRY_BLOCK_PTR_FOR_FN (cfun))
 	continue;
-      /* TMP is variables live-on-entry from BB that aren't defined in the
+      /* Variables live-on-entry from BB that aren't defined in the
 	 predecessor block.  This should be the live on entry vars to pred.
 	 Note that liveout is the DEFs in a block while live on entry is
-	 being calculated.  */
-      bitmap_and_compl (tmp, loe, &live->liveout[pred_bb->index]);
-
-      /* Add these bits to live-on-entry for the pred. if there are any
+	 being calculated.
+	 Add these bits to live-on-entry for the pred. if there are any
 	 changes, and pred_bb has been visited already, add it to the
 	 revisit stack.  */
-      change = bitmap_ior_into (live_on_entry (live, pred_bb), tmp);
-      if (bitmap_bit_p (visited, pred_bb->index) && change)
+      change = bitmap_ior_and_compl_into (live_on_entry (live, pred_bb),
+					  loe, &live->liveout[pred_bb->index]);
+      if (change
+	  && bitmap_bit_p (visited, pred_bb->index))
 	{
 	  bitmap_clear_bit (visited, pred_bb->index);
 	  *(live->stack_top)++ = pred_bb->index;
@@ -1074,23 +1096,21 @@ live_worklist (tree_live_info_p live)
   unsigned b;
   basic_block bb;
   sbitmap visited = sbitmap_alloc (last_basic_block_for_fn (cfun) + 1);
-  bitmap tmp = BITMAP_ALLOC (&liveness_bitmap_obstack);
 
   bitmap_clear (visited);
 
   /* Visit all the blocks in reverse order and propagate live on entry values
      into the predecessors blocks.  */
   FOR_EACH_BB_REVERSE_FN (bb, cfun)
-    loe_visit_block (live, bb, visited, tmp);
+    loe_visit_block (live, bb, visited);
 
   /* Process any blocks which require further iteration.  */
   while (live->stack_top != live->work_stack)
     {
       b = *--(live->stack_top);
-      loe_visit_block (live, BASIC_BLOCK_FOR_FN (cfun, b), visited, tmp);
+      loe_visit_block (live, BASIC_BLOCK_FOR_FN (cfun, b), visited);
     }
 
-  BITMAP_FREE (tmp);
   sbitmap_free (visited);
 }
 
@@ -1175,7 +1195,7 @@ set_var_live_on_entry (tree ssa_name, tr
 
 /* Calculate the live on exit vectors based on the entry info in LIVEINFO.  */
 
-void
+static void
 calculate_live_on_exit (tree_live_info_p liveinfo)
 {
   basic_block bb;
@@ -1232,7 +1252,6 @@ calculate_live_ranges (var_map map)
   unsigned i;
   tree_live_info_p live;
 
-  bitmap_obstack_initialize (&liveness_bitmap_obstack);
   live = new_tree_live_info (map);
   for (i = 0; i < num_var_partitions (map); i++)
     {
Index: gcc/tree-ssa-live.h
===================================================================
--- gcc/tree-ssa-live.h	(revision 221205)
+++ gcc/tree-ssa-live.h	(working copy)
@@ -242,6 +242,10 @@ typedef struct tree_live_info_d
 
   /* Top of workstack.  */
   int *stack_top;
+
+  /* Obstacks to allocate the bitmaps on.  */
+  bitmap_obstack livein_obstack;
+  bitmap_obstack liveout_obstack;
 } *tree_live_info_p;
 
 
@@ -249,7 +253,8 @@ typedef struct tree_live_info_d
 #define LIVEDUMP_EXIT	0x02
 #define LIVEDUMP_ALL	(LIVEDUMP_ENTRY | LIVEDUMP_EXIT)
 extern void delete_tree_live_info (tree_live_info_p);
-extern void calculate_live_on_exit (tree_live_info_p);
+extern void delete_tree_live_info_livein (tree_live_info_p);
+extern void delete_tree_live_info_liveout (tree_live_info_p);
 extern tree_live_info_p calculate_live_ranges (var_map);
 extern void debug (tree_live_info_d &ref);
 extern void debug (tree_live_info_d *ptr);

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] Improve memory usage on PR64928
  2015-03-05 16:04 [PATCH] Improve memory usage on PR64928 Richard Biener
@ 2015-03-06 12:33 ` Richard Biener
  0 siblings, 0 replies; 2+ messages in thread
From: Richard Biener @ 2015-03-06 12:33 UTC (permalink / raw)
  To: gcc-patches

On Thu, 5 Mar 2015, Richard Biener wrote:

> 
> I am currently testing the following patch to reduce peak memory
> usage of the out-of-SSA phase for the testcase in the PR.  The
> issue is (as usual) big live and SSA conflict graph memory use.
> This side tackles live info and frees livein before computing
> the conflict graph (which only needs liveout).
> 
> Bootstrap and regtest ongoing on x86_64-unknown-linux-gnu.

I'm currently giving the following slightly re-factored patch final
testing.  Peak memory usage drops from 7.6GB to 5.8GB for the
"small" testcase in the PR.  When I remove SSA coalescing from the
picture (I have a followup patch to do that, by simply limiting the
amount of coalescing we do) then memory usage peaks at 7.6GB again
which is because CSE and DF blow up later on the testcase.

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

Richard.

2015-03-06  Richard Biener  <rguenther@suse.de>

	PR middle-end/64928
	* tree-ssa-live.h (struct tree_live_info_d): Add livein_obstack
	and liveout_obstack members.
	(calculate_live_on_exit): Remove.
	(calculate_live_ranges): Change declaration.
	* tree-ssa-live.c (liveness_bitmap_obstack): Remove global var.
	(new_tree_live_info): Adjust.
	(calculate_live_ranges): Delete livein when not wanted.
	(calculate_live_ranges): Do not initialize liveness_bitmap_obstack.
	Deal with partly deleted live info.
	(loe_visit_block): Remove temporary bitmap by using
	bitmap_ior_and_compl_into.
	(live_worklist): Adjust accordingly.
	(calculate_live_on_exit): Make static.
	* tree-ssa-coalesce.c (coalesce_ssa_name): Tell calculate_live_ranges
	we do not need livein.

Index: gcc/tree-ssa-live.c
===================================================================
--- gcc/tree-ssa-live.c	(revision 221207)
+++ gcc/tree-ssa-live.c	(working copy)
@@ -973,13 +973,6 @@ remove_unused_locals (void)
   timevar_pop (TV_REMOVE_UNUSED);
 }
 
-/* Obstack for globale liveness info bitmaps.  We don't want to put these
-   on the default obstack because these bitmaps can grow quite large and
-   we'll hold on to all that memory until the end of the compiler run.
-   As a bonus, delete_tree_live_info can destroy all the bitmaps by just
-   releasing the whole obstack.  */
-static bitmap_obstack liveness_bitmap_obstack;
-
 /* Allocate and return a new live range information object base on MAP.  */
 
 static tree_live_info_p
@@ -992,18 +985,20 @@ new_tree_live_info (var_map map)
   live->map = map;
   live->num_blocks = last_basic_block_for_fn (cfun);
 
+  bitmap_obstack_initialize (&live->livein_obstack);
+  bitmap_obstack_initialize (&live->liveout_obstack);
   live->livein = XNEWVEC (bitmap_head, last_basic_block_for_fn (cfun));
   FOR_EACH_BB_FN (bb, cfun)
-    bitmap_initialize (&live->livein[bb->index], &liveness_bitmap_obstack);
+    bitmap_initialize (&live->livein[bb->index], &live->livein_obstack);
 
   live->liveout = XNEWVEC (bitmap_head, last_basic_block_for_fn (cfun));
   FOR_EACH_BB_FN (bb, cfun)
-    bitmap_initialize (&live->liveout[bb->index], &liveness_bitmap_obstack);
+    bitmap_initialize (&live->liveout[bb->index], &live->liveout_obstack);
 
   live->work_stack = XNEWVEC (int, last_basic_block_for_fn (cfun));
   live->stack_top = live->work_stack;
 
-  live->global = BITMAP_ALLOC (&liveness_bitmap_obstack);
+  live->global = BITMAP_ALLOC (NULL);
   return live;
 }
 
@@ -1013,10 +1008,18 @@ new_tree_live_info (var_map map)
 void
 delete_tree_live_info (tree_live_info_p live)
 {
-  bitmap_obstack_release (&liveness_bitmap_obstack);
+  if (live->livein)
+    {
+      bitmap_obstack_release (&live->livein_obstack);
+      free (live->livein);
+    }
+  if (live->liveout)
+    {
+      bitmap_obstack_release (&live->liveout_obstack);
+      free (live->liveout);
+    }
+  BITMAP_FREE (live->global);
   free (live->work_stack);
-  free (live->liveout);
-  free (live->livein);
   free (live);
 }
 
@@ -1027,8 +1030,7 @@ delete_tree_live_info (tree_live_info_p
    it each time.  */
 
 static void
-loe_visit_block (tree_live_info_p live, basic_block bb, sbitmap visited,
-		 bitmap tmp)
+loe_visit_block (tree_live_info_p live, basic_block bb, sbitmap visited)
 {
   edge e;
   bool change;
@@ -1046,17 +1048,17 @@ loe_visit_block (tree_live_info_p live,
       pred_bb = e->src;
       if (pred_bb == ENTRY_BLOCK_PTR_FOR_FN (cfun))
 	continue;
-      /* TMP is variables live-on-entry from BB that aren't defined in the
+      /* Variables live-on-entry from BB that aren't defined in the
 	 predecessor block.  This should be the live on entry vars to pred.
 	 Note that liveout is the DEFs in a block while live on entry is
-	 being calculated.  */
-      bitmap_and_compl (tmp, loe, &live->liveout[pred_bb->index]);
-
-      /* Add these bits to live-on-entry for the pred. if there are any
+	 being calculated.
+	 Add these bits to live-on-entry for the pred. if there are any
 	 changes, and pred_bb has been visited already, add it to the
 	 revisit stack.  */
-      change = bitmap_ior_into (live_on_entry (live, pred_bb), tmp);
-      if (bitmap_bit_p (visited, pred_bb->index) && change)
+      change = bitmap_ior_and_compl_into (live_on_entry (live, pred_bb),
+					  loe, &live->liveout[pred_bb->index]);
+      if (change
+	  && bitmap_bit_p (visited, pred_bb->index))
 	{
 	  bitmap_clear_bit (visited, pred_bb->index);
 	  *(live->stack_top)++ = pred_bb->index;
@@ -1074,23 +1076,21 @@ live_worklist (tree_live_info_p live)
   unsigned b;
   basic_block bb;
   sbitmap visited = sbitmap_alloc (last_basic_block_for_fn (cfun) + 1);
-  bitmap tmp = BITMAP_ALLOC (&liveness_bitmap_obstack);
 
   bitmap_clear (visited);
 
   /* Visit all the blocks in reverse order and propagate live on entry values
      into the predecessors blocks.  */
   FOR_EACH_BB_REVERSE_FN (bb, cfun)
-    loe_visit_block (live, bb, visited, tmp);
+    loe_visit_block (live, bb, visited);
 
   /* Process any blocks which require further iteration.  */
   while (live->stack_top != live->work_stack)
     {
       b = *--(live->stack_top);
-      loe_visit_block (live, BASIC_BLOCK_FOR_FN (cfun, b), visited, tmp);
+      loe_visit_block (live, BASIC_BLOCK_FOR_FN (cfun, b), visited);
     }
 
-  BITMAP_FREE (tmp);
   sbitmap_free (visited);
 }
 
@@ -1175,7 +1175,7 @@ set_var_live_on_entry (tree ssa_name, tr
 
 /* Calculate the live on exit vectors based on the entry info in LIVEINFO.  */
 
-void
+static void
 calculate_live_on_exit (tree_live_info_p liveinfo)
 {
   basic_block bb;
@@ -1226,13 +1226,12 @@ calculate_live_on_exit (tree_live_info_p
    each partition.  Return a new live info object.  */
 
 tree_live_info_p
-calculate_live_ranges (var_map map)
+calculate_live_ranges (var_map map, bool want_livein)
 {
   tree var;
   unsigned i;
   tree_live_info_p live;
 
-  bitmap_obstack_initialize (&liveness_bitmap_obstack);
   live = new_tree_live_info (map);
   for (i = 0; i < num_var_partitions (map); i++)
     {
@@ -1248,6 +1247,14 @@ calculate_live_ranges (var_map map)
 #endif
 
   calculate_live_on_exit (live);
+
+  if (!want_livein)
+    {
+      bitmap_obstack_release (&live->livein_obstack);
+      free (live->livein);
+      live->livein = NULL;
+    }
+
   return live;
 }
 
Index: gcc/tree-ssa-live.h
===================================================================
--- gcc/tree-ssa-live.h	(revision 221207)
+++ gcc/tree-ssa-live.h	(working copy)
@@ -242,6 +242,10 @@ typedef struct tree_live_info_d
 
   /* Top of workstack.  */
   int *stack_top;
+
+  /* Obstacks to allocate the bitmaps on.  */
+  bitmap_obstack livein_obstack;
+  bitmap_obstack liveout_obstack;
 } *tree_live_info_p;
 
 
@@ -249,8 +253,7 @@ typedef struct tree_live_info_d
 #define LIVEDUMP_EXIT	0x02
 #define LIVEDUMP_ALL	(LIVEDUMP_ENTRY | LIVEDUMP_EXIT)
 extern void delete_tree_live_info (tree_live_info_p);
-extern void calculate_live_on_exit (tree_live_info_p);
-extern tree_live_info_p calculate_live_ranges (var_map);
+extern tree_live_info_p calculate_live_ranges (var_map, bool);
 extern void debug (tree_live_info_d &ref);
 extern void debug (tree_live_info_d *ptr);
 extern void dump_live_info (FILE *, tree_live_info_p, int);
Index: gcc/tree-ssa-coalesce.c
===================================================================
--- gcc/tree-ssa-coalesce.c	(revision 221207)
+++ gcc/tree-ssa-coalesce.c	(working copy)
@@ -1344,7 +1344,7 @@ coalesce_ssa_name (void)
   if (dump_file && (dump_flags & TDF_DETAILS))
     dump_var_map (dump_file, map);
 
-  liveinfo = calculate_live_ranges (map);
+  liveinfo = calculate_live_ranges (map, false);
 
   if (dump_file && (dump_flags & TDF_DETAILS))
     dump_live_info (dump_file, liveinfo, LIVEDUMP_ENTRY);

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2015-03-06 12:33 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-05 16:04 [PATCH] Improve memory usage on PR64928 Richard Biener
2015-03-06 12:33 ` Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).