Hi!

This is small, but quite common memory leak in slp vectorization.
vec_alloc (vec_defs, number_of_vects);
on vl_ptr-ish vec<tree> *vec_defs; first calls new on the vec<tree>
(i.e. allocates sizeof (void *) bytes), and then actually creates vector
pointed to by that.  Later on we copy the content of what it points to,
but don't actually free the void * sized allocation.
Fixed by changing the vector to be actually vec<vec<tree> > *, which also
simplifies the callers.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2013-02-28  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/56461
        * tree-vectorizer.h (vect_get_slp_defs): Change 3rd argument
        type to vec<vec<tree> > *.
        * tree-vect-slp.c (vect_get_slp_defs): Likewise.  Change vec_defs
        to be vec<tree> instead of vec<tree> *, set vec_defs
        to vNULL and call vec_defs.create (number_of_vects), adjust other
        uses of vec_defs.
        * tree-vect-stmts.c (vect_get_vec_defs, vectorizable_call,
        vectorizable_condition): Adjust vect_get_slp_defs callers.

--- gcc/tree-vectorizer.h.jj    2013-02-05 16:45:40.000000000 +0100
+++ gcc/tree-vectorizer.h       2013-02-28 14:17:45.276135327 +0100
@@ -978,7 +978,7 @@ extern bool vect_analyze_slp (loop_vec_i
 extern bool vect_make_slp_decision (loop_vec_info);
 extern void vect_detect_hybrid_slp (loop_vec_info);
 extern void vect_get_slp_defs (vec<tree> , slp_tree,
-                              vec<slp_void_p> *, int);
+                              vec<vec<tree> > *, int);
 
 extern LOC find_bb_location (basic_block);
 extern bb_vec_info vect_slp_analyze_bb (basic_block);
