re PR tree-optimization/19831 (Missing DSE/malloc/free optimization)
authorRichard Guenther <rguenther@suse.de>
Wed, 1 Jul 2009 12:27:33 +0000 (12:27 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 1 Jul 2009 12:27:33 +0000 (12:27 +0000)
2009-07-01  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/19831
* tree-ssa-dce.c (propagate_necessity): Calls to functions
that only act as barriers do not make any previous stores
necessary.
* tree-ssa-structalias.c (handle_lhs_call): Delay making
HEAP variables global, do not add a constraint from nonlocal.
(find_func_aliases): Handle escapes through return statements.
(compute_points_to_sets): Make escaped HEAP variables global.

* gcc.dg/tree-ssa/20041122-1.c: Enable TBAA, scan FRE dump,
make allocated memory escape.  Un-XFAIL.
* gcc.dg/vect/pr21591.c: Make allocated memory escape.
* gcc.dg/vect/pr31699.c: Likewise.
* gcc.dg/tree-ssa/ssa-dce-7.c: New testcase.

libmudflap/
* testsuite/libmudflap.c/fail11-frag.c: Make allocated memory
escape.
* testsuite/libmudflap.c/fail12-frag.c: Likewise.
* testsuite/libmudflap.c/fail16-frag.c: Likewise.
* testsuite/libmudflap.c/fail31-frag.c: Likewise.

From-SVN: r149140

13 files changed:
gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/20041122-1.c
gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-7.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/pr21591.c
gcc/testsuite/gcc.dg/vect/pr31699.c
gcc/tree-ssa-dce.c
gcc/tree-ssa-structalias.c
libmudflap/ChangeLog
libmudflap/testsuite/libmudflap.c/fail11-frag.c
libmudflap/testsuite/libmudflap.c/fail12-frag.c
libmudflap/testsuite/libmudflap.c/fail16-frag.c
libmudflap/testsuite/libmudflap.c/fail31-frag.c

index 68911788d790ef030a6f20b3b9739944a5b7efe2..205ca44e1dc7be8f3a49f8568f106d4eb10209e4 100644 (file)
@@ -1,3 +1,14 @@
+2009-07-01  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/19831
+       * tree-ssa-dce.c (propagate_necessity): Calls to functions
+       that only act as barriers do not make any previous stores
+       necessary.
+       * tree-ssa-structalias.c (handle_lhs_call): Delay making
+       HEAP variables global, do not add a constraint from nonlocal.
+       (find_func_aliases): Handle escapes through return statements.
+       (compute_points_to_sets): Make escaped HEAP variables global.
+
 2009-07-01  Paolo Bonzini  <bonzini@gnu.org>
 
        PR bootstrap/40597
index 513a973da1efe011d532a10c7a1ec88325318687..e929100fad19632aa4430ff17147cf11971c1749 100644 (file)
@@ -1,3 +1,12 @@
+2009-07-01  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/19831
+       * gcc.dg/tree-ssa/20041122-1.c: Enable TBAA, scan FRE dump,
+       make allocated memory escape.  Un-XFAIL.
+       * gcc.dg/vect/pr21591.c: Make allocated memory escape.
+       * gcc.dg/vect/pr31699.c: Likewise.
+       * gcc.dg/tree-ssa/ssa-dce-7.c: New testcase.
+
 2009-06-30  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/40566
index d72d133e154d391d01f77c708a5837b0d4dce753..6007949546e2235a8d833cc6122a134b37598c1c 100644 (file)
@@ -1,6 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O1 -fdump-tree-dom2" } */
-
+/* { dg-options "-O1 -fstrict-aliasing -fdump-tree-fre" } */
 
 __extension__ typedef __SIZE_TYPE__ size_t;
 extern void *xmalloc (size_t) __attribute__ ((__malloc__));
@@ -17,10 +16,10 @@ struct basic_block_def
 typedef struct basic_block_def *basic_block;
 extern int n_basic_blocks;
 extern edge frob ();
-void
-find_unreachable_blocks (int frobit)
+basic_block *
+find_unreachable_blocks (void)
 {
-  basic_block *tos, *worklist, bb;
+  basic_block *tos, *worklist;
   tos = worklist = xmalloc (sizeof (basic_block) * n_basic_blocks);
   edge e = frob();
   if (!(e->dest->flags & 4))
@@ -28,11 +27,12 @@ find_unreachable_blocks (int frobit)
       e->dest->flags |= 4;
       *tos++ = e->dest;
     }
+  return worklist;
 }
 
 /* If the aliasing code does its job properly, then we should be
    able to determine that modifying e->dest->flags does not
-   modify e or e->dest.  The net result is that we only need one
-   load of e->dest.  */
-/* { dg-final { scan-tree-dump-times "->dest" 1 "dom2" { xfail *-*-* } } } */
-/* { dg-final { cleanup-tree-dump "dom2" } } */
+   modify e or e->dest if we can assert strict-aliasing rules.
+   The net result is that we only need one load of e->dest.  */
+/* { dg-final { scan-tree-dump-times "->dest" 1 "fre" } } */
+/* { dg-final { cleanup-tree-dump "fre" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-7.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-7.c
new file mode 100644 (file)
index 0000000..792dfb0
--- /dev/null
@@ -0,0 +1,33 @@
+/* { dg-do link } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+
+extern void link_error (void);
+void foo(int n)
+{
+  int * f = (int*) __builtin_malloc (n * sizeof (int));
+  int * ff = (int*) __builtin_malloc (n * sizeof (int));
+  int i;
+
+  for (i = 0; i < n; ++i)
+    {
+      f[i] = 1;
+      ff[i] = 2;
+      if (f[i] != 1)
+       link_error ();
+      if (ff[i] != 2)
+       link_error ();
+    }
+
+  __builtin_free (f);
+  __builtin_free (ff);
+}
+int main()
+{
+  return 0;
+}
+
+/* We should have removed the calls to link_error () and all stores
+   to the allocated memory.  */
+
+/* { dg-final { scan-tree-dump-times "\\\*D" 0 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
index 8c3bef42a559fece865e0ee3a4d93ee536362207..425777738c2c62e229b208944c7ef0e38c957851 100644 (file)
@@ -10,6 +10,8 @@ struct a
 struct a *malloc1(__SIZE_TYPE__) __attribute__((malloc));
 void free(void*);
 
+struct a *p, *q, *r;
+
 void f(void)
 {
    struct a *a = malloc1(sizeof(struct a));
@@ -26,9 +28,9 @@ void f(void)
    {
       a->a1[i] = b->a1[i] + c->a1[i];
    }
-   free(a);
-   free(b);
-   free(c);
+   p = a;
+   q = b;
+   r = c;
 }
 
 /* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } */
