]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Backport PRs 59354, 61634, 63844, 64909
authorRichard Biener <rguenther@suse.de>
Mon, 23 Feb 2015 11:14:25 +0000 (11:14 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 23 Feb 2015 11:14:25 +0000 (11:14 +0000)
2015-02-23  Richard Biener  <rguenther@suse.de>

Backport from mainline
2014-11-19  Richard Biener  <rguenther@suse.de>

PR tree-optimization/63844
* omp-low.c (fixup_child_record_type): Use a restrict qualified
referece type for the receiver parameter.

2014-11-27  Richard Biener  <rguenther@suse.de>

PR tree-optimization/61634
* tree-vect-slp.c: Include gimple-walk.h.
(vect_detect_hybrid_slp_stmts): Rewrite to propagate hybrid
down the SLP tree for one scalar statement.
(vect_detect_hybrid_slp_1): New walker function.
(vect_detect_hybrid_slp_2): Likewise.
(vect_detect_hybrid_slp): Properly handle pattern statements
in a pre-scan over all loop stmts.

* gcc.dg/vect/pr61634.c: New testcase.

2015-01-14  Richard Biener  <rguenther@suse.de>

PR tree-optimization/59354
* tree-vect-slp.c (vect_build_slp_tree_1): Treat loads from
groups larger than the slp group size as having gaps.

* gcc.dg/vect/pr59354.c: New testcase.

2015-02-10  Richard Biener  <rguenther@suse.de>

PR tree-optimization/64909
* tree-vect-loop.c (vect_estimate_min_profitable_iters): Properly
pass a scalar-stmt count estimate to the cost model.
* tree-vect-data-refs.c (vect_peeling_hash_get_lowest_cost): Likewise.

* gcc.dg/vect/costmodel/x86_64/costmodel-pr64909.c: New testcase.

From-SVN: r220912

gcc/ChangeLog
gcc/omp-low.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-pr64909.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/pr59354.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/pr61634.c [new file with mode: 0644]
gcc/tree-vect-data-refs.c
gcc/tree-vect-loop.c
gcc/tree-vect-slp.c

index 098531d7952d22b2f72741d479db3f538d358e96..b2b2398a1d01652867bf9b7fdb804cfa2ff90e72 100644 (file)
@@ -1,3 +1,36 @@
+2015-02-23  Richard Biener  <rguenther@suse.de>
+
+       Backport from mainline
+       2014-11-19  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/63844
+       * omp-low.c (fixup_child_record_type): Use a restrict qualified
+       referece type for the receiver parameter.
+
+       2014-11-27  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/61634
+       * tree-vect-slp.c: Include gimple-walk.h.
+       (vect_detect_hybrid_slp_stmts): Rewrite to propagate hybrid
+       down the SLP tree for one scalar statement.
+       (vect_detect_hybrid_slp_1): New walker function.
+       (vect_detect_hybrid_slp_2): Likewise.
+       (vect_detect_hybrid_slp): Properly handle pattern statements
+       in a pre-scan over all loop stmts.
+
+       2015-01-14  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/59354
+       * tree-vect-slp.c (vect_build_slp_tree_1): Treat loads from
+       groups larger than the slp group size as having gaps.
+
+       2015-02-10  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/64909
+       * tree-vect-loop.c (vect_estimate_min_profitable_iters): Properly
+       pass a scalar-stmt count estimate to the cost model.
+       * tree-vect-data-refs.c (vect_peeling_hash_get_lowest_cost): Likewise.
+
 2015-02-20  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        Backport from mainline
index f0059be6b5dbb05365d994e519a4da8cd65fef3a..f42c1d266cb5c5347852bbd2e9c2ec431e7b1a41 100644 (file)
@@ -1483,7 +1483,8 @@ fixup_child_record_type (omp_context *ctx)
       layout_type (type);
     }
 
