diff options
Diffstat (limited to 'gcc/omp-low.c')
-rw-r--r-- | gcc/omp-low.c | 131 |
1 files changed, 123 insertions, 8 deletions
diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 5643480..676b1df 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -2026,7 +2026,8 @@ scan_sharing_clauses (tree clauses, omp_context *ctx, decl = OMP_CLAUSE_DECL (c); /* Global variables with "omp declare target" attribute don't need to be copied, the receiver side will use them - directly. */ + directly. However, global variables with "omp declare target link" + attribute need to be copied. */ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP && DECL_P (decl) && ((OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER @@ -2034,7 +2035,9 @@ scan_sharing_clauses (tree clauses, omp_context *ctx, != GOMP_MAP_FIRSTPRIVATE_REFERENCE)) || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) && is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)) - && varpool_node::get_create (decl)->offloadable) + && varpool_node::get_create (decl)->offloadable + && !lookup_attribute ("omp declare target link", + DECL_ATTRIBUTES (decl))) break; if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER) @@ -18588,13 +18591,45 @@ add_decls_addresses_to_decl_constructor (vec<tree, va_gc> *v_decls, for (unsigned i = 0; i < len; i++) { tree it = (*v_decls)[i]; - bool is_function = TREE_CODE (it) != VAR_DECL; + bool is_var = TREE_CODE (it) == VAR_DECL; + bool is_link_var + = is_var +#ifdef ACCEL_COMPILER + && DECL_HAS_VALUE_EXPR_P (it) +#endif + && lookup_attribute ("omp declare target link", DECL_ATTRIBUTES (it)); - CONSTRUCTOR_APPEND_ELT (v_ctor, NULL_TREE, build_fold_addr_expr (it)); - if (!is_function) - CONSTRUCTOR_APPEND_ELT (v_ctor, NULL_TREE, - fold_convert (const_ptr_type_node, - DECL_SIZE_UNIT (it))); + tree size = NULL_TREE; + if (is_var) + size = fold_convert (const_ptr_type_node, DECL_SIZE_UNIT (it)); + + tree addr; + if (!is_link_var) + addr = build_fold_addr_expr (it); + else + { +#ifdef ACCEL_COMPILER + /* For "omp declare target link" vars add address of the pointer to + the target table, instead of address of the var. */ + tree value_expr = DECL_VALUE_EXPR (it); + tree link_ptr_decl = TREE_OPERAND (value_expr, 0); + varpool_node::finalize_decl (link_ptr_decl); + addr = build_fold_addr_expr (link_ptr_decl); +#else + addr = build_fold_addr_expr (it); +#endif + + /* Most significant bit of the size marks "omp declare target link" + vars in host and target tables. */ + unsigned HOST_WIDE_INT isize = tree_to_uhwi (size); + isize |= 1ULL << (int_size_in_bytes (const_ptr_type_node) + * BITS_PER_UNIT - 1); + size = wide_int_to_tree (const_ptr_type_node, isize); + } + + CONSTRUCTOR_APPEND_ELT (v_ctor, NULL_TREE, addr); + if (is_var) + CONSTRUCTOR_APPEND_ELT (v_ctor, NULL_TREE, size); } } @@ -19831,4 +19866,84 @@ make_pass_oacc_device_lower (gcc::context *ctxt) return new pass_oacc_device_lower (ctxt); } +/* "omp declare target link" handling pass. */ + +namespace { + +const pass_data pass_data_omp_target_link = +{ + GIMPLE_PASS, /* type */ + "omptargetlink", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + TV_NONE, /* tv_id */ + PROP_ssa, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_update_ssa, /* todo_flags_finish */ +}; + +class pass_omp_target_link : public gimple_opt_pass +{ +public: + pass_omp_target_link (gcc::context *ctxt) + : gimple_opt_pass (pass_data_omp_target_link, ctxt) + {} + + /* opt_pass methods: */ + virtual bool gate (function *fun) + { +#ifdef ACCEL_COMPILER + tree attrs = DECL_ATTRIBUTES (fun->decl); + return lookup_attribute ("omp declare target", attrs) + || lookup_attribute ("omp target entrypoint", attrs); +#else + (void) fun; + return false; +#endif + } + + virtual unsigned execute (function *); +}; + +/* Callback for walk_gimple_stmt used to scan for link var operands. */ + +static tree +find_link_var_op (tree *tp, int *walk_subtrees, void *) +{ + tree t = *tp; + + if (TREE_CODE (t) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (t) + && lookup_attribute ("omp declare target link", DECL_ATTRIBUTES (t))) + { + *walk_subtrees = 0; + return t; + } + + return NULL_TREE; +} + +unsigned +pass_omp_target_link::execute (function *fun) +{ + basic_block bb; + FOR_EACH_BB_FN (bb, fun) + { + gimple_stmt_iterator gsi; + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + if (walk_gimple_stmt (&gsi, NULL, find_link_var_op, NULL)) + gimple_regimplify_operands (gsi_stmt (gsi), &gsi); + } + + return 0; +} + +} // anon namespace + +gimple_opt_pass * +make_pass_omp_target_link (gcc::context *ctxt) +{ + return new pass_omp_target_link (ctxt); +} + #include "gt-omp-low.h" |