public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] openmp: Implicit 'declare target' for C++ static initializers
@ 2020-10-28 14:20 Kwok Cheung Yeung
  2020-10-29 10:03 ` Jakub Jelinek
  0 siblings, 1 reply; 10+ messages in thread
From: Kwok Cheung Yeung @ 2020-10-28 14:20 UTC (permalink / raw)
  To: Jakub Jelinek, GCC Patches

[-- Attachment #1: Type: text/plain, Size: 1247 bytes --]

Hello

OpenMP 5.0 has a new feature for implicitly marking variables and functions that 
are referenced in the initializers of static variables and functions that are 
already marked 'declare target'. Support was added in the commit 'openmp: 
Implement discovery of implicit declare target to clauses' 
(dc703151d4f4560e647649506d5b4ceb0ee11e90). However, this does not work with 
non-constant C++ initializers, where the initializers can contain references to 
other (non-constant) variables and function calls.

The C++ front-end stores the initialization information in the static_aggregates 
list (with the variable decl in the TREE_VALUE of an entry and the 
initialization in TREE_PURPOSE) rather than in TREE_INITIAL(var_decl). I have 
added an extra function in omp-offload.cpp to walk the variable initialiser 
trees in static_aggregates, and added a call to it from the FE shortly before 
the initializations are emitted. I have also added a testcase to ensure that the 
implicitly marked variables/functions can be referenced in offloaded code.

The libgomp tests have been run with offloading to a Nvidia card with no 
regressions, and I have also bootstrapped the compiler with no offloading on 
x86-64. Okay for trunk?

Thanks

Kwok

[-- Attachment #2: c++_init_implicit_target.patch --]
[-- Type: text/plain, Size: 4741 bytes --]

commit d2c8c5bd2826851b727e93a8ea2141596e50a621
Author: Kwok Cheung Yeung <kcy@codesourcery.com>
Date:   Wed Oct 28 07:13:14 2020 -0700

    openmp: Implicitly add 'declare target' directives for dynamic static initializers in C++
    
    2020-10-28  Kwok Cheung Yeung  <kcy@codesourcery.com>
    
    	cp/
    	* decl2.c: Include omp-offload.h
    	(c_parse_final_cleanups): Call omp_mark_target_static_initializers.
    	* omp-offload.c (omp_discover_declare_target_var_r): Add all static
    	variables to worklist.
    	(omp_discover_implicit_declare_target): Check that worklist items
    	that are variable declarations have an initialization expression
    	before walking.
    	(omp_mark_target_static_initializers): New.
    	* omp-offload.h	(omp_mark_target_static_initializers): New prototype.
    
    	libgomp/
    	* testsuite/libgomp.c++/declare_target-3.C: New.

diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 2f0d637..b207d58 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -48,6 +48,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "intl.h"
 #include "c-family/c-ada-spec.h"
 #include "asan.h"
+#include "omp-offload.h"
 
 /* Id for dumping the raw trees.  */
 int raw_dump_id;
@@ -4970,6 +4971,12 @@ c_parse_final_cleanups (void)
 	  /* Make sure the back end knows about all the variables.  */
 	  write_out_vars (vars);
 
+	  /* Mark functions and variables in static initializers as
+	     'omp declare target' if the initialized variable is marked
+	     as such.  */
+	  if (flag_openmp)
+	    omp_mark_target_static_initializers (vars);
+
 	  /* Set the line and file, so that it is obviously not from
 	     the source file.  */
 	  input_location = locus_at_end_of_parsing;
diff --git a/gcc/omp-offload.c b/gcc/omp-offload.c
index 3e9c31d..8ecc181 100644
--- a/gcc/omp-offload.c
+++ b/gcc/omp-offload.c
@@ -296,7 +296,7 @@ omp_discover_declare_target_var_r (tree *tp, int *walk_subtrees, void *data)
 	  DECL_ATTRIBUTES (*tp)
 	    = remove_attribute ("omp declare target link", DECL_ATTRIBUTES (*tp));
 	}
-      if (TREE_STATIC (*tp) && DECL_INITIAL (*tp))
+      if (TREE_STATIC (*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);
@@ -348,7 +348,7 @@ omp_discover_implicit_declare_target (void)
   while (!worklist.is_empty ())
     {
       tree decl = worklist.pop ();
-      if (VAR_P (decl))
+      if (VAR_P (decl) && DECL_INITIAL (decl))
 	walk_tree_without_duplicates (&DECL_INITIAL (decl),
 				      omp_discover_declare_target_var_r,
 				      &worklist);
@@ -363,6 +363,33 @@ omp_discover_implicit_declare_target (void)
     }
 }
 
+void
+omp_mark_target_static_initializers (tree vars)
+{
+  tree node;
+  auto_vec<tree> worklist;
+
+  for (node = vars; node; node = TREE_CHAIN (node))
+    if (omp_declare_target_var_p (TREE_VALUE (node)))
+	worklist.safe_push (TREE_VALUE (node));
+
+  while (!worklist.is_empty ())
+    {
+      tree decl = worklist.pop ();
+
+      if (!VAR_P (decl) || !TREE_STATIC (decl))
+	continue;
+
+      for (node = vars; node; node = TREE_CHAIN (node))
+	if (TREE_VALUE (node) == decl)
+	  {
+	    walk_tree_without_duplicates (&TREE_PURPOSE (node),
+					  omp_discover_declare_target_var_r,
+					  &worklist);
+	    break;
+	  }
+    }
+}
 
 /* Create new symbols containing (address, size) pairs for global variables,
    marked with "omp declare target" attribute, as well as addresses for the
diff --git a/gcc/omp-offload.h b/gcc/omp-offload.h
index 0809189..a23a4d3 100644
--- a/gcc/omp-offload.h
+++ b/gcc/omp-offload.h
@@ -31,5 +31,6 @@ extern GTY(()) vec<tree, va_gc> *offload_vars;
 
 extern void omp_finish_file (void);
 extern void omp_discover_implicit_declare_target (void);
+extern void omp_mark_target_static_initializers (tree vars);
 
 #endif /* GCC_OMP_DEVICE_H */
diff --git a/libgomp/testsuite/libgomp.c++/declare_target-3.C b/libgomp/testsuite/libgomp.c++/declare_target-3.C
new file mode 100644
index 0000000..c545613
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/declare_target-3.C
@@ -0,0 +1,36 @@
+/* { dg-do run } */
+/* { dg-additional-options "-fdump-tree-gimple" } */
+
+#include <stdlib.h>
+
+int f()
+{
+  return 54321;
+}
+
+int g()
+{
+  return 3333;
+}
+
+static int x = f() + 7777;
+static int y = g() + x + 12345;
+
+#pragma omp declare target(y)
+
+int main()
+{
+  int err = 0;
+  #pragma omp target map(from:err)
+  {
+    err |= x != 62098;
+    err |= y != 77776;
+    err |= f() != 54321;
+    err |= g() != 3333;
+  }
+  if (err)
+    abort ();
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "__attribute__\\(\\(omp declare target\\)\\)" 2 "gimple" } } */

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2020-12-18 20:21 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-28 14:20 [PATCH] openmp: Implicit 'declare target' for C++ static initializers Kwok Cheung Yeung
2020-10-29 10:03 ` Jakub Jelinek
2020-11-19 18:07   ` Kwok Cheung Yeung
2020-11-27 21:55     ` PING " Kwok Cheung Yeung
2020-12-08 16:24     ` Jakub Jelinek
2020-12-18 15:10       ` Kwok Cheung Yeung
2020-12-18 15:47         ` Jakub Jelinek
2020-12-18 19:31         ` Jakub Jelinek
2020-12-18 20:15           ` Kwok Cheung Yeung
2020-12-18 20:21             ` Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).