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  <hubi...@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 <rguent...@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imend

Reply via email to