[PATCH][RFC] Handle realloc in PTA and alias analysis

Richard Biener rguenther@suse.de
Thu May 22 10:00:00 GMT 2014


On Wed, 21 May 2014, Richard Biener wrote:

> On Wed, 21 May 2014, Richard Biener wrote:
> 
> > 
> > PR56955 prompted me to handle BUILT_IN_REALLOC just the same
> > way we already handle BUILT_IN_STR[N]DUP.
> > 
> > Bootstrap and regtest running on x86_64-unknown-linux-gnu.
> > 
> > Now this will disambiguate *p and *q for p = realloc (q, n)
> > for any value of n (including those that don't actually
> > trigger re-allocation and thus where p == q after the call).
> > I don't think that any such use would be valid - but I can
> > certainly play safer here and implement the points-to part
> > as a pass-through (that is, make p point to what q points).
> > That's of course less optimization.
> 
> Like with incremental
> 
> Index: gcc/tree-ssa-structalias.c
> ===================================================================
> --- gcc/tree-ssa-structalias.c.orig     2014-05-21 15:37:58.762890034 
> +0200
> +++ gcc/tree-ssa-structalias.c  2014-05-21 15:35:52.044898758 +0200
> @@ -4313,6 +4313,17 @@ find_func_aliases_for_builtin_call (stru
>             process_all_all_constraints (lhsc, rhsc);
>             lhsc.release ();
>             rhsc.release ();
> +           /* For realloc the resulting pointer can be equal to the
> +              argument as well.  But only doing this wouldn't be
> +              correct because with ptr == 0 realloc behaves like malloc.  
> */
> +           if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_REALLOC)
> +             {
> +               get_constraint_for (gimple_call_lhs (t), &lhsc);
> +               get_constraint_for (gimple_call_arg (t, 0), &rhsc);
> +               process_all_all_constraints (lhsc, rhsc);
> +               lhsc.release ();
> +               rhsc.release ();
> +             }
>             return true;
>           }
>         break;
> 
> that of course makes it a somewhat pointless excercise if
> points-to doesn't figure out sth fancy for the argument to
> realloc (like its NULL or the result of an earlier malloc call,
> still optimizes the testcase as expected).

The following is what I have applied after bootstrapping and
testing on x86_64-unknown-linux-gnu.

Richard.

2014-05-21  Richard Biener  <rguenther@suse.de>

	* tree-ssa-alias.c (ref_maybe_used_by_call_p_1): Handle
	BUILT_IN_REALLOC like BUILT_IN_STRDUP.
	(call_may_clobber_ref_p_1): Handle BUILT_IN_REALLOC as allocation
	and deallocation site.
	* tree-ssa-structalias.c (find_func_aliases_for_builtin_call):
	Handle BUILT_IN_REALLOC similar to BUILT_IN_STRDUP with also
	passing through the incoming points-to set.
	(handle_lhs_call): Use flags argument instead of recomputing it.
	(find_func_aliases_for_call): Call handle_lhs_call with proper
	call return flags.

	* gcc.dg/tree-ssa/alias-33.c: New testcase.

