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 <richard.sandif...@arm.com> 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; }