OSDN Git Service

PR tree-optimization/37027
authorirar <irar@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 19 Apr 2010 09:10:45 +0000 (09:10 +0000)
committerMasaki Muranaka <monaka@monami-software.com>
Sun, 23 May 2010 05:33:53 +0000 (14:33 +0900)
* tree-vectorizer.h (struct _loop_vec_info): Add new field reductions
and macro to access it.
(vectorizable_reduction): Add argument.
(vect_get_slp_defs): Likewise.
* tree-vect-loop.c (vect_analyze_scalar_cycles_1): Collect reduction
statements for possible use in SLP.
(new_loop_vec_info): Initialize LOOP_VINFO_REDUCTIONS.
(destroy_loop_vec_info): Free LOOP_VINFO_REDUCTIONS.
(vect_create_epilog_for_reduction): Handle SLP. Modify documentation,
add new argument.
(vectorizable_reduction): Likewise.
* tree-vect-stmts.c (vect_get_vec_defs): Update call to
vect_get_slp_defs.
(vectorizable_type_demotion, vectorizable_type_promotion,
vectorizable_store): Likewise.
(vect_analyze_stmt): Update call to vectorizable_reduction.
(vect_transform_stmt): Likewise.
* tree-vect-slp.c (vect_get_and_check_slp_defs): Handle reduction.
(vect_build_slp_tree): Fix indentation. Check that there are no loads
from different interleaving chains in same node.
(vect_slp_rearrange_stmts): New function.
(vect_supported_load_permutation_p): Allow load permutations for
reductions. Call vect_slp_rearrange_stmts() to rearrange statements
inside SLP nodes if necessary.
(vect_analyze_slp_instance): Handle reductions.
(vect_analyze_slp): Try to build SLP instances originating from groups
of reductions.
(vect_detect_hybrid_slp_stmts): Skip reduction statements.
(vect_get_constant_vectors): Create initial vectors for reductions
according to reduction code. Add new argument.
(vect_get_slp_defs): Add new argument, pass it to
vect_get_constant_vectors.
(vect_schedule_slp_instance): Remove SLP tree root statements.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158506 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/tree-vect-loop.c
gcc/tree-vect-slp.c

index 5bf2460..c04a319 100644 (file)
@@ -1,3 +1,40 @@
+2010-04-19 Ira Rosen <irar@il.ibm.com>
+
+       PR tree-optimization/37027
+       * tree-vectorizer.h (struct _loop_vec_info): Add new field reductions 
+       and macro to access it.
+       (vectorizable_reduction): Add argument.
+       (vect_get_slp_defs): Likewise.
+       * tree-vect-loop.c (vect_analyze_scalar_cycles_1): Collect reduction
+       statements for possible use in SLP.
+       (new_loop_vec_info): Initialize LOOP_VINFO_REDUCTIONS.
+       (destroy_loop_vec_info): Free LOOP_VINFO_REDUCTIONS.
+       (vect_create_epilog_for_reduction): Handle SLP. Modify documentation,
+       add new argument.
+       (vectorizable_reduction): Likewise.
+       * tree-vect-stmts.c (vect_get_vec_defs): Update call to 
+       vect_get_slp_defs.
+       (vectorizable_type_demotion, vectorizable_type_promotion,
+       vectorizable_store): Likewise.
+       (vect_analyze_stmt): Update call to vectorizable_reduction.
+       (vect_transform_stmt): Likewise.
+       * tree-vect-slp.c (vect_get_and_check_slp_defs): Handle reduction.
+       (vect_build_slp_tree): Fix indentation. Check that there are no loads
+       from different interleaving chains in same node.
+       (vect_slp_rearrange_stmts): New function.
+       (vect_supported_load_permutation_p): Allow load permutations for 
+       reductions. Call vect_slp_rearrange_stmts() to rearrange statements
+       inside SLP nodes if necessary.
+       (vect_analyze_slp_instance): Handle reductions.
+       (vect_analyze_slp): Try to build SLP instances originating from groups
+       of reductions.
+       (vect_detect_hybrid_slp_stmts): Skip reduction statements.
+       (vect_get_constant_vectors): Create initial vectors for reductions
+       according to reduction code. Add new argument.
+       (vect_get_slp_defs): Add new argument, pass it to 
+       vect_get_constant_vectors.
+       (vect_schedule_slp_instance): Remove SLP tree root statements.
+
 2010-04-19  Jakub Jelinek  <jakub@redhat.com>
 
        * tree.h (ENUM_IS_SCOPED): Define.
