]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/60841 (gcc: internal compiler error: Killed (program cc1...
authorRichard Biener <rguenther@suse.de>
Thu, 17 Apr 2014 08:09:02 +0000 (08:09 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 17 Apr 2014 08:09:02 +0000 (08:09 +0000)
2014-04-17   Richard Biener  <rguenther@suse.de>

PR tree-optimization/60841
* tree-vect-data-refs.c (vect_analyze_data_refs): Count stmts.
* tree-vect-loop.c (vect_analyze_loop_2): Pass down number
of stmts to SLP build.
* tree-vect-slp.c (vect_slp_analyze_bb_1): Likewise.
(vect_analyze_slp): Likewise.
(vect_analyze_slp_instance): Likewise.
(vect_build_slp_tree): Limit overall SLP tree growth.
* tree-vectorizer.h (vect_analyze_data_refs,
vect_analyze_slp): Adjust prototypes.

* gcc.dg/vect/pr60841.c: New testcase.

From-SVN: r209467

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/pr60841.c [new file with mode: 0644]
gcc/tree-vect-data-refs.c
gcc/tree-vect-loop.c
gcc/tree-vect-slp.c
gcc/tree-vectorizer.h

index 320e15ab2899c34f2f2d97319cd8257c7db00b37..a8664ea9836d89682ad1a5060073c7f113be9ae0 100644 (file)
@@ -1,3 +1,16 @@
+2014-04-17   Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/60841
+       * tree-vect-data-refs.c (vect_analyze_data_refs): Count stmts.
+       * tree-vect-loop.c (vect_analyze_loop_2): Pass down number
+       of stmts to SLP build.
+       * tree-vect-slp.c (vect_slp_analyze_bb_1): Likewise.
+       (vect_analyze_slp): Likewise.
+       (vect_analyze_slp_instance): Likewise.
+       (vect_build_slp_tree): Limit overall SLP tree growth.
+       * tree-vectorizer.h (vect_analyze_data_refs,
+       vect_analyze_slp): Adjust prototypes.
+
 2014-04-17  Evgeny Stupachenko  <evstupac@gmail.com>
 
        * config/i386/i386.c (x86_add_stmt_cost): Fix vector cost model for
index b8d40b7a0eef5b9ee1ba40e163a18d2c2c0a34b9..7e9b599766f211cb2115a561724df0b848d7410b 100644 (file)
@@ -1,3 +1,8 @@
+2014-04-17   Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/60841
+       * gcc.dg/vect/pr60841.c: New testcase.
+
 2014-04-16  Jan Hubicka  <hubicka@ucw.cz>
 
        * g++.dg/ipa/devirt-31.C: New testcase.
diff --git a/gcc/testsuite/gcc.dg/vect/pr60841.c b/gcc/testsuite/gcc.dg/vect/pr60841.c
new file mode 100644 (file)
index 0000000..44b5d01
--- /dev/null
@@ -0,0 +1,183 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-ffast-math" } */
+
+/* This testcase shouldn't consume much memory or produce a 1GB vectorizer
+   dump file due to SLP tree explosion.  */
+
+struct S { int f1, f2, f3, f4; } a;
+struct T { short f3, f2, f1, f4; };
+int b, c, d, e, f, g;
+unsigned long z;
+
+void
+foo (struct T *p, struct T *q, int x, int w)
+{
+  for (; x; x++)
+    {
+      struct S h;
+      int i;
+      struct T j;
+      struct T *r;
+      h = a;
+      g = 0;
+      r = p + 2 * (c + 4) + 1;
+      j = *r;
+      r = p;
+      f = r->f1 - 1;
+      b = +1.0 + f * f;
+      i = (r->f2 + j.f2) / 2;
+      f = r->f3 - 1;
+      b += 1.0 - i * f * f;
+      f = r->f4 - 1;
+      if (b)
+       b += -1.0 - i * f;
+      if (b / w)
+       {
+         h.f1 += 8.0 * r->f1;
+         h.f2 += 8.0 * r->f2;
+         h.f3 += 8.0 * r->f3;
+         h.f4 += 8.0 * r->f4;
+         g = 1;
+       }
+      r++;
+      f = r->f1;
+      i = (r->f2 + j.f2) / 2;
+      f = r->f3 - 1;
+      b += 1.0 - i * f * f;
+      i = (r->f4);
+      if (b * 65535UL / w)
+       {
+         h.f1 += 10.0 * r->f1;
+         h.f2 += 10.0 * r->f2;
+         h.f3 += 10.0 * r->f3;
+         h.f4 += 10.0 * r->f4;
+         g += 10.0;
+       }
+      r++;
+      f = r->f1;
+      z = 5UL * i;
+      f = r->f2;
+      i = (r->f3 + j.f3) / 2;
+      b = -i * f * f;
+      i = (r->f4 + j.f4) / 2;
+      if (b * 65535UL / 25.0f)
+       {
+         h.f1 += 8.0 * r->f1;
+         h.f2 += 8.0 * r->f2;
+         h.f3 += 8.0 * r->f3;
+         h.f4 += 8.0 * r->f4;
+         g += 8.0;
+       }
+      r++;
+      f = r->f1 - j.f1;
+      b = 1 * 2.0 * i * f * f;
+      f = r->f2;
+      b += 4.0 * f;
+      i = r->f3 / 2;
+      f = r->f4 - 1;
+      if (b * 1)
+       {
+         h.f1 += 8.0 * r->f1;
+         h.f2 += 8.0 * r->f2;
+         h.f3 += 8.0 * r->f3;
+         h.f4 += 8.0 * r->f4;
+         g += 8.0;
+       }
+      b = 4.0 * 1 * f;
+      if (b * 65535UL / 25.0f)
+       {
+         h.f1 += 20.0 * r->f1;
+         h.f2 += 20.0 * r->f2;
+         h.f3 += 20.0 * r->f3;
+         h.f4 += 20.0 * r->f4;
+         g += 20.0;
+       }
+      b = 5 * (0.0 - i);
+      if (b < 0)
+       {
+         h.f1 += 8.0 * r->f1;
+         h.f2 += 8.0 * r->f2;
+         h.f3 += 8.0 * r->f3;
+         h.f4 += 8.0 * r->f4;
+         g += 8.0;
+       }
+      r = p + 2 * (c + 4);
+      i = (r->f1 + j.f1);
+      b = 1 * 2.0 * i * 1;
+      f = r->f2 - 1;
+      i = (r->f3 + j.f3) / 2;
+      b = 5 * (0.0 - i) * f * f;
+      i = (r->f4 + j.f4) / 2;
+      if (b * 65535UL / 25.0f)
+       {
+         h.f1 += 10.0 * r->f1;
+         h.f2 += 10.0 * r->f2;
+         h.f3 += 10.0 * r->f3;
+         h.f4 += 10.0 * r->f4;
+         g += 10.0;
+       }
+      r++;
+      f = r->f1;
+      b = 5UL * i * f;
+      i = (r->f2 + j.f2) / 2;
+      f = r->f3 - 1;
+      b = 5 * (0.0 - i) * f * f;
+      f = r->f4 - 1;
+      if (b * 65535UL / 25.0f)
+       {
+         h.f1 += 40.0 * r->f1;
+         h.f2 += 40.0 * r->f2;
+         h.f3 += 40.0 * r->f3;
+         h.f4 += 40.0 * r->f4;
+         g += 40.0;
+       }
+      r++;
+      i = (r->f1 + j.f1);
+      b = 5 * i * f;
+      f = r->f2;
+      b = 4.0 * f * f;
+      f = r->f3;
+      i = (r->f4 + j.f4) / 2;
+      b = 5 * (0.0 - i) * f * f;
+      if (b * 25.0f)
+       {
+         h.f1 += 8.0 * r->f1;
+         h.f2 += 8.0 * r->f2;
+         h.f3 += 8.0 * r->f3;
+         h.f4 += 8.0 * r->f4;
+         g += 8.0;
+       }
+      r = p + 4 * (c + 4);
+      i = r->f1 / 2;
+      b = 5 * (1.0 + i);
+      i = r->f2 + j.f2;
+      f = r->f3 - 1;
+      b = 5 * (0.0 - i) * f * f;
+      i = (r->f4 + j.f4) / 2;
+      if (b * 65535UL / 25.0f)
+       {
+         h.f1 += 5.0 * r->f1;
+         h.f2 += 5.0 * r->f2;
+         h.f3 += 5.0 * r->f3;
+         h.f4 += 5.0 * r->f4;
+         g += 5.0;
+       }
+      b = 5 * (1.0 + i);
+      if (b < 0)
+       {
+         h.f1 += 5.0 * r->f1;
+         h.f2 += 5.0 * r->f2;
+         h.f3 += 5.0 * r->f3;
+         h.f4 += 5.0 * r->f4;
+         g += 5.0;
+       }
+      q->f1 = (h.f1 + g / 2 - 1) / g;
+      q->f2 = (h.f2 + g / 2 - 1) / g;
+      q->f3 = (h.f3 + g / 2 - 1) / g;
+      q->f4 = (h.f4 + g / 2 - 1) / g;
+      p++;
+      q++;
+    }
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
index fbc35a3fe3cf7085bdd50db704d9ff02ecd217fb..274cdbdcf80ba926725524d1347f49e02f3ffcf6 100644 (file)
@@ -3172,7 +3172,7 @@ vect_check_gather (gimple stmt, loop_vec_info loop_vinfo, tree *basep,
 bool
 vect_analyze_data_refs (loop_vec_info loop_vinfo,
                        bb_vec_info bb_vinfo,
-                       int *min_vf)
+                       int *min_vf, unsigned *n_stmts)
 {
   struct loop *loop = NULL;
   basic_block bb = NULL;
@@ -3207,6 +3207,9 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
          for (gsi = gsi_start_bb (bbs[i]); !gsi_end_p (gsi); gsi_next (&gsi))
            {
              gimple stmt = gsi_stmt (gsi);
+             if (is_gimple_debug (stmt))
+               continue;
+             ++*n_stmts;
              if (!find_data_references_in_stmt (loop, stmt, &datarefs))
                {
                  if (is_gimple_call (stmt) && loop->safelen)
@@ -3260,6 +3263,9 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
        {
          gimple stmt = gsi_stmt (gsi);
+         if (is_gimple_debug (stmt))
+           continue;
+         ++*n_stmts;
          if (!find_data_references_in_stmt (NULL, stmt,
                                             &BB_VINFO_DATAREFS (bb_vinfo)))
            {
index def3bc46174cc0950c9ed6ad7444cb3abb29570c..7ec079a83749232e7fa10b889680b3a5b832fbc7 100644 (file)
@@ -1629,6 +1629,7 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo)
   int max_vf = MAX_VECTORIZATION_FACTOR;
   int min_vf = 2;
   unsigned int th;
+  unsigned int n_stmts = 0;
 
   /* Find all data references in the loop (which correspond to vdefs/vuses)
      and analyze their evolution in the loop.  Also adjust the minimal
@@ -1637,7 +1638,7 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo)
      FORNOW: Handle only simple, array references, which
      alignment can be forced, and aligned pointer-references.  */
 
-  ok = vect_analyze_data_refs (loop_vinfo, NULL, &min_vf);
+  ok = vect_analyze_data_refs (loop_vinfo, NULL, &min_vf, &n_stmts);
   if (!ok)
     {
       if (dump_enabled_p ())
@@ -1747,7 +1748,7 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo)
     }
 
   /* Check the SLP opportunities in the loop, analyze and build SLP trees.  */
-  ok = vect_analyze_slp (loop_vinfo, NULL);
+  ok = vect_analyze_slp (loop_vinfo, NULL, n_stmts);
   if (ok)
     {
       /* Decide which possible SLP instances to SLP.  */
index 65f8b022e9242b4cd360ef8b1e7299207af24b3b..0ab267f7d8e0ee3c8ca3f37db07a5528f2a57329 100644 (file)
@@ -849,9 +849,10 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
                      unsigned int *max_nunits,
                      vec<slp_tree> *loads,
                      unsigned int vectorization_factor,
-                    bool *matches, unsigned *npermutes)
+                    bool *matches, unsigned *npermutes, unsigned *tree_size,
+                    unsigned max_tree_size)
 {
-  unsigned nops, i, this_npermutes = 0;
+  unsigned nops, i, this_npermutes = 0, this_tree_size = 0;
   gimple stmt;
 
   if (!matches)
@@ -911,6 +912,12 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
       if (oprnd_info->first_dt != vect_internal_def)
         continue;
 
+      if (++this_tree_size > max_tree_size)
+       {
+         vect_free_oprnd_info (oprnds_info);
+         return false;
+       }
+
       child = vect_create_new_slp_node (oprnd_info->def_stmts);
       if (!child)
        {
@@ -921,7 +928,8 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
       bool *matches = XALLOCAVEC (bool, group_size);
       if (vect_build_slp_tree (loop_vinfo, bb_vinfo, &child,
                               group_size, max_nunits, loads,
-                              vectorization_factor, matches, npermutes))
+                              vectorization_factor, matches,
+                              npermutes, &this_tree_size, max_tree_size))
        {
          oprnd_info->def_stmts = vNULL;
          SLP_TREE_CHILDREN (*node).quick_push (child);
@@ -961,7 +969,8 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
          if (vect_build_slp_tree (loop_vinfo, bb_vinfo, &child,
                                   group_size, max_nunits, loads,
                                   vectorization_factor,
-                                  matches, npermutes))
+                                  matches, npermutes, &this_tree_size,
+                                  max_tree_size))
            {
              oprnd_info->def_stmts = vNULL;
              SLP_TREE_CHILDREN (*node).quick_push (child);
@@ -977,6 +986,9 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
       return false;
     }
 
+  if (tree_size)
+    *tree_size += this_tree_size;
+
   vect_free_oprnd_info (oprnds_info);
   return true;
 }
@@ -1436,7 +1448,7 @@ vect_analyze_slp_cost (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
 
 static bool
 vect_analyze_slp_instance (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
-                           gimple stmt)
+                           gimple stmt, unsigned max_tree_size)
 {
   slp_instance new_instance;
   slp_tree node;
@@ -1536,7 +1548,8 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
   /* Build the tree for the SLP instance.  */
   if (vect_build_slp_tree (loop_vinfo, bb_vinfo, &node, group_size,
                           &max_nunits, &loads,
-                          vectorization_factor, NULL, NULL))
+                          vectorization_factor, NULL, NULL, NULL,
+                          max_tree_size))
     {
       /* Calculate the unrolling factor based on the smallest type.  */
       if (max_nunits > nunits)
@@ -1641,7 +1654,8 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
    trees of packed scalar stmts if SLP is possible.  */
 
 bool
-vect_analyze_slp (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
+vect_analyze_slp (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
+                 unsigned max_tree_size)
 {
   unsigned int i;
   vec<gimple> grouped_stores;
@@ -1664,7 +1678,8 @@ vect_analyze_slp (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
 
   /* Find SLP sequences starting from groups of grouped stores.  */
   FOR_EACH_VEC_ELT (grouped_stores, i, first_element)
-    if (vect_analyze_slp_instance (loop_vinfo, bb_vinfo, first_element))
+    if (vect_analyze_slp_instance (loop_vinfo, bb_vinfo, first_element,
+                                  max_tree_size))
       ok = true;
 
   if (bb_vinfo && !ok)
@@ -1681,7 +1696,8 @@ vect_analyze_slp (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
     {
       /* Find SLP sequences starting from reduction chains.  */
       FOR_EACH_VEC_ELT (reduc_chains, i, first_element)
-        if (vect_analyze_slp_instance (loop_vinfo, bb_vinfo, first_element))
+        if (vect_analyze_slp_instance (loop_vinfo, bb_vinfo, first_element,
+                                      max_tree_size))
           ok = true;
         else
           return false;
@@ -1693,7 +1709,8 @@ vect_analyze_slp (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
 
   /* Find SLP sequences starting from groups of reductions.  */
   if (loop_vinfo && LOOP_VINFO_REDUCTIONS (loop_vinfo).length () > 1
-      && vect_analyze_slp_instance (loop_vinfo, bb_vinfo, reductions[0]))
+      && vect_analyze_slp_instance (loop_vinfo, bb_vinfo, reductions[0],
+                                   max_tree_size))
     ok = true;
 
   return true;
@@ -2071,12 +2088,13 @@ vect_slp_analyze_bb_1 (basic_block bb)
   slp_instance instance;
   int i;
   int min_vf = 2;
+  unsigned n_stmts = 0;
 
   bb_vinfo = new_bb_vec_info (bb);
   if (!bb_vinfo)
     return NULL;
 
-  if (!vect_analyze_data_refs (NULL, bb_vinfo, &min_vf))
+  if (!vect_analyze_data_refs (NULL, bb_vinfo, &min_vf, &n_stmts))
     {
       if (dump_enabled_p ())
         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -2124,7 +2142,7 @@ vect_slp_analyze_bb_1 (basic_block bb)
 
   /* Check the SLP opportunities in the basic block, analyze and build SLP
      trees.  */
-  if (!vect_analyze_slp (NULL, bb_vinfo))
+  if (!vect_analyze_slp (NULL, bb_vinfo, n_stmts))
     {
       if (dump_enabled_p ())
         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 
index 035d654e7ad6354d69972c08c6ecc64aed97b071..c5cb037042fc474ab522be0fb30e65066f0d8eaa 100644 (file)
@@ -1057,7 +1057,8 @@ extern bool vect_analyze_data_ref_accesses (loop_vec_info, bb_vec_info);
 extern bool vect_prune_runtime_alias_test_list (loop_vec_info);
 extern tree vect_check_gather (gimple, loop_vec_info, tree *, tree *,
                               int *);
-extern bool vect_analyze_data_refs (loop_vec_info, bb_vec_info, int *);
+extern bool vect_analyze_data_refs (loop_vec_info, bb_vec_info, int *,
+                                   unsigned *);
 extern tree vect_create_data_ref_ptr (gimple, tree, struct loop *, tree,
                                      tree *, gimple_stmt_iterator *,
                                      gimple *, bool, bool *);
@@ -1107,7 +1108,7 @@ extern bool vect_transform_slp_perm_load (slp_tree, vec<tree> ,
                                           slp_instance, bool);
 extern bool vect_schedule_slp (loop_vec_info, bb_vec_info);
 extern void vect_update_slp_costs_according_to_vf (loop_vec_info);
-extern bool vect_analyze_slp (loop_vec_info, bb_vec_info);
+extern bool vect_analyze_slp (loop_vec_info, bb_vec_info, unsigned);
 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,