On Fri, Jul 17, 2015 at 15:05:59 +0200, Jakub Jelinek wrote: > As the testcases show, #pragma omp declare target has now a new form (well, > two; with some issues on it pending), where it is used just as a single > declarative directive rather than a pair of them and allows marking > vars and functions by name as "omp declare target" vars/functions (which the > middle-end etc. already handles),
There is an issue - such variables are not added to the offloading tables, because when varpool_node::get_create is called for the first time, the variable doesn't yet have "omp declare target" attribute, and when it's called for the second time, it just returns existing node. Functions also aren't marked as offloadable. I tried to fix this by moving the code from varpool_node::get_create to varpool_node::finalize_decl, but it helped only C, but doesn't fix C++. Therefore, I decided to iterate through all functions and variables, like in the patch bellow. But it doesn't work for static vars, declared inside functions, because they do not appear in symtab :( diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 1a64d789..0ba04ef 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -511,16 +511,6 @@ cgraph_node::create (tree decl) gcc_assert (TREE_CODE (decl) == FUNCTION_DECL); node->decl = decl; - - if ((flag_openacc || flag_openmp) - && lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl))) - { - node->offloadable = 1; -#ifdef ENABLE_OFFLOADING - g->have_offload = true; -#endif - } - node->register_symbol (); if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL) diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 04a4d3f..9ac7b36 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -1016,6 +1016,25 @@ analyze_functions (bool first_time) symtab->state = CONSTRUCTION; input_location = UNKNOWN_LOCATION; + /* Process offloadable functions and variables. */ + if (first_time && (flag_openacc || flag_openmp)) + FOR_EACH_SYMBOL (node) + if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (node->decl))) + { + node->offloadable = 1; + +#ifdef ENABLE_OFFLOADING + g->have_offload = true; + + if (TREE_CODE (node->decl) == VAR_DECL && !DECL_EXTERNAL (node->decl)) + { + if (!in_lto_p) + vec_safe_push (offload_vars, node->decl); + node->force_output = 1; + } +#endif + } + /* Ugly, but the fixup can not happen at a time same body alias is created; C++ FE is confused about the COMDAT groups being right. */ if (symtab->cpp_implicit_aliases_done) diff --git a/gcc/varpool.c b/gcc/varpool.c index 7d11e20..077dd40 100644 --- a/gcc/varpool.c +++ b/gcc/varpool.c @@ -154,19 +154,6 @@ varpool_node::get_create (tree decl) node = varpool_node::create_empty (); node->decl = decl; - - if ((flag_openacc || flag_openmp) && !DECL_EXTERNAL (decl) - && lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl))) - { - node->offloadable = 1; -#ifdef ENABLE_OFFLOADING - g->have_offload = true; - if (!in_lto_p) - vec_safe_push (offload_vars, decl); - node->force_output = 1; -#endif - } - node->register_symbol (); return node; } diff --git a/libgomp/testsuite/libgomp.c++/target-13.C b/libgomp/testsuite/libgomp.c++/target-13.C index 376672d..5279ac0 100644 --- a/libgomp/testsuite/libgomp.c++/target-13.C +++ b/libgomp/testsuite/libgomp.c++/target-13.C @@ -1,11 +1,14 @@ extern "C" void abort (void); +int g; +#pragma omp declare target (g) + #pragma omp declare target int foo (void) { static int s; - return ++s; + return ++s + g; } #pragma omp end declare target diff --git a/libgomp/testsuite/libgomp.c/target-28.c b/libgomp/testsuite/libgomp.c/target-28.c index c9a2999..96e9e05 100644 --- a/libgomp/testsuite/libgomp.c/target-28.c +++ b/libgomp/testsuite/libgomp.c/target-28.c @@ -1,11 +1,14 @@ extern void abort (void); +int g; +#pragma omp declare target (g) + #pragma omp declare target int foo (void) { static int s; - return ++s; + return ++s + g; } #pragma omp end declare target -- Ilya