]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
openmp: Add nothing directive support
authorJakub Jelinek <jakub@redhat.com>
Wed, 18 Aug 2021 09:10:43 +0000 (11:10 +0200)
committerJakub Jelinek <jakub@redhat.com>
Wed, 18 Aug 2021 09:10:43 +0000 (11:10 +0200)
As has been clarified, it is intentional that nothing directive is accepted
in substatements of selection and looping statements and after labels and
is handled as if the directive just isn't there, so that
void
foo (int x)
{
  if (x)
    #pragma omp metadirective when (...:nothing) when (...:parallel)
    bar ();
}
behaves consistently; declarative and stand-alone directives aren't allowed
at that point, but constructs are parsed with the following statement as
the construct body and nothing or missing default on metadirective therefore
should handle the following statement as part of the if substatement instead
of having nothing as the substatement and bar done unconditionally after the
if.

2021-08-18  Jakub Jelinek  <jakub@redhat.com>

gcc/c-family/
* c-pragma.h (enum pragma_kind): Add PRAGMA_OMP_NOTHING.
* c-pragma.c (omp_pragmas): Add nothing directive.
* c-omp.c (omp_directives): Uncomment nothing directive entry.
gcc/c/
* c-parser.c (c_parser_omp_nothing): New function.
(c_parser_pragma): Handle PRAGMA_OMP_NOTHING.
gcc/cp/
* parser.c (cp_parser_omp_nothing): New function.
(cp_parser_pragma): Handle PRAGMA_OMP_NOTHING.
gcc/testsuite/
* c-c++-common/gomp/nothing-1.c: New test.
* g++.dg/gomp/attrs-1.C (bar): Add nothing directive test.
* g++.dg/gomp/attrs-2.C (bar): Likewise.
* g++.dg/gomp/attrs-9.C: Likewise.
libgomp/
* testsuite/libgomp.c-c++-common/nothing-1.c: New test.

gcc/c-family/c-omp.c
gcc/c-family/c-pragma.c
gcc/c-family/c-pragma.h
gcc/c/c-parser.c
gcc/cp/parser.c
gcc/testsuite/c-c++-common/gomp/nothing-1.c [new file with mode: 0644]
gcc/testsuite/g++.dg/gomp/attrs-1.C
gcc/testsuite/g++.dg/gomp/attrs-2.C
gcc/testsuite/g++.dg/gomp/attrs-9.C
libgomp/testsuite/libgomp.c-c++-common/nothing-1.c [new file with mode: 0644]

index de49d2668314edcfbcd9cb35e5d385de7724149f..d4e98bfd76ba1d3cd2549aae3c57144298d2cb82 100644 (file)
@@ -3007,8 +3007,8 @@ static const struct c_omp_directive omp_directives[] = {
     C_OMP_DIR_CONSTRUCT, true },
   /* { "metadirective", nullptr, nullptr, PRAGMA_OMP_METADIRECTIVE,
     C_OMP_DIR_???, ??? },  */
-  /* { "nothing", nullptr, nullptr, PRAGMA_OMP_NOTHING,
-    C_OMP_DIR_UTILITY, false },  */
+  { "nothing", nullptr, nullptr, PRAGMA_OMP_NOTHING,
+    C_OMP_DIR_UTILITY, false },
   /* ordered with depend clause is C_OMP_DIR_STANDALONE.  */
   { "ordered", nullptr, nullptr, PRAGMA_OMP_ORDERED,
     C_OMP_DIR_CONSTRUCT, true },
