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.
This commit is contained in:
parent
2d5fb576bd
commit
c9da53d698
2 changed files with 65 additions and 42 deletions
|
@ -95,7 +95,15 @@ struct GTY((user)) modref_base_node
|
|||
|
||||
void collapse ()
|
||||
{
|
||||
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 ()
|
||||
{
|
||||
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 ();
|
||||
|
|
|
@ -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,27 +637,21 @@ 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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
summary->stores_lto = modref_records_lto::create_ggc
|
||||
(param_modref_max_bases,
|
||||
param_modref_max_refs);
|
||||
}
|
||||
summary->finished = false;
|
||||
|
@ -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
|
||||
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
|
||||
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
|
||||
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++]))
|
||||
|
|
Loading…
Add table
Reference in a new issue