-  TREE_TYPE (ctx->receiver_decl) = build_pointer_type (type);
+  TREE_TYPE (ctx->receiver_decl)
+    = build_qualified_type (build_reference_type (type), TYPE_QUAL_RESTRICT);
 }
 
 /* Instantiate decls as necessary in CTX to satisfy the data sharing
index d54b35e384992c5bf4c4ddc1c68594feebae9036..d9bff1567fc792fa6ad74d0faff14b0b3e5a7e4a 100644 (file)
@@ -1,3 +1,21 @@
+2015-02-23  Richard Biener  <rguenther@suse.de>
+
+       Backport from mainline
+       2014-11-27  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/61634
+       * gcc.dg/vect/pr61634.c: New testcase.
+
+       2015-01-14  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/59354
+       * gcc.dg/vect/pr59354.c: New testcase.
+
+       2015-02-10  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/64909
+       * gcc.dg/vect/costmodel/x86_64/costmodel-pr64909.c: New testcase.
+
 2015-02-23  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
 
        Backport from mainline
diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-pr64909.c b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-pr64909.c
new file mode 100644 (file)
index 0000000..0f9feac
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+/* { dg-additional-options "-mtune=bdver1" } */
+
+unsigned short a[32];
+unsigned int b[32];
+void t()
+{
+  int i;
+  for (i=0;i<12;i++)
+    b[i]=a[i];
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops in function" "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr59354.c b/gcc/testsuite/gcc.dg/vect/pr59354.c
new file mode 100644 (file)
index 0000000..37fca9d
--- /dev/null
@@ -0,0 +1,35 @@
+/* { dg-do run } */
+/* { dg-additional-options "-O3" } */
+
+#include "tree-vect.h"
+
+void abort (void);
+
+unsigned int a[256];
+unsigned char b[256];
+
+int main()
+{
+  int i, z, x, y;
+
+  check_vect ();
+
+  for(i = 0; i < 256; i++)
+    {
+      a[i] = i % 5;
+      __asm__ volatile ("");
+    }
+
+  for (z = 0; z < 16; z++)
+    for (y = 0; y < 4; y++)
+      for (x = 0; x < 4; x++)
+       b[y*64 + z*4 + x] = a[z*16 + y*4 + x];
+
+  if (b[4] != 1)
+    abort ();
+
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loop" "vect" { target { vect_pack_trunc } } } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr61634.c b/gcc/testsuite/gcc.dg/vect/pr61634.c
new file mode 100644 (file)
index 0000000..80b2c3a
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+
+int a, b, c, d;
+short *e;
+void fn1 (int p1[], int p2, int p3[], int p4[], int p5[], int *p6)
+{
+  int f;
+  c = *p1;
+  d = *p5;
+  (void)p6;
+  for (; a; a--)
+    {
+      f = *e >> 2;
+      *e++ = f;
+      b += f * f;
+      f = *e >> 2;
+      *e++ = f;
+    }
+  p4[0] = p3[0];
+  for (;; p2--)
+    ;
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
index 49303b1b58aa100bab1347ccdf65fedd4ec94d9f..04d6dc9d4f04b369bea3066bb7a6d785754052f6 100644 (file)
@@ -1150,10 +1150,13 @@ vect_peeling_hash_get_lowest_cost (_vect_peel_info **slot,
     }
 
   single_iter_cost = vect_get_single_scalar_iteration_cost (loop_vinfo);
-  outside_cost += vect_get_known_peeling_cost (loop_vinfo, elem->npeel,
-                                              &dummy, single_iter_cost,
-                                              &prologue_cost_vec,
-                                              &epilogue_cost_vec);
+  outside_cost += vect_get_known_peeling_cost
+    (loop_vinfo, elem->npeel, &dummy,
+     /* ???  We use this cost as number of stmts with scalar_stmt cost,
+       thus divide by that.  This introduces rounding errors, thus better 
+       introduce a new cost kind (raw_cost?  scalar_iter_cost?). */
+     single_iter_cost / vect_get_stmt_cost (scalar_stmt),
+     &prologue_cost_vec, &epilogue_cost_vec);
 
   /* Prologue and epilogue costs are added to the target model later.
      These costs depend only on the scalar iteration cost, the
index 59512fea651df71156e6fd8303033fd228d8645e..bb8a9841d632e3298407e7c2686e8449a8ce6621 100644 (file)
@@ -2801,6 +2801,11 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo,
      statements.  */
 
   scalar_single_iter_cost = vect_get_single_scalar_iteration_cost (loop_vinfo);
+  /* ???  Below we use this cost as number of stmts with scalar_stmt cost,
+     thus divide by that.  This introduces rounding errors, thus better
+     introduce a new cost kind (raw_cost?  scalar_iter_cost?). */
+  int scalar_single_iter_stmts
+    = scalar_single_iter_cost / vect_get_stmt_cost (scalar_stmt);
 
   /* Add additional cost for the peeled instructions in prologue and epilogue
      loop.
@@ -2835,10 +2840,10 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo,
       /* FORNOW: Don't attempt to pass individual scalar instructions to
         the model; just assume linear cost for scalar iterations.  */
       (void) add_stmt_cost (target_cost_data,
-                           peel_iters_prologue * scalar_single_iter_cost,
+                           peel_iters_prologue * scalar_single_iter_stmts,
                            scalar_stmt, NULL, 0, vect_prologue);
       (void) add_stmt_cost (target_cost_data, 
-                           peel_iters_epilogue * scalar_single_iter_cost,
+                           peel_iters_epilogue * scalar_single_iter_stmts,
                            scalar_stmt, NULL, 0, vect_epilogue);
     }
   else
@@ -2854,7 +2859,7 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo,
 
       (void) vect_get_known_peeling_cost (loop_vinfo, peel_iters_prologue,
                                          &peel_iters_epilogue,
-                                         scalar_single_iter_cost,
+                                         scalar_single_iter_stmts,
                                          &prologue_cost_vec,
                                          &epilogue_cost_vec);
 
index 59842291a9987806b8d5af023e3f2946cc7f6443..7a03b2e9f65e7cdeb40db08b7765b3541d58fa7b 100644 (file)
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "optabs.h"
 #include "tree-vectorizer.h"
 #include "langhooks.h"
+#include "gimple-walk.h"
 
 /* Extract the location of the basic block in the source code.
    Return the basic block location if succeed and NULL if not.  */
@@ -671,8 +672,11 @@ vect_build_slp_tree_1 (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
                 ???  We should enhance this to only disallow gaps
                 inside vectors.  */
               if ((unrolling_factor > 1
-                  && GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) == stmt
-                  && GROUP_GAP (vinfo_for_stmt (stmt)) != 0)
+                  && ((GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) == stmt
+                       && GROUP_GAP (vinfo_for_stmt (stmt)) != 0)
+                      /* If the group is split up then GROUP_GAP
+                         isn't correct here, nor is GROUP_FIRST_ELEMENT.  */
+                      || GROUP_SIZE (vinfo_for_stmt (stmt)) > group_size))
                  || (GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) != stmt
                      && GROUP_GAP (vinfo_for_stmt (stmt)) != 1))
                 {
@@ -1761,51 +1765,83 @@ vect_make_slp_decision (loop_vec_info loop_vinfo)
    can't be SLPed) in the tree rooted at NODE.  Mark such stmts as HYBRID.  */
 
 static void
-vect_detect_hybrid_slp_stmts (slp_tree node)
+vect_detect_hybrid_slp_stmts (slp_tree node, unsigned i, slp_vect_type stype)
 {
-  int i;
-  vec<gimple> stmts = SLP_TREE_SCALAR_STMTS (node);
-  gimple stmt = stmts[0];
+  gimple stmt = SLP_TREE_SCALAR_STMTS (node)[i];
   imm_use_iterator imm_iter;
   gimple use_stmt;
-  stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
+  stmt_vec_info use_vinfo, stmt_vinfo = vinfo_for_stmt (stmt);
   slp_tree child;
   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
-  struct loop *loop = NULL;
-  bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_vinfo);
-  basic_block bb = NULL;
+  struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+  int j;
+
+  /* Propagate hybrid down the SLP tree.  */
+  if (stype == hybrid)
+    ;
+  else if (HYBRID_SLP_STMT (stmt_vinfo))
+    stype = hybrid;
+  else
+    {
+      /* Check if a pure SLP stmt has uses in non-SLP stmts.  */
+      gcc_checking_assert (PURE_SLP_STMT (stmt_vinfo));
+      if (TREE_CODE (gimple_op (stmt, 0)) == SSA_NAME)
+       FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, gimple_op (stmt, 0))
+         if (gimple_bb (use_stmt)
+             && flow_bb_inside_loop_p (loop, gimple_bb (use_stmt))
+             && (use_vinfo = vinfo_for_stmt (use_stmt))
+             && !STMT_SLP_TYPE (use_vinfo)
+             && (STMT_VINFO_RELEVANT (use_vinfo)
+                 || VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (use_vinfo))
+                 || (STMT_VINFO_IN_PATTERN_P (use_vinfo)
+                     && STMT_VINFO_RELATED_STMT (use_vinfo)
+                     && !STMT_SLP_TYPE (vinfo_for_stmt
+                           (STMT_VINFO_RELATED_STMT (use_vinfo)))))
+             && !(gimple_code (use_stmt) == GIMPLE_PHI
+                  && STMT_VINFO_DEF_TYPE (use_vinfo) == vect_reduction_def))
+           stype = hybrid;
+    }
+
+  if (stype == hybrid)
+    STMT_SLP_TYPE (stmt_vinfo) = hybrid;
+
+  FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), j, child)
+    vect_detect_hybrid_slp_stmts (child, i, stype);
+}
 
