aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorIra Rosen <irar@il.ibm.com>2008-08-23 17:04:12 +0000
committerIra Rosen <irar@gcc.gnu.org>2008-08-23 17:04:12 +0000
commit8b7b9d66fe761fb42a55d016c90a4790f301f6c0 (patch)
tree4732cf98327fb0a83820979f35dc3cc279be0a92 /gcc
parentf4185118a442bf05af6b640909cd1dec96dc84e9 (diff)
downloadgcc-8b7b9d66fe761fb42a55d016c90a4790f301f6c0.zip
gcc-8b7b9d66fe761fb42a55d016c90a4790f301f6c0.tar.gz
gcc-8b7b9d66fe761fb42a55d016c90a4790f301f6c0.tar.bz2
re PR middle-end/37161 (Revision 139225 caused gfortran.dg/vect/pr33301.f -O)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/tree-vect-analyze.c83
-rw-r--r--gcc/tree-vect-transform.c26
-rw-r--r--gcc/tree-vectorizer.h2
4 files changed, 84 insertions, 41 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8f291e8..1e1deeb 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/tree-vect-analyze.c b/gcc/tree-vect-analyze.c
index 0f2efd8..305ba4c 100644
--- a/gcc/tree-vect-analyze.c
+++ b/gcc/tree-vect-analyze.c
@@ -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. */
diff --git a/gcc/tree-vect-transform.c b/gcc/tree-vect-transform.c
index c0c299b..0744527 100644
--- a/gcc/tree-vect-transform.c
+++ b/gcc/tree-vect-transform.c
@@ -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);
}
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index a22353c..10e7aa3 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -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.