index 4f9cf581b5837c3e98288ddf8f3b90c60f6c845f..6015d5cd4e597cf3e2be7d0c8505c0406ebce40e 100644 (file)
@@ -7,13 +7,15 @@
 float x[256];
 
 __attribute__ ((noinline))
-void foo(void)
+double *foo(void)
 {
  double *z = malloc (sizeof(double) * 256);
 
  int i;
  for (i=0; i<256; ++i)
    z[i] = x[i] + 1.0f;
+
+ return z;
 }
 
 
index 8522c5c5797a094e3a10a565d0e7995009991b7f..6be298e414f7bb44c7b5e108264aeaaabacf6bcc 100644 (file)
@@ -676,8 +676,19 @@ propagate_necessity (struct edge_list *el)
 
          if (is_gimple_call (stmt))
            {
+             tree callee = gimple_call_fndecl (stmt);
              unsigned i;
 
+             /* Calls to functions that are merely acting as barriers
+                or that only store to memory do not make any previous
+                stores necessary.  */
+             if (callee != NULL_TREE
+                 && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL
+                 && (DECL_FUNCTION_CODE (callee) == BUILT_IN_MEMSET
+                     || DECL_FUNCTION_CODE (callee) == BUILT_IN_MALLOC
+                     || DECL_FUNCTION_CODE (callee) == BUILT_IN_FREE))
+               continue;
+
              /* Calls implicitly load from memory, their arguments
                 in addition may explicitly perform memory loads.  */
              mark_all_reaching_defs_necessary (stmt);
index ad5482aa4aec92cbbd8808eca940786f0984e4a0..84edf00e2b265662c32e5cc0eee90944cc474af0 100644 (file)
@@ -3473,7 +3473,9 @@ handle_lhs_call (tree lhs, int flags, VEC(ce_s, heap) *rhsc)
     {
       varinfo_t vi;
       vi = make_constraint_from_heapvar (get_vi_for_tree (lhs), "HEAP");
-      make_copy_constraint (vi, nonlocal_id);
+      /* We delay marking allocated storage global until we know if
+         it escapes.  */
+      vi->is_global_var = 0;
     }
   else if (VEC_length (ce_s, rhsc) > 0)
     {
@@ -3910,6 +3912,13 @@ find_func_aliases (gimple origt)
     {
       make_escape_constraint (gimple_assign_rhs1 (t));
     }
+  /* Handle escapes through return.  */
+  else if (gimple_code (t) == GIMPLE_RETURN
+          && gimple_return_retval (t) != NULL_TREE
+          && could_have_pointers (gimple_return_retval (t)))
+    {
+      make_escape_constraint (gimple_return_retval (t));
+    }
   /* Handle asms conservatively by adding escape constraints to everything.  */
   else if (gimple_code (t) == GIMPLE_ASM)
     {
@@ -5350,6 +5359,7 @@ compute_points_to_sets (void)
   struct scc_info *si;
   basic_block bb;
   unsigned i;
+  varinfo_t vi;
 
   timevar_push (TV_TREE_PTA);
 
@@ -5447,6 +5457,13 @@ compute_points_to_sets (void)
      points-to solution queries.  */
   cfun->gimple_df->escaped.escaped = 0;
 
+  /* Mark escaped HEAP variables as global.  */
+  for (i = 0; VEC_iterate (varinfo_t, varmap, i, vi); ++i)
+    if (vi->is_heap_var
+       && !vi->is_global_var)
+      vi->is_global_var = pt_solution_includes (&cfun->gimple_df->escaped,
+                                               vi->decl);
+
   /* Compute the points-to sets for pointer SSA_NAMEs.  */
   for (i = 0; i < num_ssa_names; ++i)
     {
index 11d6f525f4043251363e63621a99e0d2f73644ec..75031657d06f077a297a7c3bf91f5e9e9e69dcfc 100644 (file)
@@ -1,3 +1,12 @@
+2009-07-01  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/19831
+       * testsuite/libmudflap.c/fail11-frag.c: Make allocated memory
+       escape.
+       * testsuite/libmudflap.c/fail12-frag.c: Likewise.
+       * testsuite/libmudflap.c/fail16-frag.c: Likewise.
+       * testsuite/libmudflap.c/fail31-frag.c: Likewise.
+
 2009-06-30  Richard Sandiford  <r.sandiford@uk.ibm.com>
 
        * testsuite/lib/libmudflap.exp (libmudflap-init): Don't add "."
index 72038fdba30b4757e57d0ce0049e60a54d4f8bb7..ebd1db9671794ff210193c13db16053decc13813 100644 (file)
@@ -1,11 +1,12 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+char *y;
 int main ()
 {
 int i = 10;
 char *x = (char *) malloc (i * sizeof (char));
-
+y = x;
 while (i--)
 {
   ++x;
index da8bfb7c046aa8509f655776ef960a405e1fc820..46dbdb23642575bf5d3b4a352fecf54c4d114bae 100644 (file)
@@ -1,11 +1,12 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+int *y;
 int main ()
 {
 int i = 10;
 int *x = (int *) malloc (i * sizeof (int));
-
+y = x;
 while (i--)
 {
   ++x;
index 317e2744731121ab6355f21605f456030378ac40..6ac6187e2ad4919df1680f7bbc236625ed4edd05 100644 (file)
@@ -1,6 +1,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+void *p;
 int main ()
 {
 struct base {
@@ -15,7 +16,7 @@ struct derived {
 struct base *bp;
 
 bp = (struct base *) malloc (sizeof (struct base));;
-
+p = bp;
 bp->basic = 10;
 ((struct derived *)bp)->extra = 'x';
 return 0;
index b15056c970c197318e9353625a94999bf62112b8..bd9a903ccfd02e0be9464f2989e648099cbd249e 100644 (file)
@@ -8,11 +8,12 @@ int main ()
   int z = h (4, 10);
   return 0;
 }
-
+int *p;
 int h (int i, int j)
 {
   int k[i];
   k[j] = i;
+  p = k;
   return j;
 }