diff mbox series

[C++] Re: Free more of CFG in release_function_body

Message ID 20201127132622.GB78170@kam.mff.cuni.cz
State New
Headers show
Series [C++] Re: Free more of CFG in release_function_body | expand

Commit Message

Jan Hubicka Nov. 27, 2020, 1:26 p.m. UTC
> > On Wed, Nov 25, 2020 at 3:11 PM Jan Hubicka <hubicka@ucw.cz> wrote:
> > >
> > > > 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.
> > >
> > > Unforutnately the patch does not surive LTO bootstrap.  The problem is
> > > that we keep DECL_INITIAL that points to blocks and blocks points to
> > > var_decls and these points to SSA_NAMES that points to statements and
> > > those points to basic blocks.
> > 
> > VAR_DECLs point to SSA_NAMEs?  It's the other way around.  We for sure
> > free SSA_NAMEs (well, maybe not explicitely with ggc_free).
> 
> I am going to debug this more carefully now.  I think it was VAR_DECL
> with variadic type pointing to SSA_NAME.  Should be easy to reduct with
> gcac compiler.

Hi,
it turns out that the pointers to statements leaks through saved scopes
in C++ FE.  Scopes seems to point to internal blocks of functions even
after we finish their compiling.

This patch adds code to free pointers.  I tried to clear saved_blocks
but it breaks since C++ finalization uses them, but it does not look
into previous class levels.

Patch lto-bootstraps/regtestes x86_64-linux with all languages. OK?

Honza

	* cfg.c (free_block): Call ggc_free on BB itself.

	* cp-tre.eh (cp_tree_c_finish_parsing): Declare.
	* semantics.c (finish_translation_unit): Call finish_parsing
	* tree.c (cp_tree_c_finish_parsing): New function.

Comments

Jeff Law Nov. 30, 2020, 1:24 a.m. UTC | #1
On 11/27/20 6:26 AM, Jan Hubicka wrote:
>>> On Wed, Nov 25, 2020 at 3:11 PM Jan Hubicka <hubicka@ucw.cz> wrote:
>>>>> 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.
>>>> Unforutnately the patch does not surive LTO bootstrap.  The problem is
>>>> that we keep DECL_INITIAL that points to blocks and blocks points to
>>>> var_decls and these points to SSA_NAMES that points to statements and
>>>> those points to basic blocks.
>>> VAR_DECLs point to SSA_NAMEs?  It's the other way around.  We for sure
>>> free SSA_NAMEs (well, maybe not explicitely with ggc_free).
>> I am going to debug this more carefully now.  I think it was VAR_DECL
>> with variadic type pointing to SSA_NAME.  Should be easy to reduct with
>> gcac compiler.
> Hi,
> it turns out that the pointers to statements leaks through saved scopes
> in C++ FE.  Scopes seems to point to internal blocks of functions even
> after we finish their compiling.
>
> This patch adds code to free pointers.  I tried to clear saved_blocks
> but it breaks since C++ finalization uses them, but it does not look
> into previous class levels.
>
> Patch lto-bootstraps/regtestes x86_64-linux with all languages. OK?
>
> Honza
>
> 	* cfg.c (free_block): Call ggc_free on BB itself.
I'll ACK this bit.  The C++ team should own the rest, while it looks
reasonable to me, there may be some reason I'm not aware of that they're
keeping that stuff around.