index 216c225..b5a7b19 100644 (file)
@@ -1,3 +1,14 @@
+2010-04-19 Ira Rosen <irar@il.ibm.com>
+
+       PR tree-optimization/37027      
+       * lib/target-supports.exp 
+       (check_effective_target_vect_widen_sum_hi_to_si_pattern): New.
+       * gcc.dg/vect/pr37027.c: New test.
+       * gcc.dg/vect/slp-reduc-1.c, gcc.dg/vect/slp-reduc-2.c, 
+       gcc.dg/vect/slp-reduc-3.c, gcc.dg/vect/slp-reduc-4.c, 
+       gcc.dg/vect/slp-reduc-5.c, gcc.dg/vect/slp-reduc-6.c, 
+       gcc.dg/vect/vect-complex-6.c: Likewise. 
+
 2010-04-19  Jakub Jelinek  <jakub@redhat.com>
 
        * g++.dg/debug/dwarf2/enum1.C: New test.
index 817d573..e6e9008 100644 (file)
@@ -513,8 +513,8 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop)
       gcc_assert (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_unknown_def_type);
 
       nested_cycle = (loop != LOOP_VINFO_LOOP (loop_vinfo));
-      reduc_stmt = vect_force_simple_reduction (loop_vinfo, phi, !nested_cycle,
-                                               &double_reduc);
+      reduc_stmt = vect_is_simple_reduction (loop_vinfo, phi, !nested_cycle,
+                                             &double_reduc);
       if (reduc_stmt)
         {
           if (double_reduc)
@@ -1584,7 +1584,7 @@ report_vect_op (gimple stmt, const char *msg)
 }
 
 
-/* Function vect_is_simple_reduction_1
+/* Function vect_is_simple_reduction
 
    (1) Detect a cross-iteration def-use cycle that represents a simple
    reduction computation. We look for the following pattern:
@@ -1612,23 +1612,18 @@ report_vect_op (gimple stmt, const char *msg)
      a1 = phi < a0, a2 >
      inner loop (def of a3)
      a2 = phi < a3 >
-
-   If MODIFY is true it tries also to rework the code in-place to enable
-   detection of more reduction patterns.  For the time being we rewrite
-   "res -= RHS" into "rhs += -RHS" when it seems worthwhile.
 */
 
-static gimple
-vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
-                           bool check_reduction, bool *double_reduc,
-                           bool modify)
+gimple
+vect_is_simple_reduction (loop_vec_info loop_info, gimple phi,
+                          bool check_reduction, bool *double_reduc)
 {
   struct loop *loop = (gimple_bb (phi))->loop_father;
   struct loop *vect_loop = LOOP_VINFO_LOOP (loop_info);
   edge latch_e = loop_latch_edge (loop);
   tree loop_arg = PHI_ARG_DEF_FROM_EDGE (phi, latch_e);
   gimple def_stmt, def1 = NULL, def2 = NULL;
-  enum tree_code orig_code, code;
+  enum tree_code code;
   tree op1, op2, op3 = NULL_TREE, op4 = NULL_TREE;
   tree type;
   int nloop_uses;
@@ -1748,14 +1743,7 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
       return NULL;
     }
 
-  code = orig_code = gimple_assign_rhs_code (def_stmt);
-
-  /* We can handle "res -= x[i]", which is non-associative by
-     simply rewriting this into "res += -x[i]".  Avoid changing
-     gimple instruction for the first simple tests and only do this
-     if we're allowed to change code at all.  */
-  if (code == MINUS_EXPR && modify)
-    code = PLUS_EXPR;
+  code = gimple_assign_rhs_code (def_stmt);
 
   if (check_reduction
       && (!commutative_tree_code (code) || !associative_tree_code (code)))
