This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gomp5] OpenMP flush with memory-order-clause


Hi!

The flush directive can now have optional memory-order clause.

Tested on x86_64-linux, committed to gomp-5_0-branch.

2018-06-19  Jakub Jelinek  <jakub@redhat.com>

c-family/
	* c-common.h (c_finish_omp_flush): Add MO argument.
	* c-omp.c: Include memmodel.h.
	(c_finish_omp_flush): Add MO argument, if not MEMMODEL_LAST, emit
	__atomic_thread_fence call with the given value.
c/
	* c-parser.c: Include memmodel.h.
	(c_parser_omp_flush): Parse flush with memory-order-clause.
cp/
	* cp-tree.h (finish_omp_flush): Add MO argument.
	* parser.c: Include memmodel.h.
	(cp_parser_omp_flush): Parse flush with memory-order-clause.
	* semantics.c (finish_omp_flush): Add MO argument, if not
	MEMMODEL_LAST, emit __atomic_thread_fence call with the given value.
testsuite/
	* c-c++-common/gomp/flush-1.c: New test.
	* c-c++-common/gomp/flush-2.c: New test.

--- gcc/c-family/c-common.h.jj	2018-06-04 18:16:27.363395319 +0200
+++ gcc/c-family/c-common.h	2018-06-19 10:42:21.289381950 +0200
@@ -1149,7 +1149,7 @@ extern void c_finish_omp_barrier (locati
 extern tree c_finish_omp_atomic (location_t, enum tree_code, enum tree_code,
 				 tree, tree, tree, tree, tree, bool,
 				 enum omp_memory_order, bool = false);
-extern void c_finish_omp_flush (location_t);
+extern void c_finish_omp_flush (location_t, int);
 extern void c_finish_omp_taskwait (location_t);
 extern void c_finish_omp_taskyield (location_t);
 extern tree c_finish_omp_for (location_t, enum tree_code, tree, tree, tree,
--- gcc/c-family/c-omp.c.jj	2018-06-04 19:21:03.361751435 +0200
+++ gcc/c-family/c-omp.c	2018-06-19 10:42:21.290381951 +0200
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3.
 #include "c-pragma.h"
 #include "omp-general.h"
 #include "gomp-constants.h"
+#include "memmodel.h"
 
 
 /* Complete a #pragma oacc wait construct.  LOC is the location of
@@ -421,12 +422,21 @@ c_finish_omp_atomic (location_t loc, enu
    the #pragma.  */
 
 void
-c_finish_omp_flush (location_t loc)
+c_finish_omp_flush (location_t loc, int mo)
 {
   tree x;
 
-  x = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE);
-  x = build_call_expr_loc (loc, x, 0);
+  if (mo == MEMMODEL_LAST)
+    {
+      x = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE);
+      x = build_call_expr_loc (loc, x, 0);
+    }
+  else
+    {
+      x = builtin_decl_explicit (BUILT_IN_ATOMIC_THREAD_FENCE);
+      x = build_call_expr_loc (loc, x, 1,
+			       build_int_cst (integer_type_node, mo));
+    }
   add_stmt (x);
 }
 
--- gcc/c/c-parser.c.jj	2018-06-18 19:07:09.152186493 +0200
+++ gcc/c/c-parser.c	2018-06-19 10:42:21.288381950 +0200
@@ -68,6 +68,7 @@ along with GCC; see the file COPYING3.
 #include "intl.h"
 #include "c-family/name-hint.h"
 #include "tree-iterator.h"