Index: gcc/tree-ssa-alias.c
===================================================================
*** gcc/tree-ssa-alias.c.orig	2014-05-21 16:21:18.995711011 +0200
--- gcc/tree-ssa-alias.c	2014-05-22 09:44:40.940400943 +0200
*************** ref_maybe_used_by_call_p_1 (gimple call,
*** 1594,1599 ****
--- 1594,1600 ----
  	/* These read memory pointed to by the first argument.  */
  	case BUILT_IN_STRDUP:
  	case BUILT_IN_STRNDUP:
+ 	case BUILT_IN_REALLOC:
  	  {
  	    ao_ref dref;
  	    tree size = NULL_TREE;
*************** call_may_clobber_ref_p_1 (gimple call, a
*** 1991,1996 ****
--- 1992,2006 ----
  	    tree ptr = gimple_call_arg (call, 0);
  	    return ptr_deref_may_alias_ref_p_1 (ptr, ref);
  	  }
+ 	/* Realloc serves both as allocation point and deallocation point.  */
+ 	case BUILT_IN_REALLOC:
+ 	  {
+ 	    tree ptr = gimple_call_arg (call, 0);
+ 	    /* Unix98 specifies that errno is set on allocation failure.  */
+ 	    return ((flag_errno_math
+ 		     && targetm.ref_may_alias_errno (ref))
+ 		    || ptr_deref_may_alias_ref_p_1 (ptr, ref));
+ 	  }
  	case BUILT_IN_GAMMA_R:
  	case BUILT_IN_GAMMAF_R:
  	case BUILT_IN_GAMMAL_R:
Index: gcc/tree-ssa-structalias.c
===================================================================
*** gcc/tree-ssa-structalias.c.orig	2014-05-21 16:21:18.995711011 +0200
--- gcc/tree-ssa-structalias.c	2014-05-22 09:43:05.807407492 +0200
*************** handle_lhs_call (gimple stmt, tree lhs,
*** 3974,3980 ****
  
    /* If the call returns an argument unmodified override the rhs
       constraints.  */
-   flags = gimple_call_return_flags (stmt);
    if (flags & ERF_RETURNS_ARG
        && (flags & ERF_RETURN_ARG_MASK) < gimple_call_num_args (stmt))
      {
--- 3974,3979 ----
*************** find_func_aliases_for_builtin_call (stru
*** 4299,4307 ****
  	return true;
        case BUILT_IN_STRDUP:
        case BUILT_IN_STRNDUP:
  	if (gimple_call_lhs (t))
  	  {
! 	    handle_lhs_call (t, gimple_call_lhs (t), gimple_call_flags (t),
  			     vNULL, fndecl);
  	    get_constraint_for_ptr_offset (gimple_call_lhs (t),
  					   NULL_TREE, &lhsc);
--- 4298,4308 ----
  	return true;
        case BUILT_IN_STRDUP:
        case BUILT_IN_STRNDUP:
+       case BUILT_IN_REALLOC:
  	if (gimple_call_lhs (t))
  	  {
! 	    handle_lhs_call (t, gimple_call_lhs (t),
! 			     gimple_call_return_flags (t) | ERF_NOALIAS,
  			     vNULL, fndecl);
  	    get_constraint_for_ptr_offset (gimple_call_lhs (t),
  					   NULL_TREE, &lhsc);
*************** find_func_aliases_for_builtin_call (stru
*** 4312,4317 ****
--- 4313,4329 ----
  	    process_all_all_constraints (lhsc, rhsc);
  	    lhsc.release ();
  	    rhsc.release ();
+ 	    /* For realloc the resulting pointer can be equal to the
+ 	       argument as well.  But only doing this wouldn't be
+ 	       correct because with ptr == 0 realloc behaves like malloc.  */
+ 	    if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_REALLOC)
+ 	      {
+ 		get_constraint_for (gimple_call_lhs (t), &lhsc);
+ 		get_constraint_for (gimple_call_arg (t, 0), &rhsc);
+ 		process_all_all_constraints (lhsc, rhsc);
+ 		lhsc.release ();
+ 		rhsc.release ();
+ 	      }
  	    return true;
  	  }
  	break;
*************** find_func_aliases_for_call (struct funct
*** 4535,4541 ****
        else
  	handle_rhs_call (t, &rhsc);
        if (gimple_call_lhs (t))
! 	handle_lhs_call (t, gimple_call_lhs (t), flags, rhsc, fndecl);
        rhsc.release ();
      }
    else
--- 4547,4554 ----
        else
  	handle_rhs_call (t, &rhsc);
        if (gimple_call_lhs (t))
! 	handle_lhs_call (t, gimple_call_lhs (t),
! 			 gimple_call_return_flags (t), rhsc, fndecl);
        rhsc.release ();
      }
    else
Index: gcc/testsuite/gcc.dg/tree-ssa/alias-33.c
===================================================================
*** /dev/null	1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gcc.dg/tree-ssa/alias-33.c	2014-05-22 09:43:05.808407492 +0200
***************
*** 0 ****
--- 1,20 ----
+ /* { dg-do run } */
+ /* { dg-options "-O -fdump-tree-fre1-details" } */
+ 
+ int j;
+ int main ()
+ {
+   int i = 1;
+   int **p;
+   j = 0;
+   p = __builtin_malloc (sizeof (int *));
+   *p = &i;
+   p = __builtin_realloc (p, 2 * sizeof (int *));
+   **p = 0;
+   if (i != 0)
+     __builtin_abort ();
+   return j;
+ }
+ 
+ /* { dg-final { scan-tree-dump "Replaced j with 0" "fre1" } } */
+ /* { dg-final { cleanup-tree-dump "fre1" } } */



More information about the Gcc-patches mailing list