Jeff
Jason Merrill Nov. 30, 2020, 10:28 p.m. UTC | #2
On 11/27/20 8:26 AM, Jan Hubicka wrote:
>>> On Wed, Nov 25, 2020 at 3:11 PM Jan Hubicka <hubicka@ucw.cz> wrote:
>>>>
>>>>> 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.
>>>>
>>>> Unforutnately the patch does not surive LTO bootstrap.  The problem is
>>>> that we keep DECL_INITIAL that points to blocks and blocks points to
>>>> var_decls and these points to SSA_NAMES that points to statements and
>>>> those points to basic blocks.
>>>
>>> VAR_DECLs point to SSA_NAMEs?  It's the other way around.  We for sure
>>> free SSA_NAMEs (well, maybe not explicitely with ggc_free).
>>
>> I am going to debug this more carefully now.  I think it was VAR_DECL
>> with variadic type pointing to SSA_NAME.  Should be easy to reduct with
>> gcac compiler.
> 
> Hi,
> it turns out that the pointers to statements leaks through saved scopes
> in C++ FE.  Scopes seems to point to internal blocks of functions even
> after we finish their compiling.
> 
> This patch adds code to free pointers.  I tried to clear saved_blocks
> but it breaks since C++ finalization uses them, but it does not look
> into previous class levels.
> 
> Patch lto-bootstraps/regtestes x86_64-linux with all languages. OK?
> 
> Honza
> 
> 	* cfg.c (free_block): Call ggc_free on BB itself.
> 
> 	* cp-tre.eh (cp_tree_c_finish_parsing): Declare.
> 	* semantics.c (finish_translation_unit): Call finish_parsing
> 	* tree.c (cp_tree_c_finish_parsing): New function.
> diff --git a/gcc/cfg.c b/gcc/cfg.c
> index 529b6ed2105..e8bd1456c9f 100644
> --- a/gcc/cfg.c
> +++ b/gcc/cfg.c
> @@ -102,8 +102,7 @@ free_block (basic_block bb)
>      bb->succs = NULL;
>      vec_free (bb->preds);
>      bb->preds = NULL;
> -   /* Do not free BB itself yet since we leak pointers to dead statements
> -      that points to dead basic blocks.  */
> +   ggc_free (bb);
>   }
>   
>   /* Free the memory associated with the CFG in FN.  */
> diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
> index 021de76e142..665d171d9b0 100644
> --- a/gcc/cp/cp-tree.h
> +++ b/gcc/cp/cp-tree.h
> @@ -7986,6 +7986,8 @@ struct uid_sensitive_constexpr_evaluation_checker
>     bool evaluation_restricted_p () const;
>   };
>   
> +void cp_tree_c_finish_parsing ();
> +
>   /* In cp-ubsan.c */
>   extern void cp_ubsan_maybe_instrument_member_call (tree);
>   extern void cp_ubsan_instrument_member_accesses (tree *);
> diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
> index 5ff70ff4844..e9d17c21985 100644
> --- a/gcc/cp/semantics.c
> +++ b/gcc/cp/semantics.c
> @@ -3094,6 +3094,7 @@ finish_translation_unit (void)
>   	       "%<#pragma omp end declare target%>");
>         scope_chain->omp_declare_target_attribute = 0;
>       }
> +  cp_tree_c_finish_parsing ();

This is too soon for this call; it should be from c_parse_final_cleanups 
by the call to fini_constexpr, so that it follows template instantiation 
at EOF.

>   }
>   
>   /* Finish a template type parameter, specified as AGGR IDENTIFIER.
> diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
> index 28e591086b3..e63d383c0a3 100644
> --- a/gcc/cp/tree.c
> +++ b/gcc/cp/tree.c
> @@ -5844,6 +5844,19 @@ maybe_warn_zero_as_null_pointer_constant (tree expr, location_t loc)
>     return false;
>   }
>   
> +/* Release memory we no longer need after parsing.  */
> +void
> +cp_tree_c_finish_parsing ()
> +{
> +  saved_scope *chain = scope_chain;
> +  while (chain)
> +    {
> +      chain->x_previous_class_level = NULL;
> +      chain = chain->prev;
> +    }

This can just be invalidate_class_lookup_cache ().  scope_chain->prev 
will always be NULL at this point.

OK with those changes.

> +  deleted_copy_types = NULL;
> +}
> +
>   #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
>   /* Complain that some language-specific thing hanging off a tree
>      node has been accessed improperly.  */
diff mbox series

Patch

diff --git a/gcc/cfg.c b/gcc/cfg.c
index 529b6ed2105..e8bd1456c9f 100644
--- a/gcc/cfg.c
+++ b/gcc/cfg.c
@@ -102,8 +102,7 @@  free_block (basic_block bb)
    bb->succs = NULL;
    vec_free (bb->preds);
    bb->preds = NULL;
-   /* Do not free BB itself yet since we leak pointers to dead statements
-      that points to dead basic blocks.  */
+   ggc_free (bb);
 }
 
 /* Free the memory associated with the CFG in FN.  */
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 021de76e142..665d171d9b0 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7986,6 +7986,8 @@  struct uid_sensitive_constexpr_evaluation_checker
   bool evaluation_restricted_p () const;
 };
 
+void cp_tree_c_finish_parsing ();
+
 /* In cp-ubsan.c */
 extern void cp_ubsan_maybe_instrument_member_call (tree);
 extern void cp_ubsan_instrument_member_accesses (tree *);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 5ff70ff4844..e9d17c21985 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -3094,6 +3094,7 @@  finish_translation_unit (void)
 	       "%<#pragma omp end declare target%>");
       scope_chain->omp_declare_target_attribute = 0;
     }
+  cp_tree_c_finish_parsing ();
 }
 
 /* Finish a template type parameter, specified as AGGR IDENTIFIER.
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 28e591086b3..e63d383c0a3 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -5844,6 +5844,19 @@  maybe_warn_zero_as_null_pointer_constant (tree expr, location_t loc)
   return false;
 }
 
+/* Release memory we no longer need after parsing.  */
+void
+cp_tree_c_finish_parsing ()
+{
+  saved_scope *chain = scope_chain;
+  while (chain)
+    {
+      chain->x_previous_class_level = NULL;
+      chain = chain->prev;
+    }
+  deleted_copy_types = NULL;
+}
+
 #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
 /* Complain that some language-specific thing hanging off a tree
    node has been accessed improperly.  */