Commit 8b7b9d66 by Ira Rosen Committed by Ira Rosen

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
parent f4185118
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
......
......@@ -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. */
......
......@@ -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);
}
......
......@@ -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.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment