public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/omp/gcc-11] openmp: Add warning when functions containing metadirectives with 'construct={target}' called direct
@ 2022-01-28 16:47 Kwok Yeung
0 siblings, 0 replies; only message in thread
From: Kwok Yeung @ 2022-01-28 16:47 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:d6d82af79181c20d48c61df62360a79a04104c05
commit d6d82af79181c20d48c61df62360a79a04104c05
Author: Kwok Cheung Yeung <kcy@codesourcery.com>
Date: Fri Jan 28 13:56:33 2022 +0000
openmp: Add warning when functions containing metadirectives with 'construct={target}' called directly
void f(void)
{
#pragma omp metadirective \
when (construct={target}: A) \
default (B)
...
}
...
{
#pragma omp target
f(); // Target call
f(); // Local call
}
With the OpenMP 5.0/5.1 specifications, we would expect A to be selected in
the metadirective when the target call is made, but B when f is called
directly outside of a target context. However, since GCC does not have
separate copies of f for local and target calls, and the construct selector
is static, it must be resolved one way or the other at compile-time (currently
in the favour of selecting A), which may be unexpected behaviour.
This patch attempts to detect the above situation, and will emit a warning
if found.
2022-01-28 Kwok Cheung Yeung <kcy@codesourcery.com>
gcc/
* gimplify.c (gimplify_omp_metadirective): Mark offloadable functions
containing metadirectives with 'construct={target}' in the selector.
* omp-general.c (omp_has_target_constructor_p): New.
* omp-general.h (omp_has_target_constructor_p): New prototype.
* omp-low.c (lower_omp_1): Emit warning if marked functions called
outside of a target context.
gcc/testsuite/
* c-c++-common/gomp/metadirective-4.c (main): Add expected warning.
* gfortran.dg/gomp/metadirective-4.f90 (test): Likewise.
libgomp/
* testsuite/libgomp.c-c++-common/metadirective-2.c (main): Add
expected warning.
* testsuite/libgomp.fortran/metadirective-2.f90 (test): Likewise.
Diff:
---
gcc/gimplify.c | 21 +++++++++++++++++++++
gcc/omp-general.c | 21 +++++++++++++++++++++
gcc/omp-general.h | 1 +
gcc/omp-low.c | 18 ++++++++++++++++++
gcc/testsuite/c-c++-common/gomp/metadirective-4.c | 2 +-
gcc/testsuite/gfortran.dg/gomp/metadirective-4.f90 | 2 +-
.../libgomp.c-c++-common/metadirective-2.c | 2 +-
.../testsuite/libgomp.fortran/metadirective-2.f90 | 2 +-
8 files changed, 65 insertions(+), 4 deletions(-)
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index d33da65778d..6e0c900e26c 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -15251,6 +15251,27 @@ gimplify_omp_metadirective (tree *expr_p, gimple_seq *pre_p, gimple_seq *,
{
auto_vec<tree> selectors;
+ /* Mark offloadable functions containing metadirectives that specify
+ a 'construct' selector with a 'target' constructor. */
+ if (offloading_function_p (current_function_decl))
+ {
+ for (tree clause = OMP_METADIRECTIVE_CLAUSES (*expr_p);
+ clause != NULL_TREE; clause = TREE_CHAIN (clause))
+ {
+ tree selector = TREE_PURPOSE (clause);
+
+ if (omp_has_target_constructor_p (selector))
+ {
+ tree id = get_identifier ("omp metadirective construct target");
+
+ DECL_ATTRIBUTES (current_function_decl)
+ = tree_cons (id, NULL_TREE,
+ DECL_ATTRIBUTES (current_function_decl));
+ break;
+ }
+ }
+ }
+
/* Try to resolve the metadirective. */
vec<struct omp_metadirective_variant> candidates
= omp_resolve_metadirective (*expr_p);
diff --git a/gcc/omp-general.c b/gcc/omp-general.c
index bf54b969133..33c2a9b514a 100644
--- a/gcc/omp-general.c
+++ b/gcc/omp-general.c
@@ -2931,6 +2931,27 @@ omp_resolve_metadirective (gimple *gs)
return omp_get_dynamic_candidates (variants);
}
+bool
+omp_has_target_constructor_p (tree selector)
+{
+ if (selector == NULL_TREE)
+ return false;
+
+ tree selector_set = TREE_PURPOSE (selector);
+ if (strcmp (IDENTIFIER_POINTER (selector_set), "construct") != 0)
+ return false;
+
+ enum tree_code constructs[5];
+ int nconstructs
+ = omp_constructor_traits_to_codes (TREE_VALUE (selector), constructs);
+
+ for (int i = 0; i < nconstructs; i++)
+ if (constructs[i] == OMP_TARGET)
+ return true;
+
+ return false;
+}
+
/* Encode an oacc launch argument. This matches the GOMP_LAUNCH_PACK
macro on gomp-constants.h. We do not check for overflow. */
diff --git a/gcc/omp-general.h b/gcc/omp-general.h
index f6c70ccd348..cac03951192 100644
--- a/gcc/omp-general.h
+++ b/gcc/omp-general.h
@@ -126,6 +126,7 @@ extern tree omp_get_context_selector (tree, const char *, const char *);
extern tree omp_resolve_declare_variant (tree);
extern vec<struct omp_metadirective_variant> omp_resolve_metadirective (tree);
extern vec<struct omp_metadirective_variant> omp_resolve_metadirective (gimple *);
+extern bool omp_has_target_constructor_p (tree);
extern tree oacc_launch_pack (unsigned code, tree device, unsigned op);
extern tree oacc_replace_fn_attrib_attr (tree attribs, tree dims);
extern void oacc_replace_fn_attrib (tree fn, tree dims);
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 9445a6b18dd..05e32f225f3 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -14893,6 +14893,24 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
tree fndecl;
call_stmt = as_a <gcall *> (stmt);
fndecl = gimple_call_fndecl (call_stmt);
+ if (fndecl
+ && lookup_attribute ("omp metadirective construct target",
+ DECL_ATTRIBUTES (fndecl)))
+ {
+ bool in_target_ctx = false;
+
+ for (omp_context *up = ctx; up; up = up->outer)
+ if (gimple_code (up->stmt) == GIMPLE_OMP_TARGET)
+ {
+ in_target_ctx = true;
+ break;
+ }
+ if (!ctx || !in_target_ctx)
+ warning_at (gimple_location (stmt), 0,
+ "direct calls to an offloadable function containing "
+ "metadirectives with a %<construct={target}%> "
+ "selector may produce unexpected results");
+ }
if (fndecl
&& fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
switch (DECL_FUNCTION_CODE (fndecl))
diff --git a/gcc/testsuite/c-c++-common/gomp/metadirective-4.c b/gcc/testsuite/c-c++-common/gomp/metadirective-4.c
index c4b109295db..25efbe046bf 100644
--- a/gcc/testsuite/c-c++-common/gomp/metadirective-4.c
+++ b/gcc/testsuite/c-c++-common/gomp/metadirective-4.c
@@ -25,7 +25,7 @@ void f(double a[], double x) {
/* TODO: This does not execute a version of f with the default clause
active as might be expected. */
- f (a, 2.71828);
+ f (a, 2.71828); /* { dg-warning "direct calls to an offloadable function containing metadirectives with a 'construct={target}' selector may produce unexpected results" } */
return 0;
}
diff --git a/gcc/testsuite/gfortran.dg/gomp/metadirective-4.f90 b/gcc/testsuite/gfortran.dg/gomp/metadirective-4.f90
index b82c9ea96d9..65eb05cd2fb 100644
--- a/gcc/testsuite/gfortran.dg/gomp/metadirective-4.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/metadirective-4.f90
@@ -13,7 +13,7 @@ program test
! TODO: This does not execute a version of f with the default clause
! active as might be expected.
- call f (a, 2.71828)
+ call f (a, 2.71828) ! { dg-warning "direct calls to an offloadable function containing metadirectives with a 'construct={target}' selector may produce unexpected results" }
contains
subroutine f (a, x)
integer :: i
diff --git a/libgomp/testsuite/libgomp.c-c++-common/metadirective-2.c b/libgomp/testsuite/libgomp.c-c++-common/metadirective-2.c
index cd5c6c5e21a..55a6098e525 100644
--- a/libgomp/testsuite/libgomp.c-c++-common/metadirective-2.c
+++ b/libgomp/testsuite/libgomp.c-c++-common/metadirective-2.c
@@ -31,7 +31,7 @@ void f(double a[], double x) {
/* TODO: This does not execute a version of f with the default clause
active as might be expected. */
- f (a, M_E);
+ f (a, M_E); /* { dg-warning "direct calls to an offloadable function containing metadirectives with a 'construct={target}' selector may produce unexpected results" } */
for (i = 0; i < N; i++)
if (fabs (a[i] - (M_E * i)) > EPSILON)
diff --git a/libgomp/testsuite/libgomp.fortran/metadirective-2.f90 b/libgomp/testsuite/libgomp.fortran/metadirective-2.f90
index 32017a00077..d83474cf2db 100644
--- a/libgomp/testsuite/libgomp.fortran/metadirective-2.f90
+++ b/libgomp/testsuite/libgomp.fortran/metadirective-2.f90
@@ -19,7 +19,7 @@ program test
! TODO: This does not execute a version of f with the default clause
! active as might be expected.
- call f (a, E_CONST)
+ call f (a, E_CONST) ! { dg-warning "direct calls to an offloadable function containing metadirectives with a 'construct={target}' selector may produce unexpected results" }
do i = 1, N
if (abs (a(i) - (E_CONST * i)) .gt. EPSILON) stop 2
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-01-28 16:47 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-28 16:47 [gcc/devel/omp/gcc-11] openmp: Add warning when functions containing metadirectives with 'construct={target}' called direct Kwok Yeung
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).