Ping! On Fri, 2 Dec 2016 16:46:29 +0100 Andre Vehreschild <ve...@gmx.de> wrote:
> Hi all, > > attached patch adds a call to sync_all after an ALLOCATE allocating a coarray. > This is to adhere to standard wanting: > > ..., execution of the segment (11.6.2) following the statement is delayed > until all other active images in the current team have executed the same > statement the same number of times in this team. > > This, esp. the "statement", means that assigning the SOURCE= is to come before > the sync all, which means we have to do it explicitly after that assignment. > Or the other way around the sync all can be done in library caf_register(). > > Bootstraps and regtests ok on x86_64-linux/F23. Ok for trunk? > > Regards, > Andre -- Andre Vehreschild * Email: vehre ad gmx dot de
gcc/fortran/ChangeLog: 2016-12-02 Andre Vehreschild <ve...@gcc.gnu.org> PR fortran/78505 * trans-stmt.c (gfc_trans_allocate): Add sync all after the execution of the whole allocate-statement to adhere to the standard. gcc/testsuite/ChangeLog: 2016-12-02 Andre Vehreschild <ve...@gcc.gnu.org> PR fortran/78505 * gfortran.dg/coarray_alloc_with_implicit_sync_1.f90: New test.
diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c index 514db28..2219bcc 100644 --- a/gcc/fortran/trans-stmt.c +++ b/gcc/fortran/trans-stmt.c @@ -5506,7 +5506,7 @@ gfc_trans_allocate (gfc_code * code) stmtblock_t block; stmtblock_t post; tree nelems; - bool upoly_expr, tmp_expr3_len_flag = false, al_len_needs_set; + bool upoly_expr, tmp_expr3_len_flag = false, al_len_needs_set, is_coarray ; gfc_symtree *newsym = NULL; if (!code->ext.alloc.list) @@ -5516,6 +5516,7 @@ gfc_trans_allocate (gfc_code * code) expr3 = expr3_vptr = expr3_len = expr3_esize = NULL_TREE; label_errmsg = label_finish = errmsg = errlen = NULL_TREE; e3_is = E3_UNSET; + is_coarray = false; gfc_init_block (&block); gfc_init_block (&post); @@ -5555,8 +5556,9 @@ gfc_trans_allocate (gfc_code * code) expression. */ if (code->expr3) { - bool vtab_needed = false, temp_var_needed = false, - is_coarray = gfc_is_coarray (code->expr3); + bool vtab_needed = false, temp_var_needed = false; + + is_coarray = gfc_is_coarray (code->expr3); /* Figure whether we need the vtab from expr3. */ for (al = code->ext.alloc.list; !vtab_needed && al != NULL; @@ -6093,6 +6095,9 @@ gfc_trans_allocate (gfc_code * code) tree caf_decl, token; gfc_se caf_se; + /* Set flag, to add synchronize after the allocate. */ + is_coarray = true; + gfc_init_se (&caf_se, NULL); caf_decl = gfc_get_tree_for_caf_expr (expr); @@ -6114,6 +6119,11 @@ gfc_trans_allocate (gfc_code * code) } else { + /* Allocating coarrays needs a sync after the allocate executed. + Set the flag to add the sync after all objects are allocated. */ + is_coarray = is_coarray || (gfc_caf_attr (expr).codimension + && flag_coarray == GFC_FCOARRAY_LIB); + if (expr->ts.type == BT_CHARACTER && al_len != NULL_TREE && expr3_len != NULL_TREE) { @@ -6357,6 +6367,15 @@ gfc_trans_allocate (gfc_code * code) gfc_add_modify (&block, se.expr, tmp); } + if (is_coarray && flag_coarray == GFC_FCOARRAY_LIB) + { + /* Add a sync all after the allocation has been executed. */ + tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all, + 3, null_pointer_node, null_pointer_node, + integer_zero_node); + gfc_add_expr_to_block (&post, tmp); + } + gfc_add_block_to_block (&block, &se.post); gfc_add_block_to_block (&block, &post); diff --git a/gcc/testsuite/gfortran.dg/coarray_alloc_with_implicit_sync_1.f90 b/gcc/testsuite/gfortran.dg/coarray_alloc_with_implicit_sync_1.f90 new file mode 100644 index 0000000..1dbbcb7 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/coarray_alloc_with_implicit_sync_1.f90 @@ -0,0 +1,10 @@ +! { dg-do compile } +! { dg-options "-fdump-tree-original -fcoarray=lib" } +! Check that allocating a coarray adds an implicit sync all. + + implicit none + integer, allocatable :: f(:)[:] + allocate( f(20)[*], source = 1 ) +end + +! { dg-final { scan-tree-dump-times "_gfortran_caf_sync_all \\(" 1 "original" } }