+#include "memmodel.h"
 
 /* We need to walk over decls with incomplete struct/union/enum types
    after parsing the whole translation unit.
@@ -16109,20 +16110,46 @@ c_parser_omp_critical (location_t loc, c
    # pragma omp flush flush-vars[opt] new-line
 
    flush-vars:
-     ( variable-list ) */
+     ( variable-list )
+
+   OpenMP 5.0:
+   # pragma omp flush memory-order-clause new-line  */
 
 static void
 c_parser_omp_flush (c_parser *parser)
 {
   location_t loc = c_parser_peek_token (parser)->location;
   c_parser_consume_pragma (parser);
+  enum memmodel mo = MEMMODEL_LAST;
+  if (c_parser_next_token_is (parser, CPP_NAME))
+    {
+      const char *p
+	= IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+
+      if (!strcmp (p, "acq_rel"))
+	mo = MEMMODEL_ACQ_REL;
+      else if (!strcmp (p, "release"))
+	mo = MEMMODEL_RELEASE;
+      else if (!strcmp (p, "acquire"))
+	mo = MEMMODEL_ACQUIRE;
+      else
+	error_at (c_parser_peek_token (parser)->location,
+		  "expected %<acq_rel%>, %<release%> or %<acquire%>");
+      c_parser_consume_token (parser);
+    }
   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
-    c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
+    {
+      if (mo != MEMMODEL_LAST)
+	error_at (c_parser_peek_token (parser)->location,
+		  "%<flush%> list specified together with memory order "
+		  "clause");
+      c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
+    }
   else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
     c_parser_error (parser, "expected %<(%> or end of line");
   c_parser_skip_to_pragma_eol (parser);
 
-  c_finish_omp_flush (loc);
+  c_finish_omp_flush (loc, mo);
 }
 
 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
--- gcc/cp/cp-tree.h.jj	2018-06-04 18:17:56.411535752 +0200
+++ gcc/cp/cp-tree.h	2018-06-19 10:42:21.292381953 +0200
@@ -6968,7 +6968,7 @@ extern void finish_omp_atomic			(enum tr
 						 tree, tree, tree, tree, tree,
 						 tree, enum omp_memory_order);
 extern void finish_omp_barrier			(void);
-extern void finish_omp_flush			(void);
+extern void finish_omp_flush			(int);
 extern void finish_omp_taskwait			(void);
 extern void finish_omp_taskyield		(void);
 extern void finish_omp_cancel			(tree);
--- gcc/cp/parser.c.jj	2018-06-18 19:07:09.152186493 +0200
+++ gcc/cp/parser.c	2018-06-19 10:42:21.296381957 +0200
@@ -44,6 +44,7 @@ along with GCC; see the file COPYING3.
 #include "gcc-rich-location.h"
 #include "tree-iterator.h"
 #include "c-family/name-hint.h"
+#include "memmodel.h"
 
 
 /* The lexer.  */
