public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [Patch] C, C++, Fortran, OpenMP: Add support for 'flush seq_cst' construct
@ 2021-09-06 16:08 Marcel Vollweiler
  2021-09-07  8:08 ` Jakub Jelinek
  0 siblings, 1 reply; 2+ messages in thread
From: Marcel Vollweiler @ 2021-09-06 16:08 UTC (permalink / raw)
  To: gcc-patches; +Cc: jakub Jelinek, Tobias Burnus, fortran

[-- Attachment #1: Type: text/plain, Size: 1512 bytes --]

Hi,

this patch adds support for the 'seq_cst' memory order clause on the
'flush' directive which was introduced in OpenMP 5.1 (p.275ff of the
OpenMP 5.1 Specification):

"If neither memory-order-clause nor a list appears on the flush
construct then the behavior is as if memory-order-clause is seq_cst.

A flush construct with the seq_cst clause, executed on a given thread,
operates as if all data storage blocks that are accessible to the thread
are flushed by a strong flush operation.

...

An implementation may implement a flush construct with a list by
ignoring the list and treating it the same as a flush construct with the
seq_cst clause."

I am not completely sure about the correct memory model specification:
"MEMMODEL_SYNC_SEQ_CST" vs. "MEMMODEL_SEQ_CST".
As "MEMMODEL_SYNC_SEQ_CST" is already used for flush without a clause
(that should behave in the same way than using seq_cst), see
expand_builtin_sync_synchronize in gcc/builtins.c, and regarding the
discussion in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65697 I found
it appropriate to use "MEMMODEL_SYNC_SEQ_CST" in order to guarantee a
strong flush.

I tested on x86_64-linux with nvptx offloading with no regressions.

Marcel



-----------------
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955

[-- Attachment #2: seq_cst_patch_v0.diff --]
[-- Type: text/plain, Size: 10305 bytes --]

C, C++, Fortran, OpenMP: Add support for 'flush seq_cst' construct.

This patch adds support for the 'seq_cst' memory order clause on the 'flush'
directive which was introduced in OpenMP 5.1.

gcc/c-family/ChangeLog:

	* c-omp.c (c_finish_omp_flush): Handle MEMMODEL_SEQ_CST.

gcc/c/ChangeLog:

	* c-parser.c (c_parser_omp_flush): Parse 'seq_cst' clause on 'flush' 
	directive.

gcc/cp/ChangeLog:

	* parser.c (cp_parser_omp_flush): Parse 'seq_cst' clause on 'flush'
	directive.
	* semantics.c (finish_omp_flush): Handle MEMMODEL_SEQ_CST.

gcc/fortran/ChangeLog:

	* openmp.c (gfc_match_omp_flush): Parse 'seq_cst' clause on 'flush'
        directive.
	* trans-openmp.c (gfc_trans_omp_flush): Handle OMP_MEMORDER_SEQ_CST.

gcc/testsuite/ChangeLog:

	* c-c++-common/gomp/flush-1.c: Add test case for 'seq_cst'.
	* c-c++-common/gomp/flush-2.c: Add test case for 'seq_cst'.
	* g++.dg/gomp/attrs-1.C:  Adapt test to handle all flush clauses.
	* gfortran.dg/gomp/flush-1.f90:  Add test case for 'seq_cst'.
	* gfortran.dg/gomp/flush-2.f90:  Add test case for 'seq_cst'.

diff --git a/gcc/c-family/c-omp.c b/gcc/c-family/c-omp.c
index 18de7e4..4b95fc1 100644
--- a/gcc/c-family/c-omp.c
+++ b/gcc/c-family/c-omp.c
@@ -606,7 +606,7 @@ c_finish_omp_flush (location_t loc, int mo)
 {
   tree x;
 
-  if (mo == MEMMODEL_LAST)
+  if (mo == MEMMODEL_LAST || mo == MEMMODEL_SEQ_CST)
     {
       x = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE);
       x = build_call_expr_loc (loc, x, 0);
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 3b1d10f..4d074ec 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -18339,7 +18339,9 @@ c_parser_omp_flush (c_parser *parser)
       const char *p
 	= IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
 
-      if (!strcmp (p, "acq_rel"))
+      if (!strcmp (p, "seq_cst"))
+	mo = MEMMODEL_SEQ_CST;
+      else if (!strcmp (p, "acq_rel"))
 	mo = MEMMODEL_ACQ_REL;
       else if (!strcmp (p, "release"))
 	mo = MEMMODEL_RELEASE;
@@ -18347,7 +18349,8 @@ c_parser_omp_flush (c_parser *parser)
 	mo = MEMMODEL_ACQUIRE;
       else
 	error_at (c_parser_peek_token (parser)->location,
-		  "expected %<acq_rel%>, %<release%> or %<acquire%>");
+		  "expected %<seq_cst%>, %<acq_rel%>, %<release%> or "
+		  "%<acquire%>");
       c_parser_consume_token (parser);
     }
   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index ea71f9c..f9c2c8a 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -40742,7 +40742,9 @@ cp_parser_omp_flush (cp_parser *parser, cp_token *pragma_tok)
     {
       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
       const char *p = IDENTIFIER_POINTER (id);
-      if (!strcmp (p, "acq_rel"))
+      if (!strcmp (p, "seq_cst"))
+	mo = MEMMODEL_SEQ_CST;
+      else if (!strcmp (p, "acq_rel"))
 	mo = MEMMODEL_ACQ_REL;
       else if (!strcmp (p, "release"))
 	mo = MEMMODEL_RELEASE;
@@ -40750,7 +40752,8 @@ cp_parser_omp_flush (cp_parser *parser, cp_token *pragma_tok)
 	mo = MEMMODEL_ACQUIRE;
       else
 	error_at (cp_lexer_peek_token (parser->lexer)->location,
-		  "expected %<acq_rel%>, %<release%> or %<acquire%>");
+		  "expected %<seq_cst%>, %<acq_rel%>, %<release%> or "
+		  "%<acquire%>");
       cp_lexer_consume_token (parser->lexer);
     }
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index f4b042f..8b78e89 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -10039,7 +10039,7 @@ finish_omp_flush (int mo)
 {
   tree fn = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE);
   releasing_vec vec;
-  if (mo != MEMMODEL_LAST)
+  if (mo != MEMMODEL_LAST && mo != MEMMODEL_SEQ_CST)
     {
       fn = builtin_decl_explicit (BUILT_IN_ATOMIC_THREAD_FENCE);
       vec->quick_push (build_int_cst (integer_type_node, mo));
diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index 64ecd54..a64b7f5 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -3782,7 +3782,9 @@ gfc_match_omp_flush (void)
   enum gfc_omp_memorder mo = OMP_MEMORDER_UNSET;
   if (gfc_match_omp_eos () == MATCH_NO && gfc_peek_ascii_char () != '(')
     {
-      if (gfc_match ("acq_rel") == MATCH_YES)
+      if (gfc_match ("seq_cst") == MATCH_YES)
+	mo = OMP_MEMORDER_SEQ_CST;
+      else if (gfc_match ("acq_rel") == MATCH_YES)
 	mo = OMP_MEMORDER_ACQ_REL;
       else if (gfc_match ("release") == MATCH_YES)
 	mo = OMP_MEMORDER_RELEASE;
@@ -3790,7 +3792,7 @@ gfc_match_omp_flush (void)
 	mo = OMP_MEMORDER_ACQUIRE;
       else
 	{
-	  gfc_error ("Expected AQC_REL, RELEASE, or ACQUIRE at %C");
+	  gfc_error ("Expected SEQ_CST, AQC_REL, RELEASE, or ACQUIRE at %C");
 	  return MATCH_ERROR;
 	}
       c = gfc_get_omp_clauses ();
diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c
index 6f9b0e3..e55e0c8 100644
--- a/gcc/fortran/trans-openmp.c
+++ b/gcc/fortran/trans-openmp.c
@@ -5413,7 +5413,8 @@ gfc_trans_omp_flush (gfc_code *code)
 {
   tree call;
   if (!code->ext.omp_clauses
-      || code->ext.omp_clauses->memorder == OMP_MEMORDER_UNSET)
+      || code->ext.omp_clauses->memorder == OMP_MEMORDER_UNSET
+      || code->ext.omp_clauses->memorder == OMP_MEMORDER_SEQ_CST)
     {
       call = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE);
       call = build_call_expr_loc (input_location, call, 0);
diff --git a/gcc/testsuite/c-c++-common/gomp/flush-1.c b/gcc/testsuite/c-c++-common/gomp/flush-1.c
index 7c3e529..717b951 100644
--- a/gcc/testsuite/c-c++-common/gomp/flush-1.c
+++ b/gcc/testsuite/c-c++-common/gomp/flush-1.c
@@ -1,4 +1,5 @@
 /* { dg-additional-options "-fdump-tree-gimple" } */
+/* { dg-final { scan-tree-dump "foo \\(6\\);\[\n\r]*  __sync_synchronize \\(\\);\[\n\r]*  foo \\(6\\);" "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" } } */
@@ -37,3 +38,11 @@ f4 (void)
   #pragma omp flush
   foo (5);
 }
+
+void
+f5 (void)
+{
+  foo (6);
+  #pragma omp flush seq_cst
+  foo (6);
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/flush-2.c b/gcc/testsuite/c-c++-common/gomp/flush-2.c
index 00baa8a..30ef598 100644
--- a/gcc/testsuite/c-c++-common/gomp/flush-2.c
+++ b/gcc/testsuite/c-c++-common/gomp/flush-2.c
@@ -8,10 +8,11 @@ foo (void)
   #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 seq_cst
+  #pragma omp flush relaxed		/* { dg-error "expected 'seq_cst', 'acq_rel', 'release' or 'acquire'" } */
+  #pragma omp flush foobar		/* { dg-error "expected 'seq_cst', '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" } */
+  #pragma omp flush seq_cst (a, b)	/* { dg-error "'flush' list specified together with memory order clause" } */
 }
diff --git a/gcc/testsuite/g++.dg/gomp/attrs-1.C b/gcc/testsuite/g++.dg/gomp/attrs-1.C
index cd20845..c871c51 100644
--- a/gcc/testsuite/g++.dg/gomp/attrs-1.C
+++ b/gcc/testsuite/g++.dg/gomp/attrs-1.C
@@ -528,6 +528,12 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
   ;
   [[omp::directive (flush acq_rel)]]
   ;
+  [[omp::directive (flush acquire)]]
+  ;
+  [[omp::directive (flush release)]]
+  ;
+  [[omp::directive (flush seq_cst)]]
+  ;
   [[omp::directive (flush (p, f))]]
   ;
   [[omp::directive (simd
diff --git a/gcc/testsuite/gfortran.dg/gomp/flush-1.f90 b/gcc/testsuite/gfortran.dg/gomp/flush-1.f90
index d0b7f9e..904bb1d 100644
--- a/gcc/testsuite/gfortran.dg/gomp/flush-1.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/flush-1.f90
@@ -1,4 +1,5 @@
 ! { dg-additional-options "-fdump-tree-gimple" }
+! { dg-final { scan-tree-dump "foo \\(6\\);\[\n\r]*  __sync_synchronize \\(\\);\[\n\r]*  foo \\(6\\);" "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" } }
@@ -39,3 +40,10 @@ subroutine f4
   !$omp flush
   call foo (5)
 end
+
+subroutine f5
+  use m
+  call foo (6)
+  !$omp flush seq_cst
+  call foo (6)
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/flush-2.f90 b/gcc/testsuite/gfortran.dg/gomp/flush-2.f90
index 6857371..ba23444 100644
--- a/gcc/testsuite/gfortran.dg/gomp/flush-2.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/flush-2.f90
@@ -9,10 +9,11 @@ subroutine foo (void)
   !$omp flush acquire
   !$omp flush release
   !$omp flush acq_rel
-  !$omp flush relaxed		! { dg-error "Expected AQC_REL, RELEASE, or ACQUIRE" }
-  !$omp flush seq_cst		! { dg-error "Expected AQC_REL, RELEASE, or ACQUIRE" }
-  !$omp flush foobar		! { dg-error "Expected AQC_REL, RELEASE, or ACQUIRE" }
+  !$omp flush seq_cst
+  !$omp flush relaxed		! { dg-error "Expected SEQ_CST, AQC_REL, RELEASE, or ACQUIRE" }
+  !$omp flush foobar		! { dg-error "Expected SEQ_CST, AQC_REL, RELEASE, or ACQUIRE" }
   !$omp flush acquire (a, b)	! { dg-error "List specified together with memory order clause in FLUSH directive" }
   !$omp flush release (a, b)	! { dg-error "List specified together with memory order clause in FLUSH directive" }
   !$omp flush acq_rel (a, b)	! { dg-error "List specified together with memory order clause in FLUSH directive" }
-end
+  !$omp flush seq_cst (a, b)	! { dg-error "List specified together with memory order clause in FLUSH directive" }
+  end

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [Patch] C, C++, Fortran, OpenMP: Add support for 'flush seq_cst' construct
  2021-09-06 16:08 [Patch] C, C++, Fortran, OpenMP: Add support for 'flush seq_cst' construct Marcel Vollweiler
@ 2021-09-07  8:08 ` Jakub Jelinek
  0 siblings, 0 replies; 2+ messages in thread
