]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR middle-end/37161 (Revision 139225 caused gfortran.dg/vect/pr33301.f -O)
authorIra Rosen <irar@il.ibm.com>
Sat, 23 Aug 2008 17:04:12 +0000 (17:04 +0000)
committerIra Rosen <irar@gcc.gnu.org>
Sat, 23 Aug 2008 17:04:12 +0000 (17:04 +0000)
PR tree-optimization/37161
* tree-vectorizer.h (vect_get_smallest_scalar_type): Declare.
* tree-vect-analyze.c (vect_get_smallest_scalar_type): New function.
(vect_determine_vectorization_factor): Move the scalar type
retrieval to vect_get_smallest_scalar_type.
(vect_build_slp_tree): Call vect_get_smallest_scalar_type to get
scalar type. Remove redundant computation.
* tree-vect-transform.c (vect_get_constant_vectors): Add argument.
(vect_get_slp_defs): Take the type of RHS into account if
necessary by calling vect_get_smallest_scalar_type. Call
vect_get_constant_vectors with additional argument.

From-SVN: r139518

gcc/ChangeLog
gcc/tree-vect-analyze.c
gcc/tree-vect-transform.c
gcc/tree-vectorizer.h

index 8f291e83f3fa95b6923752635d965dd4dc82e8ab..1e1deebced5dc2dee52de948e77c64945d4eb7ad 100644 (file)
@@ -1,3 +1,17 @@
+2008-08-23  Ira Rosen  <irar@il.ibm.com>
+
+       PR tree-optimization/37161
+       * tree-vectorizer.h (vect_get_smallest_scalar_type): Declare.
+       * tree-vect-analyze.c (vect_get_smallest_scalar_type): New function.
+       (vect_determine_vectorization_factor): Move the scalar type
+       retrieval to vect_get_smallest_scalar_type.
+       (vect_build_slp_tree): Call vect_get_smallest_scalar_type to get
+       scalar type. Remove redundant computation.
+       * tree-vect-transform.c (vect_get_constant_vectors): Add argument.
+       (vect_get_slp_defs): Take the type of RHS into account if
+       necessary by calling vect_get_smallest_scalar_type. Call
+       vect_get_constant_vectors with additional argument.
+
 2008-08-23  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
 
        PR 35648
index 0f2efd85ed526ca491258a5a232ad94b7878de70..305ba4c6603719899bca71cf90a1a459eaf298fc 100644 (file)
@@ -44,6 +44,50 @@ along with GCC; see the file COPYING3.  If not see
 
 static bool vect_can_advance_ivs_p (loop_vec_info);
 