@@ -35256,16 +35257,41 @@ cp_parser_omp_critical (cp_parser *parse
    # pragma omp flush flush-vars[opt] new-line
 
    flush-vars:
-     ( variable-list ) */
+     ( variable-list )
+
+   OpenMP 5.0:
+   # pragma omp flush memory-order-clause new-line  */
 
 static void
 cp_parser_omp_flush (cp_parser *parser, cp_token *pragma_tok)
 {
+  enum memmodel mo = MEMMODEL_LAST;
+  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+    {
+      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+      const char *p = IDENTIFIER_POINTER (id);
+      if (!strcmp (p, "acq_rel"))
+	mo = MEMMODEL_ACQ_REL;
+      else if (!strcmp (p, "release"))
+	mo = MEMMODEL_RELEASE;
+      else if (!strcmp (p, "acquire"))
+	mo = MEMMODEL_ACQUIRE;
+      else
+	error_at (cp_lexer_peek_token (parser->lexer)->location,
+		  "expected %<acq_rel%>, %<release%> or %<acquire%>");
+      cp_lexer_consume_token (parser->lexer);
+    }
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
-    (void) cp_parser_omp_var_list (parser, OMP_CLAUSE_ERROR, NULL);
+    {
+      if (mo != MEMMODEL_LAST)
+	error_at (cp_lexer_peek_token (parser->lexer)->location,
+		  "%<flush%> list specified together with memory order "
+		  "clause");
+      (void) cp_parser_omp_var_list (parser, OMP_CLAUSE_ERROR, NULL);
+    }
   cp_parser_require_pragma_eol (parser, pragma_tok);
 
-  finish_omp_flush ();
+  finish_omp_flush (mo);
 }
 
 /* Helper function, to parse omp for increment expression.  */
--- gcc/cp/semantics.c.jj	2018-06-13 19:25:03.003926735 +0200
+++ gcc/cp/semantics.c	2018-06-19 10:42:21.297381958 +0200
@@ -44,6 +44,7 @@ along with GCC; see the file COPYING3.
 #include "attribs.h"
 #include "gomp-constants.h"
 #include "predict.h"
+#include "memmodel.h"
 
 /* There routines provide a modular interface to perform many parsing
    operations.  They may therefore be used during actual parsing, or
@@ -8754,10 +8755,15 @@ finish_omp_barrier (void)
 }
 
 void
-finish_omp_flush (void)
+finish_omp_flush (int mo)
 {
   tree fn = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE);
   vec<tree, va_gc> *vec = make_tree_vector ();
+  if (mo != MEMMODEL_LAST)
+    {
+      fn = builtin_decl_explicit (BUILT_IN_ATOMIC_THREAD_FENCE);
+      vec->quick_push (build_int_cst (integer_type_node, mo));
+    }
   tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
   release_tree_vector (vec);
   finish_expr_stmt (stmt);
--- gcc/testsuite/c-c++-common/gomp/flush-1.c.jj	2018-06-19 10:56:51.074211728 +0200
+++ gcc/testsuite/c-c++-common/gomp/flush-1.c	2018-06-19 10:56:44.314202801 +0200
@@ -0,0 +1,39 @@
+/* { dg-additional-options "-fdump-tree-gimple" } */
+/* { dg-final { scan-tree-dump "foo \\(4\\);\[\n\r]*  __atomic_thread_fence \\(4\\);\[\n\r]*  foo \\(4\\);" "gimple" } } */
+/* { dg-final { scan-tree-dump "foo \\(3\\);\[\n\r]*  __atomic_thread_fence \\(3\\);\[\n\r]*  foo \\(3\\);" "gimple" } } */
+/* { dg-final { scan-tree-dump "foo \\(2\\);\[\n\r]*  __atomic_thread_fence \\(2\\);\[\n\r]*  foo \\(2\\);" "gimple" } } */
+/* { dg-final { scan-tree-dump "foo \\(5\\);\[\n\r]*  __sync_synchronize \\(\\);\[\n\r]*  foo \\(5\\);" "gimple" } } */
+
+void foo (int);
+
+void
+f1 (void)
+{
+  foo (4);
+  #pragma omp flush acq_rel
+  foo (4);
+}
+
+void
+f2 (void)
+{
+  foo (3);
+  #pragma omp flush release
+  foo (3);
+}
+
+void
+f3 (void)
+{
+  foo (2);
+  #pragma omp flush acquire
+  foo (2);
+}
+
+void
+f4 (void)
+{
+  foo (5);
+  #pragma omp flush
+  foo (5);
+}
--- gcc/testsuite/c-c++-common/gomp/flush-2.c.jj	2018-06-19 10:58:33.981347616 +0200
+++ gcc/testsuite/c-c++-common/gomp/flush-2.c	2018-06-19 10:59:27.909418839 +0200
@@ -0,0 +1,17 @@
+int a, b;
+
+void
+foo (void)
+{
+  #pragma omp flush
+  #pragma omp flush (a, b)
+  #pragma omp flush acquire
+  #pragma omp flush release
+  #pragma omp flush acq_rel
+  #pragma omp flush relaxed		/* { dg-error "expected 'acq_rel', 'release' or 'acquire'" } */
+  #pragma omp flush seq_cst		/* { dg-error "expected 'acq_rel', 'release' or 'acquire'" } */
+  #pragma omp flush foobar		/* { dg-error "expected 'acq_rel', 'release' or 'acquire'" } */
+  #pragma omp flush acquire (a, b)	/* { dg-error "'flush' list specified together with memory order clause" } */
+  #pragma omp flush release (a, b)	/* { dg-error "'flush' list specified together with memory order clause" } */
+  #pragma omp flush acq_rel (a, b)	/* { dg-error "'flush' list specified together with memory order clause" } */
+}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]