diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cgraphunit.c | 4 | ||||
-rw-r--r-- | gcc/omp-offload.c | 133 | ||||
-rw-r--r-- | gcc/omp-offload.h | 1 |
4 files changed, 148 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bd84f8f..ffa0055 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2020-05-12 Jakub Jelinek <jakub@redhat.com> + + * omp-offload.h (omp_discover_implicit_declare_target): Declare. + * omp-offload.c: Include context.h. + (omp_declare_target_fn_p, omp_declare_target_var_p, + omp_discover_declare_target_fn_r, omp_discover_declare_target_var_r, + omp_discover_implicit_declare_target): New functions. + * cgraphunit.c (analyze_functions): Call + omp_discover_implicit_declare_target. + 2020-05-12 Richard Biener <rguenther@suse.de> * gimple-fold.c (maybe_canonicalize_mem_ref_addr): Canonicalize diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 0563932..01b3f82 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -206,6 +206,7 @@ along with GCC; see the file COPYING3. If not see #include "stringpool.h" #include "attribs.h" #include "ipa-inline.h" +#include "omp-offload.h" /* Queue of cgraph nodes scheduled to be added into cgraph. This is a secondary queue used during optimization to accommodate passes that @@ -1160,6 +1161,9 @@ analyze_functions (bool first_time) node->fixup_same_cpp_alias_visibility (node->get_alias_target ()); build_type_inheritance_graph (); + if (flag_openmp && first_time) + omp_discover_implicit_declare_target (); + /* Analysis adds static variables that in turn adds references to new functions. So we need to iterate the process until it stabilize. */ while (changed) diff --git a/gcc/omp-offload.c b/gcc/omp-offload.c index c66f38b..c1eb378 100644 --- a/gcc/omp-offload.c +++ b/gcc/omp-offload.c @@ -52,6 +52,7 @@ along with GCC; see the file COPYING3. If not see #include "stringpool.h" #include "attribs.h" #include "cfgloop.h" +#include "context.h" /* Describe the OpenACC looping structure of a function. The entire function is held in a 'NULL' loop. */ @@ -158,6 +159,138 @@ add_decls_addresses_to_decl_constructor (vec<tree, va_gc> *v_decls, } } +/* Return true if DECL is a function for which its references should be + analyzed. */ + +static bool +omp_declare_target_fn_p (tree decl) +{ + return (TREE_CODE (decl) == FUNCTION_DECL + && lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl)) + && !lookup_attribute ("omp declare target host", + DECL_ATTRIBUTES (decl)) + && (!flag_openacc + || oacc_get_fn_attrib (decl) == NULL_TREE)); +} + +/* Return true if DECL Is a variable for which its initializer references + should be analyzed. */ + +static bool +omp_declare_target_var_p (tree decl) +{ + return (VAR_P (decl) + && lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl)) + && !lookup_attribute ("omp declare target link", + DECL_ATTRIBUTES (decl))); +} + +/* Helper function for omp_discover_implicit_declare_target, called through + walk_tree. Mark referenced FUNCTION_DECLs implicitly as + declare target to. */ + +static tree +omp_discover_declare_target_fn_r (tree *tp, int *walk_subtrees, void *data) +{ + if (TREE_CODE (*tp) == FUNCTION_DECL + && !omp_declare_target_fn_p (*tp) + && !lookup_attribute ("omp declare target host", DECL_ATTRIBUTES (*tp))) + { + tree id = get_identifier ("omp declare target"); + if (!DECL_EXTERNAL (*tp) && DECL_SAVED_TREE (*tp)) + ((vec<tree> *) data)->safe_push (*tp); + DECL_ATTRIBUTES (*tp) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (*tp)); + symtab_node *node = symtab_node::get (*tp); + if (node != NULL) + { + node->offloadable = 1; + if (ENABLE_OFFLOADING) + g->have_offload = true; + } + } + else if (TYPE_P (*tp)) + *walk_subtrees = 0; + /* else if (TREE_CODE (*tp) == OMP_TARGET) + { + if (tree dev = omp_find_clause (OMP_TARGET_CLAUSES (*tp))) + if (OMP_DEVICE_ANCESTOR (dev)) + *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. */ + +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); + else if (VAR_P (*tp) + && is_global_var (*tp) + && !omp_declare_target_var_p (*tp)) + { + tree id = get_identifier ("omp declare target"); + if (lookup_attribute ("omp declare target link", DECL_ATTRIBUTES (*tp))) + { + error_at (DECL_SOURCE_LOCATION (*tp), + "%qD specified both in declare target %<link%> and " + "implicitly in %<to%> clauses", *tp); + DECL_ATTRIBUTES (*tp) + = remove_attribute ("omp declare target link", DECL_ATTRIBUTES (*tp)); + } + if (TREE_STATIC (*tp) && DECL_INITIAL (*tp)) + ((vec<tree> *) data)->safe_push (*tp); + DECL_ATTRIBUTES (*tp) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (*tp)); + symtab_node *node = symtab_node::get (*tp); + if (node != NULL && !node->offloadable) + { + node->offloadable = 1; + if (ENABLE_OFFLOADING) + { + g->have_offload = true; + if (is_a <varpool_node *> (node)) + vec_safe_push (offload_vars, node->decl); + } + } + } + else if (TYPE_P (*tp)) + *walk_subtrees = 0; + return NULL_TREE; +} + +/* Perform the OpenMP implicit declare target to discovery. */ + +void +omp_discover_implicit_declare_target (void) +{ + cgraph_node *node; + varpool_node *vnode; + 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); + 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) + walk_tree_without_duplicates (&DECL_SAVED_TREE (decl), + omp_discover_declare_target_fn_r, + &worklist); + else + walk_tree_without_duplicates (&DECL_INITIAL (decl), + omp_discover_declare_target_var_r, + &worklist); + } +} + + /* Create new symbols containing (address, size) pairs for global variables, marked with "omp declare target" attribute, as well as addresses for the functions, which are outlined offloading regions. */ diff --git a/gcc/omp-offload.h b/gcc/omp-offload.h index 6adc576..0809189 100644 --- a/gcc/omp-offload.h +++ b/gcc/omp-offload.h @@ -30,5 +30,6 @@ extern GTY(()) vec<tree, va_gc> *offload_funcs; extern GTY(()) vec<tree, va_gc> *offload_vars; extern void omp_finish_file (void); +extern void omp_discover_implicit_declare_target (void); #endif /* GCC_OMP_DEVICE_H */ |