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 <rguent...@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);