This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] DCE free (NULL)


It looks like we can DCE free (NULL) without problems (but it's
questionable to fold malloc (0) to NULL or to DCE pairs of
malloc / free).  Thus the following patch implements DCEing
free (NULL) in the builtin folder.

The patch was triggered by maybe teaching the Fortran frontend
to emit free () unguarded and thus the pattern in the testcase
could result regularly from user code.

Bootstrap and regtest running on x86_64-unknown-linux-gnu.

Richard.

2010-04-29  Richard Guenther  <rguenther@suse.de>

	* builtins.c (fold_builtin_1): Delete free (0).

	* gcc.dg/tree-ssa/builtin-free.c: New testcase.

Index: gcc/builtins.c
===================================================================
*** gcc/builtins.c	(revision 158900)
--- gcc/builtins.c	(working copy)
*************** fold_builtin_1 (location_t loc, tree fnd
*** 9817,9823 ****
    enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
    switch (fcode)
      {
- 
      case BUILT_IN_CONSTANT_P:
        {
  	tree val = fold_builtin_constant_p (arg0);
--- 9817,9822 ----
*************** fold_builtin_1 (location_t loc, tree fnd
*** 10199,10204 ****
--- 10198,10208 ----
      case BUILT_IN_VPRINTF:
        return fold_builtin_printf (loc, fndecl, arg0, NULL_TREE, ignore, fcode);
  
+     case BUILT_IN_FREE:
+       if (integer_zerop (arg0))
+ 	return build_empty_stmt (loc);
+       break;
+ 
      default:
        break;
      }
Index: gcc/testsuite/gcc.dg/tree-ssa/builtin-free.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/builtin-free.c	(revision 0)
--- gcc/testsuite/gcc.dg/tree-ssa/builtin-free.c	(revision 0)
***************
*** 0 ****
--- 1,20 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O2 -fdump-tree-optimized" } */
+ 
+ void bar (void *);
+ void foo(unsigned n)
+ {
+   void *p = __builtin_malloc (n);
+   if (p)
+     {
+       bar (p);
+       __builtin_free (p);
+       p = 0;
+     }
+   __builtin_free (p);
+ }
+ 
+ /* We should remove the redundant call to free.  */
+ 
+ /* { dg-final { scan-tree-dump-times "free" 1 "optimized" } } */
+ /* { dg-final { cleanup-tree-dump "optimized" } } */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]