aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2020-09-24 08:28:09 +0200
committerJan Hubicka <jh@suse.cz>2020-09-24 08:28:09 +0200
commitc9da53d6987af5f8ff68b58dd76a9fbc900a6a21 (patch)
treee0bed9ee6fe0d60237cdb71cbae19944289b800a /gcc
parent2d5fb576bdda843da47aea2e025bb5d45e883827 (diff)
downloadgcc-c9da53d6987af5f8ff68b58dd76a9fbc900a6a21.zip
gcc-c9da53d6987af5f8ff68b58dd76a9fbc900a6a21.tar.gz
gcc-c9da53d6987af5f8ff68b58dd76a9fbc900a6a21.tar.bz2
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ipa-modref-tree.h36
-rw-r--r--gcc/ipa-modref.c71
2 files changed, 65 insertions, 42 deletions
diff --git a/gcc/ipa-modref-tree.h b/gcc/ipa-modref-tree.h
index 3bdd305..82e959a 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 9cc9056..43545c1 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++]))