From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1432) id DA7FB3858031; Thu, 17 Dec 2020 19:00:24 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DA7FB3858031 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: =?utf-8?q?Thomas_K=C3=B6nig?= To: gcc-cvs@gcc.gnu.org Subject: [gcc/devel/coarray_native] Use __builtin_atomic_thread_fence and implement SYNC_MEMORY. X-Act-Checkin: gcc X-Git-Author: Thomas Koenig X-Git-Refname: refs/heads/devel/coarray_native X-Git-Oldrev: e3caaf97e6fbe6743d7d9c1a2ba3777eec86b5a1 X-Git-Newrev: d91352b42efcb2a81039ab1911d4fda414143ddb Message-Id: <20201217190024.DA7FB3858031@sourceware.org> Date: Thu, 17 Dec 2020 19:00:24 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 17 Dec 2020 19:00:25 -0000 https://gcc.gnu.org/g:d91352b42efcb2a81039ab1911d4fda414143ddb commit d91352b42efcb2a81039ab1911d4fda414143ddb Author: Thomas Koenig Date: Thu Dec 17 15:58:45 2020 +0100 Use __builtin_atomic_thread_fence and implement SYNC_MEMORY. gcc/fortran/ChangeLog: * trans.c (gfc_trans_memory_barrier_fence): New function. * trans.h (gfc_trans_memory_barrier_fence): Prototype it. * trans-stmt.c (gfc_trans_sync): For shared coarrays, use memory fence. Don't do anything else for SYNC MEMORY. gcc/testsuite/ChangeLog: * gfortran.dg/caf-shared/sync_all_1.f90: New test. * gfortran.dg/caf-shared/sync_memory_1.f90: New test. Diff: --- gcc/fortran/trans-stmt.c | 23 +++++++++++++++++----- gcc/fortran/trans.c | 16 +++++++++++++++ gcc/fortran/trans.h | 1 + .../gfortran.dg/caf-shared/sync_all_1.f90 | 9 +++++++++ .../gfortran.dg/caf-shared/sync_memory_1.f90 | 6 ++++++ 5 files changed, 50 insertions(+), 5 deletions(-) diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c index 368165e69f9..8db4333457c 100644 --- a/gcc/fortran/trans-stmt.c +++ b/gcc/fortran/trans-stmt.c @@ -1307,11 +1307,16 @@ gfc_trans_sync (gfc_code *code, gfc_exec_op type) /* 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 || flag_coarray == GFC_FCOARRAY_SHARED) + if (flag_coarray == GFC_FCOARRAY_LIB) { tmp = gfc_trans_memory_barrier (); gfc_add_expr_to_block (&se.pre, tmp); } + else if (flag_coarray == GFC_FCOARRAY_SHARED) + { + tmp = gfc_trans_memory_barrier_fence (); + gfc_add_expr_to_block (&se.pre, tmp); + } if (flag_coarray != GFC_FCOARRAY_LIB && flag_coarray != GFC_FCOARRAY_SHARED) { @@ -1332,8 +1337,16 @@ gfc_trans_sync (gfc_code *code, gfc_exec_op type) stat = gfc_build_addr_expr (NULL, stat); if(type == EXEC_SYNC_MEMORY) - tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_memory, - 3, stat, errmsg, errmsglen); + { + /* For shared coarrays, there is no need for a memory + fence here because that is emitted anyway below. */ + if (flag_coarray != GFC_FCOARRAY_SHARED) + tmp = build_call_expr_loc (input_location, + gfor_fndecl_caf_sync_memory, + 3, stat, errmsg, errmsglen); + else + tmp = NULL_TREE; + } else { if (flag_coarray == GFC_FCOARRAY_LIB) @@ -1343,8 +1356,8 @@ gfc_trans_sync (gfc_code *code, gfc_exec_op type) tmp = build_call_expr_loc (input_location, gfor_fndecl_cas_sync_all, 1, stat); } - - gfc_add_expr_to_block (&se.pre, tmp); + if (tmp != NULL_TREE) + gfc_add_expr_to_block (&se.pre, tmp); } else { diff --git a/gcc/fortran/trans.c b/gcc/fortran/trans.c index aa30710d51d..fa7fd9d88aa 100644 --- a/gcc/fortran/trans.c +++ b/gcc/fortran/trans.c @@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see #include "trans-types.h" #include "trans-const.h" #include "diagnostic-core.h" +#include "memmodel.h" /* For MEMMODEL_ enums. */ /* Naming convention for backend interface code: @@ -49,6 +50,7 @@ const char gfc_msg_fault[] = N_("Array reference out of bounds"); const char gfc_msg_wrong_return[] = N_("Incorrect function return value"); /* Insert a memory barrier into the code. */ + tree gfc_trans_memory_barrier (void) { @@ -63,6 +65,20 @@ gfc_trans_memory_barrier (void) return tmp; } +/* Same as above, but do it by calling + __builtin_atomic_thread_fence. */ + +tree +gfc_trans_memory_barrier_fence (void) +{ + tree call, mode; + call = builtin_decl_explicit (BUILT_IN_ATOMIC_THREAD_FENCE); + mode = build_int_cst (integer_type_node, MEMMODEL_ACQ_REL); + call = build_call_expr_loc (input_location, call, 1, mode); + return call; +} + + /* Return a location_t suitable for 'tree' for a gfortran locus. The way the parser works in gfortran, loc->lb->location contains only the line number and LOCATION_COLUMN is 0; hence, the column has to be added when generating diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h index eef90f647a0..95e4741906c 100644 --- a/gcc/fortran/trans.h +++ b/gcc/fortran/trans.h @@ -504,6 +504,7 @@ void gfc_conv_expr_type (gfc_se * se, gfc_expr *, tree); /* Insert a memory barrier into the code. */ tree gfc_trans_memory_barrier (void); +tree gfc_trans_memory_barrier_fence (void); /* trans-expr.c */ tree gfc_conv_scalar_to_descriptor (gfc_se *, tree, symbol_attribute); diff --git a/gcc/testsuite/gfortran.dg/caf-shared/sync_all_1.f90 b/gcc/testsuite/gfortran.dg/caf-shared/sync_all_1.f90 new file mode 100644 index 00000000000..95343f54818 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/caf-shared/sync_all_1.f90 @@ -0,0 +1,9 @@ +! { dg-do compile } +! { dg-options "-fdump-tree-original" } +program main + sync all +end program main +! { dg-final { scan-tree-dump-times "__atomic_thread_fence \\(4\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "_gfortran_cas_coarray_sync_all" 1 "original" } } + + diff --git a/gcc/testsuite/gfortran.dg/caf-shared/sync_memory_1.f90 b/gcc/testsuite/gfortran.dg/caf-shared/sync_memory_1.f90 new file mode 100644 index 00000000000..25a7dcc421e --- /dev/null +++ b/gcc/testsuite/gfortran.dg/caf-shared/sync_memory_1.f90 @@ -0,0 +1,6 @@ +! { dg-do compile } +! { dg-options "-fdump-tree-original" } +program main + sync memory +end program main +! { dg-final { scan-tree-dump-times "__atomic_thread_fence \\(4\\)" 1 "original" } }