The following applies to -fcoarray=lib; for -fcoarray=single there
should be no change.
The coarray communication library needs to know about the coarrays
even before the function containing them has been invoked. Thus, the
coarrays (of all translation units) need to be registered at start up.
This patch handles this by creating a _caf_init function with
constructor attribute, which is nested in the the parent's procedure
if the latter contains local nonallocatable (and thus: static/SAVE)
coarrays variables.
At the same time, all (nonallocatable) coarrays have been turned into
pointers - to allow the communication library to allocate the memory.
This allows optimizations, e.g., by allocating in memory which is
available for all images on the same node (cf. MPI_Alloc_mem).
Additionally, a "token" is saved with the coarray, which allows the
coarray library to identify the coarray. In a simple implementation,
it could simply use the base_addr of the coarray or enumerate them
through.
Example: The small example program
------------- < test.f90 >-----------------
program caf_program
integer :: a[*] = 7
a = 8
end program caf_program
------------- </ test.f90 >-----------------
is turned into the following tree (-fdump-tree-original)
------------- < test.f90.003t.original >-----------------
_caf_init.1 ()
{
a = (integer(kind=4) * restrict) _gfortran_caf_register (4, 0,
&caf_token.0, 0B, 0B, 0);
*a = 7;
}
caf_program ()
{
static void * caf_token.0;
static integer(kind=4) * restrict a;
void _caf_init.1 (void);
(integer(kind=4)) *a = 8;
}
main (integer(kind=4) argc, character(kind=1) * * argv)
{
static integer(kind=4) options.2[8] = {68, 1023, 0, 0, 1, 1, 0, 1};
_gfortran_caf_init (&argc, &argv, &_gfortran_caf_this_image,
&_gfortran_caf_num_images);
_gfortran_set_args (argc, argv);
_gfortran_set_options (8, &options.2[0]);
_gfortran_caf_sync_all (0B, 0);
caf_program ();
__sync_synchronize ();
_gfortran_caf_finalize ();
return 0;
}
------------- </ test.f90.003t.original >-----------------
Note: By construction, _gfortran_caf_register is called before
_gfortran_caf_init; thus, the MPI library will be initialized by the
first _gfortran_caf_register call, unless the program does not have
any nonallocatable coarrays.
No test cases, but the ones in gfortran.dg/coarray/ should already
test this functionality.
To be done in later patches:
- Coarrays declared in modules (module variables)
- Allocatable coarrays
Note: As constructors are never optimized away [unless they are
pure/const], static coarrays and also uncalled functions containing
static coarrays will not be optimized away. (Cf. PRs middle-end/49106
and middle-end/49108.)
Bootstrapped and regtested on x86-64-linux.
OK for the trunk?
Tobias