This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFC: Add ADD_RESTRICT tree code


Hi,

On Thu, 13 Oct 2011, Jakub Jelinek wrote:

> I'd sum up my previous mail as noting that restricted pointers are objects,
> so restrict is not property of expressions.  So e.g. I don't think
> we should add ADD_RESTRICT (or, at least, not an ADD_RESTRICT with different
> tag) on every assignment to a restrict pointer object.

Yes, if you meant to include "from non-restrict pointer objects".

> E.g. the restrict tag for cases we don't handle yet currently
> (GLOBAL_RESTRICT/PARM_RESTRICT) could be based on a DECL_UID (for fields
> on FIELD_DECL uid, I think we are not duplicating the fields anywhere,
> for VAR_DECLs based on DECL_ABSTRACT_ORIGIN's DECL_UID?)

field_decls are shared between different variants of types.  That should 
lead only to more conflicts between restrict pointers so would be 
conservatively correct, but something to keep in mind.

> We probably can't use restrict when we have t->p where p is restrict field
> or int *restrict *q with *q directly, it would be PTA's job to find that
> out.

Right.  Your reading of the standard (and after thinking about it some 
more last night I agree that it can be read like you do, but I still think 
it's a omission and loophole in it, and goes against the intent of 
restrict which was about making it easy to disambiguate for the compiler) 
implies some IMHO severe limitations on restrict from addressable objects, 
because we can't be sure anymore if something didn't change one restrict 
pointer behind our back to some other restrict pointer making them based 
on each other and some other object:

struct S {int * restrict p;};
void foo (struct S *s, struct S *t) {
  s->p[0] = 0;
  t->p[0] = 1;  // undefined if s->p == t->p; the caller was responsible 
                // to not do that
}

but:

void foo (struct S *a, struct S *b) {
  *some_global_variable = something_else;
  a->p[0] = 0;
  b->p[0] = 1;  // here a->p == b->p can be well defined, when 
                // a == b, and some_global_variable == &a->p.
                // Due to that the caller is _not_ responsible to not
                // call with a == b.
}

I don't immediately see how we can easily disambiguate s->p[0] from 
t->p[0] while also not disambiguating a->p[0] and b->p[0].


Ciao,
Michael.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]