From: Jakub Jelinek @ 2021-09-07  8:08 UTC (permalink / raw)
  To: Marcel Vollweiler; +Cc: gcc-patches, Tobias Burnus, fortran

On Mon, Sep 06, 2021 at 06:08:14PM +0200, Marcel Vollweiler wrote:
> C, C++, Fortran, OpenMP: Add support for 'flush seq_cst' construct.
> 
> This patch adds support for the 'seq_cst' memory order clause on the 'flush'
> directive which was introduced in OpenMP 5.1.
> 
> gcc/c-family/ChangeLog:
> 
> 	* c-omp.c (c_finish_omp_flush): Handle MEMMODEL_SEQ_CST.
> 
> gcc/c/ChangeLog:
> 
> 	* c-parser.c (c_parser_omp_flush): Parse 'seq_cst' clause on 'flush' 
> 	directive.
> 
> gcc/cp/ChangeLog:
> 
> 	* parser.c (cp_parser_omp_flush): Parse 'seq_cst' clause on 'flush'
> 	directive.
> 	* semantics.c (finish_omp_flush): Handle MEMMODEL_SEQ_CST.
> 
> gcc/fortran/ChangeLog:
> 
> 	* openmp.c (gfc_match_omp_flush): Parse 'seq_cst' clause on 'flush'
>         directive.
> 	* trans-openmp.c (gfc_trans_omp_flush): Handle OMP_MEMORDER_SEQ_CST.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* c-c++-common/gomp/flush-1.c: Add test case for 'seq_cst'.
> 	* c-c++-common/gomp/flush-2.c: Add test case for 'seq_cst'.
> 	* g++.dg/gomp/attrs-1.C:  Adapt test to handle all flush clauses.
> 	* gfortran.dg/gomp/flush-1.f90:  Add test case for 'seq_cst'.
> 	* gfortran.dg/gomp/flush-2.f90:  Add test case for 'seq_cst'.

Just single space after :, not two.

> --- a/gcc/testsuite/g++.dg/gomp/attrs-1.C
> +++ b/gcc/testsuite/g++.dg/gomp/attrs-1.C
> @@ -528,6 +528,12 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
>    ;
>    [[omp::directive (flush acq_rel)]]
>    ;
> +  [[omp::directive (flush acquire)]]
> +  ;
> +  [[omp::directive (flush release)]]
> +  ;
> +  [[omp::directive (flush seq_cst)]]
> +  ;
>    [[omp::directive (flush (p, f))]]
>    ;
>    [[omp::directive (simd

When changing attrs-1.C, please also add corresponding change to attrs-2.C
too, with commas after the directive name (i.e. flush, acquire etc.).

Ok for trunk with those nits fixed, thanks.

	Jakub


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-09-07  8:08 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-06 16:08 [Patch] C, C++, Fortran, OpenMP: Add support for 'flush seq_cst' construct Marcel Vollweiler
2021-09-07  8:08 ` Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).