aboutsummaryrefslogtreecommitdiff
path: root/gcc/omp-offload.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-05-14 09:48:32 +0200
committerJakub Jelinek <jakub@redhat.com>2020-05-14 09:48:32 +0200
commit49ddde69fc8e1e4c48d4b0027ea37ac862da0f1f (patch)
tree5cb3ecbf1dbf9cc8e8e3b975b3f83a959e3353de /gcc/omp-offload.c
parent42ef8a5e662a765dc794a7a5c0227bcd83556e44 (diff)
downloadgcc-49ddde69fc8e1e4c48d4b0027ea37ac862da0f1f.zip
gcc-49ddde69fc8e1e4c48d4b0027ea37ac862da0f1f.tar.gz
gcc-49ddde69fc8e1e4c48d4b0027ea37ac862da0f1f.tar.bz2
openmp: Also implicitly mark as declare target to functions mentioned in target regions
OpenMP 5.0 also specifies that functions referenced from target regions (except for target regions with device(ancestor:)) are also implicitly declare target to. This patch implements that. 2020-05-14 Jakub Jelinek <jakub@redhat.com> * function.h (struct function): Add has_omp_target bit. * omp-offload.c (omp_discover_declare_target_fn_r): New function, old renamed to ... (omp_discover_declare_target_tgt_fn_r): ... this. (omp_discover_declare_target_var_r): Call omp_discover_declare_target_tgt_fn_r instead of omp_discover_declare_target_fn_r. (omp_discover_implicit_declare_target): Also queue functions with has_omp_target bit set, for those walk with omp_discover_declare_target_fn_r, for declare target to functions walk with omp_discover_declare_target_tgt_fn_r. gcc/c/ * c-parser.c (c_parser_omp_target): Set cfun->has_omp_target. gcc/cp/ * cp-gimplify.c (cp_genericize_r): Set cfun->has_omp_target. gcc/fortran/ * trans-openmp.c: Include function.h. (gfc_trans_omp_target): Set cfun->has_omp_target. libgomp/ * testsuite/libgomp.c-c++-common/target-40.c: New test.
Diffstat (limited to 'gcc/omp-offload.c')
-rw-r--r--gcc/omp-offload.c44
1 files changed, 36 insertions, 8 deletions
diff --git a/gcc/omp-offload.c b/gcc/omp-offload.c
index c1eb378..3e7012d 100644
--- a/gcc/omp-offload.c
+++ b/gcc/omp-offload.c
@@ -190,7 +190,7 @@ omp_declare_target_var_p (tree decl)
declare target to. */
static tree
-omp_discover_declare_target_fn_r (tree *tp, int *walk_subtrees, void *data)
+omp_discover_declare_target_tgt_fn_r (tree *tp, int *walk_subtrees, void *data)
{
if (TREE_CODE (*tp) == FUNCTION_DECL
&& !omp_declare_target_fn_p (*tp)
@@ -219,6 +219,24 @@ omp_discover_declare_target_fn_r (tree *tp, int *walk_subtrees, void *data)
return NULL_TREE;
}
+/* Similarly, but ignore references outside of OMP_TARGET regions. */
+
+static tree
+omp_discover_declare_target_fn_r (tree *tp, int *walk_subtrees, void *data)
+{
+ if (TREE_CODE (*tp) == OMP_TARGET)
+ {
+ /* And not OMP_DEVICE_ANCESTOR. */
+ walk_tree_without_duplicates (&OMP_TARGET_BODY (*tp),
+ omp_discover_declare_target_tgt_fn_r,
+ data);
+ *walk_subtrees = 0;
+ }
+ else if (TYPE_P (*tp))
+ *walk_subtrees = 0;
+ return NULL_TREE;
+}
+
/* Helper function for omp_discover_implicit_declare_target, called through
walk_tree. Mark referenced FUNCTION_DECLs implicitly as
declare target to. */
@@ -227,7 +245,7 @@ static tree
omp_discover_declare_target_var_r (tree *tp, int *walk_subtrees, void *data)
{
if (TREE_CODE (*tp) == FUNCTION_DECL)
- return omp_discover_declare_target_fn_r (tp, walk_subtrees, data);
+ return omp_discover_declare_target_tgt_fn_r (tp, walk_subtrees, data);
else if (VAR_P (*tp)
&& is_global_var (*tp)
&& !omp_declare_target_var_p (*tp))
@@ -271,21 +289,31 @@ omp_discover_implicit_declare_target (void)
auto_vec<tree> worklist;
FOR_EACH_DEFINED_FUNCTION (node)
- if (omp_declare_target_fn_p (node->decl) && DECL_SAVED_TREE (node->decl))
- worklist.safe_push (node->decl);
+ if (DECL_SAVED_TREE (node->decl))
+ {
+ if (omp_declare_target_fn_p (node->decl))
+ worklist.safe_push (node->decl);
+ else if (DECL_STRUCT_FUNCTION (node->decl)
+ && DECL_STRUCT_FUNCTION (node->decl)->has_omp_target)
+ worklist.safe_push (node->decl);
+ }
FOR_EACH_STATIC_INITIALIZER (vnode)
if (omp_declare_target_var_p (vnode->decl))
worklist.safe_push (vnode->decl);
while (!worklist.is_empty ())
{
tree decl = worklist.pop ();
- if (TREE_CODE (decl) == FUNCTION_DECL)
+ if (VAR_P (decl))
+ walk_tree_without_duplicates (&DECL_INITIAL (decl),
+ omp_discover_declare_target_var_r,
+ &worklist);
+ else if (omp_declare_target_fn_p (decl))
walk_tree_without_duplicates (&DECL_SAVED_TREE (decl),
- omp_discover_declare_target_fn_r,
+ omp_discover_declare_target_tgt_fn_r,
&worklist);
else
- walk_tree_without_duplicates (&DECL_INITIAL (decl),
- omp_discover_declare_target_var_r,
+ walk_tree_without_duplicates (&DECL_SAVED_TREE (decl),
+ omp_discover_declare_target_fn_r,
&worklist);
}
}