index 5f0096ffc70cf1f18e1f93153ebd3c232fd85e48..238309d4a775b858142909dbdc252c64698eabf1 100644 (file)
@@ -1328,6 +1328,7 @@ static const struct omp_pragma_def omp_pragmas[] = {
   { "depobj", PRAGMA_OMP_DEPOBJ },
   { "end", PRAGMA_OMP_END_DECLARE_TARGET },
   { "flush", PRAGMA_OMP_FLUSH },
+  { "nothing", PRAGMA_OMP_NOTHING },
   { "requires", PRAGMA_OMP_REQUIRES },
   { "scope", PRAGMA_OMP_SCOPE },
   { "section", PRAGMA_OMP_SECTION },
index 2b9e5eac675a5af98f76f3dd996c5775a2e5ef94..dc9e8a6616df91d25645ea32d621a75c4e2bcdb4 100644 (file)
@@ -57,6 +57,7 @@ enum pragma_kind {
   PRAGMA_OMP_FLUSH,
   PRAGMA_OMP_FOR,
   PRAGMA_OMP_LOOP,
+  PRAGMA_OMP_NOTHING,
   PRAGMA_OMP_MASKED,
   PRAGMA_OMP_MASTER,
   PRAGMA_OMP_ORDERED,
index 565efc4d2e96d0430c7735899ace3399941bd5a7..d5f51b11423113b517f7d20f79fae5c830979f9b 100644 (file)
@@ -1578,6 +1578,7 @@ static tree c_parser_omp_for_loop (location_t, c_parser *, enum tree_code,
 static void c_parser_omp_taskwait (c_parser *);
 static void c_parser_omp_taskyield (c_parser *);
 static void c_parser_omp_cancel (c_parser *);
+static void c_parser_omp_nothing (c_parser *);
 
 enum pragma_context { pragma_external, pragma_struct, pragma_param,
                      pragma_stmt, pragma_compound };
@@ -12480,6 +12481,10 @@ c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p)
       c_parser_omp_requires (parser);
       return false;
 
+    case PRAGMA_OMP_NOTHING:
+      c_parser_omp_nothing (parser);
+      return false;
+
     case PRAGMA_OMP_ORDERED:
       return c_parser_omp_ordered (parser, context, if_p);
 
@@ -21908,6 +21913,16 @@ c_parser_omp_taskloop (location_t loc, c_parser *parser,
   return ret;
 }
 
+/* OpenMP 5.1
+   #pragma omp nothing new-line  */
+
+static void
+c_parser_omp_nothing (c_parser *parser)
+{
+  c_parser_consume_pragma (parser);
+  c_parser_skip_to_pragma_eol (parser);
+}
+
 /* Main entry point to parsing most OpenMP pragmas.  */
 
 static void
index 8f2d0fce8071f8ca253ae88817fec6908edc6711..04116fbcef4a7e1c15c0bae5f315dc1dc2a2ebf3 100644 (file)
@@ -45564,6 +45564,16 @@ cp_parser_omp_requires (cp_parser *parser, cp_token *pragma_tok)
 }
 
 
+/* OpenMP 5.1:
+   #pragma omp nothing new-line  */
+
+static void
+cp_parser_omp_nothing (cp_parser *parser, cp_token *pragma_tok)
+{
+  cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+}
+
+
 /* OpenMP 4.5:
    #pragma omp taskloop taskloop-clause[optseq] new-line
      for-loop
@@ -46673,6 +46683,10 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context, bool *if_p)
        }
       return cp_parser_omp_requires (parser, pragma_tok);
 
+    case PRAGMA_OMP_NOTHING:
+      cp_parser_omp_nothing (parser, pragma_tok);
+      return false;
+
     case PRAGMA_OMP_ORDERED:
       if (context != pragma_stmt && context != pragma_compound)
        goto bad_stmt;
diff --git a/gcc/testsuite/c-c++-common/gomp/nothing-1.c b/gcc/testsuite/c-c++-common/gomp/nothing-1.c
new file mode 100644 (file)
index 0000000..d50c92a
--- /dev/null
@@ -0,0 +1,37 @@
+#pragma omp nothing
+
+struct S
+{
+  #pragma omp nothing
+  int s;
+};
+
+int
+foo (int i)
+{
+  #pragma omp nothing
+  if (0)
+    #pragma omp nothing
+    i++;
+  if (1)
+    ;
+  else
+    #pragma omp nothing
+    i++;
+  switch (0)
+    #pragma omp nothing
+    {
+    default:
+      break;
+    }
+  while (0)
+    #pragma omp nothing
+    i++;
+  for (; 0;)
+    #pragma omp nothing
+    i++;
+  lab:
+  #pragma omp nothing
+  i++;
+  return i;
+}
index 686acf5042fe82d18db4ed077f148cfba2af6098..435d54fb762e1370eab273e2334d6d827cbe91bd 100644 (file)
@@ -111,6 +111,7 @@ void
 bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
      int nte, int tl, int nth, int g, int nta, int fi, int pp, int *q, int *dd, int ntm)
 {
+  [[omp::directive (nothing)]];
   [[omp::directive (for simd
     private (p) firstprivate (f) lastprivate (l) linear (ll:1) reduction(+:r) schedule(static, 4) collapse(1) nowait
     safelen(8) simdlen(4) aligned(q: 32) nontemporal(ntm) if(i1) order(concurrent) allocate (f))]]
index 2190457c877966e1af2bdaa09c9a6fb7e0bb25ae..bea657f02b9a80433867c81b2fb2ad42da710397 100644 (file)
@@ -111,6 +111,7 @@ void
 bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
      int nte, int tl, int nth, int g, int nta, int fi, int pp, int *q, int *dd, int ntm)
 {
+  [[omp::directive (nothing)]];
   [[omp::directive (for simd,
     private (p),firstprivate (f),lastprivate (l),linear (ll:1),reduction(+:r),schedule(static, 4),collapse(1),nowait,
     safelen(8),simdlen(4),aligned(q: 32),nontemporal(ntm),if(i1),order(concurrent),allocate (f))]]
index 0af556c728423429deb6cb5877af90dd5b09362f..08cd2b1dfd94e4efede5b674c86258e0fce38487 100644 (file)
@@ -13,3 +13,4 @@ int b, c;
 int d;
 [[omp::directive (end declare target)]];
 [[omp::directive (end declare target)]];
+[[omp::directive (nothing)]];
diff --git a/libgomp/testsuite/libgomp.c-c++-common/nothing-1.c b/libgomp/testsuite/libgomp.c-c++-common/nothing-1.c
new file mode 100644 (file)
index 0000000..69716b1
--- /dev/null
@@ -0,0 +1,47 @@
+#include <stdlib.h>
+
+#pragma omp nothing
+
+struct S
+{
+  #pragma omp nothing
+  int s;
+};
+
+int
+foo (int i)
+{
+  #pragma omp nothing
+  if (0)
+    #pragma omp nothing
+    i++;
+  if (1)
+    ;
+  else
+    #pragma omp nothing
+    i++;
+  switch (0)
+    #pragma omp nothing
+    {
+    default:
+      break;
+    }
+  while (0)
+    #pragma omp nothing
+    i++;
+  for (; 0;)
+    #pragma omp nothing
+    i++;
+  lab:
+  #pragma omp nothing
+  i++;
+  return i;
+}
+
+int
+main ()
+{
+  if (foo (5) != 6 || foo (-2) != -1)
+    abort ();
+  return 0;
+}