diff options
author | Jakub Jelinek <jakub@redhat.com> | 2020-05-14 09:48:32 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2020-05-14 09:48:32 +0200 |
commit | 49ddde69fc8e1e4c48d4b0027ea37ac862da0f1f (patch) | |
tree | 5cb3ecbf1dbf9cc8e8e3b975b3f83a959e3353de /gcc/omp-offload.c | |
parent | 42ef8a5e662a765dc794a7a5c0227bcd83556e44 (diff) | |
download | gcc-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.c | 44 |
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); } } |