On November 24, 2015 10:59:01 AM GMT+01:00, Richard Biener <richard.guent...@gmail.com> wrote: >On Tue, Nov 24, 2015 at 9:45 AM, Jan Hubicka <hubi...@ucw.cz> wrote: >> Hi, >> while looking into the earlier bug I noticed that type_hash_canon is >used to >> avoid producing type duplicates. The type is however created, then >looked up >> in the cache and if it exists it is never used. The function takes >care to >> remove the code found memory stats but never actually free it. I >suppose it is >> artifact of conversion from obstack to ggc. We produce a lot of type >duplicates >> this way that is not very cool. >> >> It always bit bothered me that unify_scc does not update the >statistics so >> this patch introduces free_node that can be used to free given tree >node. >> >> Bootstrapped/regtested x86_64-linux, OK? > >Ok.
ISTM that you could have used code also for the statistics. Thanks, > >Thanks, >Richard. > >> >> * tree.c (free_node): New function. >> (type_hash_canon): Use it. >> * tree.h (free_node): Declare. >> * lto.c (unify_scc): Use free_node. >> >> Index: tree.c >> =================================================================== >> --- tree.c (revision 230718) >> +++ tree.c (working copy) >> @@ -1103,6 +1103,27 @@ make_node_stat (enum tree_code code MEM_ >> >> return t; >> } >> + >> +/* Free tree node. */ >> + >> +void >> +free_node (tree node) >> +{ >> + enum tree_code code = TREE_CODE (node); >> + if (GATHER_STATISTICS) >> + { >> + tree_code_counts[(int) TREE_CODE (node)]--; >> + tree_node_counts[(int) t_kind]--; >> + tree_node_sizes[(int) t_kind] -= tree_code_size (TREE_CODE >(node)); >> + } >> + if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR)) >> + vec_free (CONSTRUCTOR_ELTS (node)); >> + else if (code == BLOCK) >> + vec_free (BLOCK_NONLOCALIZED_VARS (node)); >> + else if (code == TREE_BINFO) >> + vec_free (BINFO_BASE_ACCESSES (node)); >> + ggc_free (node); >> +} >> >> /* Return a new node with the same contents as NODE except that its >> TREE_CHAIN, if it has one, is zero and it has a fresh uid. */ >> @@ -7100,12 +7123,7 @@ type_hash_canon (unsigned int hashcode, >> { >> tree t1 = ((type_hash *) *loc)->type; >> gcc_assert (TYPE_MAIN_VARIANT (t1) == t1); >> - if (GATHER_STATISTICS) >> - { >> - tree_code_counts[(int) TREE_CODE (type)]--; >> - tree_node_counts[(int) t_kind]--; >> - tree_node_sizes[(int) t_kind] -= sizeof (struct >tree_type_non_common); >> - } >> + free_node (type); >> return t1; >> } >> else >> Index: tree.h >> =================================================================== >> --- tree.h (revision 230718) >> +++ tree.h (working copy) >> @@ -3763,6 +3763,10 @@ extern int allocate_decl_uid (void); >> extern tree make_node_stat (enum tree_code MEM_STAT_DECL); >> #define make_node(t) make_node_stat (t MEM_STAT_INFO) >> >> +/* Free tree node. */ >> + >> +extern void free_node (tree); >> + >> /* Make a copy of a node, with all the same contents. */ >> >> extern tree copy_node_stat (tree MEM_STAT_DECL); >> Index: lto/lto.c >> =================================================================== >> --- lto/lto.c (revision 230718) >> +++ lto/lto.c (working copy) >> @@ -1623,13 +1622,9 @@ unify_scc (struct data_in *data_in, unsi >> data_in->location_cache.revert_location_cache (); >> for (unsigned i = 0; i < len; ++i) >> { >> - enum tree_code code; >> if (TYPE_P (scc->entries[i])) >> num_merged_types++; >> - code = TREE_CODE (scc->entries[i]); >> - if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR)) >> - vec_free (CONSTRUCTOR_ELTS (scc->entries[i])); >> - ggc_free (scc->entries[i]); >> + free_node (scc->entries[i]); >> } >> >> break;