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