--- gcc/tree-vect-slp.c.jj      2013-01-31 18:28:54.000000000 +0100
+++ gcc/tree-vect-slp.c 2013-02-28 14:18:48.339791016 +0100
@@ -2614,14 +2614,14 @@ vect_get_slp_vect_defs (slp_tree slp_nod
 
 void
 vect_get_slp_defs (vec<tree> ops, slp_tree slp_node,
-                   vec<slp_void_p> *vec_oprnds, int reduc_index)
+                  vec<vec<tree> > *vec_oprnds, int reduc_index)
 {
   gimple first_stmt;
   int number_of_vects = 0, i;
   unsigned int child_index = 0;
   HOST_WIDE_INT lhs_size_unit, rhs_size_unit;
   slp_tree child = NULL;
-  vec<tree> *vec_defs;
+  vec<tree> vec_defs;
   tree oprnd;
   bool vectorized_defs;
 
@@ -2676,19 +2676,20 @@ vect_get_slp_defs (vec<tree> ops, slp_tr
         }
 
       /* Allocate memory for vectorized defs.  */
-      vec_alloc (vec_defs, number_of_vects);
+      vec_defs = vNULL;
+      vec_defs.create (number_of_vects);
 
       /* For reduction defs we call vect_get_constant_vectors (), since we are
          looking for initial loop invariant values.  */
       if (vectorized_defs && reduc_index == -1)
         /* The defs are already vectorized.  */
-        vect_get_slp_vect_defs (child, vec_defs);
+       vect_get_slp_vect_defs (child, &vec_defs);
       else
         /* Build vectors from scalar defs.  */
-        vect_get_constant_vectors (oprnd, slp_node, vec_defs, i,
+       vect_get_constant_vectors (oprnd, slp_node, &vec_defs, i,
                                    number_of_vects, reduc_index);
 
-      vec_oprnds->quick_push ((slp_void_p) vec_defs);
+      vec_oprnds->quick_push (vec_defs);
 
       /* For reductions, we only need initial values.  */
       if (reduc_index != -1)
--- gcc/tree-vect-stmts.c.jj    2013-02-26 10:58:16.000000000 +0100
+++ gcc/tree-vect-stmts.c       2013-02-28 14:23:38.181910467 +0100
@@ -1583,7 +1583,7 @@ vect_get_vec_defs (tree op0, tree op1, g
       int nops = (op1 == NULL_TREE) ? 1 : 2;
       vec<tree> ops;
       ops.create (nops);
-      vec<slp_void_p> vec_defs;
+      vec<vec<tree> > vec_defs;
       vec_defs.create (nops);
 
       ops.quick_push (op0);
@@ -1592,9 +1592,9 @@ vect_get_vec_defs (tree op0, tree op1, g
 
       vect_get_slp_defs (ops, slp_node, &vec_defs, reduc_index);
 
-      *vec_oprnds0 = *((vec<tree> *) vec_defs[0]);
+      *vec_oprnds0 = vec_defs[0];
       if (op1)
-        *vec_oprnds1 = *((vec<tree> *) vec_defs[1]);
+       *vec_oprnds1 = vec_defs[1];
 
       ops.release ();
       vec_defs.release ();
@@ -1882,14 +1882,14 @@ vectorizable_call (gimple stmt, gimple_s
 
          if (slp_node)
            {
-             vec<slp_void_p> vec_defs;
+             vec<vec<tree> > vec_defs;
              vec_defs.create (nargs);
              vec<tree> vec_oprnds0;
 
              for (i = 0; i < nargs; i++)
                vargs.quick_push (gimple_call_arg (stmt, i));
              vect_get_slp_defs (vargs, slp_node, &vec_defs, -1);
-             vec_oprnds0 = *((vec<tree> *) vec_defs[0]);
+             vec_oprnds0 = vec_defs[0];
 
              /* Arguments are ready.  Create the new vector stmt.  */
              FOR_EACH_VEC_ELT (vec_oprnds0, i, vec_oprnd0)
@@ -1897,7 +1897,7 @@ vectorizable_call (gimple stmt, gimple_s
                  size_t k;
                  for (k = 0; k < nargs; k++)
                    {
-                     vec<tree> vec_oprndsk = *((vec<tree> *) vec_defs[k]);
+                     vec<tree> vec_oprndsk = vec_defs[k];
                      vargs[k] = vec_oprndsk[i];
                    }
                  new_stmt = gimple_build_call_vec (fndecl, vargs);
@@ -1909,7 +1909,7 @@ vectorizable_call (gimple stmt, gimple_s
 
              for (i = 0; i < nargs; i++)
                {
-                 vec<tree> vec_oprndsi = *((vec<tree> *) vec_defs[i]);
+                 vec<tree> vec_oprndsi = vec_defs[i];
                  vec_oprndsi.release ();
                }
              vec_defs.release ();
@@ -1958,14 +1958,14 @@ vectorizable_call (gimple stmt, gimple_s
 
          if (slp_node)
            {
-             vec<slp_void_p> vec_defs;
+             vec<vec<tree> > vec_defs;
              vec_defs.create (nargs);
              vec<tree> vec_oprnds0;
 
              for (i = 0; i < nargs; i++)
                vargs.quick_push (gimple_call_arg (stmt, i));
              vect_get_slp_defs (vargs, slp_node, &vec_defs, -1);
-             vec_oprnds0 = *((vec<tree> *) vec_defs[0]);
+             vec_oprnds0 = vec_defs[0];
 
              /* Arguments are ready.  Create the new vector stmt.  */
              for (i = 0; vec_oprnds0.iterate (i, &vec_oprnd0); i += 2)
@@ -1974,7 +1974,7 @@ vectorizable_call (gimple stmt, gimple_s
                  vargs.truncate (0);
                  for (k = 0; k < nargs; k++)
                    {
-                     vec<tree> vec_oprndsk = *((vec<tree> *) vec_defs[k]);
+                     vec<tree> vec_oprndsk = vec_defs[k];
                      vargs.quick_push (vec_oprndsk[i]);
                      vargs.quick_push (vec_oprndsk[i + 1]);
                    }
@@ -1987,7 +1987,7 @@ vectorizable_call (gimple stmt, gimple_s
 
              for (i = 0; i < nargs; i++)
                {
-                 vec<tree> vec_oprndsi = *((vec<tree> *) vec_defs[i]);
+                 vec<tree> vec_oprndsi = vec_defs[i];
                  vec_oprndsi.release ();
                }
              vec_defs.release ();
@@ -5392,7 +5392,7 @@ vectorizable_condition (gimple stmt, gim
             {
               vec<tree> ops;
              ops.create (4);
-              vec<slp_void_p> vec_defs;
+             vec<vec<tree> > vec_defs;
 
              vec_defs.create (4);
               ops.safe_push (TREE_OPERAND (cond_expr, 0));
@@ -5400,10 +5400,10 @@ vectorizable_condition (gimple stmt, gim
               ops.safe_push (then_clause);
               ops.safe_push (else_clause);
               vect_get_slp_defs (ops, slp_node, &vec_defs, -1);
-              vec_oprnds3 = *((vec<tree> *) vec_defs.pop ());
-              vec_oprnds2 = *((vec<tree> *) vec_defs.pop ());
-              vec_oprnds1 = *((vec<tree> *) vec_defs.pop ());
-              vec_oprnds0 = *((vec<tree> *) vec_defs.pop ());
+             vec_oprnds3 = vec_defs.pop ();
+             vec_oprnds2 = vec_defs.pop ();
+             vec_oprnds1 = vec_defs.pop ();
+             vec_oprnds0 = vec_defs.pop ();
 
               ops.release ();
               vec_defs.release ();

        Jakub

Reply via email to