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. 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;