Commit b690cc0f by Richard Guenther Committed by Richard Biener

tree-vectorizer.h (struct _stmt_vec_info): Document that vectype is the type of the LHS.

2010-04-09  Richard Guenther  <rguenther@suse.de>

	* tree-vectorizer.h (struct _stmt_vec_info): Document
	that vectype is the type of the LHS.
	(supportable_widening_operation, supportable_narrowing_operation): 
	Get both input and output vector types as arguments.
	(vect_is_simple_use_1): Declare.
	(get_same_sized_vectype): Likewise.
	* tree-vect-loop.c (vect_determine_vectorization_factor):
	Set STMT_VINFO_VECTYPE to the vector type of the def.
	(vectorizable_reduction): Adjust.
	* tree-vect-patterns.c (vect_recog_widen_mult_pattern):
	Adjust.  Specify the output vector type.
	(vect_pattern_recog_1): Adjust.
	* tree-vect-stmts.c (get_same_sized_vectype): New function.
	(vectorizable_call): Adjust.
	(vectorizable_conversion): Likewise.
	(vectorizable_operation): Likewise.
	(vectorizable_type_demotion): Likewise.
	(vectorizable_type_promotion): Likewise.
	(vect_analyze_stmt): Set STMT_VINFO_VECTYPE to the vector type of
	the def.
	(vect_is_simple_use_1): New function.
	(supportable_widening_operation): Get both input and output
	vector types.
	(supportable_narrowing_operation): Likewise.
	* tree-vect-slp.c (vect_schedule_slp_instance): Adjust.

