diff mbox

[Fortran] Sync memory action delegated to OpenCoarrays

Message ID CAHqFgjVuc4irPkUTQ9L6kTYfp+jdAkr34Qefi6VGroP3SW0icg@mail.gmail.com
State New
Headers show

Commit Message

Alessandro Fanfarillo March 6, 2015, 6:38 p.m. UTC
Dear all,

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.

Any suggestions?

Best regards

Alessandro
commit fdb560e3f548fe60edf26717b8de6bb92f3fd555
Author: Alessandro Fanfarillo <fanfarillo.gcc@gmail.com>
Date:   Fri Mar 6 10:25:56 2015 -0800

    Sync memory is translated into an invokation to _gfortran_caf_sync_memory()

Comments

Tobias Burnus March 6, 2015, 8:01 p.m. UTC | #1
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.
|
diff mbox

Patch

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;