[11/46] Pass back a stmt_vec_info from vect_is_simple_use
authorRichard Sandiford <richard.sandiford@arm.com>
Tue, 31 Jul 2018 14:22:01 +0000 (14:22 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Tue, 31 Jul 2018 14:22:01 +0000 (14:22 +0000)
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-31  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.

From-SVN: r263126

gcc/ChangeLog
gcc/tree-vect-loop.c
gcc/tree-vect-patterns.c
gcc/tree-vect-slp.c
gcc/tree-vect-stmts.c
gcc/tree-vectorizer.h

index a5695829357b4ce77e60cc9b0c544354f9dd6e15..873b298d31474281f1df60e89beb972ece6b3f59 100644 (file)
@@ -1,3 +1,17 @@
+2018-07-31  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * 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.
+
 2018-07-31  Richard Sandiford  <richard.sandiford@arm.com>
 
        * tree-vectorizer.h (stmt_vec_info): Temporarily change from
index e451cbcff8dca5974a6c6abaee8f39151663c02d..1f8847f529f2f6aaca7db9e0e04f60238f96456f 100644 (file)
@@ -6090,7 +6090,6 @@ vectorizable_reduction (gimple *stmt, gimple_stmt_iterator *gsi,
   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, gimple_stmt_iterator *gsi,
       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, gimple_stmt_iterator *gsi,
        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, gimple_stmt_iterator *gsi,
              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 *stmt,
   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 f4174e46bbcc6e8728d22989edb05465eac4388a..4ac8f9b4b39649ea2b41bc58eef2e84b197910e0 100644 (file)
@@ -250,7 +250,9 @@ type_conversion_p (tree name, gimple *use_stmt, bool check_sign,
   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 (vec_info *vinfo, tree op,
   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 (vec_info *vinfo, tree op,
         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 stmt_vinfo, tree *type_out)
       || !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 883de92b26cd73abd08ddf63998aa01bd5b06399..fbb419f3ee8f47240899284f2810dac8c5866572 100644 (file)
@@ -303,7 +303,6 @@ vect_get_and_check_slp_defs (vec_info *vinfo, unsigned char *swap,
   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 @@ again:
 
       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 @@ again:
          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 @@ again:
              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 @@ again:
               return -1;
             }
 
-          switch (gimple_code (def_stmt))
+         switch (gimple_code (def_stmt_info->stmt))
             {
             case GIMPLE_PHI:
             case GIMPLE_ASSIGN:
@@ -499,7 +496,7 @@ again:
        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:
index 629e2055498eca378f2d50123fd272e4c3e7ce64..c5524dd82f310bab9fb505f8f1c7fc7bdcbac559 100644 (file)
@@ -459,11 +459,9 @@ process_use (gimple *stmt, tree use, loop_vec_info loop_vinfo,
             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, loop_vec_info loop_vinfo,
   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, loop_vec_info loop_vinfo,
       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, loop_vec_info loop_vinfo,
 
   /* 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, loop_vec_info loop_vinfo,
        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, loop_vec_info loop_vinfo,
     }
 
 
-  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, gimple *stmt, tree vectype)
       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, gimple *stmt, tree vectype)
       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_stmt_iterator *gsi,
     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_stmt_iterator *gsi,
       /* 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, tree vector_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, tree vector_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_info *vinfo, enum vect_def_type *dt,
              *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_info *vinfo, enum vect_def_type *dt,
 
 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_info *vinfo, enum vect_def_type *dt,
       || *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 31d2db4d8c52275c57a487eb0cfd8562751ae07a..e302d3524a2898ca27fe3492693f489f5a46047a 100644 (file)
@@ -1532,9 +1532,10 @@ extern tree get_mask_type_for_scalar_type (tree);
 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 *,