https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120972
--- Comment #4 from Feng Xue <fxue at os dot amperecomputing.com> ---
(In reply to Richard Biener from comment #3)
> (In reply to Feng Xue from comment #2)
> > (In reply to Richard Biener from comment #1)
> > > Yes, it's not possible to implement the standards restrict qualification
> > > constraints reliably for pointers not in the outermost scope of a function
> > > and after the compiler was allowed to do CSE or other code transforms.
> > >
> > > For simplicity only function parameters (and select "global" cases)
> > > are handled in the implementation which resides in points-to analysis.
> > >
> > > In principle 'restrict' should be handled in the C/C++ language frontends
> > > instead.
> >
> > Maybe, I caught your point, w/o front-end scope information, we do not know
> > the effective lifetime of "__restrict__" pointer merely from def/use chain
> > in the gimple. An example:
> >
> > void foo (int *p)
> > {
> > int *a_escaped;
> >
> > {
> > int * __restrict__ a = ...;
> >
> > /* no alias between "a" and "p" */
> > *a = ...;
> >
> > /* Make "a" escaped from block scope */
> > a_escaped = a + offset;
> > }
> >
> > /* By source-level declaration syntax, "a_escaped" and "p" may be
> > aliased. But in the gimple, we do not know usage of "a_escaped" does not
> > belongs to lifetime constrainted by "__restrict__", and could lead to an
> > incorrect conclusion that "a_escaped" and "p" are alias-free. */
> >
> > *a_escaped = ...;
> >
> > ...
> > }
> >
> > But for the 2nd case, all pointers are defined in the outermost scope of
> > function. How about an enhancement? Besides parameters, we could also mark
> > all __restrict__ pointers declared in the outermost scope, and ignore others
> > in any enclosed scopes, as you said, probably this could be done that at the
> > front-end stage.
>
> Outermost scope would work as long as there is no inlining or optimization
> happening before since we happily elide scopes and "globalize" variables.
inline void goo()
{
int * __restrict__ p;
...
}
void foo()
{
goo();
}
->
void foo()
{
// goo();
{
// Would DECL_CONTEXT(p) become "foo" from "goo" after inline?
int * __restrict__ p;
...
}
}
I do not deep dive into related code how DECL_CONTEXT() varies with inline or
optimization. If this is quite compilicated to track, my thought is to
introduce another DECL_CONTEXT_RAW() or similar stuff, that is set to its
original function, when analyzing alias for a restrict var, we would also check
if DECL_CONTEXT and DECL_CONTEXT_RAW is matched or not.
> That is, it's quite difficult to prove handling user(!) variables in the
> outermost scope is correct. You'd check that DECL_CONTEXT of a variable
> is the same as DECL_INITIAL (cfun->decl), but I'm not sure this will
> never "break". Depending on frontends there might or might not be an
> additional "outer" scope from DECL_INITIAL IIRC.
>
> Does handling variables in the outermost scope matter in practice?
In reality, we encounter an application with a hot loop containing lots of
memory accesses, whose pointers are defined as __restrict__ variables
initialized in the outermost scope, and those fake aliasing relations prevent
vectorization.