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;

Reply via email to