diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/fortran/trans-common.cc | 21 | ||||
-rw-r--r-- | gcc/fortran/trans-decl.cc | 81 |
2 files changed, 76 insertions, 26 deletions
diff --git a/gcc/fortran/trans-common.cc b/gcc/fortran/trans-common.cc index 5f44e7b..e714342 100644 --- a/gcc/fortran/trans-common.cc +++ b/gcc/fortran/trans-common.cc @@ -98,6 +98,9 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "tm.h" #include "tree.h" +#include "cgraph.h" +#include "context.h" +#include "omp-offload.h" #include "gfortran.h" #include "trans.h" #include "stringpool.h" @@ -497,6 +500,24 @@ build_common_decl (gfc_common_head *com, tree union_type, bool is_init) = tree_cons (get_identifier ("omp declare target"), omp_clauses, DECL_ATTRIBUTES (decl)); + if (com->omp_declare_target_link || com->omp_declare_target) + { + /* Add to offload_vars; get_create does so for omp_declare_target, + omp_declare_target_link requires manual work. */ + gcc_assert (symtab_node::get (decl) == 0); + symtab_node *node = symtab_node::get_create (decl); + if (node != NULL && com->omp_declare_target_link) + { + node->offloadable = 1; + if (ENABLE_OFFLOADING) + { + g->have_offload = true; + if (is_a <varpool_node *> (node)) + vec_safe_push (offload_vars, decl); + } + } + } + /* Place the back end declaration for this common block in GLOBAL_BINDING_LEVEL. */ gfc_map_of_all_commons[identifier] = pushdecl_top_level (decl); diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc index 82fa2bb..0fdc41b 100644 --- a/gcc/fortran/trans-decl.cc +++ b/gcc/fortran/trans-decl.cc @@ -46,7 +46,9 @@ along with GCC; see the file COPYING3. If not see #include "trans-stmt.h" #include "gomp-constants.h" #include "gimplify.h" +#include "context.h" #include "omp-general.h" +#include "omp-offload.h" #include "attr-fnspec.h" #include "tree-iterator.h" #include "dependency.h" @@ -1472,19 +1474,18 @@ gfc_add_assign_aux_vars (gfc_symbol * sym) } -static tree -add_attributes_to_decl (symbol_attribute sym_attr, tree list) +static void +add_attributes_to_decl (tree *decl_p, const gfc_symbol *sym) { unsigned id; - tree attr; + tree list = NULL_TREE; + symbol_attribute sym_attr = sym->attr; for (id = 0; id < EXT_ATTR_NUM; id++) if (sym_attr.ext_attr & (1 << id) && ext_attr_list[id].middle_end_name) { - attr = build_tree_list ( - get_identifier (ext_attr_list[id].middle_end_name), - NULL_TREE); - list = chainon (list, attr); + tree ident = get_identifier (ext_attr_list[id].middle_end_name); + list = tree_cons (ident, NULL_TREE, list); } tree clauses = NULL_TREE; @@ -1547,6 +1548,7 @@ add_attributes_to_decl (symbol_attribute sym_attr, tree list) clauses = c; } + bool has_declare = true; if (sym_attr.omp_declare_target_link || sym_attr.oacc_declare_link) list = tree_cons (get_identifier ("omp declare target link"), @@ -1558,12 +1560,45 @@ add_attributes_to_decl (symbol_attribute sym_attr, tree list) || sym_attr.oacc_declare_device_resident) list = tree_cons (get_identifier ("omp declare target"), clauses, list); + else + has_declare = false; if (sym_attr.omp_declare_target_indirect) list = tree_cons (get_identifier ("omp declare target indirect"), clauses, list); - return list; + decl_attributes (decl_p, list, 0); + + if (has_declare + && VAR_P (*decl_p) + && sym->ns->proc_name->attr.flavor != FL_MODULE) + { + has_declare = false; + for (gfc_namespace* ns = sym->ns->contained; ns; ns = ns->sibling) + if (ns->proc_name->attr.omp_declare_target) + { + has_declare = true; + break; + } + } + + if (has_declare && VAR_P (*decl_p) && has_declare) + { + /* Add to offload_vars; get_create does so for omp_declare_target, + omp_declare_target_link requires manual work. */ + gcc_assert (symtab_node::get (*decl_p) == 0); + symtab_node *node = symtab_node::get_create (*decl_p); + if (node != NULL && sym_attr.omp_declare_target_link) + { + node->offloadable = 1; + if (ENABLE_OFFLOADING) + { + g->have_offload = true; + if (is_a <varpool_node *> (node)) + vec_safe_push (offload_vars, *decl_p); + } + } + } } @@ -1578,7 +1613,6 @@ gfc_get_symbol_decl (gfc_symbol * sym) { tree decl; tree length = NULL_TREE; - tree attributes; int byref; bool intrinsic_array_parameter = false; bool fun_or_res; @@ -1864,12 +1898,6 @@ gfc_get_symbol_decl (gfc_symbol * sym) decl = build_decl (gfc_get_location (&sym->declared_at), VAR_DECL, gfc_sym_identifier (sym), gfc_sym_type (sym)); - /* Add attributes to variables. Functions are handled elsewhere. */ - attributes = add_attributes_to_decl (sym->attr, NULL_TREE); - decl_attributes (&decl, attributes, 0); - if (sym->ts.deferred && VAR_P (length)) - decl_attributes (&length, attributes, 0); - /* Symbols from modules should have their assembler names mangled. This is done here rather than in gfc_finish_var_decl because it is different for string length variables. */ @@ -2035,6 +2063,12 @@ gfc_get_symbol_decl (gfc_symbol * sym) TREE_READONLY (decl) = 1; } + /* Add attributes to variables. Functions are handled elsewhere. */ + add_attributes_to_decl (&decl, sym); + + if (sym->ts.deferred && VAR_P (length)) + decl_attributes (&length, DECL_ATTRIBUTES (decl), 0); + return decl; } @@ -2071,7 +2105,6 @@ static tree get_proc_pointer_decl (gfc_symbol *sym) { tree decl; - tree attributes; if (sym->module || sym->fn_result_spec) { @@ -2151,8 +2184,7 @@ get_proc_pointer_decl (gfc_symbol *sym) && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))) set_decl_tls_model (decl, decl_default_tls_model (decl)); - attributes = add_attributes_to_decl (sym->attr, NULL_TREE); - decl_attributes (&decl, attributes, 0); + add_attributes_to_decl (&decl, sym); return decl; } @@ -2166,7 +2198,6 @@ gfc_get_extern_function_decl (gfc_symbol * sym, gfc_actual_arglist *actual_args, { tree type; tree fndecl; - tree attributes; gfc_expr e; gfc_intrinsic_sym *isym; gfc_expr argexpr; @@ -2364,8 +2395,7 @@ module_sym: DECL_EXTERNAL (fndecl) = 1; TREE_PUBLIC (fndecl) = 1; - attributes = add_attributes_to_decl (sym->attr, NULL_TREE); - decl_attributes (&fndecl, attributes, 0); + add_attributes_to_decl (&fndecl, sym); gfc_set_decl_assembler_name (fndecl, mangled_name); @@ -2424,7 +2454,7 @@ module_sym: static void build_function_decl (gfc_symbol * sym, bool global) { - tree fndecl, type, attributes; + tree fndecl, type; symbol_attribute attr; tree result_decl; gfc_formal_arglist *f; @@ -2475,15 +2505,14 @@ build_function_decl (gfc_symbol * sym, bool global) if (sym->attr.referenced || sym->attr.entry_master) TREE_USED (fndecl) = 1; - attributes = add_attributes_to_decl (attr, NULL_TREE); - decl_attributes (&fndecl, attributes, 0); + add_attributes_to_decl (&fndecl, sym); /* Figure out the return type of the declared function, and build a RESULT_DECL for it. If this is a subroutine with alternate returns, build a RESULT_DECL for it. */ result_decl = NULL_TREE; /* TODO: Shouldn't this just be TREE_TYPE (TREE_TYPE (fndecl)). */ - if (attr.function) + if (sym->attr.function) { if (gfc_return_by_reference (sym)) type = void_type_node; @@ -2530,7 +2559,7 @@ build_function_decl (gfc_symbol * sym, bool global) /* Set attributes for PURE functions. A call to a PURE function in the Fortran 95 sense is both pure and without side effects in the C sense. */ - if (attr.pure || attr.implicit_pure) + if (sym->attr.pure || sym->attr.implicit_pure) { /* TODO: check if a pure SUBROUTINE has no INTENT(OUT) arguments including an alternate return. In that case it can also be |