/* 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)
{
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)
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
{
#include "trans-types.h"
#include "trans-const.h"
#include "diagnostic-core.h"
+#include "memmodel.h" /* For MEMMODEL_ enums. */
/* Naming convention for backend interface code:
const char gfc_msg_wrong_return[] = N_("Incorrect function return value");
/* Insert a memory barrier into the code. */
+
tree
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