@@ -1875,24 +1863,6 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
       return NULL;
     }
 
-  /* If we detected "res -= x[i]" earlier, rewrite it into
-     "res += -x[i]" now.  If this turns out to be useless reassoc
-     will clean it up again.  */
-  if (orig_code == MINUS_EXPR)
-    {
-      tree rhs = gimple_assign_rhs2 (def_stmt);
-      tree negrhs = make_ssa_name (SSA_NAME_VAR (rhs), NULL);
-      gimple negate_stmt = gimple_build_assign_with_ops (NEGATE_EXPR, negrhs,
-                                                        rhs, NULL);
-      gimple_stmt_iterator gsi = gsi_for_stmt (def_stmt);
-      set_vinfo_for_stmt (negate_stmt, new_stmt_vec_info (negate_stmt, 
-                                                         loop_info, NULL));
-      gsi_insert_before (&gsi, negate_stmt, GSI_NEW_STMT);
-      gimple_assign_set_rhs2 (def_stmt, negrhs);
-      gimple_assign_set_rhs_code (def_stmt, PLUS_EXPR);
-      update_stmt (def_stmt);
-    }
-
   /* Reduction is safe. We're dealing with one of the following:
      1) integer arithmetic and no trapv
      2) floating point arithmetic, and special flags permit this optimization
@@ -1970,28 +1940,6 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
     }
 }
 
-/* Wrapper around vect_is_simple_reduction_1, that won't modify code
-   in-place.  Arguments as there.  */
-
-static gimple
-vect_is_simple_reduction (loop_vec_info loop_info, gimple phi,
-                          bool check_reduction, bool *double_reduc)
-{
-  return vect_is_simple_reduction_1 (loop_info, phi, check_reduction,
-                                    double_reduc, false);
-}
-
-/* Wrapper around vect_is_simple_reduction_1, which will modify code
-   in-place if it enables detection of more reductions.  Arguments
-   as there.  */
-
-gimple
-vect_force_simple_reduction (loop_vec_info loop_info, gimple phi,
-                          bool check_reduction, bool *double_reduc)
-{
-  return vect_is_simple_reduction_1 (loop_info, phi, check_reduction,
-                                    double_reduc, true);
-}
 
 /* Function vect_estimate_min_profitable_iters
 
@@ -3013,7 +2961,7 @@ vect_create_epilog_for_reduction (VEC (tree, heap) *vect_defs, gimple stmt,
   enum vect_def_type dt = vect_unknown_def_type;
   int j, i;
   VEC (tree, heap) *scalar_results = NULL;
-  unsigned int group_size = 1, k, ratio;
+  int group_size = 1, k, ratio;
   VEC (tree, heap) *vec_initial_defs = NULL;
   VEC (gimple, heap) *phis;
 
@@ -3491,8 +3439,7 @@ vect_finalize_reduction:
           v_out2 = reduce <v_out1>
           s_out3 = extract_field <v_out2, 0>
           s_out4 = adjust_result <s_out3>
-          use <s_out4>  
-          use <s_out4> */
+          use <s_out4>  */
 
   /* In SLP we may have several statements in NEW_PHIS and REDUCTION_PHIS (in 
      case that GROUP_SIZE is greater than vectorization factor). Therefore, we
@@ -3500,13 +3447,8 @@ vect_finalize_reduction:
      (GROUP_SIZE / number of new vector stmts) scalar results correspond to
      the first vector stmt, etc.  
      (RATIO is equal to (GROUP_SIZE / number of new vector stmts)).  */ 
-  if (group_size > VEC_length (gimple, new_phis))
-    {
-      ratio = group_size / VEC_length (gimple, new_phis);
-      gcc_assert (!(group_size % VEC_length (gimple, new_phis)));
-    }
-  else
-    ratio = 1;
+  ratio = group_size / VEC_length (gimple, new_phis);
+  gcc_assert (!(group_size % VEC_length (gimple, new_phis)));
 
   for (k = 0; k < group_size; k++)
     {
@@ -3754,10 +3696,6 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
       nested_cycle = true;
     }
 
