diff options
author | Thomas Koenig <tkoenig@gcc.gnu.org> | 2020-12-17 15:58:45 +0100 |
---|---|---|
committer | Thomas Koenig <tkoenig@gcc.gnu.org> | 2020-12-17 15:58:45 +0100 |
commit | d91352b42efcb2a81039ab1911d4fda414143ddb (patch) | |
tree | 6490b113627c273530061610ef767b753e185135 | |
parent | e3caaf97e6fbe6743d7d9c1a2ba3777eec86b5a1 (diff) | |
download | gcc-d91352b42efcb2a81039ab1911d4fda414143ddb.zip gcc-d91352b42efcb2a81039ab1911d4fda414143ddb.tar.gz gcc-d91352b42efcb2a81039ab1911d4fda414143ddb.tar.bz2 |
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.
-rw-r--r-- | gcc/fortran/trans-stmt.c | 23 | ||||
-rw-r--r-- | gcc/fortran/trans.c | 16 | ||||
-rw-r--r-- | gcc/fortran/trans.h | 1 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/caf-shared/sync_all_1.f90 | 9 | ||||
-rw-r--r-- | gcc/testsuite/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 368165e..8db4333 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 aa30710..fa7fd9d 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 eef90f6..95e4741 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 0000000..95343f5 --- /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 0000000..25a7dcc --- /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" } } |