public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r11-3424] Fix memory allocations in ipa-modref.
@ 2020-09-24  6:28 Jan Hubicka
  0 siblings, 0 replies; only message in thread
From: Jan Hubicka @ 2020-09-24  6:28 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:c9da53d6987af5f8ff68b58dd76a9fbc900a6a21

commit r11-3424-gc9da53d6987af5f8ff68b58dd76a9fbc900a6a21
Author: Jan Hubicka <jh@suse.cz>
Date:   Thu Sep 24 08:28:09 2020 +0200

    Fix memory allocations in ipa-modref.
    
    Pair ggc_delete with ggc_alloc_no_dtor.  I copy same scheme as used by Martin
    in ipa-fnsummary, that is creating a static member function create_ggc hidding
    the ugly bits and using it in ipa-modref.c.
    
    I also noticed that modref-tree leaks memory on destruction/collapse method and
    fixed that.
    
    Bootstrapped/regtested x86_64-linux.
    
    gcc/ChangeLog:
    
    2020-09-24  Jan Hubicka  <hubicka@ucw.cz>
    
            * ipa-modref-tree.h (modref_base::collapse): Release memory.
            (modref_tree::create_ggc): New member function.
            (modref_tree::colapse): Release memory.
            (modref_tree::~modref_tree): New destructor.
            * ipa-modref.c (modref_summaries::create_ggc): New function.
            (analyze_function): Use create_ggc.
            (modref_summaries::duplicate): Likewise.
            (read_modref_records): Likewise.
            (modref_read): Likewise.

Diff:
---
 gcc/ipa-modref-tree.h | 36 ++++++++++++++++++++++++--
 gcc/ipa-modref.c      | 71 ++++++++++++++++++++++-----------------------------
 2 files changed, 65 insertions(+), 42 deletions(-)

diff --git a/gcc/ipa-modref-tree.h b/gcc/ipa-modref-tree.h
index 3bdd3058aa1..82e959a7d46 100644
--- a/gcc/ipa-modref-tree.h
+++ b/gcc/ipa-modref-tree.h
@@ -95,7 +95,15 @@ struct GTY((user)) modref_base_node
 
   void collapse ()
   {
-    vec_free (refs);
+    size_t i;
+    modref_ref_node <T> *r;
+
+    if (refs)
+      {
+	FOR_EACH_VEC_SAFE_ELT (refs, i, r)
+	  ggc_free (r);
+	vec_free (refs);
+      }
     refs = NULL;
     every_ref = true;
   }
@@ -214,12 +222,36 @@ struct GTY((user)) modref_tree
     return NULL;
   }
 
+  /* Return ggc allocated instance.  We explicitly call destructors via
+     ggc_delete and do not want finalizers to be registered and
+     called at the garbage collection time.  */
+  static modref_tree<T> *create_ggc (size_t max_bases, size_t max_refs)
+  {
+    return new (ggc_alloc_no_dtor<modref_tree<T>> ())
+	 modref_tree<T> (max_bases, max_refs);
+  }
+
   void collapse ()
   {
-    vec_free (bases);
+    size_t i;
+    modref_base_node <T> *n;
+
+    if (bases)
+      {
+	FOR_EACH_VEC_SAFE_ELT (bases, i, n)
+	  {
+	    n->collapse ();
+	    ggc_free (n);
+	  }
+	vec_free (bases);
+      }
     bases = NULL;
     every_base = true;
   }
+  ~modref_tree ()
+  {
+    collapse ();
+  }
 };
 
 void modref_c_tests ();
diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c
index 9cc90565891..43545c1fb09 100644
--- a/gcc/ipa-modref.c
+++ b/gcc/ipa-modref.c
@@ -84,6 +84,11 @@ public:
      ipa-modref pass execution needs to be analyzed in IPA mode while all
      other insertions leads to normal analysis.  */
   bool ipa;
+  static modref_summaries *create_ggc (symbol_table *symtab)
+  {
+    return new (ggc_alloc_no_dtor<modref_summaries> ())
+	     modref_summaries (symtab);
+  }
 };
 
 /* Global variable holding all modref summaries.  */
@@ -608,8 +613,7 @@ analyze_function (function *f, bool ipa)
 
   /* Initialize the summary.  */
   if (!summaries)
-    summaries = new (ggc_alloc <modref_summaries> ())
-		     modref_summaries (symtab);
+    summaries = modref_summaries::create_ggc (symtab);
   else /* Remove existing summary if we are re-running the pass.  */
     summaries->remove (cgraph_node::get (f->decl));
 