-  /* FORNOW: SLP not supported.  */
-  if (STMT_SLP_TYPE (stmt_info))
-    return false;
-
   /* 1. Is vectorizable reduction?  */
   /* Not supportable if the reduction variable is used in the loop.  */
   if (STMT_VINFO_RELEVANT (stmt_info) > vect_used_in_outer)
@@ -3890,9 +3828,12 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
   if (STMT_VINFO_LIVE_P (vinfo_for_stmt (reduc_def_stmt)))
     return false;
 
+  if (slp_node)
+    ncopies = 1;
+  else
+    ncopies = (LOOP_VINFO_VECT_FACTOR (loop_vinfo)
+               / TYPE_VECTOR_SUBPARTS (vectype_in));
 
-  ncopies = (LOOP_VINFO_VECT_FACTOR (loop_vinfo)
-            / TYPE_VECTOR_SUBPARTS (vectype_in));
   gcc_assert (ncopies >= 1);
 
   vec_mode = TYPE_MODE (vectype_in);
@@ -4203,24 +4144,34 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
 
       for (i = 0; VEC_iterate (tree, vec_oprnds0, i, def0); i++)
         {
-          if (reduc_index == 0)
-            expr = build2 (code, vectype_out, reduc_def, loop_vec_def0);
+          if (slp_node)
+            reduc_def = PHI_RESULT (VEC_index (gimple, phis, i));
           else
-            expr = build2 (code, vectype_out, loop_vec_def0, reduc_def);
-        }
-      else
-        {
-          if (reduc_index == 0)
-            expr = build3 (code, vectype_out, reduc_def, loop_vec_def0,
-                           loop_vec_def1);
+            {
+              if (!single_defuse_cycle || j == 0)
+                reduc_def = PHI_RESULT (new_phi);
+            }
+
+          def1 = ((op_type == ternary_op)
+                  ? VEC_index (tree, vec_oprnds1, i) : NULL);
+          if (op_type == binary_op)
+            {
+              if (reduc_index == 0)
+                expr = build2 (code, vectype_out, reduc_def, def0);
+              else
+                expr = build2 (code, vectype_out, def0, reduc_def);
+            }
           else
             {
-              if (reduc_index == 1)
-                expr = build3 (code, vectype_out, loop_vec_def0, reduc_def,
-                               loop_vec_def1);
+              if (reduc_index == 0)
+                expr = build3 (code, vectype_out, reduc_def, def0, def1);
               else
-                expr = build3 (code, vectype_out, loop_vec_def0, loop_vec_def1,
-                              reduc_def);
+                {
+                  if (reduc_index == 1)
+                    expr = build3 (code, vectype_out, def0, reduc_def, def1);
+                  else
+                    expr = build3 (code, vectype_out, def0, def1, reduc_def);
+                }
             }
 
           new_stmt = gimple_build_assign (vec_dest, expr);
index f313294..99a865f 100644 (file)
@@ -344,19 +344,6 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
          print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
        }
 
-      /* Fail to vectorize statements marked as unvectorizable.  */
-      if (!STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (stmt)))
-        {
-          if (vect_print_dump_info (REPORT_SLP))
-            {
-              fprintf (vect_dump,
-                       "Build SLP failed: unvectorizable statement ");
-              print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
-            }
-
-          return false;
-        }
-
       lhs = gimple_get_lhs (stmt);
       if (lhs == NULL_TREE)
        {
@@ -1226,7 +1213,7 @@ vect_analyze_slp (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
     }
 
   /* Find SLP sequences starting from groups of reductions.  */
-  if (loop_vinfo && VEC_length (gimple, LOOP_VINFO_REDUCTIONS (loop_vinfo)) > 1
+  if (loop_vinfo &&  VEC_length (gimple, LOOP_VINFO_REDUCTIONS (loop_vinfo))
       && vect_analyze_slp_instance (loop_vinfo, bb_vinfo, 
                                     VEC_index (gimple, reductions, 0)))
     ok = true;