Add support for copy specifier to fnspec

Richard Biener rguenther@suse.de
Thu Nov 12 13:38:23 GMT 2020


On Thu, 12 Nov 2020, Jan Hubicka wrote:

> Hi,
> here is updated patch that replaces 'C' by '1'...'9' so we still have
> place to specify size.
> As discussed on IRC, this seems better alternative.
> 
> Bootstrapped/regtested x86_64-linux, OK?

OK.

Richard.

> Honza
> 
> gcc/ChangeLog:
> 
> 2020-11-12  Jan Hubicka  <hubicka@ucw.cz>
> 
> 	* attr-fnspec.h: Update topleve comment.
> 	(attr_fnspec::arg_direct_p): Accept 1...9.
> 	(attr_fnspec::arg_maybe_written_p): Reject 1...9.
> 	(attr_fnspec::arg_copied_to_arg_p): New member function.
> 	* builtins.c (builtin_fnspec): Update fnspec of block copy.
> 	* tree-ssa-alias.c (attr_fnspec::verify): Update.
> 
> diff --git a/gcc/attr-fnspec.h b/gcc/attr-fnspec.h
> index 28135328437..766414a2520 100644
> --- a/gcc/attr-fnspec.h
> +++ b/gcc/attr-fnspec.h
> @@ -41,6 +41,9 @@
>  		written and does not escape
>       'w' or 'W' specifies that the memory pointed to by the parameter does not
>  		escape
> +     '1'....'9' specifies that the memory pointed to by the parameter is
> +		copied to memory pointed to by different parameter
> +		(as in memcpy).
>       '.'	specifies that nothing is known.
>     The uppercase letter in addition specifies that the memory pointed to
>     by the parameter is not dereferenced.  For 'r' only read applies
> @@ -51,8 +54,8 @@
>       ' '        nothing is known
>       't'	the size of value written/read corresponds to the size of
>  		of the pointed-to type of the argument type
> -     '1'...'9'  the size of value written/read is given by the specified
> -		argument
> +     '1'...'9'  specifies the size of value written/read is given by the
> +		specified argument
>   */
>  
>  #ifndef ATTR_FNSPEC_H
> @@ -122,7 +125,8 @@ public:
>    {
>      unsigned int idx = arg_idx (i);
>      gcc_checking_assert (arg_specified_p (i));
> -    return str[idx] == 'R' || str[idx] == 'O' || str[idx] == 'W';
> +    return str[idx] == 'R' || str[idx] == 'O'
> +	   || str[idx] == 'W' || (str[idx] >= '1' && str[idx] <= '9');
>    }
>  
>    /* True if argument is used.  */
> @@ -161,6 +165,7 @@ public:
>      unsigned int idx = arg_idx (i);
>      gcc_checking_assert (arg_specified_p (i));
>      return str[idx] != 'r' && str[idx] != 'R'
> +	   && (str[idx] < '1' || str[idx] > '9')
>  	   && str[idx] != 'x' && str[idx] != 'X';
>    }
>  
> @@ -190,6 +195,21 @@ public:
>      return str[idx + 1] == 't';
>    }
>  
> +  /* Return true if memory pointer to by argument is copied to a memory
> +     pointed to by a different argument (as in memcpy).
> +     In this case set ARG.  */
> +  bool
> +  arg_copied_to_arg_p (unsigned int i, unsigned int *arg)
> +  {
> +    unsigned int idx = arg_idx (i);
> +    gcc_checking_assert (arg_specified_p (i));
> +    if (str[idx] < '1' || str[idx] > '9')
> +      return false;
> +    *arg = str[idx] - '1';
> +    return true;
> +  }
> +
> +
>    /* True if the argument does not escape.  */
>    bool
>    arg_noescape_p (unsigned int i)
> @@ -230,7 +250,7 @@ public:
>      return str[1] != 'c' && str[1] != 'C';
>    }
>  
> -  /* Return true if all memory written by the function 
> +  /* Return true if all memory written by the function
>       is specified by fnspec.  */
>    bool
>    global_memory_written_p ()
> diff --git a/gcc/builtins.c b/gcc/builtins.c
> index da25343beb1..4ec1766cffd 100644
> --- a/gcc/builtins.c
> +++ b/gcc/builtins.c
> @@ -12939,16 +12939,16 @@ builtin_fnspec (tree callee)
>  	 argument.  */
>        case BUILT_IN_STRCAT:
>        case BUILT_IN_STRCAT_CHK:
> -	return "1cW R ";
> +	return "1cW 1 ";
>        case BUILT_IN_STRNCAT:
>        case BUILT_IN_STRNCAT_CHK:
> -	return "1cW R3";
> +	return "1cW 13";
>        case BUILT_IN_STRCPY:
>        case BUILT_IN_STRCPY_CHK:
> -	return "1cO R ";
> +	return "1cO 1 ";
>        case BUILT_IN_STPCPY:
>        case BUILT_IN_STPCPY_CHK:
> -	return ".cO R ";
> +	return ".cO 1 ";
>        case BUILT_IN_STRNCPY:
>        case BUILT_IN_MEMCPY:
>        case BUILT_IN_MEMMOVE:
> @@ -12957,15 +12957,15 @@ builtin_fnspec (tree callee)
>        case BUILT_IN_STRNCPY_CHK:
>        case BUILT_IN_MEMCPY_CHK:
>        case BUILT_IN_MEMMOVE_CHK:
> -	return "1cO3R3";
> +	return "1cO313";
>        case BUILT_IN_MEMPCPY:
>        case BUILT_IN_MEMPCPY_CHK:
> -	return ".cO3R3";
> +	return ".cO313";
>        case BUILT_IN_STPNCPY:
>        case BUILT_IN_STPNCPY_CHK:
> -	return ".cO3R3";
> +	return ".cO313";
>        case BUILT_IN_BCOPY:
> -	return ".cR3O3";
> +	return ".c23O3";
>        case BUILT_IN_BZERO:
>  	return ".cO2";
>        case BUILT_IN_MEMCMP:
> diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
> index e64011d04df..b1e8e5b5352 100644
> --- a/gcc/tree-ssa-alias.c
> +++ b/gcc/tree-ssa-alias.c
> @@ -3797,6 +3797,8 @@ attr_fnspec::verify ()
>        default:
>  	err = true;
>      }
> +  if (err)
> +    internal_error ("invalid fn spec attribute \"%s\"", str);
>  
>    /* Now check all parameters.  */
>    for (unsigned int i = 0; arg_specified_p (i); i++)
> @@ -3813,21 +3815,28 @@ attr_fnspec::verify ()
>  	  case 'w':
>  	  case 'W':
>  	  case '.':
> +	    if ((str[idx + 1] >= '1' && str[idx + 1] <= '9')
> +		|| str[idx + 1] == 't')
> +	      {
> +		if (str[idx] != 'r' && str[idx] != 'R'
> +		    && str[idx] != 'w' && str[idx] != 'W'
> +		    && str[idx] != 'o' && str[idx] != 'O')
> +		  err = true;
> +		if (str[idx] != 't'
> +		    /* Size specified is scalar, so it should be described
> +		       by ". " if specified at all.  */
> +		    && (arg_specified_p (str[idx + 1] - '1')
> +			&& str[arg_idx (str[idx + 1] - '1')] != '.'))
> +		  err = true;
> +	      }
> +	    else if (str[idx + 1] != ' ')
> +	      err = true;
>  	    break;
>  	  default:
> -	    err = true;
> +	    if (str[idx] < '1' || str[idx] > '9')
> +	      err = true;
>  	}
> -      if ((str[idx + 1] >= '1' && str[idx + 1] <= '9')
> -	  || str[idx + 1] == 't')
> -	{
> -	  if (str[idx] != 'r' && str[idx] != 'R'
> -	      && str[idx] != 'w' && str[idx] != 'W'
> -	      && str[idx] != 'o' && str[idx] != 'O')
> -	    err = true;
> -	}
> -      else if (str[idx + 1] != ' ')
> -	err = true;
> +      if (err)
> +	internal_error ("invalid fn spec attribute \"%s\" arg %i", str, i);
>      }
> -  if (err)
> -    internal_error ("invalid fn spec attribute \"%s\"", str);
>  }
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imend


More information about the Gcc-patches mailing list