Hello all,
I seek a tree attribute which tells that a "pointer" (in the
C/middle-end sense) does not alias with any other variable in the
translation unit (i.e. like "restrict"), but on the other hand, it
should prevent code movements and value assumptions across (impure)
function calls - as it is done for non-restrict pointers.
The primary usage are Fortran's coarrays. Those variables exists on all
processes ("images") and can be accessed remotely using one-side
communication semantics. As coarrays are also used in hot loops, I would
like avoid using a non-restricted pointer. A similar issue exists for
variables with the ASYNCHRONOUS attribute.
Middle-end question: How to handle this best with regards to the middle end?
C/C++ question: As one can also with C/C++ use asynchronous I/O,
asynchronous communication via libraries as MPI, or single-sided
communication via POSIX threads - or with C++0x's std:thread: How do you
handle it? Just by avoiding "restrict"? Or do you have a solution, which
can also be applied for Fortran? I'm sure that a "restrict + hope &
pray" solution won't work reliably and thus is not used ;-)
Fortran question: Do my requirements make sense? That is: No code
movements for any variable which is a coarray or has the asynchronous
attribute in the scoping unit. Plus, no assumption of the value after
any call to any impure function? Can something be relaxed or has
anything to be tightened?
ASYNCHRONOUS is defined in the Fortran standard (e.g 2008, Section
5.3.4) and extended to explicitly allow for asynchronous user functions
in Technical Report 29113. The latter functionality will be used in the
Message Passing Interface (MPI) specification 3.0. Like VOLATILE, the
asynchronous attribute might be restricted to a block (in C: { ... }).
Coarrays are defined in the Fortran 2008 standard. (For semantics of
interest, see especially Section 8.5 and, in particular, Subsection 8.5.2.)
The Fortran 2008 standard is available at
ftp://ftp.nag.co.uk/sc22wg5/N1801-N1850/N1830.pdf and the PDTR 29113 at
ftp://ftp.nag.co.uk/sc22wg5/N1851-N1900/N1866.pdf
Example 1: Asynchronous I/O; in this example using build-in functions,
but asynchronous MPI communication would be another example
integer, ASYNCHRONOUS :: a
...
READ(unit_number,ID=idvar, asynchronous='yes') a
...
WAIT(ID=idvar)
... = a
Here, "= a" may not be moved before WAIT.
Example 2: Coarray with sync. The SYNC is not directly called, but via a
wrapper function to increase the fun factor.
subroutine sub(coarray)
integer :: coarray[*]
coarray = 5
call SYNC_calling_proc()
! coarray is modified remotely
call SYNC_calling_proc()
if (coarray /= 5) ...
end subroutine sub
Here, the "if" may not be removed as the image could have been changed
remotely.
Example 3: Allow other optimizations
subroutine sub(coarray1, coarray2)
integer :: coarray1[*], coarray2[*]
coarray1 = 5
coarray2 = 7
if (coarray1 /= 5)
Here, the "if" can be removed as "coarray1" cannot alias with any other
variable in "sub" as it is not TARGET - and, in particular, it cannot
alias with "coarray2" as neither of them is a pointer.
Tobias