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;
  }

Reply via email to