Apart from that, I noticed that when using GGC memory, the machinery implicitly calls dtors for types
that have __has_trivial_destructor == true. That's case of ipa_node_params_t, but as symbol_summary already
calls a dtor before ggc_free is called. Problem comes when hash_table marks a memory slot as empty and GGC finalizer
calls dtor for an invalid memory. Thus I believe not using such finalizer is proper fix.
Last change fixes issue where ipa_free_all_node_params destroys a symbol_summary (living in GGC memory) and dtor
is called for second time via ggc release mechanism.
Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.
Ready to be installed?
Martin
From 08a3ecda47d9d52cd4bb6435aaf18b5b099ef683 Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Thu, 2 Feb 2017 11:13:13 +0100
Subject: [PATCH] Fix memory leaks in IPA CP (PR ipa/79337).
gcc/ChangeLog:
2017-02-02 Martin Liska <mliska@suse.cz>
PR ipa/79337
* ipa-prop.c (ipa_node_params_t::insert): Remove current
implementation.
(ipa_node_params_t::remove): Likewise.
* ipa-prop.h (ipa_node_params::ipa_node_params): Make default
initialization from ipa_node_params_t::insert.
(ipa_node_params::~ipa_node_params): Move from
ipa_node_params_t::release.
* symbol-summary.h (symbol_summary::m_released): New member.
Do not release a summary twice. Do not allow to call finalizer
for types of a summary that live in GGC memory.
---
gcc/ipa-prop.c | 32 --------------------------------
gcc/ipa-prop.h | 28 ++++++++++++++++++++++++++--
gcc/symbol-summary.h | 27 ++++++++++++++-------------
3 files changed, 40 insertions(+), 47 deletions(-)
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index 93a2390c321..8c5ba25fcec 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -320,6 +320,12 @@ struct GTY(()) ipa_param_descriptor
struct GTY((for_user)) ipa_node_params
{
+ /* Default constructor. */
+ ipa_node_params ();
+
+ /* Default destructor. */
+ ~ipa_node_params ();
+
/* Information about individual formal parameters that are gathered when
summaries are generated. */
vec<ipa_param_descriptor, va_gc> *descriptors;
@@ -356,6 +362,24 @@ struct GTY((for_user)) ipa_node_params
unsigned versionable : 1;
};
+inline
+ipa_node_params::ipa_node_params ()
+: descriptors (NULL), lattices (NULL), ipcp_orig_node (NULL),
+ known_csts (vNULL), known_contexts (vNULL), analysis_done (0),
+ node_enqueued (0), do_clone_for_all_contexts (0), is_all_contexts_clone (0),
+ node_dead (0), node_within_scc (0), node_calling_single_call (0),
+ versionable (0)
+{
+}
+
+inline
+ipa_node_params::~ipa_node_params ()
+{
+ free (lattices);
+ known_csts.release ();
+ known_contexts.release ();
+}
+
/* Intermediate information that we get from alias analysis about a particular
parameter in a particular basic_block. When a parameter or the memory it
references is marked modified, we use that information in all dominated
@@ -580,9 +604,9 @@ public:
function_summary<ipa_node_params *> (table, ggc) { }
/* Hook that is called by summary when a node is deleted. */
- virtual void insert (cgraph_node *, ipa_node_params *info);
+ virtual void insert (cgraph_node *, ipa_node_params *) {}
/* Hook that is called by summary when a node is deleted. */
- virtual void remove (cgraph_node *, ipa_node_params *info);
+ virtual void remove (cgraph_node *, ipa_node_params *) {}