commit 75c93d3085116748115c8f69ad5ad58f4ad9369c Author: Alessandro Fanfarillo Date: Sun Dec 6 18:50:51 2015 +0100 Introducing __sync_synchronize() after image control statements, send and get diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index ba176a1..b450fae 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,13 @@ +2015-12-06 Alessandro Fanfarillo + + * trans.c (gfc_allocate_using_lib,gfc_deallocate_with_status): + Introducing __sync_synchronize() after image control statements. + * trans-stmt.c (gfc_trans_sync,gfc_trans_event_post_wait, + gfc_trans_lock_unlock): Ditto. + * trans-intrinsic.c (gfc_conv_intrinsic_caf_get, + conv_caf_send): Introducing __sync_synchronize() after send, + get and sendget. + 2015-12-05 Paul Thomas PR fortran/68676 diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c index 21efe44..07795ca 100644 --- a/gcc/fortran/trans-intrinsic.c +++ b/gcc/fortran/trans-intrinsic.c @@ -1222,6 +1222,12 @@ gfc_conv_intrinsic_caf_get (gfc_se *se, gfc_expr *expr, tree lhs, tree lhs_kind, se->expr = res_var; if (array_expr->ts.type == BT_CHARACTER) se->string_length = argse.string_length; + + /* It guarantees memory consistency within the same segment */ + tmp = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE); + tmp = build_call_expr_loc (input_location, tmp, 0); + gfc_add_expr_to_block (&se->pre, tmp); + } @@ -1390,6 +1396,12 @@ conv_caf_send (gfc_code *code) { gfc_add_expr_to_block (&block, tmp); gfc_add_block_to_block (&block, &lhs_se.post); gfc_add_block_to_block (&block, &rhs_se.post); + + /* It guarantees memory consistency within the same segment */ + tmp = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE); + tmp = build_call_expr_loc (input_location, tmp, 0); + gfc_add_expr_to_block (&block, tmp); + return gfc_finish_block (&block); } diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c index 3df483a..b1de0f5 100644 --- a/gcc/fortran/trans-stmt.c +++ b/gcc/fortran/trans-stmt.c @@ -818,6 +818,11 @@ gfc_trans_lock_unlock (gfc_code *code, gfc_exec_op op) errmsg, errmsg_len); gfc_add_expr_to_block (&se.pre, tmp); + /* It guarantees memory consistency within the same segment */ + tmp = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE); + tmp = build_call_expr_loc (input_location, tmp, 0); + gfc_add_expr_to_block (&se.pre, tmp); + if (stat2 != NULL_TREE) gfc_add_modify (&se.pre, stat2, fold_convert (TREE_TYPE (stat2), stat)); @@ -995,6 +1000,11 @@ gfc_trans_event_post_wait (gfc_code *code, gfc_exec_op op) errmsg, errmsg_len); gfc_add_expr_to_block (&se.pre, tmp); + /* It guarantees memory consistency within the same segment */ + tmp = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE); + tmp = build_call_expr_loc (input_location, tmp, 0); + gfc_add_expr_to_block (&se.pre, tmp); + if (stat2 != NULL_TREE) gfc_add_modify (&se.pre, stat2, fold_convert (TREE_TYPE (stat2), stat)); @@ -1080,6 +1090,15 @@ gfc_trans_sync (gfc_code *code, gfc_exec_op type) fold_convert (integer_type_node, images)); } + /* Per F2008, 8.5.1, a SYNC MEMORY is implied by calling the + image control statements SYNC IMAGES and SYNC ALL. */ + if (flag_coarray == GFC_FCOARRAY_LIB) + { + tmp = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE); + tmp = build_call_expr_loc (input_location, tmp, 0); + gfc_add_expr_to_block (&se.pre, tmp); + } + if (flag_coarray != GFC_FCOARRAY_LIB) { /* Set STAT to zero. */ diff --git a/gcc/fortran/trans.c b/gcc/fortran/trans.c index 001db41..e7803bd 100644 --- a/gcc/fortran/trans.c +++ b/gcc/fortran/trans.c @@ -746,6 +746,11 @@ gfc_allocate_using_lib (stmtblock_t * block, tree pointer, tree size, TREE_TYPE (pointer), pointer, fold_convert ( TREE_TYPE (pointer), tmp)); gfc_add_expr_to_block (block, tmp); + + /* It guarantees memory consistency within the same segment */ + tmp = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE); + tmp = build_call_expr_loc (input_location, tmp, 0); + gfc_add_expr_to_block (block, tmp); } @@ -1356,6 +1361,11 @@ gfc_deallocate_with_status (tree pointer, tree status, tree errmsg, token, pstat, errmsg, errlen); gfc_add_expr_to_block (&non_null, tmp); + /* It guarantees memory consistency within the same segment */ + tmp = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE); + tmp = build_call_expr_loc (input_location, tmp, 0); + gfc_add_expr_to_block (&non_null, tmp); + if (status != NULL_TREE) { tree stat = build_fold_indirect_ref_loc (input_location, status);