re PR tree-optimization/79338 (Memory leak in tree-parloops.c)
authorJakub Jelinek <jakub@redhat.com>
Sat, 4 Feb 2017 07:44:13 +0000 (08:44 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Sat, 4 Feb 2017 07:44:13 +0000 (08:44 +0100)
PR tree-optimization/79338
* tree-parloops.c (gather_scalar_reductions): Don't call
vect_analyze_loop_form for loop->inner before destroying loop's
loop_vinfo.

From-SVN: r245183

gcc/ChangeLog
gcc/tree-parloops.c

index 40993e5a0dd4cb9dd5eac13304734e4a7407db96..3be3f74599414800a9c75472e73895134023b7e8 100644 (file)
@@ -1,3 +1,10 @@
+2017-02-04  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/79338
+       * tree-parloops.c (gather_scalar_reductions): Don't call
+       vect_analyze_loop_form for loop->inner before destroying loop's
+       loop_vinfo.
+
 2017-02-03  Martin Sebor  <msebor@redhat.com>
 
        PR tree-optimization/79327
index 779258b90b4a34db66f39d4af689deed77903c07..83aa8308deff28601b6a1fd77b26e7325d765acc 100644 (file)
@@ -2513,8 +2513,8 @@ gather_scalar_reductions (loop_p loop, reduction_info_table_type *reduction_list
 {
   gphi_iterator gsi;
   loop_vec_info simple_loop_info;
-  loop_vec_info simple_inner_loop_info = NULL;
-  bool allow_double_reduc = true;
+  auto_vec<gphi *, 4> double_reduc_phis;
+  auto_vec<gimple *, 4> double_reduc_stmts;
 
   if (!stmt_vec_info_vec.exists ())
     init_stmt_vec_info_vec ();
@@ -2544,43 +2544,55 @@ gather_scalar_reductions (loop_p loop, reduction_info_table_type *reduction_list
 
       if (double_reduc)
        {
-         if (!allow_double_reduc
-             || loop->inner->inner != NULL)
+         if (loop->inner->inner != NULL)
            continue;
 
-         if (!simple_inner_loop_info)
-           {
-             simple_inner_loop_info = vect_analyze_loop_form (loop->inner);
-             if (!simple_inner_loop_info)
-               {
-                 allow_double_reduc = false;
-                 continue;
-               }
-           }
-
-         use_operand_p use_p;
-         gimple *inner_stmt;
-         bool single_use_p = single_imm_use (res, &use_p, &inner_stmt);
-         gcc_assert (single_use_p);
-         if (gimple_code (inner_stmt) != GIMPLE_PHI)
-           continue;
-         gphi *inner_phi = as_a <gphi *> (inner_stmt);
-         if (simple_iv (loop->inner, loop->inner, PHI_RESULT (inner_phi),
-                        &iv, true))
-           continue;
-
-         gimple *inner_reduc_stmt
-           = vect_force_simple_reduction (simple_inner_loop_info, inner_phi,
-                                          true, &double_reduc, true);
-         gcc_assert (!double_reduc);
-         if (inner_reduc_stmt == NULL)
-           continue;
+         double_reduc_phis.safe_push (phi);
+         double_reduc_stmts.safe_push (reduc_stmt);
+         continue;
        }
 
       build_new_reduction (reduction_list, reduc_stmt, phi);
     }
   destroy_loop_vec_info (simple_loop_info, true);
-  destroy_loop_vec_info (simple_inner_loop_info, true);
+
+  if (!double_reduc_phis.is_empty ())
+    {
+      simple_loop_info = vect_analyze_loop_form (loop->inner);
+      if (simple_loop_info)
+       {
+         gphi *phi;
+         unsigned int i;
+
+         FOR_EACH_VEC_ELT (double_reduc_phis, i, phi)
+           {
+             affine_iv iv;
+             tree res = PHI_RESULT (phi);
+             bool double_reduc;
+
+             use_operand_p use_p;
+             gimple *inner_stmt;
+             bool single_use_p = single_imm_use (res, &use_p, &inner_stmt);
+             gcc_assert (single_use_p);
+             if (gimple_code (inner_stmt) != GIMPLE_PHI)
+               continue;
+             gphi *inner_phi = as_a <gphi *> (inner_stmt);
+             if (simple_iv (loop->inner, loop->inner, PHI_RESULT (inner_phi),
+                            &iv, true))
+               continue;
+
+             gimple *inner_reduc_stmt
+               = vect_force_simple_reduction (simple_loop_info, inner_phi,
+                                              true, &double_reduc, true);
+             gcc_assert (!double_reduc);
+             if (inner_reduc_stmt == NULL)
+               continue;
+
+             build_new_reduction (reduction_list, double_reduc_stmts[i], phi);
+           }
+         destroy_loop_vec_info (simple_loop_info, true);
+       }
+    }
 
  gather_done:
   /* Release the claim on gimple_uid.  */