double_reduc = true;
}
+ vect_reduction_type reduction_type
+ = STMT_VINFO_VEC_REDUCTION_TYPE (stmt_info);
+ if ((double_reduc || reduction_type != TREE_CODE_REDUCTION)
+ && ncopies > 1)
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "multiple types in double reduction or condition "
+ "reduction.\n");
+ return false;
+ }
+
if (code == COND_EXPR)
{
/* Only call during the analysis stage, otherwise we'll lose
- STMT_VINFO_TYPE. We'll pass ops[0] as reduc_op, it's only
- used as a flag during analysis. */
+ STMT_VINFO_TYPE. */
if (!vec_stmt && !vectorizable_condition (stmt_info, gsi, NULL,
- ops[0], 0, NULL,
- cost_vec))
+ true, NULL, cost_vec))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
(and also the same tree-code) when generating the epilog code and
when generating the code inside the loop. */
- vect_reduction_type reduction_type
- = STMT_VINFO_VEC_REDUCTION_TYPE (stmt_info);
if (orig_stmt_info
&& (reduction_type == TREE_CODE_REDUCTION
|| reduction_type == FOLD_LEFT_REDUCTION))
return false;
}
- if ((double_reduc || reduction_type != TREE_CODE_REDUCTION)
- && ncopies > 1)
- {
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "multiple types in double reduction or condition "
- "reduction.\n");
- return false;
- }
-
/* For SLP reductions, see if there is a neutral value we can use. */
tree neutral_op = NULL_TREE;
if (slp_node)
{
gcc_assert (!slp_node);
return vectorizable_condition (stmt_info, gsi, vec_stmt,
- NULL, reduc_index, NULL, NULL);
+ true, NULL, NULL);
}
/* Create the destination vector */
{
gcc_assert (!slp_node);
vectorizable_condition (stmt_info, gsi, vec_stmt,
- PHI_RESULT (phis[0]->stmt),
- reduc_index, NULL, NULL);
- /* Multiple types are not supported for condition. */
+ true, NULL, NULL);
break;
}
if (code == LSHIFT_EXPR
stmt using VEC_COND_EXPR to replace it, put it in VEC_STMT, and insert it
at GSI.
- When STMT_INFO is vectorized as a nested cycle, REDUC_DEF is the vector
- variable to be used at REDUC_INDEX (in then clause if REDUC_INDEX is 1,
- and in else clause if it is 2).
+ When STMT_INFO is vectorized as a nested cycle, for_reduction is true.
Return true if STMT_INFO is vectorizable in this way. */
bool
vectorizable_condition (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
- stmt_vec_info *vec_stmt, tree reduc_def,
- int reduc_index, slp_tree slp_node,
- stmt_vector_for_cost *cost_vec)
+ stmt_vec_info *vec_stmt, bool for_reduction,
+ slp_tree slp_node, stmt_vector_for_cost *cost_vec)
{
vec_info *vinfo = stmt_info->vinfo;
tree scalar_dest = NULL_TREE;
tree vec_cmp_type;
bool masked = false;
- if (reduc_index && STMT_SLP_TYPE (stmt_info))
+ if (for_reduction && STMT_SLP_TYPE (stmt_info))
return false;
vect_reduction_type reduction_type
if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def
&& !(STMT_VINFO_DEF_TYPE (stmt_info) == vect_nested_cycle
- && reduc_def))
+ && for_reduction))
return false;
/* FORNOW: not yet supported. */
ncopies = vect_get_num_copies (loop_vinfo, vectype);
gcc_assert (ncopies >= 1);
- if (reduc_index && ncopies > 1)
+ if (for_reduction && ncopies > 1)
return false; /* FORNOW */
cond_expr = gimple_assign_rhs1 (stmt);
stmt_info, comp_vectype);
vect_is_simple_use (cond_expr1, loop_vinfo, &dts[1]);
}
- if (reduc_index == 1)
- vec_then_clause = reduc_def;
- else
- {
- vec_then_clause = vect_get_vec_def_for_operand (then_clause,
- stmt_info);
- vect_is_simple_use (then_clause, loop_vinfo, &dts[2]);
- }
- if (reduc_index == 2)
- vec_else_clause = reduc_def;
- else
- {
- vec_else_clause = vect_get_vec_def_for_operand (else_clause,
- stmt_info);
- vect_is_simple_use (else_clause, loop_vinfo, &dts[3]);
- }
+ vec_then_clause = vect_get_vec_def_for_operand (then_clause,
+ stmt_info);
+ vect_is_simple_use (then_clause, loop_vinfo, &dts[2]);
+ vec_else_clause = vect_get_vec_def_for_operand (else_clause,
+ stmt_info);
+ vect_is_simple_use (else_clause, loop_vinfo, &dts[3]);
}
}
else
vect_finish_stmt_generation (stmt_info, new_stmt, gsi);
vec_compare = vec_compare_name;
}
- gcc_assert (reduc_index == 2);
gcall *new_stmt = gimple_build_call_internal
(IFN_FOLD_EXTRACT_LAST, 3, else_clause, vec_compare,
vec_then_clause);
static bool
vectorizable_comparison (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
- stmt_vec_info *vec_stmt, tree reduc_def,
+ stmt_vec_info *vec_stmt,
slp_tree slp_node, stmt_vector_for_cost *cost_vec)
{
vec_info *vinfo = stmt_info->vinfo;
ncopies = vect_get_num_copies (loop_vinfo, vectype);
gcc_assert (ncopies >= 1);
- if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def
- && !(STMT_VINFO_DEF_TYPE (stmt_info) == vect_nested_cycle
- && reduc_def))
+ if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def)
return false;
if (STMT_VINFO_LIVE_P (stmt_info))
node_instance, cost_vec)
|| vectorizable_induction (stmt_info, NULL, NULL, node, cost_vec)
|| vectorizable_shift (stmt_info, NULL, NULL, node, cost_vec)
- || vectorizable_condition (stmt_info, NULL, NULL, NULL, 0, node,
+ || vectorizable_condition (stmt_info, NULL, NULL, false, node,
cost_vec)
- || vectorizable_comparison (stmt_info, NULL, NULL, NULL, node,
+ || vectorizable_comparison (stmt_info, NULL, NULL, node,
cost_vec));
else
{
|| vectorizable_load (stmt_info, NULL, NULL, node, node_instance,
cost_vec)
|| vectorizable_store (stmt_info, NULL, NULL, node, cost_vec)
- || vectorizable_condition (stmt_info, NULL, NULL, NULL, 0, node,
+ || vectorizable_condition (stmt_info, NULL, NULL, false, node,
cost_vec)
- || vectorizable_comparison (stmt_info, NULL, NULL, NULL, node,
+ || vectorizable_comparison (stmt_info, NULL, NULL, node,
cost_vec));
}
break;
case condition_vec_info_type:
- done = vectorizable_condition (stmt_info, gsi, &vec_stmt, NULL, 0,
+ done = vectorizable_condition (stmt_info, gsi, &vec_stmt, false,
slp_node, NULL);
gcc_assert (done);
break;
case comparison_vec_info_type:
- done = vectorizable_comparison (stmt_info, gsi, &vec_stmt, NULL,
+ done = vectorizable_comparison (stmt_info, gsi, &vec_stmt,
slp_node, NULL);
gcc_assert (done);
break;