Commit b0b4483e by Richard Biener Committed by Richard Biener

tree-vect-slp.c (vect_get_and_check_slp_defs): Try swapping operands to get a…

tree-vect-slp.c (vect_get_and_check_slp_defs): Try swapping operands to get a def operand kind match.

2014-10-20  Richard Biener  <rguenther@suse.de>

	* tree-vect-slp.c (vect_get_and_check_slp_defs): Try swapping
	operands to get a def operand kind match.  Signal mismatches
	to the parent so we can try swapping its operands.
	(vect_build_slp_tree): Try swapping operands if they have
	a mismatched operand kind.

From-SVN: r216463
parent c11c8664
2014-10-20 Richard Biener <rguenther@suse.de>
* tree-vect-slp.c (vect_get_and_check_slp_defs): Try swapping
operands to get a def operand kind match. Signal mismatches
to the parent so we can try swapping its operands.
(vect_build_slp_tree): Try swapping operands if they have
a mismatched operand kind.
2014-10-20 Alan Modra <amodra@gmail.com> 2014-10-20 Alan Modra <amodra@gmail.com>
PR debug/60655 PR debug/60655
...@@ -205,9 +205,11 @@ vect_get_place_in_interleaving_chain (gimple stmt, gimple first_stmt) ...@@ -205,9 +205,11 @@ vect_get_place_in_interleaving_chain (gimple stmt, gimple first_stmt)
/* Get the defs for the rhs of STMT (collect them in OPRNDS_INFO), check that /* Get the defs for the rhs of STMT (collect them in OPRNDS_INFO), check that
they are of a valid type and that they match the defs of the first stmt of they are of a valid type and that they match the defs of the first stmt of
the SLP group (stored in OPRNDS_INFO). */ the SLP group (stored in OPRNDS_INFO). If there was a fatal error
return -1, if the error could be corrected by swapping operands of the
operation return 1, if everything is ok return 0. */
static bool static int
vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
gimple stmt, bool first, gimple stmt, bool first,
vec<slp_oprnd_info> *oprnds_info) vec<slp_oprnd_info> *oprnds_info)
...@@ -220,8 +222,9 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, ...@@ -220,8 +222,9 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
struct loop *loop = NULL; struct loop *loop = NULL;
bool pattern = false; bool pattern = false;
slp_oprnd_info oprnd_info; slp_oprnd_info oprnd_info;
int op_idx = 1; int first_op_idx = 1;
tree compare_rhs = NULL_TREE; bool commutative = false;
bool first_op_cond = false;
if (loop_vinfo) if (loop_vinfo)
loop = LOOP_VINFO_LOOP (loop_vinfo); loop = LOOP_VINFO_LOOP (loop_vinfo);
...@@ -229,35 +232,41 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, ...@@ -229,35 +232,41 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
if (is_gimple_call (stmt)) if (is_gimple_call (stmt))
{ {
number_of_oprnds = gimple_call_num_args (stmt); number_of_oprnds = gimple_call_num_args (stmt);
op_idx = 3; first_op_idx = 3;
} }
else if (is_gimple_assign (stmt)) else if (is_gimple_assign (stmt))
{ {
enum tree_code code = gimple_assign_rhs_code (stmt);
number_of_oprnds = gimple_num_ops (stmt) - 1; number_of_oprnds = gimple_num_ops (stmt) - 1;
if (gimple_assign_rhs_code (stmt) == COND_EXPR) if (gimple_assign_rhs_code (stmt) == COND_EXPR)
number_of_oprnds++; {
first_op_cond = true;
commutative = true;
number_of_oprnds++;
}
else
commutative = commutative_tree_code (code);
} }
else else
return false; return -1;
bool swapped = false;
for (i = 0; i < number_of_oprnds; i++) for (i = 0; i < number_of_oprnds; i++)
{ {
if (compare_rhs) again:
if (first_op_cond)
{ {
oprnd = compare_rhs; if (i == 0 || i == 1)
compare_rhs = NULL_TREE; oprnd = TREE_OPERAND (gimple_op (stmt, first_op_idx),
swapped ? !i : i);
else
oprnd = gimple_op (stmt, first_op_idx + i - 1);
} }
else else
oprnd = gimple_op (stmt, op_idx++); oprnd = gimple_op (stmt, first_op_idx + (swapped ? !i : i));
oprnd_info = (*oprnds_info)[i]; oprnd_info = (*oprnds_info)[i];
if (COMPARISON_CLASS_P (oprnd))
{
compare_rhs = TREE_OPERAND (oprnd, 1);
oprnd = TREE_OPERAND (oprnd, 0);
}
if (!vect_is_simple_use (oprnd, NULL, loop_vinfo, bb_vinfo, &def_stmt, if (!vect_is_simple_use (oprnd, NULL, loop_vinfo, bb_vinfo, &def_stmt,
&def, &dt) &def, &dt)
|| (!def_stmt && dt != vect_constant_def)) || (!def_stmt && dt != vect_constant_def))
...@@ -270,7 +279,7 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, ...@@ -270,7 +279,7 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
} }
return false; return -1;
} }
/* Check if DEF_STMT is a part of a pattern in LOOP and get the def stmt /* Check if DEF_STMT is a part of a pattern in LOOP and get the def stmt
...@@ -288,6 +297,14 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, ...@@ -288,6 +297,14 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
pattern = true; pattern = true;
if (!first && !oprnd_info->first_pattern) if (!first && !oprnd_info->first_pattern)
{ {
if (i == 0
&& !swapped
&& commutative)
{
swapped = true;
goto again;
}
if (dump_enabled_p ()) if (dump_enabled_p ())
{ {
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
...@@ -297,7 +314,7 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, ...@@ -297,7 +314,7 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
} }
return false; return 1;
} }
def_stmt = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (def_stmt)); def_stmt = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (def_stmt));
...@@ -308,7 +325,7 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, ...@@ -308,7 +325,7 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
if (dump_enabled_p ()) if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
"Unsupported pattern.\n"); "Unsupported pattern.\n");
return false; return -1;
} }
switch (gimple_code (def_stmt)) switch (gimple_code (def_stmt))
...@@ -325,7 +342,7 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, ...@@ -325,7 +342,7 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
if (dump_enabled_p ()) if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
"unsupported defining stmt:\n"); "unsupported defining stmt:\n");
return false; return -1;
} }
} }
...@@ -352,11 +369,20 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, ...@@ -352,11 +369,20 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
|| !types_compatible_p (oprnd_info->first_op_type, || !types_compatible_p (oprnd_info->first_op_type,
TREE_TYPE (oprnd)))) TREE_TYPE (oprnd))))
{ {
/* Try swapping operands if we got a mismatch. */
if (i == 0
&& !swapped
&& commutative)
{
swapped = true;
goto again;
}
if (dump_enabled_p ()) if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
"Build SLP failed: different types\n"); "Build SLP failed: different types\n");
return false; return 1;
} }
} }
...@@ -382,11 +408,26 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, ...@@ -382,11 +408,26 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
} }
return false; return -1;
} }
} }
return true; /* Swap operands. */
if (swapped)
{
if (first_op_cond)
{
tree cond = gimple_assign_rhs1 (stmt);
swap_ssa_operands (stmt, &TREE_OPERAND (cond, 0),
&TREE_OPERAND (cond, 1));
TREE_SET_CODE (cond, swap_tree_comparison (TREE_CODE (cond)));
}
else
swap_ssa_operands (stmt, gimple_assign_rhs1_ptr (stmt),
gimple_assign_rhs2_ptr (stmt));
}
return 0;
} }
...@@ -892,13 +933,26 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, ...@@ -892,13 +933,26 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
slp_oprnd_info oprnd_info; slp_oprnd_info oprnd_info;
FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (*node), i, stmt) FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (*node), i, stmt)
{ {
if (!vect_get_and_check_slp_defs (loop_vinfo, bb_vinfo, switch (vect_get_and_check_slp_defs (loop_vinfo, bb_vinfo,
stmt, (i == 0), &oprnds_info)) stmt, (i == 0), &oprnds_info))
{ {
case 0:
break;
case -1:
matches[0] = false;
vect_free_oprnd_info (oprnds_info); vect_free_oprnd_info (oprnds_info);
return false; return false;
case 1:
matches[i] = false;
break;
} }
} }
for (i = 0; i < group_size; ++i)
if (!matches[i])
{
vect_free_oprnd_info (oprnds_info);
return false;
}
stmt = SLP_TREE_SCALAR_STMTS (*node)[0]; stmt = SLP_TREE_SCALAR_STMTS (*node)[0];
...@@ -958,13 +1012,17 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, ...@@ -958,13 +1012,17 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
*max_nunits = old_max_nunits; *max_nunits = old_max_nunits;
loads->truncate (old_nloads); loads->truncate (old_nloads);
/* Swap mismatched definition stmts. */ /* Swap mismatched definition stmts. */
dump_printf_loc (MSG_NOTE, vect_location,
"Re-trying with swapped operands of stmts ");
for (unsigned j = 0; j < group_size; ++j) for (unsigned j = 0; j < group_size; ++j)
if (!matches[j]) if (!matches[j])
{ {
gimple tem = oprnds_info[0]->def_stmts[j]; gimple tem = oprnds_info[0]->def_stmts[j];
oprnds_info[0]->def_stmts[j] = oprnds_info[1]->def_stmts[j]; oprnds_info[0]->def_stmts[j] = oprnds_info[1]->def_stmts[j];
oprnds_info[1]->def_stmts[j] = tem; oprnds_info[1]->def_stmts[j] = tem;
dump_printf (MSG_NOTE, "%d ", j);
} }
dump_printf (MSG_NOTE, "\n");
/* And try again ... */ /* And try again ... */
if (vect_build_slp_tree (loop_vinfo, bb_vinfo, &child, if (vect_build_slp_tree (loop_vinfo, bb_vinfo, &child,
group_size, max_nunits, loads, group_size, max_nunits, loads,
......
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