From-SVN: r158157
parent ced57283
2010-04-09 Richard Guenther <rguenther@suse.de>
* tree-vectorizer.h (struct _stmt_vec_info): Document
that vectype is the type of the LHS.
(supportable_widening_operation, supportable_narrowing_operation):
Get both input and output vector types as arguments.
(vect_is_simple_use_1): Declare.
(get_same_sized_vectype): Likewise.
* tree-vect-loop.c (vect_determine_vectorization_factor):
Set STMT_VINFO_VECTYPE to the vector type of the def.
(vectorizable_reduction): Adjust.
* tree-vect-patterns.c (vect_recog_widen_mult_pattern):
Adjust. Specify the output vector type.
(vect_pattern_recog_1): Adjust.
* tree-vect-stmts.c (get_same_sized_vectype): New function.
(vectorizable_call): Adjust.
(vectorizable_conversion): Likewise.
(vectorizable_operation): Likewise.
(vectorizable_type_demotion): Likewise.
(vectorizable_type_promotion): Likewise.
(vect_analyze_stmt): Set STMT_VINFO_VECTYPE to the vector type of
the def.
(vect_is_simple_use_1): New function.
(supportable_widening_operation): Get both input and output
vector types.
(supportable_narrowing_operation): Likewise.
* tree-vect-slp.c (vect_schedule_slp_instance): Adjust.
2010-04-09 Kai Tietz <kai.tietz@onevision.com>
* config/i386/cygming.h (TARGET_OS_CPP_BUILTINS): Add
......
......@@ -240,6 +240,7 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
{
tree vf_vectype;
gimple stmt = gsi_stmt (si);
stmt_info = vinfo_for_stmt (stmt);
......@@ -294,14 +295,12 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
gcc_assert (!STMT_VINFO_DATA_REF (stmt_info)
&& !is_pattern_stmt_p (stmt_info));
scalar_type = vect_get_smallest_scalar_type (stmt, &dummy,
&dummy);
scalar_type = TREE_TYPE (gimple_get_lhs (stmt));
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "get vectype for scalar type: ");
print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
}
vectype = get_vectype_for_scalar_type (scalar_type);
if (!vectype)
{
......@@ -313,23 +312,60 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
}
return false;
}
STMT_VINFO_VECTYPE (stmt_info) = vectype;
}
/* The vectorization factor is according to the smallest
scalar type (or the largest vector size, but we only
support one vector size per loop). */
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: ");
print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
}
vf_vectype = get_vectype_for_scalar_type (scalar_type);
if (!vf_vectype)
{
if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
{
fprintf (vect_dump,
"not vectorized: unsupported data-type ");
print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
}
return false;
}
if ((GET_MODE_SIZE (TYPE_MODE (vectype))
!= GET_MODE_SIZE (TYPE_MODE (vf_vectype))))
{
if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
{
fprintf (vect_dump,
"not vectorized: different sized vector "
"types in statement, ");
print_generic_expr (vect_dump, vectype, TDF_SLIM);
fprintf (vect_dump, " and ");
print_generic_expr (vect_dump, vf_vectype, TDF_SLIM);
}
return false;
}
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "vectype: ");
print_generic_expr (vect_dump, vectype, TDF_SLIM);
print_generic_expr (vect_dump, vf_vectype, TDF_SLIM);
}
nunits = TYPE_VECTOR_SUBPARTS (vectype);
nunits = TYPE_VECTOR_SUBPARTS (vf_vectype);
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "nunits = %d", nunits);
if (!vectorization_factor
|| (nunits > vectorization_factor))
vectorization_factor = nunits;
}
}
......@@ -3446,7 +3482,8 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
tree scalar_dest;
tree loop_vec_def0 = NULL_TREE, loop_vec_def1 = NULL_TREE;
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
tree vectype_out = STMT_VINFO_VECTYPE (stmt_info);
tree vectype_in = NULL_TREE;
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
enum tree_code code, orig_code, epilog_reduc_code;
......@@ -3464,8 +3501,7 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
stmt_vec_info orig_stmt_info;
tree expr = NULL_TREE;
int i;
int nunits = TYPE_VECTOR_SUBPARTS (vectype);
int ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
int ncopies;
int epilog_copies;
stmt_vec_info prev_stmt_info, prev_phi_info;
gimple first_phi = NULL;
......@@ -3491,8 +3527,6 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
nested_cycle = true;
}
gcc_assert (ncopies >= 1);
/* FORNOW: SLP not supported. */
if (STMT_SLP_TYPE (stmt_info))
return false;
......@@ -3579,12 +3613,16 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
reduction variable. */
for (i = 0; i < op_type-1; i++)
{
tree tem;
/* The condition of COND_EXPR is checked in vectorizable_condition(). */
if (i == 0 && code == COND_EXPR)
continue;
is_simple_use = vect_is_simple_use (ops[i], loop_vinfo, NULL, &def_stmt,
&def, &dt);
is_simple_use = vect_is_simple_use_1 (ops[i], loop_vinfo, NULL,
&def_stmt, &def, &dt, &tem);
if (!vectype_in)
vectype_in = tem;
gcc_assert (is_simple_use);
if (dt != vect_internal_def
&& dt != vect_external_def
......@@ -3602,7 +3640,7 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
}
is_simple_use = vect_is_simple_use (ops[i], loop_vinfo, NULL, &def_stmt,
&def, &dt);
&def, &dt);
gcc_assert (is_simple_use);
gcc_assert (dt == vect_reduction_def
|| dt == vect_nested_cycle
......@@ -3625,7 +3663,12 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
if (STMT_VINFO_LIVE_P (vinfo_for_stmt (reduc_def_stmt)))
return false;
vec_mode = TYPE_MODE (vectype);
ncopies = (LOOP_VINFO_VECT_FACTOR (loop_vinfo)
/ TYPE_VECTOR_SUBPARTS (vectype_in));
gcc_assert (ncopies >= 1);
vec_mode = TYPE_MODE (vectype_in);
if (code == COND_EXPR)
{
......@@ -3642,7 +3685,7 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
/* 4. Supportable by target? */
/* 4.1. check support for the operation in the loop */
optab = optab_for_tree_code (code, vectype, optab_default);
optab = optab_for_tree_code (code, vectype_in, optab_default);
if (!optab)
{
if (vect_print_dump_info (REPORT_DETAILS))
......@@ -3666,7 +3709,7 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
}
/* Worthwhile without SIMD support? */
if (!VECTOR_MODE_P (TYPE_MODE (vectype))
if (!VECTOR_MODE_P (TYPE_MODE (vectype_in))
&& LOOP_VINFO_VECT_FACTOR (loop_vinfo)
< vect_min_worthwhile_factor (code))
{
......@@ -3716,18 +3759,8 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
/* This is a reduction pattern: get the vectype from the type of the
reduction variable, and get the tree-code from orig_stmt. */
orig_code = gimple_assign_rhs_code (orig_stmt);
vectype = get_vectype_for_scalar_type (TREE_TYPE (def));
if (!vectype)
{
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "unsupported data-type ");
print_generic_expr (vect_dump, TREE_TYPE (def), TDF_SLIM);
}
return false;
}
vec_mode = TYPE_MODE (vectype);
gcc_assert (vectype_out);
vec_mode = TYPE_MODE (vectype_out);
}
else
{
......@@ -3755,7 +3788,7 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
epilog_reduc_code = ERROR_MARK;
if (reduction_code_for_scalar_code (orig_code, &epilog_reduc_code))
{
reduc_optab = optab_for_tree_code (epilog_reduc_code, vectype,
reduc_optab = optab_for_tree_code (epilog_reduc_code, vectype_out,
optab_default);
if (!reduc_optab)
{
......@@ -3812,7 +3845,7 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
gcc_assert (ncopies == 1);
/* Create the destination vector */
vec_dest = vect_create_destination_var (scalar_dest, vectype);
vec_dest = vect_create_destination_var (scalar_dest, vectype_out);
/* In case the vectorization factor (VF) is bigger than the number
of elements that we can fit in a vectype (nunits), we have to generate
......@@ -3910,22 +3943,22 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
if (op_type == binary_op)
{
if (reduc_index == 0)
expr = build2 (code, vectype, reduc_def, loop_vec_def0);
expr = build2 (code, vectype_out, reduc_def, loop_vec_def0);
else
expr = build2 (code, vectype, loop_vec_def0, reduc_def);
expr = build2 (code, vectype_out, loop_vec_def0, reduc_def);
}
else
{
if (reduc_index == 0)
expr = build3 (code, vectype, reduc_def, loop_vec_def0,
expr = build3 (code, vectype_out, reduc_def, loop_vec_def0,
loop_vec_def1);
else
{
if (reduc_index == 1)
expr = build3 (code, vectype, loop_vec_def0, reduc_def,
expr = build3 (code, vectype_out, loop_vec_def0, reduc_def,
loop_vec_def1);
else
expr = build3 (code, vectype, loop_vec_def0, loop_vec_def1,
expr = build3 (code, vectype_out, loop_vec_def0, loop_vec_def1,
reduc_def);
}
}
......
......@@ -362,7 +362,7 @@ vect_recog_widen_mult_pattern (gimple last_stmt,
tree oprnd0, oprnd1;
tree type, half_type0, half_type1;
gimple pattern_stmt;
tree vectype;
tree vectype, vectype_out;
tree dummy;
tree var;
enum tree_code dummy_code;
......@@ -405,14 +405,16 @@ vect_recog_widen_mult_pattern (gimple last_stmt,
/* Check target support */
vectype = get_vectype_for_scalar_type (half_type0);
vectype_out = get_vectype_for_scalar_type (type);
if (!vectype
|| !supportable_widening_operation (WIDEN_MULT_EXPR, last_stmt, vectype,
|| !supportable_widening_operation (WIDEN_MULT_EXPR, last_stmt,
vectype_out, vectype,
&dummy, &dummy, &dummy_code,
&dummy_code, &dummy_int, &dummy_vec))
return NULL;
*type_in = vectype;
*type_out = NULL_TREE;
*type_out = vectype_out;
/* Pattern supported. Create a stmt to be used to replace the pattern: */
var = vect_recog_temp_ssa_var (type, NULL);
......@@ -677,7 +679,9 @@ vect_pattern_recog_1 (
{
/* No need to check target support (already checked by the pattern
recognition function). */
pattern_vectype = type_in;
if (type_out)
gcc_assert (VECTOR_MODE_P (TYPE_MODE (type_out)));
pattern_vectype = type_out ? type_out : type_in;
}
else
{
......@@ -686,9 +690,14 @@ vect_pattern_recog_1 (
optab optab;
/* Check target support */
pattern_vectype = get_vectype_for_scalar_type (type_in);
if (!pattern_vectype)
return;
type_in = get_vectype_for_scalar_type (type_in);
if (!type_in)
return;
if (type_out)
type_out = get_vectype_for_scalar_type (type_out);
else
type_out = type_in;
pattern_vectype = type_out;
if (is_gimple_assign (pattern_stmt))
code = gimple_assign_rhs_code (pattern_stmt);
......@@ -698,15 +707,12 @@ vect_pattern_recog_1 (
code = CALL_EXPR;
}
optab = optab_for_tree_code (code, pattern_vectype, optab_default);
vec_mode = TYPE_MODE (pattern_vectype);
optab = optab_for_tree_code (code, type_in, optab_default);
vec_mode = TYPE_MODE (type_in);
if (!optab
|| (icode = optab_handler (optab, vec_mode)->insn_code) ==
CODE_FOR_nothing
|| (type_out
&& (!get_vectype_for_scalar_type (type_out)
|| (insn_data[icode].operand[0].mode !=
TYPE_MODE (get_vectype_for_scalar_type (type_out))))))
|| (insn_data[icode].operand[0].mode != TYPE_MODE (type_out)))
return;
}
......
......@@ -1971,7 +1971,7 @@ vect_schedule_slp_instance (slp_tree node, slp_instance instance,
stmt_info = vinfo_for_stmt (stmt);
/* VECTYPE is the type of the destination. */
vectype = get_vectype_for_scalar_type (TREE_TYPE (gimple_assign_lhs (stmt)));
vectype = STMT_VINFO_VECTYPE (stmt_info);
nunits = (unsigned int) TYPE_VECTOR_SUBPARTS (vectype);
group_size = SLP_INSTANCE_GROUP_SIZE (instance);
......
......@@ -409,7 +409,7 @@ typedef struct _stmt_vec_info {
used outside the loop. */
bool live;
/* The vector type to be used. */
/* The vector type to be used for the LHS of this statement. */
tree vectype;
/* The vectorized version of the stmt. */
......@@ -760,15 +760,18 @@ extern bool vect_can_advance_ivs_p (loop_vec_info);
/* In tree-vect-stmts.c. */
extern tree get_vectype_for_scalar_type (tree);
extern tree get_same_sized_vectype (tree, tree);
extern bool vect_is_simple_use (tree, loop_vec_info, bb_vec_info, gimple *,
tree *, enum vect_def_type *);
extern bool supportable_widening_operation (enum tree_code, gimple, tree,
extern bool vect_is_simple_use_1 (tree, loop_vec_info, bb_vec_info, gimple *,
tree *, enum vect_def_type *, tree *);
extern bool supportable_widening_operation (enum tree_code, gimple, tree, tree,
tree *, tree *, enum tree_code *,
enum tree_code *, int *,
VEC (tree, heap) **);
extern bool supportable_narrowing_operation (enum tree_code, const_gimple,
tree, enum tree_code *, int *,
VEC (tree, heap) **);
extern bool supportable_narrowing_operation (enum tree_code, tree, tree,
enum tree_code *,
int *, VEC (tree, heap) **);
extern stmt_vec_info new_stmt_vec_info (gimple stmt, loop_vec_info,
bb_vec_info);
extern void free_stmt_vec_info (gimple stmt);
......
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