This patch makes hoist_defs_of_uses use vec_info::lookup_def instead of:
if (!gimple_nop_p (def_stmt)
&& flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)))
to test whether a feeding scalar statement needs to be hoisted out
of the vectorised loop. It isn't worth doing in its own right,
but it's a prerequisite for the next patch, which needs to update
the stmt_vec_infos of the hoisted statements.
2018-07-30 Richard Sandiford <[email protected]>
gcc/
* tree-vect-stmts.c (hoist_defs_of_uses): Use vec_info::lookup_def
instead of gimple_nop_p and flow_bb_inside_loop_p to decide
whether a statement needs to be hoisted.
Index: gcc/tree-vect-stmts.c
===================================================================
*** gcc/tree-vect-stmts.c 2018-07-30 12:42:35.633169005 +0100
--- gcc/tree-vect-stmts.c 2018-07-30 12:42:35.629169040 +0100
*************** permute_vec_elements (tree x, tree y, tr
*** 7322,7370 ****
static bool
hoist_defs_of_uses (stmt_vec_info stmt_info, struct loop *loop)
{
ssa_op_iter i;
tree op;
bool any = false;
FOR_EACH_SSA_TREE_OPERAND (op, stmt_info->stmt, i, SSA_OP_USE)
! {
! gimple *def_stmt = SSA_NAME_DEF_STMT (op);
! if (!gimple_nop_p (def_stmt)
! && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)))
! {
! /* Make sure we don't need to recurse. While we could do
! so in simple cases when there are more complex use webs
! we don't have an easy way to preserve stmt order to fulfil
! dependencies within them. */
! tree op2;
! ssa_op_iter i2;
! if (gimple_code (def_stmt) == GIMPLE_PHI)
return false;
! FOR_EACH_SSA_TREE_OPERAND (op2, def_stmt, i2, SSA_OP_USE)
! {
! gimple *def_stmt2 = SSA_NAME_DEF_STMT (op2);
! if (!gimple_nop_p (def_stmt2)
! && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt2)))
! return false;
! }
! any = true;
! }
! }
if (!any)
return true;
FOR_EACH_SSA_TREE_OPERAND (op, stmt_info->stmt, i, SSA_OP_USE)
! {
! gimple *def_stmt = SSA_NAME_DEF_STMT (op);
! if (!gimple_nop_p (def_stmt)
! && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)))
! {
! gimple_stmt_iterator gsi = gsi_for_stmt (def_stmt);
! gsi_remove (&gsi, false);
! gsi_insert_on_edge_immediate (loop_preheader_edge (loop), def_stmt);
! }
! }
return true;
}
--- 7322,7360 ----
static bool
hoist_defs_of_uses (stmt_vec_info stmt_info, struct loop *loop)
{
+ vec_info *vinfo = stmt_info->vinfo;
ssa_op_iter i;
tree op;
bool any = false;
FOR_EACH_SSA_TREE_OPERAND (op, stmt_info->stmt, i, SSA_OP_USE)
! if (stmt_vec_info def_stmt_info = vinfo->lookup_def (op))
! {
! /* Make sure we don't need to recurse. While we could do
! so in simple cases when there are more complex use webs
! we don't have an easy way to preserve stmt order to fulfil
! dependencies within them. */
! tree op2;
! ssa_op_iter i2;
! if (gimple_code (def_stmt_info->stmt) == GIMPLE_PHI)
! return false;
! FOR_EACH_SSA_TREE_OPERAND (op2, def_stmt_info->stmt, i2, SSA_OP_USE)
! if (vinfo->lookup_def (op2))
return false;
! any = true;
! }
if (!any)
return true;
FOR_EACH_SSA_TREE_OPERAND (op, stmt_info->stmt, i, SSA_OP_USE)
! if (stmt_vec_info def_stmt_info = vinfo->lookup_def (op))
! {
! gimple_stmt_iterator gsi = gsi_for_stmt (def_stmt_info->stmt);
! gsi_remove (&gsi, false);
! gsi_insert_on_edge_immediate (loop_preheader_edge (loop),
! def_stmt_info->stmt);
! }
return true;
}