diff mbox series

[11/46] Pass back a stmt_vec_info from vect_is_simple_use

Message ID 87lga1q7lf.fsf@arm.com
State New
Headers show
Series Remove vinfo_for_stmt etc. | expand

Commit Message

Richard Sandiford July 24, 2018, 9:57 a.m. UTC
This patch makes vect_is_simple_use pass back a stmt_vec_info to
those callers that want it.  Most users only need the stmt_vec_info
but some need the gimple stmt too.

It's probably high time we added a class to represent "simple operands"
instead, but I have a separate series that tries to clean up how
operands are handled (with a view to allowing mixed vector sizes).


2018-07-24  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
	* tree-vectorizer.h (vect_is_simple_use): Add an optional
	stmt_vec_info * parameter before the optional gimple **.
	* tree-vect-stmts.c (vect_is_simple_use): Likewise.
	(process_use, vect_get_vec_def_for_operand_1): Update callers.
	(vect_get_vec_def_for_operand, vectorizable_shift): Likewise.
	* tree-vect-loop.c (vectorizable_reduction): Likewise.
	(vectorizable_live_operation): Likewise.
	* tree-vect-patterns.c (type_conversion_p): Likewise.
	(vect_look_through_possible_promotion): Likewise.
	(vect_recog_rotate_pattern): Likewise.
	* tree-vect-slp.c (vect_get_and_check_slp_defs): Likewise.

Comments

Richard Biener July 25, 2018, 9:17 a.m. UTC | #1
On Tue, Jul 24, 2018 at 11:57 AM Richard Sandiford
<richard.sandiford@arm.com> wrote:
>
> This patch makes vect_is_simple_use pass back a stmt_vec_info to
> those callers that want it.  Most users only need the stmt_vec_info
> but some need the gimple stmt too.

Hmm.  Unfortunately it's not redundant for dt_extern ...

> It's probably high time we added a class to represent "simple operands"
> instead, but I have a separate series that tries to clean up how
> operands are handled (with a view to allowing mixed vector sizes).

Well, we need to do sth similar to SLP and allow annotation on
SSA use edges, thus operand info needs to be context dependent.

One of my "plans" was to move everything over to the SLP datastructure
(imperfect as it is) to make that the "single" representation of stuff.
A very simple experiment allowing group sizes of one in SLP detection
worked reasonably well (and exposed all the cases we do not yet
handle in SLP ...).

OK.

Richard.

