diff mbox

[gomp4.1] Handle new form of #pragma omp declare target

Message ID 20151027211103.GA9097@msticlxl57.ims.intel.com
State New
Headers show

Commit Message

Ilya Verbin Oct. 27, 2015, 9:11 p.m. UTC
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 :(


 
  -- Ilya

Comments

Ilya Verbin Oct. 30, 2015, 5:44 p.m. UTC | #1
On Wed, Oct 28, 2015 at 00:11:03 +0300, Ilya Verbin wrote:
> 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 :(

Ping?  Where should I set node->offloadable for "omp declare target to (list)"
functions, global and static vars?

Thanks,
  -- Ilya
Jakub Jelinek Oct. 30, 2015, 7:12 p.m. UTC | #2
On Fri, Oct 30, 2015 at 08:44:07PM +0300, Ilya Verbin wrote:
> On Wed, Oct 28, 2015 at 00:11:03 +0300, Ilya Verbin wrote:
> > 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 :(
> 
> Ping?  Where should I set node->offloadable for "omp declare target to (list)"
> functions, global and static vars?

Perhaps already somewhere in the FEs?  I mean, when the varpool node is
created after the decl has that attribute, it already should set offsetable
itself, so perhaps when adding the attribute check if corresponding varpool
node exists already (but don't create it) and if yes, set offloadable?

	Jakub
diff mbox

Patch

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