Patchwork Handle __builtin*chk and other builtins in various spots

login
register
mail settings
Submitter Jakub Jelinek
Date June 21, 2011, 4:31 p.m.
Message ID <20110621163128.GK16443@tyan-ft48-01.lab.bos.redhat.com>
Download mbox | patch
Permalink /patch/101310/
State New
Headers show

Comments

Jakub Jelinek - June 21, 2011, 4:31 p.m.
Hi!

While working on __builtin_assume_aligned support, I've noticed
a bunch of places which handle some builtins specially in CCP/DCE/aliasing,
but don't handle other similar calls.  Additionally
in CCP for stringops that just return its first argument we can use
first arguments properties for the return value and e.g. reasoning
about alignment of malloc/calloc/alloca etc. is useful even if likely_value
for the call doesn't return CONSTANT, as it doesn't depend on the arguments.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2011-06-21  Jakub Jelinek  <jakub@redhat.com>

	* tree-ssa-ccp.c (evaluate_stmt): Try bitwise tracking for
	builtin calls even if likelyvalue is not CONSTANT.
	Handle BUILT_IN_STRDUP and BUILT_IN_STRNDUP like BUILT_IN_MALLOC.
	Return get_value_for_expr of first operand
	for BUILT_IN_{MEM{CPY,MOVE,SET},STR{,N}CPY}{,_CHK}.
	* tree-ssa-alias.c (ref_maybe_used_by_call_p_1): Handle
	BUILT_IN_{MEM{{,P}CPY,MOVE,SET},STR{,N}C{PY,AT},STPCPY}_CHK like
	their non-checking counterparts.
	(call_may_clobber_ref_p_1): Likewise.
	(stmt_kills_ref_p_1): Handle BUILT_IN_MEM{{,P}CPY,MOVE,SET}_CHK
	like their non-checking counterparts.
	* tree-ssa-structalias.c (find_func_aliases_for_builtin_call):
	Handle BUILT_IN_{MEM{{,P}CPY,MOVE,SET},STR{,N}C{PY,AT},STPCPY}_CHK
	like their non-checking counterparts.
	(find_func_clobbers): Likewise.
	* tree-ssa-dce.c (propagate_necessity): Handle BUILT_IN_MEMSET_CHK
	like BUILT_IN_MEMSET and BUILT_IN_CALLOC like BUILT_IN_MALLOC.


	Jakub
Richard Guenther - June 22, 2011, 8:46 a.m.
On Tue, Jun 21, 2011 at 6:31 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> While working on __builtin_assume_aligned support, I've noticed
> a bunch of places which handle some builtins specially in CCP/DCE/aliasing,
> but don't handle other similar calls.  Additionally
> in CCP for stringops that just return its first argument we can use
> first arguments properties for the return value and e.g. reasoning
> about alignment of malloc/calloc/alloca etc. is useful even if likely_value
> for the call doesn't return CONSTANT, as it doesn't depend on the arguments.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Ok.

Thanks,
Richard.

