openmp: Add nothing directive support

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.
This commit is contained in:
Jakub Jelinek 2021-08-18 11:10:43 +02:00
parent 0684c8d3ef
commit 5079b7781a
10 changed files with 120 additions and 2 deletions

View 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 },

View 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 },

View 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,

View 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

View 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;

View file

@ -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;
}

View 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))]]

View 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))]]

View file

@ -13,3 +13,4 @@ int b, c;
int d;
[[omp::directive (end declare target)]];
[[omp::directive (end declare target)]];
[[omp::directive (nothing)]];

View file

@ -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;
}