On Mon, 9 Nov 2020, Jan Hubicka wrote:

> > > 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
> 
> I see, missed that! 
> 
> > 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.
> 
> Yep, i am not arguing for eliminating special case of memcpy (because we
> have the additional info that it only copies pointers from *src to
> *dest).
> 
> However I find current definition of EAF_NOESCAPE bit hard to handle in
> modref, since naturally it is quite reliable to track all uses of ssa
> name that correspond to parameters, but it is harder to track where
> values read from pointed-to memory can eventually go.

Yeah - also the fnspec of memcpy _is_ wrong at the moment ...

> What I do is to walk all uses of SSA_NAME that correspond to parameter
> and try to unerstand it.  If it is one of
>  1) memory load via derefence of name
>  2) memory store where name is base of LHS
>  3) memory store where name is rhs
>  4) name is passed as a value to function 
>  5) dereferenced value from name is passed to funtion
>  6) used as value normal gimple expression
>  7) used in return (as RHS or base of memory dereference address)
>  8) it is used only in reference but not as base (as array index or so)
> 
> Then I merge in (and) flags I determine as follow:
> 
> For 1) clear EAF_USED and recurse to LHS name. Based on its flags I
> decide on:
>   - EAF_DIRECT (if LHS has EAF_UNUSED),
>   - EAF_NOCLOBBER (if LHS has EAF_NOCLOBBER)
>   - EAF_NOESCAPE (if LHS has EAF_NOESCAPE). 
> 
> For 2) I clear EAF_NOCLOBBER and EAF_UNUSED flag
> 
> For 3) I give up (clear all flags) since I would need to track where the
> memory is going.
> 
> For 4) I determine flag of function parameter
> 
> For 5) I need to do same handling as 1) where flag of "loaded value" is
> flag of the function
> 
> For 6) I determine flags of LHS and merge them in

guess you could track a SSA lattice "based on parameter N" which
would need to be a mask (thus only track up to 32 parameters?)

> For 7) I clear NOESCAPE if rhs is name itself
> and UNUSED + NOESCAPE if rhs is derefernece from name.
> 
> For 8) I do nothing.  Here the names are non-pointers that I track
> because of earlier dereference.
> 
> 
> 
> So I think 7) can be relaxed.  Main problem is hoever that we often see 1)
> and then 3) or 7) on LHS that makes us punt very often.
> 
> The fact that pointer directly does not escape but pointed to memory can
> seems still very useful since one does not need to add *ptr to points-to
> sets. But I will try relaxing 7).
> 
> If we allow values escaping to other parameters and itself, I think I
> can relax 3) if base of the store is default def of PARM_DECL.

I think the important part is to get things correct.  Maybe it's worth
to add write/read flags where the argument _does_ escape in case the
function itself is otherwise pure/const.  For PTA that doesn't make
a difference (and fnspec was all about PTA ...) but for alias-analysis
it does.

> > 
> > 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.
> 
> May be nice and also describe carefully that NOESCAPE and NOCLOBBER also
> reffers to indirect references.  Current description
> "Nonzero if the argument does not escape."
> reads to me that it is about ptr itself, not about *ptr and also it does
> not speak of the escaping to return value etc.

Well, if 'ptr' escapes then obvoiously all memory reachable from 'ptr'
escapes - escaping is always transitive.

And as escaping is in the context of the caller sth escaping to the
caller itself (via return) can hardly be considered escaping (again
this was designed for PTA ...).

I guess it makes sense to be able to separate escaping from the rest.

Richard.

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

Reply via email to