+/* Return the smallest scalar part of STMT.
+   This is used to determine the vectype of the stmt. We generally set the 
+   vectype according to the type of the result (lhs). For stmts whose 
+   result-type is different than the type of the arguments (e.g., demotion,
+   promotion), vectype will be reset appropriately (later).  Note that we have 
+   to visit the smallest datatype in this function, because that determines the
+   VF. If the smallest datatype in the loop is present only as the rhs of a 
+   promotion operation - we'd miss it.
+   Such a case, where a variable of this datatype does not appear in the lhs
+   anywhere in the loop, can only occur if it's an invariant: e.g.:
+   'int_x = (int) short_inv', which we'd expect to have been optimized away by 
+   invariant motion. However, we cannot rely on invariant motion to always take
+   invariants out of the loop, and so in the case of promotion we also have to
+   check the rhs. 
+   LHS_SIZE_UNIT and RHS_SIZE_UNIT contain the sizes of the corresponding
+   types.  */
+
+tree
+vect_get_smallest_scalar_type (gimple stmt, HOST_WIDE_INT *lhs_size_unit,
+                               HOST_WIDE_INT *rhs_size_unit)
+{
+  tree scalar_type = gimple_expr_type (stmt);
+  HOST_WIDE_INT lhs, rhs;
+
+  lhs = rhs = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (scalar_type));
+
+  if (is_gimple_assign (stmt)
+      && (gimple_assign_cast_p (stmt)
+          || gimple_assign_rhs_code (stmt) == WIDEN_MULT_EXPR
+          || gimple_assign_rhs_code (stmt) == FLOAT_EXPR))
+    {
+      tree rhs_type = TREE_TYPE (gimple_assign_rhs1 (stmt));
+
+      rhs = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (rhs_type));
+      if (rhs < lhs)
+        scalar_type = rhs_type;
+    }
+     
+  *lhs_size_unit = lhs; 
+  *rhs_size_unit = rhs;
+  return scalar_type;
+}
+
+
 /* Function vect_determine_vectorization_factor
 
    Determine the vectorization factor (VF). VF is the number of data elements
@@ -83,6 +127,7 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
   unsigned int nunits;
   stmt_vec_info stmt_info;
   int i;
+  HOST_WIDE_INT dummy;
 
   if (vect_print_dump_info (REPORT_DETAILS))
     fprintf (vect_dump, "=== vect_determine_vectorization_factor ===");
@@ -200,34 +245,8 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
              gcc_assert (! STMT_VINFO_DATA_REF (stmt_info)
                          && !is_pattern_stmt_p (stmt_info));
 
-             /* We generally set the vectype according to the type of the 
-                result (lhs).
-                For stmts whose result-type is different than the type of the
-                arguments (e.g. demotion, promotion), vectype will be reset 
-                appropriately (later).  Note that we have to visit the smallest 
-                datatype in this function, because that determines the VF.  
-                If the smallest datatype in the loop is present only as the 
-                rhs of a promotion operation - we'd miss it here.
-                Such a case, where a variable of this datatype does not appear 
-                in the lhs anywhere in the loop, can only occur if it's an
-                invariant: e.g.: 'int_x = (int) short_inv', which we'd expect
-                to have been optimized away by invariant motion. However, we 
-                cannot rely on invariant motion to always take invariants out
-                of the loop, and so in the case of promotion we also have to 
-                check the rhs.  */
-             scalar_type = gimple_expr_type (stmt);
-
-             if (is_gimple_assign (stmt)
-                 && (gimple_assign_cast_p (stmt)
-                     || gimple_assign_rhs_code (stmt) == WIDEN_MULT_EXPR
-                     || gimple_assign_rhs_code (stmt) == FLOAT_EXPR))
-               {
-                 tree rhs_type = TREE_TYPE (gimple_assign_rhs1 (stmt));
-                 if (TREE_INT_CST_LOW (TYPE_SIZE_UNIT (rhs_type))
-                     < TREE_INT_CST_LOW (TYPE_SIZE_UNIT (scalar_type)))
-                   scalar_type = rhs_type;
-               }
-
+             scalar_type = vect_get_smallest_scalar_type (stmt, &dummy, 
+                                                           &dummy);
              if (vect_print_dump_info (REPORT_DETAILS))
                {
                  fprintf (vect_dump, "get vectype for scalar type:  ");
@@ -2708,6 +2727,7 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, slp_tree *node,
   tree first_stmt_const_oprnd = NULL_TREE;
   struct data_reference *first_dr;
   bool pattern0 = false, pattern1 = false;
+  HOST_WIDE_INT dummy;
 
   /* For every stmt in NODE find its def stmt/s.  */
   for (i = 0; VEC_iterate (gimple, stmts, i, stmt); i++)
@@ -2731,7 +2751,7 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, slp_tree *node,
          return false;
        }
 
