Thanks for the quick response.

Patch built and regtested on x86_64-unknown-linux-gnu.

Currently the stub for sync memory in single.c invokes "asm volatile
("" : : : "memory")" but _gfortran_caf_sync_memory is not called when
the code is compiled with -fcoarray=single.

Please let me know if I have to change the patch for -fcoarray=single.



2015-03-06 11:20 GMT-08:00 Tobias Burnus <bur...@net-b.de>:
> Dear Alessandro,
>
> Alessandro Fanfarillo wrote:
>
> so far a "sync memory" statement is translated into a local
> "__sync_synchronize ()".
> The attached draft patch delegates the action for sync memory (when
> -fcoarray=lib is used) to the external function
> _gfortran_caf_sync_memory() implemented in the OpenCoarrays library.
>
>
> Looks good to me. However, you should add a test case with 'dg-options
> "-fdump-tree-original -fcoarray=lib"' to check that this works; cf.
> gcc/testsuite/gfortran.dg/coarray*.f90 for examples.
>
> And you have to provide a stub implementation in
> libgfortran/caf/{libcaf.h,single.c}.
>
> Tobias
>
> PS: I wonder whether it makes sense to remove the __sync_synchronize for
> -fcoarray=single and replace it by the equivalent to "asm volatile ("" : : :
> "memory")". It almost certainly does.
2015-03-09  Alessandro Fanfarillo  fanfarillo....@gmail.com

            trans-decl.c: Add function declaration caf_sync_memory
            trans.h: Ditto
            trans-stmt.c: Add caf_sync_memory invocation
            coarray_38.f90: Test case
            single.c: caf_sync_memory implementation
            libcaf.h: caf_sync_memory prototype
            
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index 3664824..a66c25c 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -153,6 +153,7 @@ tree gfor_fndecl_caf_get;
 tree gfor_fndecl_caf_send;
 tree gfor_fndecl_caf_sendget;
 tree gfor_fndecl_caf_sync_all;
+tree gfor_fndecl_caf_sync_memory;
 tree gfor_fndecl_caf_sync_images;
 tree gfor_fndecl_caf_error_stop;
 tree gfor_fndecl_caf_error_stop_str;
@@ -3451,6 +3452,10 @@ gfc_build_builtin_function_decls (void)
        get_identifier (PREFIX("caf_sync_all")), ".WW", void_type_node,
        3, pint_type, pchar_type_node, integer_type_node);
 
