On Sun, 8 Nov 2020, Jan Hubicka wrote:

> Hi,
> I implemented simple propagation of EAF arguments for ipa-modref (that is not
> hard to do).  My main aim was to detect cases where THIS parameter does not
> escape but is used to read/write pointed to memory.  This is meant to
> avoid poor code produced when we i.e. offline destructors on cold path.
> 
> Unfortunately detecting EAF_NOESCAPE for such parameters breaks.  This is 
> already
> visible on memcpy if we let it to be be handled via its fnspec
> attribute. If I disable special handling in structalias:
>
> diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
> index a4832b75436..2b614913b57 100644
> --- a/gcc/tree-ssa-structalias.c
> +++ b/gcc/tree-ssa-structalias.c
> @@ -4389,7 +4389,6 @@ find_func_aliases_for_builtin_call (struct function 
> *fn, gcall *t)
>        case BUILT_IN_STRCPY:
>        case BUILT_IN_STRNCPY:
>        case BUILT_IN_BCOPY:
> -      case BUILT_IN_MEMCPY:
>        case BUILT_IN_MEMMOVE:
>        case BUILT_IN_MEMPCPY:
>        case BUILT_IN_STPCPY:
> 
> In the following testcase we miss the fact that memcpy may merge i4p PTA
> set to i3p.
> 
> extern void exit (int);
> extern void abort (void);
> int size = 8;
> 
> int main (void)
> {
>   int i3 = -1, i4 = 55;
>   int *i3p = &i3;
>   int *i4p = &i4;
> 
>   memcpy(&i3p, &i4p, size);
>   if (i3p != i4p)
>     abort ();
>   exit (0);
> }
> 
> This seems to be documented for some degree:
> 
>         /* Add *tem = nonlocal, do not add *tem = callused as
>            EAF_NOESCAPE parameters do not escape to other parameters
>            and all other uses appear in NONLOCAL as well.  */
> 
> But it also means that some of our FNSPECs are wrong now.  I wonder if we can
> split this porperty to two different flags like EAF_NOEASCAPE and
> EAF_INDIRECT_NOESCAPE?

Note that EAF_NOESCAPE allows "escaping" to the return value (see
handle_rhs_call).  I guess for simplicity we could allow escaping
of not escaped but USED params to other written to params.  I think
we also don't handle "escaping" of a parameter indirectly to itself, thus

int i;
int *p = &i;
int **q = &p;
foo (&q);
if (*q != i)
  abort ();

and

foo (int ***p)
{
  *p = **p;
} 

or so with foos param EAF_NOESCAPE (but not EAF_DIRECT).

Splitting up EAF_NOESCAPE makes it quite difficult to understand.
Arguably explicit handling of memcpy and friends _does_ pay off
for points-to analysis since I'd say modelling all possible and useful
things in fnspec would make it a monster ... you'd basically want
to have a way to specify additional constraints in the fnspec itself,
like *1 = *2, but then also distinguish points-to effects from
may-alias ones.

I wonder if we should teach the GIMPLE FE to parse 'fn spec'
so we can write unit tests for the attribute ... or maybe simply
add this to the __GIMPLE spec string.

> Auto-detecting EAF_INDIRECT_NOESCAPE seems bit harder at least assuming
> that any read can actually load few bits of pointer possibly written
> there beause if simple member functions accesses values pointer by THIS
> and return them we lose a track if the returned value is an escape point
> I would say.
> 
> The difference in constraints are:
> 
> --- good/a.c.035t.ealias      2020-11-08 13:34:04.397499515 +0100
> +++ a.c.035t.ealias   2020-11-08 13:39:15.483438469 +0100
> @@ -106,7 +106,15 @@
>  size = NONLOCAL
>  size.0_1 = size
>  _2 = size.0_1
> -i3p = i4p
> +callarg(18) = &i3p
> +callarg(18) = callarg(18) + UNKNOWN
> +CALLUSED(16) = callarg(18)
> +CALLCLOBBERED(17) = callarg(18)
> +*callarg(18) = NONLOCAL
> +callarg(19) = &i4p
> +callarg(19) = callarg(19) + UNKNOWN
> +CALLUSED(16) = callarg(19)
> +ESCAPED = _2
>  i3p.1_3 = i3p
>  i4p.2_4 = i4p
>  ESCAPED = &NULL
> 
> ...
> 
>  Call clobber information
>  
> -ESCAPED, points-to NULL, points-to vars: { }
> +ESCAPED, points-to non-local, points-to NULL, points-to vars: { }
>  
>  Flow-insensitive points-to information
>  
> -i3p.1_3, points-to NULL, points-to vars: { D.1947 D.1948 }
> +i3p.1_3, points-to non-local, points-to escaped, points-to NULL, points-to 
> vars: { D.1947 }
>  i4p.2_4, points-to NULL, points-to vars: { D.1948 }
>  
>  main ()
> 
> Honza
> 

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

Reply via email to