On 11/27/20 8:26 AM, Jan Hubicka wrote:
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 ();

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.  */

Reply via email to