diff options
Diffstat (limited to 'gcc/omp-low.c')
-rw-r--r-- | gcc/omp-low.c | 54 |
1 files changed, 36 insertions, 18 deletions
diff --git a/gcc/omp-low.c b/gcc/omp-low.c index e7d8a7e..8ac5d94 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -86,6 +86,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-nested.h" #include "tree-eh.h" #include "cilk.h" +#include "context.h" /* Lowering of OpenMP parallel and workshare constructs proceeds in two @@ -273,6 +274,16 @@ is_parallel_ctx (omp_context *ctx) } +/* Return true if CTX is for an omp target region. */ + +static inline bool +is_targetreg_ctx (omp_context *ctx) +{ + return gimple_code (ctx->stmt) == GIMPLE_OMP_TARGET + && gimple_omp_target_kind (ctx->stmt) == GF_OMP_TARGET_KIND_REGION; +} + + /* Return true if CTX is for an omp task. */ static inline bool @@ -1642,8 +1653,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx) if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP && DECL_P (decl) && is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)) - && lookup_attribute ("omp declare target", - DECL_ATTRIBUTES (decl))) + && varpool_node::get_create (decl)->offloadable) break; if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP && OMP_CLAUSE_MAP_KIND (c) == OMP_CLAUSE_MAP_POINTER) @@ -1783,8 +1793,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx) decl = OMP_CLAUSE_DECL (c); if (DECL_P (decl) && is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)) - && lookup_attribute ("omp declare target", - DECL_ATTRIBUTES (decl))) + && varpool_node::get_create (decl)->offloadable) break; if (DECL_P (decl)) { @@ -1938,26 +1947,19 @@ create_omp_child_function (omp_context *ctx, bool task_copy) DECL_EXTERNAL (decl) = 0; DECL_CONTEXT (decl) = NULL_TREE; DECL_INITIAL (decl) = make_node (BLOCK); - bool target_p = false; - if (lookup_attribute ("omp declare target", - DECL_ATTRIBUTES (current_function_decl))) - target_p = true; + if (cgraph_node::get (current_function_decl)->offloadable) + cgraph_node::get_create (decl)->offloadable = 1; else { omp_context *octx; for (octx = ctx; octx; octx = octx->outer) - if (gimple_code (octx->stmt) == GIMPLE_OMP_TARGET - && gimple_omp_target_kind (octx->stmt) - == GF_OMP_TARGET_KIND_REGION) + if (is_targetreg_ctx (octx)) { - target_p = true; + cgraph_node::get_create (decl)->offloadable = 1; + g->have_offload = true; break; } } - if (target_p) - DECL_ATTRIBUTES (decl) - = tree_cons (get_identifier ("omp declare target"), - NULL_TREE, DECL_ATTRIBUTES (decl)); t = build_decl (DECL_SOURCE_LOCATION (decl), RESULT_DECL, NULL_TREE, void_type_node); @@ -2663,8 +2665,7 @@ check_omp_nesting_restrictions (gimple stmt, omp_context *ctx) break; case GIMPLE_OMP_TARGET: for (; ctx != NULL; ctx = ctx->outer) - if (gimple_code (ctx->stmt) == GIMPLE_OMP_TARGET - && gimple_omp_target_kind (ctx->stmt) == GF_OMP_TARGET_KIND_REGION) + if (is_targetreg_ctx (ctx)) { const char *name; switch (gimple_omp_target_kind (stmt)) @@ -8281,6 +8282,7 @@ expand_omp_target (struct omp_region *region) if (kind == GF_OMP_TARGET_KIND_REGION) { unsigned srcidx, dstidx, num; + struct cgraph_node *node; /* If the target region needs data sent from the parent function, then the very first statement (except possible @@ -8412,6 +8414,11 @@ expand_omp_target (struct omp_region *region) push_cfun (child_cfun); cgraph_edge::rebuild_edges (); + /* Prevent IPA from removing child_fn as unreachable, since there are no + refs from the parent function to child_fn in offload LTO mode. */ + node = cgraph_node::get (child_fn); + node->mark_force_output (); + /* Some EH regions might become dead, see PR34608. If pass_cleanup_cfg isn't the first pass to happen with the new child, these dead EH edges might cause problems. @@ -9326,6 +9333,17 @@ lower_omp_critical (gimple_stmt_iterator *gsi_p, omp_context *ctx) DECL_COMMON (decl) = 1; DECL_ARTIFICIAL (decl) = 1; DECL_IGNORED_P (decl) = 1; + + /* If '#pragma omp critical' is inside target region, the symbol must + be marked for offloading. */ + omp_context *octx; + for (octx = ctx->outer; octx; octx = octx->outer) + if (is_targetreg_ctx (octx)) + { + varpool_node::get_create (decl)->offloadable = 1; + break; + } + varpool_node::finalize_decl (decl); splay_tree_insert (critical_name_mutexes, (splay_tree_key) name, |