-  if (!node)
-    return;
+/* Helpers for vect_detect_hybrid_slp walking pattern stmt uses.  */
 
-  if (loop_vinfo)
-    loop = LOOP_VINFO_LOOP (loop_vinfo);
-  else
-    bb = BB_VINFO_BB (bb_vinfo);
+static tree
+vect_detect_hybrid_slp_1 (tree *tp, int *, void *data)
+{
+  walk_stmt_info *wi = (walk_stmt_info *)data;
+  struct loop *loopp = (struct loop *)wi->info;
 
-  FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt)
-    if (PURE_SLP_STMT (vinfo_for_stmt (stmt))
-       && TREE_CODE (gimple_op (stmt, 0)) == SSA_NAME)
-      FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, gimple_op (stmt, 0))
-       if (gimple_bb (use_stmt)
-            && ((loop && flow_bb_inside_loop_p (loop, gimple_bb (use_stmt)))
-                || bb == gimple_bb (use_stmt))
-           && (stmt_vinfo = vinfo_for_stmt (use_stmt))
-           && !STMT_SLP_TYPE (stmt_vinfo)
-            && (STMT_VINFO_RELEVANT (stmt_vinfo)
-                || VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_vinfo))
-               || (STMT_VINFO_IN_PATTERN_P (stmt_vinfo)
-                   && STMT_VINFO_RELATED_STMT (stmt_vinfo)
-                   && !STMT_SLP_TYPE (vinfo_for_stmt (STMT_VINFO_RELATED_STMT (stmt_vinfo)))))
-           && !(gimple_code (use_stmt) == GIMPLE_PHI
-                 && STMT_VINFO_DEF_TYPE (stmt_vinfo)
-                  == vect_reduction_def))
-         vect_mark_slp_stmts (node, hybrid, i);
+  if (wi->is_lhs)
+    return NULL_TREE;
 
