2012-09-19 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 19 Sep 2012 08:59:06 +0000 (08:59 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 19 Sep 2012 08:59:06 +0000 (08:59 +0000)
PR tree-optimization/54132
* tree-loop-distribution.c (classify_partition): Properly
check dependences for memmove.
* tree-data-ref.h (compute_affine_dependence): Declare.
* tree-data-ref.c (compute_affine_dependence): Export.

* gcc.dg/tree-ssa/ldist-21.c: New testcase.
* gcc.dg/torture/pr54132.c: Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@191463 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr54132.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/ldist-21.c [new file with mode: 0644]
gcc/tree-data-ref.c
gcc/tree-data-ref.h
gcc/tree-loop-distribution.c

index 936b7d0..fc19389 100644 (file)
@@ -1,3 +1,11 @@
+2012-09-19  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/54132
+       * tree-loop-distribution.c (classify_partition): Properly
+       check dependences for memmove.
+       * tree-data-ref.h (compute_affine_dependence): Declare.
+       * tree-data-ref.c (compute_affine_dependence): Export.
+
 2012-09-19  Zhenqiang Chen <zhenqiang.chen@arm.com>
 
        PR middle-end/54364
index df70396..bf497ee 100644 (file)
@@ -1,3 +1,9 @@
+2012-09-19  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/54132
+       * gcc.dg/tree-ssa/ldist-21.c: New testcase.
+       * gcc.dg/torture/pr54132.c: Likewise.
+
 2012-09-19  Terry Guo  <terry.guo@arm.com>
 
        * lib/gcc-dg.exp (dg_runtest_extra_prunes): New variable to define
diff --git a/gcc/testsuite/gcc.dg/torture/pr54132.c b/gcc/testsuite/gcc.dg/torture/pr54132.c
new file mode 100644 (file)
index 0000000..97bc01c
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do run } */
+
+extern void abort (void);
+void foo(char *p, int n)
+{
+  int i;
+  for (i = 1; i < n; i++)
+    p[i] = p[i - 1];
+}
+int main()
+{
+  char a[1024];
+  a[0] = 1;
+  foo (a, 1024);
+  if (a[1023] != 1)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-21.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-21.c
new file mode 100644 (file)
index 0000000..35f01ab
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-ldist-details" } */
+
+void bar(char *p, int n)
+{
+  int i;
+  for (i = 1; i < n; i++)
+    p[i-1] = p[i];
+}
+
+/* { dg-final { scan-tree-dump "generated memmove" "ldist" } } */
index 0f68fdf..4f6df91 100644 (file)
@@ -4130,7 +4130,7 @@ ddr_consistent_p (FILE *file,
    relation the first time we detect a CHREC_KNOWN element for a given
    subscript.  */
 
-static void
+void
 compute_affine_dependence (struct data_dependence_relation *ddr,
                           struct loop *loop_nest)
 {
index db33e32..b00a4f7 100644 (file)
@@ -396,6 +396,8 @@ struct data_reference *create_data_ref (loop_p, loop_p, tree, gimple, bool);
 extern bool find_loop_nest (struct loop *, VEC (loop_p, heap) **);
 extern struct data_dependence_relation *initialize_data_dependence_relation
      (struct data_reference *, struct data_reference *, VEC (loop_p, heap) *); 
+extern void compute_affine_dependence (struct data_dependence_relation *,
+                                      loop_p);
 extern void compute_self_dependence (struct data_dependence_relation *);
 extern bool compute_all_dependences (VEC (data_reference_p, heap) *,
                                     VEC (ddr_p, heap) **, VEC (loop_p, heap) *,
index f340eab..b24af33 100644 (file)
@@ -1011,6 +1011,39 @@ classify_partition (loop_p loop, struct graph *rdg, partition_t partition)
          || !operand_equal_p (DR_STEP (single_store),
                               DR_STEP (single_load), 0))
        return;
+      /* Now check that if there is a dependence this dependence is
+         of a suitable form for memmove.  */
+      VEC(loop_p, heap) *loops = NULL;
+      ddr_p ddr;
+      VEC_safe_push (loop_p, heap, loops, loop);
+      ddr = initialize_data_dependence_relation (single_load, single_store,
+                                                loops);
+      compute_affine_dependence (ddr, loop);
+      VEC_free (loop_p, heap, loops);
+      if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
+       {
+         free_dependence_relation (ddr);
+         return;
+       }
+      if (DDR_ARE_DEPENDENT (ddr) != chrec_known)
+       {
+         if (DDR_NUM_DIST_VECTS (ddr) == 0)
+           {
+             free_dependence_relation (ddr);
+             return;
+           }
+         lambda_vector dist_v;
+         FOR_EACH_VEC_ELT (lambda_vector, DDR_DIST_VECTS (ddr), i, dist_v)
+           {
+             int dist = dist_v[index_in_loop_nest (loop->num,
+                                                   DDR_LOOP_NEST (ddr))];
+             if (dist > 0 && !DDR_REVERSED_P (ddr))
+               {
+                 free_dependence_relation (ddr);
+                 return;
+               }
+           }
+       }
       partition->kind = PKIND_MEMCPY;
       partition->main_dr = single_store;
       partition->secondary_dr = single_load;