On 11/09/2015 01:11 PM, Richard Biener wrote: > On Mon, Nov 9, 2015 at 12:22 PM, Martin Liška <mli...@suse.cz> wrote: >> Hi. >> >> This is follow-up of changes that Richi started on Friday. >> >> Patch can bootstrap on x86_64-linux-pc and regression tests are running. >> >> Ready for trunk? > > * tree-ssa-dom.c (free_edge_info): Make the function extern. > ... > * tree-ssa.h (free_edge_info): Declare function extern. > > declare this in tree-ssa-threadupdate.h instead and renaming it to > sth less "public", like free_dom_edge_info. > > diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c > index fff62de..eb6b7df 100644 > --- a/gcc/ifcvt.c > +++ b/gcc/ifcvt.c > @@ -3161,6 +3161,8 @@ noce_convert_multiple_sets (struct noce_if_info > *if_info) > set_used_flags (targets[i]); > } > > + temporaries.release (); > + > set_used_flags (cond); > set_used_flags (x); > set_used_flags (y); > @@ -3194,6 +3196,7 @@ noce_convert_multiple_sets (struct noce_if_info > *if_info) > } > > num_updated_if_blocks++; > + targets.release (); > return TRUE; > > suspiciously look like candidates for an auto_vec<> (didn't check). > > @@ -1240,6 +1240,7 @@ lra_create_live_ranges_1 (bool all_p, bool dead_insn_p) > dead_set = sparseset_alloc (max_regno); > unused_set = sparseset_alloc (max_regno); > curr_point = 0; > + point_freq_vec.release (); > point_freq_vec.create (get_max_uid () * 2); > > a truncate (0) instead of a release () should be cheaper, avoiding the > re-allocation. > > @@ -674,6 +674,10 @@ sra_deinitialize (void) > assign_link_pool.release (); > obstack_free (&name_obstack, NULL); > > + for (hash_map<tree, auto_vec<access_p> >::iterator it = > + base_access_vec->begin (); it != base_access_vec->end (); ++it) > + (*it).second.release (); > + > delete base_access_vec; > > I wonder if the better fix is to provide a proper free method for the > hash_map? > A hash_map with 'auto_vec' looks suspicous - eventually a proper release > was intented here via default_hash_map_traits <>? > > Anyway, most of the things above can be improved as followup of course. > > Thanks, > Richard. > >> Thanks, >> Martin
Hi. All suggested changes were applied, sending v2 and waiting for bootstrap and regression tests. Thanks, Martin
>From c97270f2daadcca1efe6201adf1eb0df469ca91e Mon Sep 17 00:00:00 2001 From: marxin <mli...@suse.cz> Date: Mon, 9 Nov 2015 10:49:14 +0100 Subject: [PATCH 1/2] Fix memory leaks and use a pool_allocator gcc/ChangeLog: 2015-11-09 Martin Liska <mli...@suse.cz> * gcc.c (record_temp_file): Release name string. * ifcvt.c (noce_convert_multiple_sets): Use auto_vec instead of vec. * lra-lives.c (free_live_range_list): Utilize lra_live_range_pool for allocation and deallocation. (create_live_range): Likewise. (copy_live_range): Likewise. (lra_merge_live_ranges): Likewise. (remove_some_program_points_and_update_live_ranges): Likewise. (lra_create_live_ranges_1): Release point_freq_vec that can be not freed from previous iteration of the function. * tree-eh.c (lower_try_finally_switch): Use auto_vec instead of vec. * tree-sra.c (sra_deinitialize): Release all vectors in base_access_vec. * tree-ssa-dom.c (free_dom_edge_info): Make the function extern. * tree-ssa-threadupdate.c (remove_ctrl_stmt_and_useless_edges): Release edge_info for a removed edge. (thread_through_all_blocks): Free region vector. * tree-ssa.h (free_dom_edge_info): Declare function extern. --- gcc/gcc.c | 5 ++++- gcc/ifcvt.c | 8 +++++--- gcc/lra-lives.c | 14 ++++++++------ gcc/tree-eh.c | 2 +- gcc/tree-sra.c | 6 ++++++ gcc/tree-ssa-dom.c | 8 ++++---- gcc/tree-ssa-threadupdate.c | 6 +++++- gcc/tree-ssa-threadupdate.h | 1 + 8 files changed, 34 insertions(+), 16 deletions(-) diff --git a/gcc/gcc.c b/gcc/gcc.c index bbc9b23..8bbf5be 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -2345,7 +2345,10 @@ record_temp_file (const char *filename, int always_delete, int fail_delete) struct temp_file *temp; for (temp = always_delete_queue; temp; temp = temp->next) if (! filename_cmp (name, temp->name)) - goto already1; + { + free (name); + goto already1; + } temp = XNEW (struct temp_file); temp->next = always_delete_queue; diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index fff62de..3401faa 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -3076,12 +3076,12 @@ noce_convert_multiple_sets (struct noce_if_info *if_info) rtx_code cond_code = GET_CODE (cond); /* The true targets for a conditional move. */ - vec<rtx> targets = vNULL; + auto_vec<rtx> targets; /* The temporaries introduced to allow us to not consider register overlap. */ - vec<rtx> temporaries = vNULL; + auto_vec<rtx> temporaries; /* The insns we've emitted. */ - vec<rtx_insn *> unmodified_insns = vNULL; + auto_vec<rtx_insn *> unmodified_insns; int count = 0; FOR_BB_INSNS (then_bb, insn) @@ -3161,6 +3161,8 @@ noce_convert_multiple_sets (struct noce_if_info *if_info) set_used_flags (targets[i]); } + temporaries.release (); + set_used_flags (cond); set_used_flags (x); set_used_flags (y); diff --git a/gcc/lra-lives.c b/gcc/lra-lives.c index 1655c47..9453759 100644 --- a/gcc/lra-lives.c +++ b/gcc/lra-lives.c @@ -103,7 +103,7 @@ free_live_range_list (lra_live_range_t lr) while (lr != NULL) { next = lr->next; - delete lr; + lra_live_range_pool.remove (lr); lr = next; } } @@ -112,7 +112,7 @@ free_live_range_list (lra_live_range_t lr) static lra_live_range_t create_live_range (int regno, int start, int finish, lra_live_range_t next) { - lra_live_range_t p = new lra_live_range; + lra_live_range_t p = lra_live_range_pool.allocate (); p->regno = regno; p->start = start; p->finish = finish; @@ -124,7 +124,7 @@ create_live_range (int regno, int start, int finish, lra_live_range_t next) static lra_live_range_t copy_live_range (lra_live_range_t r) { - return new lra_live_range (*r); + return new (lra_live_range_pool) lra_live_range (*r); } /* Copy live range list given by its head R and return the result. */ @@ -167,7 +167,7 @@ lra_merge_live_ranges (lra_live_range_t r1, lra_live_range_t r2) r1->start = r2->start; lra_live_range_t temp = r2; r2 = r2->next; - delete temp; + lra_live_range_pool.remove (temp); } else { @@ -1081,7 +1081,7 @@ remove_some_program_points_and_update_live_ranges (void) } prev_r->start = r->start; prev_r->next = next_r; - delete r; + lra_live_range_pool.remove (r); } } } @@ -1240,7 +1240,9 @@ lra_create_live_ranges_1 (bool all_p, bool dead_insn_p) dead_set = sparseset_alloc (max_regno); unused_set = sparseset_alloc (max_regno); curr_point = 0; - point_freq_vec.create (get_max_uid () * 2); + unsigned new_length = get_max_uid () * 2; + if (point_freq_vec.length () < new_length) + point_freq_vec.safe_grow (new_length); lra_point_freq = point_freq_vec.address (); int *post_order_rev_cfg = XNEWVEC (int, last_basic_block_for_fn (cfun)); int n_blocks_inverted = inverted_post_order_compute (post_order_rev_cfg); diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index 617d657..9f68f31 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -1362,7 +1362,7 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf) int return_index, eh_index, fallthru_index; int nlabels, ndests, j, last_case_index; tree last_case; - vec<tree> case_label_vec; + auto_vec<tree> case_label_vec; gimple_seq switch_body = NULL; gimple *x; geh_else *eh_else; diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index a896308..30aee19 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -674,6 +674,12 @@ sra_deinitialize (void) assign_link_pool.release (); obstack_free (&name_obstack, NULL); + /* TODO: hash_map does not support traits that can release + value type of the hash_map. */ + for (hash_map<tree, auto_vec<access_p> >::iterator it = + base_access_vec->begin (); it != base_access_vec->end (); ++it) + (*it).second.release (); + delete base_access_vec; } diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index 3887bbe1..5cb2644 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -121,8 +121,8 @@ static void dump_dominator_optimization_stats (FILE *file, /* Free the edge_info data attached to E, if it exists. */ -static void -free_edge_info (edge e) +void +free_dom_edge_info (edge e) { struct edge_info *edge_info = (struct edge_info *)e->aux; @@ -142,7 +142,7 @@ allocate_edge_info (edge e) struct edge_info *edge_info; /* Free the old one, if it exists. */ - free_edge_info (e); + free_dom_edge_info (e); edge_info = XCNEW (struct edge_info); @@ -167,7 +167,7 @@ free_all_edge_infos (void) { FOR_EACH_EDGE (e, ei, bb->preds) { - free_edge_info (e); + free_dom_edge_info (e); e->aux = NULL; } } diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c index 184cf34..c527206 100644 --- a/gcc/tree-ssa-threadupdate.c +++ b/gcc/tree-ssa-threadupdate.c @@ -290,7 +290,10 @@ remove_ctrl_stmt_and_useless_edges (basic_block bb, basic_block dest_bb) for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); ) { if (e->dest != dest_bb) - remove_edge (e); + { + free_dom_edge_info (e); + remove_edge (e); + } else ei_next (&ei); } @@ -2522,6 +2525,7 @@ thread_through_all_blocks (bool may_peel_loop_headers) delete_jump_thread_path (path); paths.unordered_remove (i); + free (region); } /* Remove from PATHS all the jump-threads starting with an edge already diff --git a/gcc/tree-ssa-threadupdate.h b/gcc/tree-ssa-threadupdate.h index 984b6c4..e0eb3f5 100644 --- a/gcc/tree-ssa-threadupdate.h +++ b/gcc/tree-ssa-threadupdate.h @@ -46,4 +46,5 @@ extern void register_jump_thread (vec <class jump_thread_edge *> *); extern void remove_jump_threads_including (edge); extern void delete_jump_thread_path (vec <class jump_thread_edge *> *); extern void remove_ctrl_stmt_and_useless_edges (basic_block, basic_block); +extern void free_dom_edge_info (edge); #endif -- 2.6.2