-  FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
-    vect_detect_hybrid_slp_stmts (child);
+  if (TREE_CODE (*tp) == SSA_NAME
+      && !SSA_NAME_IS_DEFAULT_DEF (*tp))
+    {
+      gimple def_stmt = SSA_NAME_DEF_STMT (*tp);
+      if (flow_bb_inside_loop_p (loopp, gimple_bb (def_stmt))
+         && PURE_SLP_STMT (vinfo_for_stmt (def_stmt)))
+       STMT_SLP_TYPE (vinfo_for_stmt (def_stmt)) = hybrid;
+    }
+
+  return NULL_TREE;
 }
 
+static tree
+vect_detect_hybrid_slp_2 (gimple_stmt_iterator *gsi, bool *handled,
+                         walk_stmt_info *)
+{
+  /* If the stmt is in a SLP instance then this isn't a reason
+     to mark use definitions in other SLP instances as hybrid.  */
+  if (STMT_SLP_TYPE (vinfo_for_stmt (gsi_stmt (*gsi))) != loop_vect)
+    *handled = true;
+  return NULL_TREE;
+}
 
 /* Find stmts that must be both vectorized and SLPed.  */
 
@@ -1820,8 +1856,41 @@ vect_detect_hybrid_slp (loop_vec_info loop_vinfo)
     dump_printf_loc (MSG_NOTE, vect_location, "=== vect_detect_hybrid_slp ==="
                      "\n");
 
+  /* First walk all pattern stmt in the loop and mark defs of uses as
+     hybrid because immediate uses in them are not recorded.  */
+  for (i = 0; i < LOOP_VINFO_LOOP (loop_vinfo)->num_nodes; ++i)
+    {
+      basic_block bb = LOOP_VINFO_BBS (loop_vinfo)[i];
+      for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
+          gsi_next (&gsi))
+       {
+         gimple stmt = gsi_stmt (gsi);
+         stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
+         if (STMT_VINFO_IN_PATTERN_P (stmt_info))
+           {
+             walk_stmt_info wi;
+             memset (&wi, 0, sizeof (wi));
+             wi.info = LOOP_VINFO_LOOP (loop_vinfo);
+             gimple_stmt_iterator gsi2
+               = gsi_for_stmt (STMT_VINFO_RELATED_STMT (stmt_info));
+             walk_gimple_stmt (&gsi2, vect_detect_hybrid_slp_2,
+                               vect_detect_hybrid_slp_1, &wi);
+             walk_gimple_seq (STMT_VINFO_PATTERN_DEF_SEQ (stmt_info),
+                              vect_detect_hybrid_slp_2,
+                              vect_detect_hybrid_slp_1, &wi);
+           }
+       }
+    }
+
+  /* Then walk the SLP instance trees marking stmts with uses in
+     non-SLP stmts as hybrid, also propagating hybrid down the
+     SLP tree, collecting the above info on-the-fly.  */
   FOR_EACH_VEC_ELT (slp_instances, i, instance)
-    vect_detect_hybrid_slp_stmts (SLP_INSTANCE_TREE (instance));
+    {
+      for (unsigned i = 0; i < SLP_INSTANCE_GROUP_SIZE (instance); ++i)
+       vect_detect_hybrid_slp_stmts (SLP_INSTANCE_TREE (instance),
+                                     i, pure_slp);
+    }
 }