On Tue, 24 Nov 2020, Jan Hubicka wrote: > Hi, > at the end of processing function body we loop over basic blocks and > free all edges while we do not free the rest. I think this is leftover > from time eges was not garbage collected and we was not using ggc_free. > It makes more sense to free all associated structures (which is > importnat for WPA memory footprint). > > Bootstrapped/regtested x86_64-linux, OK?
OK. > Honza > > * cfg.c (free_block): New function. > (clear_edges): Rename to .... > (free_cfg): ... this one; also free BBs and vectors. > (expunge_block): Update comment. > * cfg.h (clear_edges): Rename to ... > (free_cfg): ... this one. > * cgraph.c (release_function_body): Use free_cfg. > diff --git a/gcc/cfg.c b/gcc/cfg.c > index de0e71db850..fc78e48d6e1 100644 > --- a/gcc/cfg.c > +++ b/gcc/cfg.c > @@ -25,7 +25,7 @@ along with GCC; see the file COPYING3. If not see > > Available functionality: > - Initialization/deallocation > - init_flow, clear_edges > + init_flow, free_cfg > - Low level basic block manipulation > alloc_block, expunge_block > - Edge manipulation > @@ -83,7 +83,7 @@ init_flow (struct function *the_fun) > the_fun->cfg->bb_flags_allocated = BB_ALL_FLAGS; > } > > -/* Helper function for remove_edge and clear_edges. Frees edge structure > +/* Helper function for remove_edge and free_cffg. Frees edge structure > without actually removing it from the pred/succ arrays. */ > > static void > @@ -93,29 +93,41 @@ free_edge (function *fn, edge e) > ggc_free (e); > } > > -/* Free the memory associated with the edge structures. */ > +/* Free basic block BB. */ > + > +static void > +free_block (basic_block bb) > +{ > + vec_free (bb->succs); > + vec_free (bb->preds); > + ggc_free (bb); > +} > + > +/* Free the memory associated with the CFG in FN. */ > > void > -clear_edges (struct function *fn) > +free_cfg (struct function *fn) > { > - basic_block bb; > edge e; > edge_iterator ei; > + basic_block next; > > - FOR_EACH_BB_FN (bb, fn) > + for (basic_block bb = ENTRY_BLOCK_PTR_FOR_FN (fn); bb; bb = next) > { > + next = bb->next_bb; > FOR_EACH_EDGE (e, ei, bb->succs) > free_edge (fn, e); > - vec_safe_truncate (bb->succs, 0); > - vec_safe_truncate (bb->preds, 0); > + free_block (bb); > } > > - FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR_FOR_FN (fn)->succs) > - free_edge (fn, e); > - vec_safe_truncate (EXIT_BLOCK_PTR_FOR_FN (fn)->preds, 0); > - vec_safe_truncate (ENTRY_BLOCK_PTR_FOR_FN (fn)->succs, 0); > - > gcc_assert (!n_edges_for_fn (fn)); > + /* Sanity check that dominance tree is freed. */ > + gcc_assert (!fn->cfg->x_dom_computed[0] && !fn->cfg->x_dom_computed[1]); > + > + vec_free (fn->cfg->x_label_to_block_map); > + vec_free (basic_block_info_for_fn (fn)); > + ggc_free (fn->cfg); > + fn->cfg = NULL; > } > > /* Allocate memory for basic_block. */ > @@ -190,8 +202,8 @@ expunge_block (basic_block b) > /* We should be able to ggc_free here, but we are not. > The dead SSA_NAMES are left pointing to dead statements that are > pointing > to dead basic blocks making garbage collector to die. > - We should be able to release all dead SSA_NAMES and at the same time we > should > - clear out BB pointer of dead statements consistently. */ > + We should be able to release all dead SSA_NAMES and at the same time we > + should clear out BB pointer of dead statements consistently. */ > } > > /* Connect E to E->src. */ > diff --git a/gcc/cfg.h b/gcc/cfg.h > index 93fde6df2bf..a9c8300f173 100644 > --- a/gcc/cfg.h > +++ b/gcc/cfg.h > @@ -82,7 +82,7 @@ struct GTY(()) control_flow_graph { > > > extern void init_flow (function *); > -extern void clear_edges (function *); > +extern void free_cfg (function *); > extern basic_block alloc_block (void); > extern void link_block (basic_block, basic_block); > extern void unlink_block (basic_block); > diff --git a/gcc/cgraph.c b/gcc/cgraph.c > index 19dfe2be23b..5c48a1bb92b 100644 > --- a/gcc/cgraph.c > +++ b/gcc/cgraph.c > @@ -1811,7 +1811,7 @@ release_function_body (tree decl) > gcc_assert (!dom_info_available_p (fn, CDI_DOMINATORS)); > gcc_assert (!dom_info_available_p (fn, CDI_POST_DOMINATORS)); > delete_tree_cfg_annotations (fn); > - clear_edges (fn); > + free_cfg (fn); > fn->cfg = NULL; > } > if (fn->value_histograms) > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Felix Imend