+      gfor_fndecl_caf_sync_memory = gfc_build_library_function_decl_with_spec (
+       get_identifier (PREFIX("caf_sync_memory")), ".WW", void_type_node,
+       3, pint_type, pchar_type_node, integer_type_node);
+
       gfor_fndecl_caf_sync_images = gfc_build_library_function_decl_with_spec (
        get_identifier (PREFIX("caf_sync_images")), ".RRWW", void_type_node,
        5, integer_type_node, pint_type, pint_type,
diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c
index 505f905..dce0e87 100644
--- a/gcc/fortran/trans-stmt.c
+++ b/gcc/fortran/trans-stmt.c
@@ -768,8 +768,7 @@ gfc_trans_sync (gfc_code *code, gfc_exec_op type)
   else
     stat = null_pointer_node;
 
-  if (code->expr3 && flag_coarray == GFC_FCOARRAY_LIB
-      && type != EXEC_SYNC_MEMORY)
+  if (code->expr3 && flag_coarray == GFC_FCOARRAY_LIB)
     {
       gcc_assert (code->expr3->expr_type == EXPR_VARIABLE);
       gfc_init_se (&argse, NULL);
@@ -778,7 +777,7 @@ gfc_trans_sync (gfc_code *code, gfc_exec_op type)
       errmsg = gfc_build_addr_expr (NULL, argse.expr);
       errmsglen = argse.string_length;
     }
-  else if (flag_coarray == GFC_FCOARRAY_LIB && type != EXEC_SYNC_MEMORY)
+  else if (flag_coarray == GFC_FCOARRAY_LIB)
     {
       errmsg = null_pointer_node;
       errmsglen = build_int_cst (integer_type_node, 0);
@@ -822,13 +821,13 @@ gfc_trans_sync (gfc_code *code, gfc_exec_op type)
        gfc_add_expr_to_block (&se.pre, tmp);
      }
 
-  if (flag_coarray != GFC_FCOARRAY_LIB || type == EXEC_SYNC_MEMORY)
+  if (flag_coarray != GFC_FCOARRAY_LIB)
     {
       /* Set STAT to zero.  */
       if (code->expr2)
        gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
     }
-  else if (type == EXEC_SYNC_ALL)
+  else if (type == EXEC_SYNC_ALL  || type == EXEC_SYNC_MEMORY)
     {
       /* SYNC ALL           =>   stat == null_pointer_node
         SYNC ALL(stat=s)   =>   stat has an integer type
@@ -840,8 +839,13 @@ gfc_trans_sync (gfc_code *code, gfc_exec_op type)
          if (TREE_TYPE (stat) == integer_type_node)
            stat = gfc_build_addr_expr (NULL, stat);
 
-         tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
-                                    3, stat, errmsg, errmsglen);
+         if(type == EXEC_SYNC_MEMORY)
+           tmp = build_call_expr_loc (input_location, 
gfor_fndecl_caf_sync_memory,
+                                      3, stat, errmsg, errmsglen);
+         else
+           tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
+                                      3, stat, errmsg, errmsglen);
+
          gfc_add_expr_to_block (&se.pre, tmp);
        }
       else
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index bd1520a..3ba2f88 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -731,6 +731,7 @@ extern GTY(()) tree gfor_fndecl_caf_get;
 extern GTY(()) tree gfor_fndecl_caf_send;
 extern GTY(()) tree gfor_fndecl_caf_sendget;
 extern GTY(()) tree gfor_fndecl_caf_sync_all;
+extern GTY(()) tree gfor_fndecl_caf_sync_memory;
 extern GTY(()) tree gfor_fndecl_caf_sync_images;
 extern GTY(()) tree gfor_fndecl_caf_error_stop;
 extern GTY(()) tree gfor_fndecl_caf_error_stop_str;
diff --git a/gcc/testsuite/gfortran.dg/coarray_38.f90 
b/gcc/testsuite/gfortran.dg/coarray_38.f90
new file mode 100644
index 0000000..01b5b31
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/coarray_38.f90
@@ -0,0 +1,11 @@
+! { dg-do compile }
+! { dg-options "-fcoarray=lib -fdump-tree-original" }
+!
+! Coarray sync memory managed by external library
+!
+implicit none
+integer :: n
+sync memory
+end
+! { dg-final { scan-tree-dump-times "_gfortran_caf_sync_memory \\(0B, 0B, 
0\\);" 1 "original" } }
+! { dg-final { cleanup-tree-dump "original" } }
diff --git a/libgfortran/caf/libcaf.h b/libgfortran/caf/libcaf.h
index bd5c9c6..27e0d62 100644
--- a/libgfortran/caf/libcaf.h
+++ b/libgfortran/caf/libcaf.h
@@ -99,6 +99,7 @@ void *_gfortran_caf_register (size_t, caf_register_t, 
caf_token_t *, int *,
                              char *, int);
 void _gfortran_caf_deregister (caf_token_t *, int *, char *, int);
 
+void _gfortran_caf_sync_memory(int *, char *, int);
 void _gfortran_caf_sync_all (int *, char *, int);
 void _gfortran_caf_sync_images (int, int[], int *, char *, int);
 
diff --git a/libgfortran/caf/single.c b/libgfortran/caf/single.c
index 7405c91..8eb61c3 100644
--- a/libgfortran/caf/single.c
+++ b/libgfortran/caf/single.c
@@ -156,6 +156,17 @@ _gfortran_caf_deregister (caf_token_t *token, int *stat,
     *stat = 0;
 }
 
+void
+_gfortran_caf_sync_memory(int *stat,
+                         char *errmsg __attribute__ ((unused)),
+                         int errmsg_len __attribute__ ((unused)))
+{
+  if (stat)
+    *stat = 0;
+
+  asm volatile("" ::: "memory");
+}
+
 
 void
 _gfortran_caf_sync_all (int *stat,

Reply via email to