mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-26 22:06:08 +08:00
openmp: Implement discovery of implicit declare target to clauses
This attempts to implement what the OpenMP 5.0 spec in declare target section says as ammended by the 5.1 changes so far (related to device_type(host)), except that it doesn't have the device(ancestor: ...) handling yet because we do not support it yet, and I've left so far out the except lambda note, because I need that clarified. 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. * testsuite/libgomp.c/target-39.c: New test.
This commit is contained in:
parent
fe8c8f1e5e
commit
dc703151d4
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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. */
|
||||
|
@ -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 */
|
||||
|
@ -1,3 +1,7 @@
|
||||
2020-05-12 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* testsuite/libgomp.c/target-39.c: New test.
|
||||
|
||||
2020-04-29 Thomas Schwinge <thomas@codesourcery.com>
|
||||
|
||||
* config/accel/openacc.f90 (acc_device_current): Set to '-1'.
|
||||
|
47
libgomp/testsuite/libgomp.c/target-39.c
Normal file
47
libgomp/testsuite/libgomp.c/target-39.c
Normal file
@ -0,0 +1,47 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-O0" } */
|
||||
|
||||
extern void abort (void);
|
||||
volatile int v;
|
||||
#pragma omp declare target to (v)
|
||||
typedef void (*fnp1) (void);
|
||||
typedef fnp1 (*fnp2) (void);
|
||||
void f1 (void) { v++; }
|
||||
void f2 (void) { v += 4; }
|
||||
void f3 (void) { v += 16; f1 (); }
|
||||
fnp1 f4 (void) { v += 64; return f2; }
|
||||
int a = 1;
|
||||
int *b = &a;
|
||||
int **c = &b;
|
||||
fnp2 f5 (void) { f3 (); return f4; }
|
||||
#pragma omp declare target to (c, f5)
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int err = 0;
|
||||
#pragma omp target map(from:err)
|
||||
{
|
||||
volatile int xa;
|
||||
int *volatile xb;
|
||||
int **volatile xc;
|
||||
fnp2 xd;
|
||||
fnp1 xe;
|
||||
err = 0;
|
||||
xa = a;
|
||||
err |= xa != 1;
|
||||
xb = b;
|
||||
err |= xb != &a;
|
||||
xc = c;
|
||||
err |= xc != &b;
|
||||
xd = f5 ();
|
||||
err |= v != 17;
|
||||
xe = xd ();
|
||||
err |= v != 81;
|
||||
xe ();
|
||||
err |= v != 85;
|
||||
}
|
||||
if (err)
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user