-      scalar_type = TREE_TYPE (lhs);
+      scalar_type = vect_get_smallest_scalar_type (stmt, &dummy, &dummy); 
       vectype = get_vectype_for_scalar_type (scalar_type);
       if (!vectype)
         {
@@ -2860,11 +2880,6 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, slp_tree *node,
                /* Load.  */
                if (i == 0)
                  {
-                    /* In case of multiple types we need to detect the smallest
-                       type.  */
-                    if (*max_nunits < TYPE_VECTOR_SUBPARTS (vectype))
-                       *max_nunits = TYPE_VECTOR_SUBPARTS (vectype);
-
                    /* First stmt of the SLP group should be the first load of 
                       the interleaving loop if data permutation is not allowed.
                       Check that there is no gap between the loads.  */
index c0c299b18fa541cafe1de008eceddf91416e171e..0744527794dd80db694911d8b75960acc8aac72a 100644 (file)
@@ -1385,11 +1385,11 @@ vect_init_vector (gimple stmt, tree vector_var, tree vector_type,
 /* For constant and loop invariant defs of SLP_NODE this function returns 
    (vector) defs (VEC_OPRNDS) that will be used in the vectorized stmts.  
    OP_NUM determines if we gather defs for operand 0 or operand 1 of the scalar
-   stmts.  */
+   stmts. NUMBER_OF_VECTORS is the number of vector defs to create.  */
 
 static void
 vect_get_constant_vectors (slp_tree slp_node, VEC(tree,heap) **vec_oprnds,
-                          unsigned int op_num)
+                          unsigned int op_num, unsigned int number_of_vectors)
 {
   VEC (gimple, heap) *stmts = SLP_TREE_SCALAR_STMTS (slp_node);
   gimple stmt = VEC_index (gimple, stmts, 0);
@@ -1405,7 +1405,6 @@ vect_get_constant_vectors (slp_tree slp_node, VEC(tree,heap) **vec_oprnds,
   unsigned int vec_num, i;
   int number_of_copies = 1;
   bool is_store = false;
-  unsigned int number_of_vectors = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node);
   VEC (tree, heap) *voprnds = VEC_alloc (tree, heap, number_of_vectors);
   bool constant_p;
 
@@ -1529,13 +1528,27 @@ vect_get_slp_defs (slp_tree slp_node, VEC (tree,heap) **vec_oprnds0,
   gimple first_stmt;
   enum tree_code code;
   int number_of_vects;
+  HOST_WIDE_INT lhs_size_unit, rhs_size_unit; 
 
+  first_stmt = VEC_index (gimple, SLP_TREE_SCALAR_STMTS (slp_node), 0);
   /* The number of vector defs is determined by the number of vector statements
      in the node from which we get those statements.  */
   if (SLP_TREE_LEFT (slp_node)) 
     number_of_vects = SLP_TREE_NUMBER_OF_VEC_STMTS (SLP_TREE_LEFT (slp_node));
   else
-    number_of_vects = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node);
+    {
+      number_of_vects = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node);
+      /* Number of vector stmts was calculated according to LHS in
+         vect_schedule_slp_instance(), fix it by replacing LHS with RHS, if
+         necessary. See vect_get_smallest_scalar_type() for details.  */
+      vect_get_smallest_scalar_type (first_stmt, &lhs_size_unit,
+                                     &rhs_size_unit);
+      if (rhs_size_unit != lhs_size_unit)
+        {
+          number_of_vects *= rhs_size_unit;
+          number_of_vects /= lhs_size_unit;
+        }
+    }
 
   /* Allocate memory for vectorized defs.  */
   *vec_oprnds0 = VEC_alloc (tree, heap, number_of_vects);
@@ -1547,9 +1560,8 @@ vect_get_slp_defs (slp_tree slp_node, VEC (tree,heap) **vec_oprnds0,
     vect_get_slp_vect_defs (SLP_TREE_LEFT (slp_node), vec_oprnds0);
   else
     /* Build vectors from scalar defs.  */
-    vect_get_constant_vectors (slp_node, vec_oprnds0, 0);
+    vect_get_constant_vectors (slp_node, vec_oprnds0, 0, number_of_vects);
 
-  first_stmt = VEC_index (gimple, SLP_TREE_SCALAR_STMTS (slp_node), 0);
   if (STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt)))
     /* Since we don't call this function with loads, this is a group of
        stores.  */
@@ -1573,7 +1585,7 @@ vect_get_slp_defs (slp_tree slp_node, VEC (tree,heap) **vec_oprnds0,
     vect_get_slp_vect_defs (SLP_TREE_RIGHT (slp_node), vec_oprnds1);
   else
     /* Build vectors from scalar defs.  */
-    vect_get_constant_vectors (slp_node, vec_oprnds1, 1);
+    vect_get_constant_vectors (slp_node, vec_oprnds1, 1, number_of_vects);
 }
 
 
index a22353ccefe3fbdffd6054f0bdf722064617a774..10e7aa309004d153f9a1af232d3e4e53a0e9b3a2 100644 (file)
@@ -702,6 +702,8 @@ extern void free_stmt_vec_info (gimple stmt);
 extern loop_vec_info vect_analyze_loop (struct loop *);
 extern void vect_free_slp_tree (slp_tree);
 extern loop_vec_info vect_analyze_loop_form (struct loop *);
+extern tree vect_get_smallest_scalar_type (gimple, HOST_WIDE_INT *, 
+                                           HOST_WIDE_INT *);
 
 /** In tree-vect-patterns.c  **/
 /* Pattern recognition functions.