On Fri, 15 Nov 2024, Jan Hubicka wrote: > Hi, > To implement pointer parameters reproducible and unsequenced I would like to > use fnspec built at callgraph construction time. Pointer parameters are > either > const or non-const. After discussion with Jens, I now understand that memory > pointed to by const pointers can only be read directly and not written to. > While parameters pointed to by normal pointers can be both read and written > but > in a way that duplicated calls have no additional effect. > > I.e. > > int > test1 (int **a) [[reproducible]] > { > return **a; > } > is not valid, since it has double-indirection > > int > test2 (const int *a) [[reproducible]] > { > *(int *)a = 1 > } > > is not valid since the parmaeter is const > > int > test2 (int *a) [[reproducible]] > { > a[1] = a[0]; > } > > is valid. > > To represent the behaviour I need new fnspec specifiers. Our 'R' specifies > that parameter is readonly and only used directly, but also implies noescape > that is not promised by the standard. So I added 'I' (for input). To > represent that parameters is both read and written, but not directly I added > 'U' (for used). > > I am not 100% sure we want to go the fnspec path. It won't handle variadic > calls which I think are in general quite a minority though. > > Bootstrapped/regtested x86_64-linux with the rest of reproducible/unsequenced > code. > Does it seem sane?
fnspec was originally introduced for PTA, but 'I' and 'U' given the pointers escape, do not help PTA, as soon as pointers escape all (most) bets are lost. So where and how exactly do you plan to use those? They seems to be directed at redundancy elimination? Richard. > gcc/ChangeLog: > > * attr-fnspec.h: Add 'I' and 'U' specifiers. > (arg_direct_p): Use it. > * tree-ssa-alias.cc (attr_fnspec::verify): Accept 'I' and 'U'. > > diff --git a/gcc/attr-fnspec.h b/gcc/attr-fnspec.h > index aef4701e6d1..4c332cb6c14 100644 > --- a/gcc/attr-fnspec.h > +++ b/gcc/attr-fnspec.h > @@ -41,6 +41,10 @@ > written and does not escape > 'w' or 'W' specifies that the memory pointed to by the parameter does > not > escape > + 'I' specifies that parameter is only used read directly > + and *may* escape > + 'U' specifies that parameter is only used directly (read > + or written) and *may* escape > '1'....'9' specifies that the memory pointed to by the parameter is > copied to memory pointed to by different parameter > (as in memcpy). > @@ -125,8 +129,9 @@ public: > { > unsigned int idx = arg_idx (i); > gcc_checking_assert (arg_specified_p (i)); > - return str[idx] == 'R' || str[idx] == 'O' > - || str[idx] == 'W' || (str[idx] >= '1' && str[idx] <= '9'); > + return str[idx] == 'R' || str[idx] == 'O' || str[idx] == 'U' > + || str[idx] == 'I' || str[idx] == 'W' > + || (str[idx] >= '1' && str[idx] <= '9'); > } > > /* True if argument is used. */ > @@ -144,7 +149,8 @@ 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'); > + return str[idx] == 'r' || str[idx] == 'R' || str[idx] == 'I' > + || (str[idx] >= '1' && str[idx] <= '9'); > } > > /* True if memory reached by the argument is read (directly or indirectly) > */ > diff --git a/gcc/tree-ssa-alias.cc b/gcc/tree-ssa-alias.cc > index 8ad6a02ddc9..dca3b1cc721 100644 > --- a/gcc/tree-ssa-alias.cc > +++ b/gcc/tree-ssa-alias.cc > @@ -4138,6 +4138,8 @@ attr_fnspec::verify () > case 'O': > case 'w': > case 'W': > + case 'U': > + case 'I': > case '.': > if ((str[idx + 1] >= '1' && str[idx + 1] <= '9') > || str[idx + 1] == 't') > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, Germany; GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)