diff mbox

Add a way to free tree node

Message ID 20151124084538.GB90197@kam.mff.cuni.cz
State New
Headers show

Commit Message

Jan Hubicka Nov. 24, 2015, 8:45 a.m. UTC
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?


	* tree.c (free_node): New function.
	(type_hash_canon): Use it.
	* tree.h (free_node): Declare.
	* lto.c (unify_scc): Use free_node.

Comments

Richard Biener Nov. 24, 2015, 9:59 a.m. UTC | #1
On Tue, Nov 24, 2015 at 9:45 AM, Jan Hubicka <hubicka@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;
Bernhard Reutner-Fischer Nov. 24, 2015, 8 p.m. UTC | #2
On November 24, 2015 10:59:01 AM GMT+01:00, Richard Biener <richard.guenther@gmail.com> wrote:
>On Tue, Nov 24, 2015 at 9:45 AM, Jan Hubicka <hubicka@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;
diff mbox

Patch

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;