------- Additional Comments From joseph at codesourcery dot com 2005-01-23 20:59 ------- Subject: Re: Restrict pointers don't help
On Sun, 23 Jan 2005, steven at gcc dot gnu dot org wrote: > Zack, Joseph, could one of you comment on Jan's interpretation of > the semantics of restrict? 6.7.3.1 Formal definition of restrict [#1] Let D be a declaration of an ordinary identifier that provides a means of designating an object P as a restrict- qualified pointer to type T. [#2] If D appears inside a block and does not have storage class extern, let B denote the block. If D appears in the list of parameter declarations of a function definition, let B denote the associated block. Otherwise, let B denote the block of main (or the block of whatever function is called at program startup in a freestanding environment). I believe this much is straightforward. [#3] In what follows, a pointer expression E is said to be based on object P if (at some sequence point in the execution of B prior to the evaluation of E) modifying P to point to a copy of the array object into which it formerly pointed would change the value of E.117) Note that ``based'' is defined only for expressions with pointer types. Although things may not be clear in some cases where the representation of pointers is inspected bitwise, in plausibly optimizable cases I think the meaning of "based on" is OK. [#4] During each execution of B, let L be any lvalue that has &L based on P. If L is used to access the value of the object X that it designates, and X is also modified (by any means), then the following requirements apply: T shall not be const-qualified. Every other lvalue used to access the value of X shall also have its address based on P. Every So if something is accessed through a restricted pointer, and it is modified, all accesses are based on that pointer: all pointer dereferences not based on that pointer are independent of accesses to that which is modified. (It is still valid to have two restricted pointers to the same array of char, one used to modify the odd numbered bytes and one to modify the even numbered bytes: but a byte accessed through one pointer and modified can't be accessed through any pointer not based on the restricted pointer, whether or not that other pointer is restricted.) access that modifies X shall be considered also to modify P, for the purposes of this subclause. If P is assigned the For example, given int *restrict *restrict p; int *restrict *restrict q; with **p modified, *p is deemed modified, so even if q == p you can't then modify **q as an alias to **p that goes through the same restricted pointer object *p. But given int *restrict *p; int *restrict *q; (without the second level of "restrict") it is possible that p == q and so you can modify both **p and **q, as both those expressions involve the same restricted pointer object *p (where &*p == &*q == p == q). value of a pointer expression E that is based on another restricted pointer object P2, associated with block B2, then either the execution of B2 shall begin before the execution of B, or the execution of B2 shall end prior to the assignment. If these requirements are not met, then the behavior is undefined. The aliasing information provided by "restrict" only applies during the execution of the block which contains the declaration providing the "restrict" information. It is possible to copy the restricted pointer to an outside non-restricted pointer, and once the block has finished executing that pointer might freely alias; so that outside pointer, of similar type but lacking "restrict", can't be treated as completely interchangable with the inner pointer although it may have the same value. The restrictions on assignment between restricted pointers reduce the possible ways in which one restricted pointer might dynamically become based on another, but I'm not sure exactly what optimizations this is intended to facilitate. As optimizations don't respect block boundaries, both the fact that "restrict" only provides aliasing information during its block's execution and the possibility of restricted pointers becoming based on other restricted pointers are things to bear in mind. [#5] Here an execution of B means that portion of the execution of the program that would correspond to the lifetime of an object with scalar type and automatic storage duration associated with B. [#6] A translator is free to ignore any or all aliasing implications of uses of restrict. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14192