> 2011-06-21  Jakub Jelinek  <jakub@redhat.com>
>
>        * tree-ssa-ccp.c (evaluate_stmt): Try bitwise tracking for
>        builtin calls even if likelyvalue is not CONSTANT.
>        Handle BUILT_IN_STRDUP and BUILT_IN_STRNDUP like BUILT_IN_MALLOC.
>        Return get_value_for_expr of first operand
>        for BUILT_IN_{MEM{CPY,MOVE,SET},STR{,N}CPY}{,_CHK}.
>        * tree-ssa-alias.c (ref_maybe_used_by_call_p_1): Handle
>        BUILT_IN_{MEM{{,P}CPY,MOVE,SET},STR{,N}C{PY,AT},STPCPY}_CHK like
>        their non-checking counterparts.
>        (call_may_clobber_ref_p_1): Likewise.
>        (stmt_kills_ref_p_1): Handle BUILT_IN_MEM{{,P}CPY,MOVE,SET}_CHK
>        like their non-checking counterparts.
>        * tree-ssa-structalias.c (find_func_aliases_for_builtin_call):
>        Handle BUILT_IN_{MEM{{,P}CPY,MOVE,SET},STR{,N}C{PY,AT},STPCPY}_CHK
>        like their non-checking counterparts.
>        (find_func_clobbers): Likewise.
>        * tree-ssa-dce.c (propagate_necessity): Handle BUILT_IN_MEMSET_CHK
>        like BUILT_IN_MEMSET and BUILT_IN_CALLOC like BUILT_IN_MALLOC.
>
> --- gcc/tree-ssa-ccp.c.jj       2011-06-17 11:02:19.000000000 +0200
> +++ gcc/tree-ssa-ccp.c  2011-06-21 14:14:37.000000000 +0200
> @@ -1556,7 +1556,7 @@ evaluate_stmt (gimple stmt)
>
>   /* Resort to simplification for bitwise tracking.  */
>   if (flag_tree_bit_ccp
> -      && likelyvalue == CONSTANT
> +      && (likelyvalue == CONSTANT || is_gimple_call (stmt))
>       && !is_constant)
>     {
>       enum gimple_code code = gimple_code (stmt);
> @@ -1616,6 +1616,8 @@ evaluate_stmt (gimple stmt)
>            case BUILT_IN_MALLOC:
>            case BUILT_IN_REALLOC:
>            case BUILT_IN_CALLOC:
> +           case BUILT_IN_STRDUP:
> +           case BUILT_IN_STRNDUP:
>              val.lattice_val = CONSTANT;
>              val.value = build_int_cst (TREE_TYPE (gimple_get_lhs (stmt)), 0);
>              val.mask = shwi_to_double_int
> @@ -1631,6 +1633,20 @@ evaluate_stmt (gimple stmt)
>                              / BITS_PER_UNIT - 1));
>              break;
>
> +           /* These builtins return their first argument, unmodified.  */
> +           case BUILT_IN_MEMCPY:
> +           case BUILT_IN_MEMMOVE:
> +           case BUILT_IN_MEMSET:
> +           case BUILT_IN_STRCPY:
> +           case BUILT_IN_STRNCPY:
> +           case BUILT_IN_MEMCPY_CHK:
> +           case BUILT_IN_MEMMOVE_CHK:
> +           case BUILT_IN_MEMSET_CHK:
> +           case BUILT_IN_STRCPY_CHK:
> +           case BUILT_IN_STRNCPY_CHK:
> +             val = get_value_for_expr (gimple_call_arg (stmt, 0), true);
> +             break;
> +
>            default:;
>            }
>        }
> --- gcc/tree-ssa-alias.c.jj     2011-06-17 11:01:22.000000000 +0200
> +++ gcc/tree-ssa-alias.c        2011-06-21 14:15:42.000000000 +0200
> @@ -1,5 +1,5 @@
>  /* Alias analysis for trees.
> -   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
> +   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
>    Free Software Foundation, Inc.
>    Contributed by Diego Novillo <dnovillo@redhat.com>
>
> @@ -1199,6 +1199,24 @@ ref_maybe_used_by_call_p_1 (gimple call,
>                                           size);
>            return refs_may_alias_p_1 (&dref, ref, false);
>          }
> +       case BUILT_IN_STRCPY_CHK:
> +       case BUILT_IN_STRNCPY_CHK:
> +       case BUILT_IN_MEMCPY_CHK:
> +       case BUILT_IN_MEMMOVE_CHK:
> +       case BUILT_IN_MEMPCPY_CHK:
> +       case BUILT_IN_STPCPY_CHK:
> +       case BUILT_IN_STRCAT_CHK:
> +       case BUILT_IN_STRNCAT_CHK:
> +         {
> +           ao_ref dref;
> +           tree size = NULL_TREE;
> +           if (gimple_call_num_args (call) == 4)
> +             size = gimple_call_arg (call, 2);
> +           ao_ref_init_from_ptr_and_size (&dref,
> +                                          gimple_call_arg (call, 1),
> +                                          size);
> +           return refs_may_alias_p_1 (&dref, ref, false);
> +         }
>        case BUILT_IN_BCOPY:
>          {
>            ao_ref dref;
> @@ -1216,6 +1234,7 @@ ref_maybe_used_by_call_p_1 (gimple call,
>        case BUILT_IN_STACK_SAVE:
>        case BUILT_IN_STACK_RESTORE:
>        case BUILT_IN_MEMSET:
> +       case BUILT_IN_MEMSET_CHK:
>        case BUILT_IN_FREXP:
>        case BUILT_IN_FREXPF:
>        case BUILT_IN_FREXPL:
> @@ -1453,6 +1472,25 @@ call_may_clobber_ref_p_1 (gimple call, a
>                                           size);
>            return refs_may_alias_p_1 (&dref, ref, false);
>          }
> +       case BUILT_IN_STRCPY_CHK:
> +       case BUILT_IN_STRNCPY_CHK:
> +       case BUILT_IN_MEMCPY_CHK:
> +       case BUILT_IN_MEMMOVE_CHK:
> +       case BUILT_IN_MEMPCPY_CHK:
> +       case BUILT_IN_STPCPY_CHK:
> +       case BUILT_IN_STRCAT_CHK:
> +       case BUILT_IN_STRNCAT_CHK:
> +       case BUILT_IN_MEMSET_CHK:
> +         {
> +           ao_ref dref;
> +           tree size = NULL_TREE;
> +           if (gimple_call_num_args (call) == 4)
> +             size = gimple_call_arg (call, 2);
> +           ao_ref_init_from_ptr_and_size (&dref,
> +                                          gimple_call_arg (call, 0),
> +                                          size);
> +           return refs_may_alias_p_1 (&dref, ref, false);
> +         }
>        case BUILT_IN_BCOPY:
>          {
>            ao_ref dref;
> @@ -1697,6 +1735,10 @@ stmt_kills_ref_p_1 (gimple stmt, ao_ref
>          case BUILT_IN_MEMPCPY:
>          case BUILT_IN_MEMMOVE:
>          case BUILT_IN_MEMSET:
> +         case BUILT_IN_MEMCPY_CHK:
> +         case BUILT_IN_MEMPCPY_CHK:
> +         case BUILT_IN_MEMMOVE_CHK:
> +         case BUILT_IN_MEMSET_CHK:
>            {
>              tree dest = gimple_call_arg (stmt, 0);
>              tree len = gimple_call_arg (stmt, 2);
> --- gcc/tree-ssa-structalias.c.jj       2011-06-17 11:02:19.000000000 +0200
> +++ gcc/tree-ssa-structalias.c  2011-06-21 14:05:13.000000000 +0200
> @@ -1,5 +1,5 @@
>  /* Tree based points-to analysis
> -   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010
> +   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011
>    Free Software Foundation, Inc.
>    Contributed by Daniel Berlin <dberlin@dberlin.org>
>
> @@ -3982,6 +3982,14 @@ find_func_aliases_for_builtin_call (gimp
>       case BUILT_IN_STPNCPY:
>       case BUILT_IN_STRCAT:
>       case BUILT_IN_STRNCAT:
> +      case BUILT_IN_STRCPY_CHK:
> +      case BUILT_IN_STRNCPY_CHK:
> +      case BUILT_IN_MEMCPY_CHK:
> +      case BUILT_IN_MEMMOVE_CHK:
> +      case BUILT_IN_MEMPCPY_CHK:
> +      case BUILT_IN_STPCPY_CHK:
> +      case BUILT_IN_STRCAT_CHK:
> +      case BUILT_IN_STRNCAT_CHK:
>        {
>          tree res = gimple_call_lhs (t);
>          tree dest = gimple_call_arg (t, (DECL_FUNCTION_CODE (fndecl)
> @@ -4011,6 +4019,7 @@ find_func_aliases_for_builtin_call (gimp
>          return true;
>        }
>       case BUILT_IN_MEMSET:
> +      case BUILT_IN_MEMSET_CHK:
>        {
>          tree res = gimple_call_lhs (t);
>          tree dest = gimple_call_arg (t, 0);
> @@ -4627,6 +4636,14 @@ find_func_clobbers (gimple origt)
>          case BUILT_IN_STPNCPY:
>          case BUILT_IN_STRCAT:
>          case BUILT_IN_STRNCAT:
> +         case BUILT_IN_STRCPY_CHK:
> +         case BUILT_IN_STRNCPY_CHK:
> +         case BUILT_IN_MEMCPY_CHK:
> +         case BUILT_IN_MEMMOVE_CHK:
> +         case BUILT_IN_MEMPCPY_CHK:
> +         case BUILT_IN_STPCPY_CHK:
> +         case BUILT_IN_STRCAT_CHK:
> +         case BUILT_IN_STRNCAT_CHK:
>            {
>              tree dest = gimple_call_arg (t, (DECL_FUNCTION_CODE (decl)
>                                               == BUILT_IN_BCOPY ? 1 : 0));
> @@ -4649,6 +4666,7 @@ find_func_clobbers (gimple origt)
>          /* The following function clobbers memory pointed to by
>             its argument.  */
>          case BUILT_IN_MEMSET:
> +         case BUILT_IN_MEMSET_CHK:
>            {
>              tree dest = gimple_call_arg (t, 0);
>              unsigned i;
> --- gcc/tree-ssa-dce.c.jj       2011-06-17 11:02:19.000000000 +0200
> +++ gcc/tree-ssa-dce.c  2011-06-21 14:15:16.000000000 +0200
> @@ -830,7 +830,9 @@ propagate_necessity (struct edge_list *e
>              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_MEMSET_CHK
>                      || DECL_FUNCTION_CODE (callee) == BUILT_IN_MALLOC
> +                     || DECL_FUNCTION_CODE (callee) == BUILT_IN_CALLOC
>                      || DECL_FUNCTION_CODE (callee) == BUILT_IN_FREE
>                      || DECL_FUNCTION_CODE (callee) == BUILT_IN_ALLOCA
>                      || DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_SAVE
>
>        Jakub
>

Patch

--- gcc/tree-ssa-ccp.c.jj	2011-06-17 11:02:19.000000000 +0200
+++ gcc/tree-ssa-ccp.c	2011-06-21 14:14:37.000000000 +0200
@@ -1556,7 +1556,7 @@  evaluate_stmt (gimple stmt)
 
   /* Resort to simplification for bitwise tracking.  */
   if (flag_tree_bit_ccp
-      && likelyvalue == CONSTANT
+      && (likelyvalue == CONSTANT || is_gimple_call (stmt))
       && !is_constant)
     {
       enum gimple_code code = gimple_code (stmt);
@@ -1616,6 +1616,8 @@  evaluate_stmt (gimple stmt)
 	    case BUILT_IN_MALLOC:
 	    case BUILT_IN_REALLOC:
 	    case BUILT_IN_CALLOC:
+	    case BUILT_IN_STRDUP:
+	    case BUILT_IN_STRNDUP:
 	      val.lattice_val = CONSTANT;
 	      val.value = build_int_cst (TREE_TYPE (gimple_get_lhs (stmt)), 0);
 	      val.mask = shwi_to_double_int
@@ -1631,6 +1633,20 @@  evaluate_stmt (gimple stmt)
 			      / BITS_PER_UNIT - 1));
 	      break;
 
+	    /* These builtins return their first argument, unmodified.  */
+	    case BUILT_IN_MEMCPY:
+	    case BUILT_IN_MEMMOVE:
+	    case BUILT_IN_MEMSET:
+	    case BUILT_IN_STRCPY:
+	    case BUILT_IN_STRNCPY:
+	    case BUILT_IN_MEMCPY_CHK:
+	    case BUILT_IN_MEMMOVE_CHK:
+	    case BUILT_IN_MEMSET_CHK:
+	    case BUILT_IN_STRCPY_CHK:
+	    case BUILT_IN_STRNCPY_CHK:
+	      val = get_value_for_expr (gimple_call_arg (stmt, 0), true);
+	      break;
+
 	    default:;
 	    }
 	}
