> > On Wed, Nov 25, 2020 at 3:11 PM Jan Hubicka <hubi...@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 ();
 }
 
 /* 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.  */

Reply via email to