Hi, On Thu, 5 May 2005, Daniel Berlin wrote:
> You can do it, but apparently restrict isn't as simple as "a and b are > both restrict pointers and therefore can never alias", because that's > not the actual definition of restrict. It says stuff about pointers > "based on" restricted objects, etc. > > Joseph Myers has shown some very weird but legal things you can do with > restrict that make it all but pointless to try to handle, at least for > the non function argument case. Disagreement here. Some of Josephs weird examples were things like: void f(int* restrict a, int * restrict b) { for (i=0; i < N; i+=2) a[i] = 2*b[i]; } int array[N]; f (&array[0], &array[1]); I.e. interleaving the pointers in a way that they both point into the same object. This is not forbidden by restrict, but it also poses no problem. The two restrict pointers still may not actually point to the same memory objects (individual array elements here), so the compiler can still trivially apply the "two restrict pointers don't alias" rule. Then there is the problem of "based on". This allows a non-restrict pointer to sometimes alias a restrict pointer. One could ignore this rule at first, for ease of implementation, and say that a unrestricted pointer can alias everything again. restricted pointers themself can only be based on other restricted pointers under very narrow circumstances, which effectively prevents them again to be aliased at their points of dereference. User actually using restrict in their programs will most probably use restrict for each pointer possible, so just handling that two restrict pointers can't alias alone would probably catch 90% of all cases. (I've actually had one user who was very confused that the vectorizer didn't do anything on his very simple two-line function, although he made all three pointer arguments be restricted). As you said the most important would probably be to handle restrict pointers in function arguments. I would add to that also those pointers which are not used in any RHS of any statement (except for being dereferenced of course). This would ensure that no other pointer is based on them. And it would allow users to write code like: void f(int* a, int *b, int n) { if (a > b+n || b > a+n) { // arrays don't overlap int * restrict ar = a; int * restrict br = b; /* Make this nonaliasing known to the compiler */ for (int i = 0; i < n; i++) ar[i] += br[i]; } else { /* They overlap, can't optimize as much */ for (int i = 0; i < n; i++) a[i] += b[i]; } } Ciao, Michael.