--- gcc/tree-ssa-alias.c.jj	2011-06-17 11:01:22.000000000 +0200
+++ gcc/tree-ssa-alias.c	2011-06-21 14:15:42.000000000 +0200
@@ -1,5 +1,5 @@ 
 /* Alias analysis for trees.
-   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
    Contributed by Diego Novillo <dnovillo@redhat.com>
 
@@ -1199,6 +1199,24 @@  ref_maybe_used_by_call_p_1 (gimple call,
 					   size);
 	    return refs_may_alias_p_1 (&dref, ref, false);
 	  }
+	case BUILT_IN_STRCPY_CHK:
+	case BUILT_IN_STRNCPY_CHK:
+	case BUILT_IN_MEMCPY_CHK:
+	case BUILT_IN_MEMMOVE_CHK:
+	case BUILT_IN_MEMPCPY_CHK:
+	case BUILT_IN_STPCPY_CHK:
+	case BUILT_IN_STRCAT_CHK:
+	case BUILT_IN_STRNCAT_CHK:
+	  {
+	    ao_ref dref;
+	    tree size = NULL_TREE;
+	    if (gimple_call_num_args (call) == 4)
+	      size = gimple_call_arg (call, 2);
+	    ao_ref_init_from_ptr_and_size (&dref,
+					   gimple_call_arg (call, 1),
+					   size);
+	    return refs_may_alias_p_1 (&dref, ref, false);
+	  }
 	case BUILT_IN_BCOPY:
 	  {
 	    ao_ref dref;
@@ -1216,6 +1234,7 @@  ref_maybe_used_by_call_p_1 (gimple call,
 	case BUILT_IN_STACK_SAVE:
 	case BUILT_IN_STACK_RESTORE:
 	case BUILT_IN_MEMSET:
+	case BUILT_IN_MEMSET_CHK:
 	case BUILT_IN_FREXP:
 	case BUILT_IN_FREXPF:
 	case BUILT_IN_FREXPL:
@@ -1453,6 +1472,25 @@  call_may_clobber_ref_p_1 (gimple call, a
 					   size);
 	    return refs_may_alias_p_1 (&dref, ref, false);
 	  }
+	case BUILT_IN_STRCPY_CHK:
+	case BUILT_IN_STRNCPY_CHK:
+	case BUILT_IN_MEMCPY_CHK:
+	case BUILT_IN_MEMMOVE_CHK:
+	case BUILT_IN_MEMPCPY_CHK:
+	case BUILT_IN_STPCPY_CHK:
+	case BUILT_IN_STRCAT_CHK:
+	case BUILT_IN_STRNCAT_CHK:
+	case BUILT_IN_MEMSET_CHK:
+	  {
+	    ao_ref dref;
+	    tree size = NULL_TREE;
+	    if (gimple_call_num_args (call) == 4)
+	      size = gimple_call_arg (call, 2);
+	    ao_ref_init_from_ptr_and_size (&dref,
+					   gimple_call_arg (call, 0),
+					   size);
+	    return refs_may_alias_p_1 (&dref, ref, false);
+	  }
 	case BUILT_IN_BCOPY:
 	  {
 	    ao_ref dref;
@@ -1697,6 +1735,10 @@  stmt_kills_ref_p_1 (gimple stmt, ao_ref 
 	  case BUILT_IN_MEMPCPY:
 	  case BUILT_IN_MEMMOVE:
 	  case BUILT_IN_MEMSET:
+	  case BUILT_IN_MEMCPY_CHK:
+	  case BUILT_IN_MEMPCPY_CHK:
+	  case BUILT_IN_MEMMOVE_CHK:
+	  case BUILT_IN_MEMSET_CHK:
 	    {
 	      tree dest = gimple_call_arg (stmt, 0);
 	      tree len = gimple_call_arg (stmt, 2);
--- gcc/tree-ssa-structalias.c.jj	2011-06-17 11:02:19.000000000 +0200
+++ gcc/tree-ssa-structalias.c	2011-06-21 14:05:13.000000000 +0200
@@ -1,5 +1,5 @@ 
 /* Tree based points-to analysis
-   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010
+   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
    Contributed by Daniel Berlin <dberlin@dberlin.org>
 
@@ -3982,6 +3982,14 @@  find_func_aliases_for_builtin_call (gimp
       case BUILT_IN_STPNCPY:
       case BUILT_IN_STRCAT:
       case BUILT_IN_STRNCAT:
+      case BUILT_IN_STRCPY_CHK:
+      case BUILT_IN_STRNCPY_CHK:
+      case BUILT_IN_MEMCPY_CHK:
+      case BUILT_IN_MEMMOVE_CHK:
+      case BUILT_IN_MEMPCPY_CHK:
+      case BUILT_IN_STPCPY_CHK:
+      case BUILT_IN_STRCAT_CHK:
+      case BUILT_IN_STRNCAT_CHK:
 	{
 	  tree res = gimple_call_lhs (t);
 	  tree dest = gimple_call_arg (t, (DECL_FUNCTION_CODE (fndecl)
@@ -4011,6 +4019,7 @@  find_func_aliases_for_builtin_call (gimp
 	  return true;
 	}
       case BUILT_IN_MEMSET:
+      case BUILT_IN_MEMSET_CHK:
 	{
 	  tree res = gimple_call_lhs (t);
 	  tree dest = gimple_call_arg (t, 0);
@@ -4627,6 +4636,14 @@  find_func_clobbers (gimple origt)
 	  case BUILT_IN_STPNCPY:
 	  case BUILT_IN_STRCAT:
 	  case BUILT_IN_STRNCAT:
+	  case BUILT_IN_STRCPY_CHK:
+	  case BUILT_IN_STRNCPY_CHK:
+	  case BUILT_IN_MEMCPY_CHK:
+	  case BUILT_IN_MEMMOVE_CHK:
+	  case BUILT_IN_MEMPCPY_CHK:
+	  case BUILT_IN_STPCPY_CHK:
+	  case BUILT_IN_STRCAT_CHK:
+	  case BUILT_IN_STRNCAT_CHK:
 	    {
 	      tree dest = gimple_call_arg (t, (DECL_FUNCTION_CODE (decl)
 					       == BUILT_IN_BCOPY ? 1 : 0));
@@ -4649,6 +4666,7 @@  find_func_clobbers (gimple origt)
 	  /* The following function clobbers memory pointed to by
 	     its argument.  */
 	  case BUILT_IN_MEMSET:
+	  case BUILT_IN_MEMSET_CHK:
 	    {
 	      tree dest = gimple_call_arg (t, 0);
 	      unsigned i;
--- gcc/tree-ssa-dce.c.jj	2011-06-17 11:02:19.000000000 +0200
+++ gcc/tree-ssa-dce.c	2011-06-21 14:15:16.000000000 +0200
@@ -830,7 +830,9 @@  propagate_necessity (struct edge_list *e
 	      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_MEMSET_CHK
 		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_MALLOC
+		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_CALLOC
 		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_FREE
 		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_ALLOCA
 		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_SAVE