>
> 2018-07-24  Richard Sandiford  <richard.sandiford@arm.com>
>
> gcc/
>         * tree-vectorizer.h (vect_is_simple_use): Add an optional
>         stmt_vec_info * parameter before the optional gimple **.
>         * tree-vect-stmts.c (vect_is_simple_use): Likewise.
>         (process_use, vect_get_vec_def_for_operand_1): Update callers.
>         (vect_get_vec_def_for_operand, vectorizable_shift): Likewise.
>         * tree-vect-loop.c (vectorizable_reduction): Likewise.
>         (vectorizable_live_operation): Likewise.
>         * tree-vect-patterns.c (type_conversion_p): Likewise.
>         (vect_look_through_possible_promotion): Likewise.
>         (vect_recog_rotate_pattern): Likewise.
>         * tree-vect-slp.c (vect_get_and_check_slp_defs): Likewise.
>
> Index: gcc/tree-vectorizer.h
> ===================================================================
> --- gcc/tree-vectorizer.h       2018-07-24 10:22:33.829278607 +0100
> +++ gcc/tree-vectorizer.h       2018-07-24 10:22:37.257248166 +0100
> @@ -1532,9 +1532,10 @@ extern tree get_mask_type_for_scalar_typ
>  extern tree get_same_sized_vectype (tree, tree);
>  extern bool vect_get_loop_mask_type (loop_vec_info);
>  extern bool vect_is_simple_use (tree, vec_info *, enum vect_def_type *,
> -                               gimple ** = NULL);
> +                               stmt_vec_info * = NULL, gimple ** = NULL);
>  extern bool vect_is_simple_use (tree, vec_info *, enum vect_def_type *,
> -                               tree *, gimple ** = NULL);
> +                               tree *, stmt_vec_info * = NULL,
> +                               gimple ** = NULL);
>  extern bool supportable_widening_operation (enum tree_code, gimple *, tree,
>                                             tree, enum tree_code *,
>                                             enum tree_code *, int *,
> Index: gcc/tree-vect-stmts.c
> ===================================================================
> --- gcc/tree-vect-stmts.c       2018-07-24 10:22:33.829278607 +0100
> +++ gcc/tree-vect-stmts.c       2018-07-24 10:22:37.257248166 +0100
> @@ -459,11 +459,9 @@ process_use (gimple *stmt, tree use, loo
>              enum vect_relevant relevant, vec<gimple *> *worklist,
>              bool force)
>  {
> -  struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
>    stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
>    stmt_vec_info dstmt_vinfo;
>    basic_block bb, def_bb;
> -  gimple *def_stmt;
>    enum vect_def_type dt;
>
>    /* case 1: we are only interested in uses that need to be vectorized.  Uses
> @@ -471,7 +469,7 @@ process_use (gimple *stmt, tree use, loo
>    if (!force && !exist_non_indexing_operands_for_use_p (use, stmt))
>       return true;
>
> -  if (!vect_is_simple_use (use, loop_vinfo, &dt, &def_stmt))
> +  if (!vect_is_simple_use (use, loop_vinfo, &dt, &dstmt_vinfo))
>      {
>        if (dump_enabled_p ())
>          dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
> @@ -479,27 +477,20 @@ process_use (gimple *stmt, tree use, loo
>        return false;
>      }
>
> -  if (!def_stmt || gimple_nop_p (def_stmt))
> +  if (!dstmt_vinfo)
>      return true;
>
> -  def_bb = gimple_bb (def_stmt);
> -  if (!flow_bb_inside_loop_p (loop, def_bb))
> -    {
> -      if (dump_enabled_p ())
> -       dump_printf_loc (MSG_NOTE, vect_location, "def_stmt is out of loop.\n");
> -      return true;
> -    }
> +  def_bb = gimple_bb (dstmt_vinfo->stmt);
>
> -  /* case 2: A reduction phi (STMT) defined by a reduction stmt (DEF_STMT).
> -     DEF_STMT must have already been processed, because this should be the
> +  /* case 2: A reduction phi (STMT) defined by a reduction stmt (DSTMT_VINFO).
> +     DSTMT_VINFO must have already been processed, because this should be the
>       only way that STMT, which is a reduction-phi, was put in the worklist,
> -     as there should be no other uses for DEF_STMT in the loop.  So we just
> +     as there should be no other uses for DSTMT_VINFO in the loop.  So we just
>       check that everything is as expected, and we are done.  */
> -  dstmt_vinfo = vinfo_for_stmt (def_stmt);
>    bb = gimple_bb (stmt);
>    if (gimple_code (stmt) == GIMPLE_PHI
>        && STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def
> -      && gimple_code (def_stmt) != GIMPLE_PHI
> +      && gimple_code (dstmt_vinfo->stmt) != GIMPLE_PHI
>        && STMT_VINFO_DEF_TYPE (dstmt_vinfo) == vect_reduction_def
>        && bb->loop_father == def_bb->loop_father)
>      {
> @@ -514,7 +505,7 @@ process_use (gimple *stmt, tree use, loo
>
>    /* case 3a: outer-loop stmt defining an inner-loop stmt:
>         outer-loop-header-bb:
> -               d = def_stmt
> +               d = dstmt_vinfo
>         inner-loop:
>                 stmt # use (d)
>         outer-loop-tail-bb:
> @@ -554,7 +545,7 @@ process_use (gimple *stmt, tree use, loo
>         outer-loop-header-bb:
>                 ...
>         inner-loop:
> -               d = def_stmt
> +               d = dstmt_vinfo
>         outer-loop-tail-bb (or outer-loop-exit-bb in double reduction):
>                 stmt # use (d)          */
>    else if (flow_loop_nested_p (bb->loop_father, def_bb->loop_father))
> @@ -601,7 +592,7 @@ process_use (gimple *stmt, tree use, loo
>      }
>
>
> -  vect_mark_relevant (worklist, def_stmt, relevant, false);
> +  vect_mark_relevant (worklist, dstmt_vinfo, relevant, false);
>    return true;
>  }
>
> @@ -1563,7 +1554,9 @@ vect_get_vec_def_for_operand (tree op, g
>        dump_printf (MSG_NOTE, "\n");
>      }
>
> -  is_simple_use = vect_is_simple_use (op, loop_vinfo, &dt, &def_stmt);
> +  stmt_vec_info def_stmt_info;
> +  is_simple_use = vect_is_simple_use (op, loop_vinfo, &dt,
> +                                     &def_stmt_info, &def_stmt);
>    gcc_assert (is_simple_use);
>    if (def_stmt && dump_enabled_p ())
>      {
> @@ -1588,7 +1581,7 @@ vect_get_vec_def_for_operand (tree op, g
>        return vect_init_vector (stmt, op, vector_type, NULL);
>      }
>    else
> -    return vect_get_vec_def_for_operand_1 (def_stmt, dt);
> +    return vect_get_vec_def_for_operand_1 (def_stmt_info, dt);
>  }
>
>
> @@ -5479,7 +5472,9 @@ vectorizable_shift (gimple *stmt, gimple
>      return false;
>
>    op1 = gimple_assign_rhs2 (stmt);
> -  if (!vect_is_simple_use (op1, vinfo, &dt[1], &op1_vectype))
> +  stmt_vec_info op1_def_stmt_info;
> +  if (!vect_is_simple_use (op1, vinfo, &dt[1], &op1_vectype,
> +                          &op1_def_stmt_info))
>      {
>        if (dump_enabled_p ())
>          dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
> @@ -5524,12 +5519,8 @@ vectorizable_shift (gimple *stmt, gimple
>        /* If the shift amount is computed by a pattern stmt we cannot
>           use the scalar amount directly thus give up and use a vector
>          shift.  */
> -      if (dt[1] == vect_internal_def)
> -       {
> -         gimple *def = SSA_NAME_DEF_STMT (op1);
> -         if (is_pattern_stmt_p (vinfo_for_stmt (def)))
> -           scalar_shift_arg = false;
> -       }
> +      if (op1_def_stmt_info && is_pattern_stmt_p (op1_def_stmt_info))
> +       scalar_shift_arg = false;
>      }
>    else
>      {
> @@ -10051,7 +10042,10 @@ get_same_sized_vectype (tree scalar_type
>     VINFO - the vect info of the loop or basic block that is being vectorized.
>     OPERAND - operand in the loop or bb.
>     Output:
> -   DEF_STMT_OUT (optional) - the defining stmt in case OPERAND is an SSA_NAME.
> +   DEF_STMT_INFO_OUT (optional) - information about the defining stmt in
> +     case OPERAND is an SSA_NAME that is defined in the vectorizable region
> +   DEF_STMT_OUT (optional) - the defining stmt in case OPERAND is an SSA_NAME;
> +     the definition could be anywhere in the function
>     DT - the type of definition
>
>     Returns whether a stmt with OPERAND can be vectorized.
> @@ -10064,8 +10058,10 @@ get_same_sized_vectype (tree scalar_type
>
>  bool
>  vect_is_simple_use (tree operand, vec_info *vinfo, enum vect_def_type *dt,
> -                   gimple **def_stmt_out)
> +                   stmt_vec_info *def_stmt_info_out, gimple **def_stmt_out)
>  {
> +  if (def_stmt_info_out)
> +    *def_stmt_info_out = NULL;
>    if (def_stmt_out)
>      *def_stmt_out = NULL;
>    *dt = vect_unknown_def_type;
> @@ -10113,6 +10109,8 @@ vect_is_simple_use (tree operand, vec_in
>               *dt = vect_unknown_def_type;
>               break;
>             }
> +         if (def_stmt_info_out)
> +           *def_stmt_info_out = stmt_vinfo;
>         }
>        if (def_stmt_out)
>         *def_stmt_out = def_stmt;
> @@ -10175,14 +10173,18 @@ vect_is_simple_use (tree operand, vec_in
>
>  bool
>  vect_is_simple_use (tree operand, vec_info *vinfo, enum vect_def_type *dt,
> -                   tree *vectype, gimple **def_stmt_out)
> +                   tree *vectype, stmt_vec_info *def_stmt_info_out,
> +                   gimple **def_stmt_out)
>  {
> +  stmt_vec_info def_stmt_info;
>    gimple *def_stmt;
> -  if (!vect_is_simple_use (operand, vinfo, dt, &def_stmt))
> +  if (!vect_is_simple_use (operand, vinfo, dt, &def_stmt_info, &def_stmt))
>      return false;
>
>    if (def_stmt_out)
>      *def_stmt_out = def_stmt;
> +  if (def_stmt_info_out)
> +    *def_stmt_info_out = def_stmt_info;
>
>    /* Now get a vector type if the def is internal, otherwise supply
>       NULL_TREE and leave it up to the caller to figure out a proper
> @@ -10193,8 +10195,7 @@ vect_is_simple_use (tree operand, vec_in
>        || *dt == vect_double_reduction_def
>        || *dt == vect_nested_cycle)
>      {
> -      stmt_vec_info stmt_info = vinfo_for_stmt (def_stmt);
> -      *vectype = STMT_VINFO_VECTYPE (stmt_info);
> +      *vectype = STMT_VINFO_VECTYPE (def_stmt_info);
>        gcc_assert (*vectype != NULL_TREE);
>        if (dump_enabled_p ())
>         {
> Index: gcc/tree-vect-loop.c
> ===================================================================
> --- gcc/tree-vect-loop.c        2018-07-24 10:22:33.821278677 +0100
> +++ gcc/tree-vect-loop.c        2018-07-24 10:22:37.253248202 +0100
> @@ -6090,7 +6090,6 @@ vectorizable_reduction (gimple *stmt, gi
>    int op_type;
>    optab optab;
>    tree new_temp = NULL_TREE;
> -  gimple *def_stmt;
>    enum vect_def_type dt, cond_reduc_dt = vect_unknown_def_type;
>    gimple *cond_reduc_def_stmt = NULL;
>    enum tree_code cond_reduc_op_code = ERROR_MARK;
> @@ -6324,13 +6323,14 @@ vectorizable_reduction (gimple *stmt, gi
>        if (i == 0 && code == COND_EXPR)
>          continue;
>
> -      is_simple_use = vect_is_simple_use (ops[i], loop_vinfo,
> -                                         &dts[i], &tem, &def_stmt);
> +      stmt_vec_info def_stmt_info;
> +      is_simple_use = vect_is_simple_use (ops[i], loop_vinfo, &dts[i], &tem,
> +                                         &def_stmt_info);
>        dt = dts[i];
>        gcc_assert (is_simple_use);
>        if (dt == vect_reduction_def)
>         {
> -          reduc_def_stmt = def_stmt;
> +         reduc_def_stmt = def_stmt_info;
>           reduc_index = i;
>           continue;
>         }
> @@ -6352,11 +6352,11 @@ vectorizable_reduction (gimple *stmt, gi
>         return false;
>
>        if (dt == vect_nested_cycle)
> -        {
> -          found_nested_cycle_def = true;
> -          reduc_def_stmt = def_stmt;
> -          reduc_index = i;
> -        }
> +       {
> +         found_nested_cycle_def = true;
> +         reduc_def_stmt = def_stmt_info;
> +         reduc_index = i;
> +       }
>
>        if (i == 1 && code == COND_EXPR)
>         {
> @@ -6367,11 +6367,11 @@ vectorizable_reduction (gimple *stmt, gi
>               cond_reduc_val = ops[i];
>             }
>           if (dt == vect_induction_def
> -             && def_stmt != NULL
> -             && is_nonwrapping_integer_induction (def_stmt, loop))
> +             && def_stmt_info
> +             && is_nonwrapping_integer_induction (def_stmt_info, loop))
>             {
>               cond_reduc_dt = dt;
> -             cond_reduc_def_stmt = def_stmt;
> +             cond_reduc_def_stmt = def_stmt_info;
>             }
>         }
>      }
> @@ -7958,7 +7958,7 @@ vectorizable_live_operation (gimple *stm
>    else
>      {
>        enum vect_def_type dt = STMT_VINFO_DEF_TYPE (stmt_info);
> -      vec_lhs = vect_get_vec_def_for_operand_1 (stmt, dt);
> +      vec_lhs = vect_get_vec_def_for_operand_1 (stmt_info, dt);
>        gcc_checking_assert (ncopies == 1
>                            || !LOOP_VINFO_FULLY_MASKED_P (loop_vinfo));
>
> Index: gcc/tree-vect-patterns.c
> ===================================================================
> --- gcc/tree-vect-patterns.c    2018-07-24 10:22:33.825278642 +0100
> +++ gcc/tree-vect-patterns.c    2018-07-24 10:22:37.253248202 +0100
> @@ -250,7 +250,9 @@ type_conversion_p (tree name, gimple *us
>    enum vect_def_type dt;
>
>    stmt_vinfo = vinfo_for_stmt (use_stmt);
> -  if (!vect_is_simple_use (name, stmt_vinfo->vinfo, &dt, def_stmt))
> +  stmt_vec_info def_stmt_info;
> +  if (!vect_is_simple_use (name, stmt_vinfo->vinfo, &dt, &def_stmt_info,
> +                          def_stmt))
>      return false;
>
>    if (dt != vect_internal_def
> @@ -371,9 +373,10 @@ vect_look_through_possible_promotion (ve
>    while (TREE_CODE (op) == SSA_NAME && INTEGRAL_TYPE_P (op_type))
>      {
>        /* See whether OP is simple enough to vectorize.  */
> +      stmt_vec_info def_stmt_info;
>        gimple *def_stmt;
>        vect_def_type dt;
> -      if (!vect_is_simple_use (op, vinfo, &dt, &def_stmt))
> +      if (!vect_is_simple_use (op, vinfo, &dt, &def_stmt_info, &def_stmt))
>         break;
>
>        /* If OP is the input of a demotion, skip over it to see whether
> @@ -407,17 +410,15 @@ vect_look_through_possible_promotion (ve
>          the cast is potentially vectorizable.  */
>        if (!def_stmt)
>         break;
> -      if (dt == vect_internal_def)
> -       {
> -         caster = vinfo_for_stmt (def_stmt);
> -         /* Ignore pattern statements, since we don't link uses for them.  */
> -         if (single_use_p
> -             && !STMT_VINFO_RELATED_STMT (caster)
> -             && !has_single_use (res))
> -           *single_use_p = false;
> -       }
> -      else
> -       caster = NULL;
> +      caster = def_stmt_info;
> +
> +      /* Ignore pattern statements, since we don't link uses for them.  */
> +      if (caster
> +         && single_use_p
> +         && !STMT_VINFO_RELATED_STMT (caster)
> +         && !has_single_use (res))
> +       *single_use_p = false;
> +
>        gassign *assign = dyn_cast <gassign *> (def_stmt);
>        if (!assign || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
>         break;
> @@ -1988,7 +1989,8 @@ vect_recog_rotate_pattern (stmt_vec_info
>        || !TYPE_UNSIGNED (type))
>      return NULL;
>
> -  if (!vect_is_simple_use (oprnd1, vinfo, &dt, &def_stmt))
> +  stmt_vec_info def_stmt_info;
> +  if (!vect_is_simple_use (oprnd1, vinfo, &dt, &def_stmt_info, &def_stmt))
>      return NULL;
>
>    if (dt != vect_internal_def
> Index: gcc/tree-vect-slp.c
> ===================================================================
> --- gcc/tree-vect-slp.c 2018-07-24 10:22:33.825278642 +0100
> +++ gcc/tree-vect-slp.c 2018-07-24 10:22:37.253248202 +0100
> @@ -303,7 +303,6 @@ vect_get_and_check_slp_defs (vec_info *v
>    gimple *stmt = stmts[stmt_num];
>    tree oprnd;
>    unsigned int i, number_of_oprnds;
> -  gimple *def_stmt;
>    enum vect_def_type dt = vect_uninitialized_def;
>    bool pattern = false;
>    slp_oprnd_info oprnd_info;
> @@ -357,7 +356,8 @@ vect_get_and_check_slp_defs (vec_info *v
>
>        oprnd_info = (*oprnds_info)[i];
>
> -      if (!vect_is_simple_use (oprnd, vinfo, &dt, &def_stmt))
> +      stmt_vec_info def_stmt_info;
> +      if (!vect_is_simple_use (oprnd, vinfo, &dt, &def_stmt_info))
>         {
>           if (dump_enabled_p ())
>             {
> @@ -370,13 +370,10 @@ vect_get_and_check_slp_defs (vec_info *v
>           return -1;
>         }
>
> -      /* Check if DEF_STMT is a part of a pattern in LOOP and get the def stmt
> -         from the pattern.  Check that all the stmts of the node are in the
> -         pattern.  */
> -      if (def_stmt && gimple_bb (def_stmt)
> -         && vect_stmt_in_region_p (vinfo, def_stmt)
> -         && vinfo_for_stmt (def_stmt)
> -         && is_pattern_stmt_p (vinfo_for_stmt (def_stmt)))
> +      /* Check if DEF_STMT_INFO is a part of a pattern in LOOP and get
> +        the def stmt from the pattern.  Check that all the stmts of the
> +        node are in the pattern.  */
> +      if (def_stmt_info && is_pattern_stmt_p (def_stmt_info))
>          {
>            pattern = true;
>            if (!first && !oprnd_info->first_pattern
> @@ -405,7 +402,7 @@ vect_get_and_check_slp_defs (vec_info *v
>               return 1;
>              }
>
> -          dt = STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt));
> +         dt = STMT_VINFO_DEF_TYPE (def_stmt_info);
>
>            if (dt == vect_unknown_def_type)
>              {
> @@ -415,7 +412,7 @@ vect_get_and_check_slp_defs (vec_info *v
>                return -1;
>              }
>
> -          switch (gimple_code (def_stmt))
> +         switch (gimple_code (def_stmt_info->stmt))
>              {
>              case GIMPLE_PHI:
>              case GIMPLE_ASSIGN:
> @@ -499,7 +496,7 @@ vect_get_and_check_slp_defs (vec_info *v
>         case vect_reduction_def:
>         case vect_induction_def:
>         case vect_internal_def:
> -         oprnd_info->def_stmts.quick_push (def_stmt);
> +         oprnd_info->def_stmts.quick_push (def_stmt_info);
>           break;
>
>         default:
diff mbox series

Patch

Index: gcc/tree-vectorizer.h
===================================================================
--- gcc/tree-vectorizer.h	2018-07-24 10:22:33.829278607 +0100
+++ gcc/tree-vectorizer.h	2018-07-24 10:22:37.257248166 +0100
@@ -1532,9 +1532,10 @@  extern tree get_mask_type_for_scalar_typ
 extern tree get_same_sized_vectype (tree, tree);
 extern bool vect_get_loop_mask_type (loop_vec_info);
 extern bool vect_is_simple_use (tree, vec_info *, enum vect_def_type *,
-				gimple ** = NULL);
+				stmt_vec_info * = NULL, gimple ** = NULL);
 extern bool vect_is_simple_use (tree, vec_info *, enum vect_def_type *,
-				tree *, gimple ** = NULL);
+				tree *, stmt_vec_info * = NULL,
+				gimple ** = NULL);
 extern bool supportable_widening_operation (enum tree_code, gimple *, tree,
 					    tree, enum tree_code *,
 					    enum tree_code *, int *,
Index: gcc/tree-vect-stmts.c
===================================================================
--- gcc/tree-vect-stmts.c	2018-07-24 10:22:33.829278607 +0100
+++ gcc/tree-vect-stmts.c	2018-07-24 10:22:37.257248166 +0100
@@ -459,11 +459,9 @@  process_use (gimple *stmt, tree use, loo
 	     enum vect_relevant relevant, vec<gimple *> *worklist,
 	     bool force)
 {
-  struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
   stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
   stmt_vec_info dstmt_vinfo;
   basic_block bb, def_bb;
-  gimple *def_stmt;
   enum vect_def_type dt;
 
   /* case 1: we are only interested in uses that need to be vectorized.  Uses
@@ -471,7 +469,7 @@  process_use (gimple *stmt, tree use, loo
   if (!force && !exist_non_indexing_operands_for_use_p (use, stmt))
      return true;
 
-  if (!vect_is_simple_use (use, loop_vinfo, &dt, &def_stmt))
+  if (!vect_is_simple_use (use, loop_vinfo, &dt, &dstmt_vinfo))
     {
       if (dump_enabled_p ())
         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -479,27 +477,20 @@  process_use (gimple *stmt, tree use, loo
       return false;
     }
 
-  if (!def_stmt || gimple_nop_p (def_stmt))
+  if (!dstmt_vinfo)
     return true;
 
-  def_bb = gimple_bb (def_stmt);
-  if (!flow_bb_inside_loop_p (loop, def_bb))
-    {
-      if (dump_enabled_p ())
-	dump_printf_loc (MSG_NOTE, vect_location, "def_stmt is out of loop.\n");
-      return true;
-    }
+  def_bb = gimple_bb (dstmt_vinfo->stmt);
 
-  /* case 2: A reduction phi (STMT) defined by a reduction stmt (DEF_STMT).
-     DEF_STMT must have already been processed, because this should be the
+  /* case 2: A reduction phi (STMT) defined by a reduction stmt (DSTMT_VINFO).
+     DSTMT_VINFO must have already been processed, because this should be the
      only way that STMT, which is a reduction-phi, was put in the worklist,
-     as there should be no other uses for DEF_STMT in the loop.  So we just
+     as there should be no other uses for DSTMT_VINFO in the loop.  So we just
      check that everything is as expected, and we are done.  */
-  dstmt_vinfo = vinfo_for_stmt (def_stmt);
   bb = gimple_bb (stmt);
   if (gimple_code (stmt) == GIMPLE_PHI
       && STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def
-      && gimple_code (def_stmt) != GIMPLE_PHI
+      && gimple_code (dstmt_vinfo->stmt) != GIMPLE_PHI
       && STMT_VINFO_DEF_TYPE (dstmt_vinfo) == vect_reduction_def
       && bb->loop_father == def_bb->loop_father)
     {
@@ -514,7 +505,7 @@  process_use (gimple *stmt, tree use, loo
 
   /* case 3a: outer-loop stmt defining an inner-loop stmt:
 	outer-loop-header-bb:
-		d = def_stmt
+		d = dstmt_vinfo
 	inner-loop:
 		stmt # use (d)
 	outer-loop-tail-bb:
@@ -554,7 +545,7 @@  process_use (gimple *stmt, tree use, loo
 	outer-loop-header-bb:
 		...
 	inner-loop:
-		d = def_stmt
+		d = dstmt_vinfo
 	outer-loop-tail-bb (or outer-loop-exit-bb in double reduction):
 		stmt # use (d)		*/
   else if (flow_loop_nested_p (bb->loop_father, def_bb->loop_father))
@@ -601,7 +592,7 @@  process_use (gimple *stmt, tree use, loo
     }
 
 
-  vect_mark_relevant (worklist, def_stmt, relevant, false);
+  vect_mark_relevant (worklist, dstmt_vinfo, relevant, false);
   return true;
 }
 
@@ -1563,7 +1554,9 @@  vect_get_vec_def_for_operand (tree op, g
       dump_printf (MSG_NOTE, "\n");
     }
 
-  is_simple_use = vect_is_simple_use (op, loop_vinfo, &dt, &def_stmt);
+  stmt_vec_info def_stmt_info;
+  is_simple_use = vect_is_simple_use (op, loop_vinfo, &dt,
+				      &def_stmt_info, &def_stmt);
   gcc_assert (is_simple_use);
   if (def_stmt && dump_enabled_p ())
     {
@@ -1588,7 +1581,7 @@  vect_get_vec_def_for_operand (tree op, g
       return vect_init_vector (stmt, op, vector_type, NULL);
     }
   else
-    return vect_get_vec_def_for_operand_1 (def_stmt, dt);
+    return vect_get_vec_def_for_operand_1 (def_stmt_info, dt);
 }
 
 
@@ -5479,7 +5472,9 @@  vectorizable_shift (gimple *stmt, gimple
     return false;
 
   op1 = gimple_assign_rhs2 (stmt);
-  if (!vect_is_simple_use (op1, vinfo, &dt[1], &op1_vectype))
+  stmt_vec_info op1_def_stmt_info;
+  if (!vect_is_simple_use (op1, vinfo, &dt[1], &op1_vectype,
+			   &op1_def_stmt_info))
     {
       if (dump_enabled_p ())
         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -5524,12 +5519,8 @@  vectorizable_shift (gimple *stmt, gimple
       /* If the shift amount is computed by a pattern stmt we cannot
          use the scalar amount directly thus give up and use a vector
 	 shift.  */
-      if (dt[1] == vect_internal_def)
-	{
-	  gimple *def = SSA_NAME_DEF_STMT (op1);
-	  if (is_pattern_stmt_p (vinfo_for_stmt (def)))
-	    scalar_shift_arg = false;
-	}
+      if (op1_def_stmt_info && is_pattern_stmt_p (op1_def_stmt_info))
+	scalar_shift_arg = false;
     }
   else
     {
@@ -10051,7 +10042,10 @@  get_same_sized_vectype (tree scalar_type
    VINFO - the vect info of the loop or basic block that is being vectorized.
    OPERAND - operand in the loop or bb.
    Output:
-   DEF_STMT_OUT (optional) - the defining stmt in case OPERAND is an SSA_NAME.
+   DEF_STMT_INFO_OUT (optional) - information about the defining stmt in
+     case OPERAND is an SSA_NAME that is defined in the vectorizable region
+   DEF_STMT_OUT (optional) - the defining stmt in case OPERAND is an SSA_NAME;
+     the definition could be anywhere in the function
    DT - the type of definition
 
    Returns whether a stmt with OPERAND can be vectorized.
@@ -10064,8 +10058,10 @@  get_same_sized_vectype (tree scalar_type
 
 bool
 vect_is_simple_use (tree operand, vec_info *vinfo, enum vect_def_type *dt,
-		    gimple **def_stmt_out)
+		    stmt_vec_info *def_stmt_info_out, gimple **def_stmt_out)
 {
+  if (def_stmt_info_out)
+    *def_stmt_info_out = NULL;
   if (def_stmt_out)
     *def_stmt_out = NULL;
   *dt = vect_unknown_def_type;
@@ -10113,6 +10109,8 @@  vect_is_simple_use (tree operand, vec_in
 	      *dt = vect_unknown_def_type;
 	      break;
 	    }
+	  if (def_stmt_info_out)
+	    *def_stmt_info_out = stmt_vinfo;
 	}
       if (def_stmt_out)
 	*def_stmt_out = def_stmt;
@@ -10175,14 +10173,18 @@  vect_is_simple_use (tree operand, vec_in
 
 bool
 vect_is_simple_use (tree operand, vec_info *vinfo, enum vect_def_type *dt,
-		    tree *vectype, gimple **def_stmt_out)
+		    tree *vectype, stmt_vec_info *def_stmt_info_out,
+		    gimple **def_stmt_out)
 {
+  stmt_vec_info def_stmt_info;
   gimple *def_stmt;
-  if (!vect_is_simple_use (operand, vinfo, dt, &def_stmt))
+  if (!vect_is_simple_use (operand, vinfo, dt, &def_stmt_info, &def_stmt))
     return false;
 
   if (def_stmt_out)
     *def_stmt_out = def_stmt;
+  if (def_stmt_info_out)
+    *def_stmt_info_out = def_stmt_info;
 
   /* Now get a vector type if the def is internal, otherwise supply
      NULL_TREE and leave it up to the caller to figure out a proper
@@ -10193,8 +10195,7 @@  vect_is_simple_use (tree operand, vec_in
       || *dt == vect_double_reduction_def
       || *dt == vect_nested_cycle)
     {
-      stmt_vec_info stmt_info = vinfo_for_stmt (def_stmt);
-      *vectype = STMT_VINFO_VECTYPE (stmt_info);
+      *vectype = STMT_VINFO_VECTYPE (def_stmt_info);
       gcc_assert (*vectype != NULL_TREE);
       if (dump_enabled_p ())
 	{
Index: gcc/tree-vect-loop.c
===================================================================
--- gcc/tree-vect-loop.c	2018-07-24 10:22:33.821278677 +0100
+++ gcc/tree-vect-loop.c	2018-07-24 10:22:37.253248202 +0100
@@ -6090,7 +6090,6 @@  vectorizable_reduction (gimple *stmt, gi
   int op_type;
   optab optab;
   tree new_temp = NULL_TREE;
-  gimple *def_stmt;
   enum vect_def_type dt, cond_reduc_dt = vect_unknown_def_type;
   gimple *cond_reduc_def_stmt = NULL;
   enum tree_code cond_reduc_op_code = ERROR_MARK;
@@ -6324,13 +6323,14 @@  vectorizable_reduction (gimple *stmt, gi
       if (i == 0 && code == COND_EXPR)
         continue;
 
-      is_simple_use = vect_is_simple_use (ops[i], loop_vinfo,
-					  &dts[i], &tem, &def_stmt);
+      stmt_vec_info def_stmt_info;
+      is_simple_use = vect_is_simple_use (ops[i], loop_vinfo, &dts[i], &tem,
+					  &def_stmt_info);
       dt = dts[i];
       gcc_assert (is_simple_use);
       if (dt == vect_reduction_def)
 	{
-          reduc_def_stmt = def_stmt;
+	  reduc_def_stmt = def_stmt_info;
 	  reduc_index = i;
 	  continue;
 	}
@@ -6352,11 +6352,11 @@  vectorizable_reduction (gimple *stmt, gi
 	return false;
 
       if (dt == vect_nested_cycle)
-        {
-          found_nested_cycle_def = true;
-          reduc_def_stmt = def_stmt;
-          reduc_index = i;
-        }
+	{
+	  found_nested_cycle_def = true;
+	  reduc_def_stmt = def_stmt_info;
+	  reduc_index = i;
+	}
 
       if (i == 1 && code == COND_EXPR)
 	{
@@ -6367,11 +6367,11 @@  vectorizable_reduction (gimple *stmt, gi
 	      cond_reduc_val = ops[i];
 	    }
 	  if (dt == vect_induction_def
-	      && def_stmt != NULL
-	      && is_nonwrapping_integer_induction (def_stmt, loop))
+	      && def_stmt_info
+	      && is_nonwrapping_integer_induction (def_stmt_info, loop))
 	    {
 	      cond_reduc_dt = dt;
-	      cond_reduc_def_stmt = def_stmt;
+	      cond_reduc_def_stmt = def_stmt_info;
 	    }
 	}
     }
@@ -7958,7 +7958,7 @@  vectorizable_live_operation (gimple *stm
   else
     {
       enum vect_def_type dt = STMT_VINFO_DEF_TYPE (stmt_info);
-      vec_lhs = vect_get_vec_def_for_operand_1 (stmt, dt);
+      vec_lhs = vect_get_vec_def_for_operand_1 (stmt_info, dt);
       gcc_checking_assert (ncopies == 1
 			   || !LOOP_VINFO_FULLY_MASKED_P (loop_vinfo));
 
Index: gcc/tree-vect-patterns.c
===================================================================
--- gcc/tree-vect-patterns.c	2018-07-24 10:22:33.825278642 +0100
+++ gcc/tree-vect-patterns.c	2018-07-24 10:22:37.253248202 +0100
@@ -250,7 +250,9 @@  type_conversion_p (tree name, gimple *us
   enum vect_def_type dt;
 
   stmt_vinfo = vinfo_for_stmt (use_stmt);
-  if (!vect_is_simple_use (name, stmt_vinfo->vinfo, &dt, def_stmt))
+  stmt_vec_info def_stmt_info;
+  if (!vect_is_simple_use (name, stmt_vinfo->vinfo, &dt, &def_stmt_info,
+			   def_stmt))
     return false;
 
   if (dt != vect_internal_def
@@ -371,9 +373,10 @@  vect_look_through_possible_promotion (ve
   while (TREE_CODE (op) == SSA_NAME && INTEGRAL_TYPE_P (op_type))
     {
       /* See whether OP is simple enough to vectorize.  */
+      stmt_vec_info def_stmt_info;
       gimple *def_stmt;
       vect_def_type dt;
-      if (!vect_is_simple_use (op, vinfo, &dt, &def_stmt))
+      if (!vect_is_simple_use (op, vinfo, &dt, &def_stmt_info, &def_stmt))
 	break;
 
       /* If OP is the input of a demotion, skip over it to see whether
@@ -407,17 +410,15 @@  vect_look_through_possible_promotion (ve
 	 the cast is potentially vectorizable.  */
       if (!def_stmt)
 	break;
-      if (dt == vect_internal_def)
-	{
-	  caster = vinfo_for_stmt (def_stmt);
-	  /* Ignore pattern statements, since we don't link uses for them.  */
-	  if (single_use_p
-	      && !STMT_VINFO_RELATED_STMT (caster)
-	      && !has_single_use (res))
-	    *single_use_p = false;
-	}
-      else
-	caster = NULL;
+      caster = def_stmt_info;
+
+      /* Ignore pattern statements, since we don't link uses for them.  */
+      if (caster
+	  && single_use_p
+	  && !STMT_VINFO_RELATED_STMT (caster)
+	  && !has_single_use (res))
+	*single_use_p = false;
+
       gassign *assign = dyn_cast <gassign *> (def_stmt);
       if (!assign || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
 	break;
@@ -1988,7 +1989,8 @@  vect_recog_rotate_pattern (stmt_vec_info
       || !TYPE_UNSIGNED (type))
     return NULL;
 
-  if (!vect_is_simple_use (oprnd1, vinfo, &dt, &def_stmt))
+  stmt_vec_info def_stmt_info;
+  if (!vect_is_simple_use (oprnd1, vinfo, &dt, &def_stmt_info, &def_stmt))
     return NULL;
 
   if (dt != vect_internal_def
Index: gcc/tree-vect-slp.c
===================================================================
--- gcc/tree-vect-slp.c	2018-07-24 10:22:33.825278642 +0100
+++ gcc/tree-vect-slp.c	2018-07-24 10:22:37.253248202 +0100
@@ -303,7 +303,6 @@  vect_get_and_check_slp_defs (vec_info *v
   gimple *stmt = stmts[stmt_num];
   tree oprnd;
   unsigned int i, number_of_oprnds;
-  gimple *def_stmt;
   enum vect_def_type dt = vect_uninitialized_def;
   bool pattern = false;
   slp_oprnd_info oprnd_info;
@@ -357,7 +356,8 @@  vect_get_and_check_slp_defs (vec_info *v
 
       oprnd_info = (*oprnds_info)[i];
 
-      if (!vect_is_simple_use (oprnd, vinfo, &dt, &def_stmt))
+      stmt_vec_info def_stmt_info;
+      if (!vect_is_simple_use (oprnd, vinfo, &dt, &def_stmt_info))
 	{
 	  if (dump_enabled_p ())
 	    {
@@ -370,13 +370,10 @@  vect_get_and_check_slp_defs (vec_info *v
 	  return -1;
 	}
 
-      /* Check if DEF_STMT is a part of a pattern in LOOP and get the def stmt
-         from the pattern.  Check that all the stmts of the node are in the
-         pattern.  */
-      if (def_stmt && gimple_bb (def_stmt)
-	  && vect_stmt_in_region_p (vinfo, def_stmt)
-	  && vinfo_for_stmt (def_stmt)
-	  && is_pattern_stmt_p (vinfo_for_stmt (def_stmt)))
+      /* Check if DEF_STMT_INFO is a part of a pattern in LOOP and get
+	 the def stmt from the pattern.  Check that all the stmts of the
+	 node are in the pattern.  */
+      if (def_stmt_info && is_pattern_stmt_p (def_stmt_info))
         {
           pattern = true;
           if (!first && !oprnd_info->first_pattern
@@ -405,7 +402,7 @@  vect_get_and_check_slp_defs (vec_info *v
 	      return 1;
             }
 
-          dt = STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt));
+	  dt = STMT_VINFO_DEF_TYPE (def_stmt_info);
 
           if (dt == vect_unknown_def_type)
             {
@@ -415,7 +412,7 @@  vect_get_and_check_slp_defs (vec_info *v
               return -1;
             }
 
-          switch (gimple_code (def_stmt))
+	  switch (gimple_code (def_stmt_info->stmt))
             {
             case GIMPLE_PHI:
             case GIMPLE_ASSIGN:
@@ -499,7 +496,7 @@  vect_get_and_check_slp_defs (vec_info *v
 	case vect_reduction_def:
 	case vect_induction_def:
 	case vect_internal_def:
-	  oprnd_info->def_stmts.quick_push (def_stmt);
+	  oprnd_info->def_stmts.quick_push (def_stmt_info);
 	  break;
 
 	default: