This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug middle-end/14192] Restrict pointers don't help
- From: "joseph at codesourcery dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 23 Jan 2005 20:59:42 -0000
- Subject: [Bug middle-end/14192] Restrict pointers don't help
- References: <20040218135530.14192.hoogerbrugge@hotmail.com>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- 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