@@ -633,28 +637,22 @@ analyze_function (function *f, bool ipa)
   if (nolto)
     {
       gcc_assert (!summary->loads);
-      summary->loads
-	 = new (ggc_alloc <modref_tree<alias_set_type> > ())
-		modref_records (param_modref_max_bases,
-				param_modref_max_refs);
+      summary->loads = modref_records::create_ggc (param_modref_max_bases,
+						   param_modref_max_refs);
       gcc_assert (!summary->stores);
-      summary->stores
-	 = new (ggc_alloc <modref_tree<alias_set_type> > ())
-		modref_records (param_modref_max_bases,
-				param_modref_max_refs);
+      summary->stores = modref_records::create_ggc (param_modref_max_bases,
+						    param_modref_max_refs);
     }
   if (lto)
     {
       gcc_assert (!summary->loads_lto);
-      summary->loads_lto
-	 = new (ggc_alloc <modref_tree<tree> > ())
-		modref_records_lto (param_modref_max_bases,
-				    param_modref_max_refs);
+      summary->loads_lto = modref_records_lto::create_ggc
+				 (param_modref_max_bases,
+				  param_modref_max_refs);
       gcc_assert (!summary->stores_lto);
-      summary->stores_lto
-	 = new (ggc_alloc <modref_tree<tree> > ())
-		modref_records_lto (param_modref_max_bases,
-				    param_modref_max_refs);
+      summary->stores_lto = modref_records_lto::create_ggc
+				 (param_modref_max_bases,
+				  param_modref_max_refs);
     }
   summary->finished = false;
   int ecf_flags = flags_from_decl_or_type (current_function_decl);
@@ -730,34 +728,30 @@ modref_summaries::duplicate (cgraph_node *, cgraph_node *,
   dst_data->finished = src_data->finished;
   if (src_data->stores)
     {
-      dst_data->stores = new (ggc_alloc <modref_tree<alias_set_type> > ())
-			      modref_records
-				 (src_data->stores->max_bases,
-				  src_data->stores->max_refs);
+      dst_data->stores = modref_records::create_ggc
+			    (src_data->stores->max_bases,
+			     src_data->stores->max_refs);
       dst_data->stores->merge (src_data->stores);
     }
   if (src_data->loads)
     {
-      dst_data->loads = new (ggc_alloc <modref_tree<alias_set_type> > ())
-			     modref_records
-				(src_data->loads->max_bases,
-				 src_data->loads->max_refs);
+      dst_data->loads = modref_records::create_ggc
+			    (src_data->loads->max_bases,
+			     src_data->loads->max_refs);
       dst_data->loads->merge (src_data->loads);
     }
   if (src_data->stores_lto)
     {
-      dst_data->stores_lto = new (ggc_alloc <modref_tree<tree> > ())
-				  modref_records_lto
-				    (src_data->stores_lto->max_bases,
-				     src_data->stores_lto->max_refs);
+      dst_data->stores_lto = modref_records_lto::create_ggc
+			    (src_data->stores_lto->max_bases,
+			     src_data->stores_lto->max_refs);
       dst_data->stores_lto->merge (src_data->stores_lto);
     }
   if (src_data->loads_lto)
     {
-      dst_data->loads_lto = new (ggc_alloc <modref_tree<tree> > ())
-				  modref_records_lto
-				    (src_data->stores_lto->max_bases,
-				     src_data->stores_lto->max_refs);
+      dst_data->loads_lto = modref_records_lto::create_ggc
+			    (src_data->loads_lto->max_bases,
+			     src_data->loads_lto->max_refs);
       dst_data->loads_lto->merge (src_data->loads_lto);
     }
 }
@@ -838,11 +832,9 @@ read_modref_records (lto_input_block *ib, struct data_in *data_in,
   /* Decide whether we want to turn LTO data types to non-LTO (i.e. when
      LTO re-streaming is not going to happen).  */
   if (flag_wpa || flag_incremental_link == INCREMENTAL_LINK_LTO)
-    *lto_ret = new (ggc_alloc <modref_records_lto> ()) modref_records_lto
-			      (max_bases, max_refs);
+    *lto_ret = modref_records_lto::create_ggc (max_bases, max_refs);
   else
-    *nolto_ret = new (ggc_alloc <modref_records> ()) modref_records
-			      (max_bases, max_refs);
+    *nolto_ret = modref_records::create_ggc (max_bases, max_refs);
 
   size_t every_base = streamer_read_uhwi (ib);
   size_t nbase = streamer_read_uhwi (ib);
@@ -1048,8 +1040,7 @@ modref_read (void)
   unsigned int j = 0;
 
   if (!summaries)
-    summaries = new (ggc_alloc <modref_summaries> ())
-		     modref_summaries (symtab);
+    summaries = modref_summaries::create_ggc (symtab);
   ((modref_summaries *)summaries)->ipa = true;
 
   while ((file_data = file_data_vec[j++]))


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-09-24  6:28 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-24  6:28 [gcc r11-3424] Fix memory allocations in ipa-modref Jan Hubicka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).