]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-vectorizer.h (struct _loop_vec_info): Add no_data_dependencies field.
authorJakub Jelinek <jakub@redhat.com>
Thu, 16 Jan 2014 20:14:45 +0000 (21:14 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 16 Jan 2014 20:14:45 +0000 (21:14 +0100)
* tree-vectorizer.h (struct _loop_vec_info): Add no_data_dependencies
field.
(LOOP_VINFO_NO_DATA_DEPENDENCIES): Define.
* tree-vect-data-refs.c (vect_analyze_data_ref_dependence): Clear it
when not giving up or versioning for alias only because of
loop->safelen.
(vect_analyze_data_ref_dependences): Set to true.
* tree-vect-stmts.c (hoist_defs_of_uses): Return false if def_stmt
is a GIMPLE_PHI.
(vectorizable_load): Use LOOP_VINFO_NO_DATA_DEPENDENCIES instead of
LOOP_REQUIRES_VERSIONING_FOR_ALIAS, add && !nested_in_vect_loop
to the condition.

From-SVN: r206687

gcc/ChangeLog
gcc/tree-vect-data-refs.c
gcc/tree-vect-stmts.c
gcc/tree-vectorizer.h

index f7a764fc09b6a8347c988c064086968b3df85556..2000ed83ac4dedae5986358edf795e3a5ba377e3 100644 (file)
@@ -1,5 +1,18 @@
 2014-01-16  Jakub Jelinek  <jakub@redhat.com>
 
+       * tree-vectorizer.h (struct _loop_vec_info): Add no_data_dependencies
+       field.
+       (LOOP_VINFO_NO_DATA_DEPENDENCIES): Define.
+       * tree-vect-data-refs.c (vect_analyze_data_ref_dependence): Clear it
+       when not giving up or versioning for alias only because of
+       loop->safelen.
+       (vect_analyze_data_ref_dependences): Set to true.
+       * tree-vect-stmts.c (hoist_defs_of_uses): Return false if def_stmt
+       is a GIMPLE_PHI.
+       (vectorizable_load): Use LOOP_VINFO_NO_DATA_DEPENDENCIES instead of
+       LOOP_REQUIRES_VERSIONING_FOR_ALIAS, add && !nested_in_vect_loop
+       to the condition.
+
        PR middle-end/58344
        * expr.c (expand_expr_real_1): Handle init == NULL_TREE.
 
index 165e41faff1498b0f972bedad2e2b6e6938e84bd..0deac8177fd141039dede98146f7ce1b1705f0bb 100644 (file)
@@ -244,6 +244,7 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
        {
          if (loop->safelen < *max_vf)
            *max_vf = loop->safelen;
+         LOOP_VINFO_NO_DATA_DEPENDENCIES (loop_vinfo) = false;
          return false;
        }
 
@@ -291,6 +292,7 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
        {
          if (loop->safelen < *max_vf)
            *max_vf = loop->safelen;
+         LOOP_VINFO_NO_DATA_DEPENDENCIES (loop_vinfo) = false;
          return false;
        }
 
@@ -447,6 +449,7 @@ vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo, int *max_vf)
     dump_printf_loc (MSG_NOTE, vect_location,
                      "=== vect_analyze_data_ref_dependences ===\n");
 
+  LOOP_VINFO_NO_DATA_DEPENDENCIES (loop_vinfo) = true;
   if (!compute_all_dependences (LOOP_VINFO_DATAREFS (loop_vinfo),
                                &LOOP_VINFO_DDRS (loop_vinfo),
                                LOOP_VINFO_LOOP_NEST (loop_vinfo), true))
index 820df7eddba4a068d42ded10a83297637c431608..2a2364d9542667fec9ecd011fcd6e11df108615f 100644 (file)
@@ -5504,6 +5504,8 @@ hoist_defs_of_uses (gimple stmt, struct loop *loop)
             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);
@@ -6434,10 +6436,12 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
              if (inv_p && !bb_vinfo)
                {
                  gcc_assert (!grouped_load);
-                 /* If we have versioned for aliasing then we are sure
-                    this is a loop invariant load and thus we can insert
-                    it on the preheader edge.  */
-                 if (LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo)
+                 /* If we have versioned for aliasing or the loop doesn't
+                    have any data dependencies that would preclude this,
+                    then we are sure this is a loop invariant load and
+                    thus we can insert it on the preheader edge.  */
+                 if (LOOP_VINFO_NO_DATA_DEPENDENCIES (loop_vinfo)
+                     && !nested_in_vect_loop
                      && hoist_defs_of_uses (stmt, loop))
                    {
                      if (dump_enabled_p ())
index 935aab9d2b045f582739fce2bdba0fb94143e25b..51367ea2500b01e26872e357c9c670b65b91604b 100644 (file)
@@ -347,6 +347,25 @@ typedef struct _loop_vec_info {
      fix it up.  */
   bool operands_swapped;
 
+  /* True if there are no loop carried data dependencies in the loop.
+     If loop->safelen <= 1, then this is always true, either the loop
+     didn't have any loop carried data dependencies, or the loop is being
+     vectorized guarded with some runtime alias checks, or couldn't
+     be vectorized at all, but then this field shouldn't be used.
+     For loop->safelen >= 2, the user has asserted that there are no
+     backward dependencies, but there still could be loop carried forward
+     dependencies in such loops.  This flag will be false if normal
+     vectorizer data dependency analysis would fail or require versioning
+     for alias, but because of loop->safelen >= 2 it has been vectorized
+     even without versioning for alias.  E.g. in:
+     #pragma omp simd
+     for (int i = 0; i < m; i++)
+       a[i] = a[i + k] * c;
+     (or #pragma simd or #pragma ivdep) we can vectorize this and it will
+     DTRT even for k > 0 && k < m, but without safelen we would not
+     vectorize this, so this field would be false.  */
+  bool no_data_dependencies;
+
   /* If if-conversion versioned this loop before conversion, this is the
      loop version without if-conversion.  */
   struct loop *scalar_loop;
@@ -385,6 +404,7 @@ typedef struct _loop_vec_info {
 #define LOOP_VINFO_PEELING_FOR_GAPS(L)     (L)->peeling_for_gaps
 #define LOOP_VINFO_OPERANDS_SWAPPED(L)     (L)->operands_swapped
 #define LOOP_VINFO_PEELING_FOR_NITER(L)    (L)->peeling_for_niter
+#define LOOP_VINFO_NO_DATA_DEPENDENCIES(L) (L)->no_data_dependencies
 #define LOOP_VINFO_SCALAR_LOOP(L)         (L)->scalar_loop
 
 #define LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT(L) \