Hello. The patch removes memory leaks that are caused by overwriting an existing item in stmt_vec_info_vec (in set_vinfo_for_stmt). My first attempt was to call free_stmt_vec_info for old entries that are overwritten, but it caused double frees as there are some references between stmt_vec_infos.
So that I've decided to allocate all stmt_vec_info structures from a memory pool, which is released in free_stmt_vec_info_vec routine. Replacing 'vec' (used for simd_clone_info and same_align_regs) to 'auto_vec' helps to reduce another leaks. To be honest, the solution is not ideal as destructor of there auto_vec is not called, however with the patch applied, there is just a single memory leak in the whole test-suite related to tree-vect-stmts.c (which is unrelated to these vectors). Patch can bootstrap and survives regression tests on x86_64-unknown-linux-gnu. Ready for trunk? Martin
>From a2f09db0c4fe3920c744ccc77cf5e28b2a7df458 Mon Sep 17 00:00:00 2001 From: marxin <mli...@suse.cz> Date: Wed, 2 Dec 2015 12:59:00 +0100 Subject: [PATCH 1/2] Fix memory leak in tree-vectorizer.h gcc/ChangeLog: 2015-12-07 Martin Liska <mli...@suse.cz> * tree-loop-distribution.c: Include alloc-pool.h. * tree-parloops.c: Likewise. * tree-ssa-loop-ivopts.c: Likewise. * tree-ssa-loop-manip.c: Likewise. * tree-ssa-loop.c: Likewise. * tree-vect-data-refs.c: Likewise. * tree-vect-loop-manip.c: Likewise. * tree-vect-loop.c: Likewise. * tree-vect-patterns.c: Likewise. * tree-vect-slp.c: Likewise. * tree-vect-stmts.c (vectorizable_simd_clone_call): Do not release arginfo. (new_stmt_vec_info): Allocate stmt_vec_info from a newly added pool allocator. (free_stmt_vec_info_vec): Release the pool. (free_stmt_vec_info): Remove an entry from the memory pool. * tree-vectorizer.c (stmt_vec_info_pool): Declare the memory pool. * tree-vectorizer.h (struct _stmt_vec_info): Replace vec with auto_vec and provide default contructor. --- gcc/tree-loop-distribution.c | 1 + gcc/tree-parloops.c | 1 + gcc/tree-ssa-loop-ivopts.c | 1 + gcc/tree-ssa-loop-manip.c | 1 + gcc/tree-ssa-loop.c | 1 + gcc/tree-vect-data-refs.c | 1 + gcc/tree-vect-loop-manip.c | 1 + gcc/tree-vect-loop.c | 1 + gcc/tree-vect-patterns.c | 1 + gcc/tree-vect-slp.c | 1 + gcc/tree-vect-stmts.c | 27 ++++++++------------------- gcc/tree-vectorizer.c | 4 ++++ gcc/tree-vectorizer.h | 23 +++++++++++++++++++---- 13 files changed, 41 insertions(+), 23 deletions(-) diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c index a1936f0..637d8dd 100644 --- a/gcc/tree-loop-distribution.c +++ b/gcc/tree-loop-distribution.c @@ -63,6 +63,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-ssa.h" #include "cfgloop.h" #include "tree-scalar-evolution.h" +#include "alloc-pool.h" #include "tree-vectorizer.h" diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c index 9b564ca..a1085c1 100644 --- a/gcc/tree-parloops.c +++ b/gcc/tree-parloops.c @@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see #include "cfgloop.h" #include "tree-scalar-evolution.h" #include "langhooks.h" +#include "alloc-pool.h" #include "tree-vectorizer.h" #include "tree-hasher.h" #include "tree-parloops.h" diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index d7a0e9e..5204d13 100644 --- a/gcc/tree-ssa-loop-ivopts.c +++ b/gcc/tree-ssa-loop-ivopts.c @@ -101,6 +101,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-ssa-propagate.h" #include "tree-ssa-address.h" #include "builtins.h" +#include "alloc-pool.h" #include "tree-vectorizer.h" /* FIXME: Expressions are expanded to RTL in this pass to determine the diff --git a/gcc/tree-ssa-loop-manip.c b/gcc/tree-ssa-loop-manip.c index b614412..f1f9866 100644 --- a/gcc/tree-ssa-loop-manip.c +++ b/gcc/tree-ssa-loop-manip.c @@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-ssa-loop.h" #include "tree-into-ssa.h" #include "tree-ssa.h" +#include "alloc-pool.h" #include "cfgloop.h" #include "tree-scalar-evolution.h" #include "params.h" diff --git a/gcc/tree-ssa-loop.c b/gcc/tree-ssa-loop.c index cf7d94e..8dab786 100644 --- a/gcc/tree-ssa-loop.c +++ b/gcc/tree-ssa-loop.c @@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see #include "cfgloop.h" #include "tree-inline.h" #include "tree-scalar-evolution.h" +#include "alloc-pool.h" #include "tree-vectorizer.h" #include "omp-low.h" diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 8810af1..e39c804 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -45,6 +45,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-ssa-loop.h" #include "cfgloop.h" #include "tree-scalar-evolution.h" +#include "alloc-pool.h" #include "tree-vectorizer.h" #include "expr.h" #include "builtins.h" diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c index 226b88f..bac5763 100644 --- a/gcc/tree-vect-loop-manip.c +++ b/gcc/tree-vect-loop-manip.c @@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-ssa.h" #include "cfgloop.h" #include "tree-scalar-evolution.h" +#include "alloc-pool.h" #include "tree-vectorizer.h" /************************************************************************* diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index ee32166..4914e73 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -44,6 +44,7 @@ along with GCC; see the file COPYING3. If not see #include "cfgloop.h" #include "params.h" #include "tree-scalar-evolution.h" +#include "alloc-pool.h" #include "tree-vectorizer.h" #include "gimple-fold.h" #include "cgraph.h" diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index 4b225fb..d5549b2 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -36,6 +36,7 @@ along with GCC; see the file COPYING3. If not see #include "gimplify.h" #include "gimple-iterator.h" #include "cfgloop.h" +#include "alloc-pool.h" #include "tree-vectorizer.h" #include "dumpfile.h" #include "builtins.h" diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index b893682..8df6343 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see #include "stor-layout.h" #include "gimple-iterator.h" #include "cfgloop.h" +#include "alloc-pool.h" #include "tree-vectorizer.h" #include "langhooks.h" #include "gimple-walk.h" diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 9f11652..b5b2572 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -45,6 +45,7 @@ along with GCC; see the file COPYING3. If not see #include "cfgloop.h" #include "tree-ssa-loop.h" #include "tree-scalar-evolution.h" +#include "alloc-pool.h" #include "tree-vectorizer.h" #include "builtins.h" #include "internal-fn.h" @@ -2788,7 +2789,7 @@ vectorizable_simd_clone_call (gimple *stmt, gimple_stmt_iterator *gsi, gimple *def_stmt; gimple *new_stmt = NULL; int ncopies, j; - vec<simd_call_arg_info> arginfo = vNULL; + auto_vec<simd_call_arg_info> arginfo; vec<tree> vargs = vNULL; size_t i, nargs; tree lhs, rtype, ratype; @@ -2854,7 +2855,6 @@ vectorizable_simd_clone_call (gimple *stmt, gimple_stmt_iterator *gsi, if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "use not simple.\n"); - arginfo.release (); return false; } @@ -3010,10 +3010,7 @@ vectorizable_simd_clone_call (gimple *stmt, gimple_stmt_iterator *gsi, } if (bestn == NULL) - { - arginfo.release (); - return false; - } + return false; for (i = 0; i < nargs; i++) if ((arginfo[i].dt == vect_constant_def @@ -3026,10 +3023,7 @@ vectorizable_simd_clone_call (gimple *stmt, gimple_stmt_iterator *gsi, if (arginfo[i].vectype == NULL || (TYPE_VECTOR_SUBPARTS (arginfo[i].vectype) > bestn->simdclone->simdlen)) - { - arginfo.release (); - return false; - } + return false; } fndecl = bestn->decl; @@ -3041,10 +3035,7 @@ vectorizable_simd_clone_call (gimple *stmt, gimple_stmt_iterator *gsi, performed using SIMD instructions. */ if ((loop == NULL || (unsigned) loop->safelen < nunits) && gimple_vuse (stmt)) - { - arginfo.release (); - return false; - } + return false; /* Sanity check: make sure that at least one copy of the vectorized stmt needs to be generated. */ @@ -3073,7 +3064,6 @@ vectorizable_simd_clone_call (gimple *stmt, gimple_stmt_iterator *gsi, dump_printf_loc (MSG_NOTE, vect_location, "=== vectorizable_simd_clone_call ===\n"); /* vect_model_simple_cost (stmt_info, ncopies, dt, NULL, NULL); */ - arginfo.release (); return true; } @@ -8333,7 +8323,7 @@ stmt_vec_info new_stmt_vec_info (gimple *stmt, vec_info *vinfo) { stmt_vec_info res; - res = (stmt_vec_info) xcalloc (1, sizeof (struct _stmt_vec_info)); + res = stmt_vec_info_pool.allocate (); STMT_VINFO_TYPE (res) = undef_vec_info_type; STMT_VINFO_STMT (res) = stmt; @@ -8396,6 +8386,7 @@ free_stmt_vec_info_vec (void) free_stmt_vec_info (STMT_VINFO_STMT (info)); gcc_assert (stmt_vec_info_vec.exists ()); stmt_vec_info_vec.release (); + stmt_vec_info_pool.release (); } @@ -8442,10 +8433,8 @@ free_stmt_vec_info (gimple *stmt) } } - STMT_VINFO_SAME_ALIGN_REFS (stmt_info).release (); - STMT_VINFO_SIMD_CLONE_INFO (stmt_info).release (); + stmt_vec_info_pool.remove (stmt_info); set_vinfo_for_stmt (stmt, NULL); - free (stmt_info); } diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c index b721c56..e9f5692 100644 --- a/gcc/tree-vectorizer.c +++ b/gcc/tree-vectorizer.c @@ -71,6 +71,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-ssa-loop-manip.h" #include "tree-cfg.h" #include "cfgloop.h" +#include "alloc-pool.h" #include "tree-vectorizer.h" #include "tree-ssa-propagate.h" #include "dbgcnt.h" @@ -82,6 +83,9 @@ source_location vect_location; /* Vector mapping GIMPLE stmt to stmt_vec_info. */ vec<stmt_vec_info> stmt_vec_info_vec; + +object_allocator <_stmt_vec_info> stmt_vec_info_pool ("STMT vec info"); + /* For mapping simduid to vectorization factor. */ diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 327f08d..d7f4de4 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -478,7 +478,20 @@ enum slp_vect_type { typedef struct data_reference *dr_p; -typedef struct _stmt_vec_info { +struct _stmt_vec_info +{ + _stmt_vec_info (): type ((enum stmt_vec_info_type) 0), live (false), + in_pattern_p (false), stmt (NULL), vinfo (0), vectype (NULL_TREE), + vectorized_stmt (NULL), data_ref_info (0), dr_base_address (NULL_TREE), + dr_init (NULL_TREE), dr_offset (NULL_TREE), dr_step (NULL_TREE), + dr_aligned_to (NULL_TREE), loop_phi_evolution_base_unchanged (NULL_TREE), + loop_phi_evolution_part (NULL_TREE), related_stmt (NULL), pattern_def_seq (0), + same_align_refs (0), simd_clone_info (0), def_type ((enum vect_def_type) 0), + slp_type ((enum slp_vect_type) 0), first_element (NULL), next_element (NULL), + same_dr_stmt (NULL), size (0), store_count (0), gap (0), min_neg_dist (0), + relevant ((enum vect_relevant) 0), vectorizable (false), + gather_scatter_p (false), strided_p (false), simd_lane_access_p (false), + v_reduc_type ((enum vect_reduction_type) 0) {} enum stmt_vec_info_type type; @@ -543,12 +556,12 @@ typedef struct _stmt_vec_info { /* List of datarefs that are known to have the same alignment as the dataref of this stmt. */ - vec<dr_p> same_align_refs; + auto_vec<dr_p> same_align_refs; /* Selected SIMD clone's function info. First vector element is SIMD clone's function decl, followed by a pair of trees (base + step) for linear arguments (pair of NULLs for other arguments). */ - vec<tree> simd_clone_info; + auto_vec<tree> simd_clone_info; /* Classify the def of this stmt. */ enum vect_def_type def_type; @@ -597,8 +610,9 @@ typedef struct _stmt_vec_info { /* For reduction loops, this is the type of reduction. */ enum vect_reduction_type v_reduc_type; +}; -} *stmt_vec_info; +typedef struct _stmt_vec_info *stmt_vec_info; /* Access Functions. */ #define STMT_VINFO_TYPE(S) (S)->type @@ -685,6 +699,7 @@ struct dataref_aux { #define MAX_VECTORIZATION_FACTOR 64 extern vec<stmt_vec_info> stmt_vec_info_vec; +extern object_allocator <_stmt_vec_info> stmt_vec_info_pool; void init_stmt_vec_info_vec (void); void free_stmt_vec_info_vec (void); -- 2.6.3