From 1f6be68256cac22721f42085e014ad0c26e6dbb9 Mon Sep 17 00:00:00 2001 From: Ilya Verbin Date: Thu, 13 Nov 2014 13:37:38 +0000 Subject: [PATCH] [PATCH 2/7] OpenMP 4.0 offloading infrastructure: LTO streaming. gcc/ * cgraph.c: Include context.h. (cgraph_node::create): Set node->offloadable and g->have_offload if decl have "omp declare target" attribute. * cgraph.h (symtab_node): Add need_lto_streaming and offloadable flags. * cgraphunit.c: Include lto-section-names.h. (ipa_passes): Call ipa_write_summaries if there is something to write to OFFLOAD_SECTION_NAME_PREFIX sections. (symbol_table::compile): Set flag_generate_lto if there is something to offload. Replace flag_lto with flag_generate_lto before lto_streamer_hooks_init. * context.c (gcc::context::context): Initialize have_offload with false. * context.h (class context): Add have_offload flag. * ipa-inline-analysis.c (inline_generate_summary): Do not exit under flag_generate_lto. (inline_free_summary): Always remove hooks. * lto-cgraph.c (referenced_from_other_partition_p): Ignore references from non-offloadable nodes while streaming a node into offload section. (reachable_from_other_partition_p): Likewise. (select_what_to_stream): New function. (compute_ltrans_boundary): Do not call lto_set_symtab_encoder_in_partition if the node should not be streamed. * lto-section-names.h (OFFLOAD_SECTION_NAME_PREFIX): Define. (section_name_prefix): Declare. * lto-streamer.c (section_name_prefix): New variable. (lto_get_section_name): Use section_name_prefix instead of LTO_SECTION_NAME_PREFIX. * lto-streamer.h (select_what_to_stream): Declare. * omp-low.c: Include context.h. (is_targetreg_ctx): New function. (scan_sharing_clauses): Use offloadable flag, instead of an attribute. (create_omp_child_function, check_omp_nesting_restrictions): Use new is_targetreg_ctx function. Replace usage of "omp declare target" attribute with a cgraph_node flag offloadable. (expand_omp_target): Set mark_force_output for offloadable functions. (lower_omp_critical): Set offloadable flag for omp critical symbol. * passes.c (ipa_write_summaries): New argument offload_lto_mode. Call select_what_to_stream. Do not call lto_set_symtab_encoder_in_partition if the node should not be streamed out. * tree-pass.h (ipa_write_summaries): New bool argument. * varpool.c: Include context.h. (varpool_node::get_create): Set node->offloadable and g->have_offload if decl have "omp declare target" attribute. gcc/lto/ * lto-object.c (lto_obj_add_section): Use section_name_prefix instead of LTO_SECTION_NAME_PREFIX. * lto-partition.c (lto_promote_cross_file_statics): Call select_what_to_stream. * lto.c (lto_section_with_id): Use section_name_prefix instead of LTO_SECTION_NAME_PREFIX. (read_cgraph_and_symbols): Read OFFLOAD_SECTION_NAME_PREFIX sections, if being built as an offload compiler. Co-Authored-By: Andrey Turetskiy Co-Authored-By: Bernd Schmidt Co-Authored-By: Michael Zolotukhin From-SVN: r217486 --- gcc/ChangeLog | 48 +++++++++++++++++++++++++++++++++++++++++ gcc/cgraph.c | 9 ++++++++ gcc/cgraph.h | 7 ++++++ gcc/cgraphunit.c | 20 ++++++++++++++++-- gcc/context.c | 2 ++ gcc/context.h | 3 +++ gcc/ipa-inline-analysis.c | 12 +++++------ gcc/lto-cgraph.c | 32 +++++++++++++++++++++++++--- gcc/lto-section-names.h | 5 +++++ gcc/lto-streamer.c | 3 ++- gcc/lto-streamer.h | 1 + gcc/lto/ChangeLog | 14 ++++++++++++ gcc/lto/lto-object.c | 3 +-- gcc/lto/lto-partition.c | 2 ++ gcc/lto/lto.c | 6 +++++- gcc/omp-low.c | 54 +++++++++++++++++++++++++++++++---------------- gcc/passes.c | 11 ++++++---- gcc/tree-pass.h | 2 +- gcc/varpool.c | 9 ++++++++ 19 files changed, 205 insertions(+), 38 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 80df1888a3b..316a00a74b3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,51 @@ +2014-11-13 Ilya Verbin + Bernd Schmidt + Andrey Turetskiy + Michael Zolotukhin + + * cgraph.c: Include context.h. + (cgraph_node::create): Set node->offloadable and g->have_offload if + decl have "omp declare target" attribute. + * cgraph.h (symtab_node): Add need_lto_streaming and offloadable flags. + * cgraphunit.c: Include lto-section-names.h. + (ipa_passes): Call ipa_write_summaries if there is something to write to + OFFLOAD_SECTION_NAME_PREFIX sections. + (symbol_table::compile): Set flag_generate_lto if there is something to + offload. + Replace flag_lto with flag_generate_lto before lto_streamer_hooks_init. + * context.c (gcc::context::context): Initialize have_offload with false. + * context.h (class context): Add have_offload flag. + * ipa-inline-analysis.c (inline_generate_summary): Do not exit under + flag_generate_lto. + (inline_free_summary): Always remove hooks. + * lto-cgraph.c (referenced_from_other_partition_p): Ignore references + from non-offloadable nodes while streaming a node into offload section. + (reachable_from_other_partition_p): Likewise. + (select_what_to_stream): New function. + (compute_ltrans_boundary): Do not call + lto_set_symtab_encoder_in_partition if the node should not be streamed. + * lto-section-names.h (OFFLOAD_SECTION_NAME_PREFIX): Define. + (section_name_prefix): Declare. + * lto-streamer.c (section_name_prefix): New variable. + (lto_get_section_name): Use section_name_prefix instead of + LTO_SECTION_NAME_PREFIX. + * lto-streamer.h (select_what_to_stream): Declare. + * omp-low.c: Include context.h. + (is_targetreg_ctx): New function. + (scan_sharing_clauses): Use offloadable flag, instead of an attribute. + (create_omp_child_function, check_omp_nesting_restrictions): Use new + is_targetreg_ctx function. Replace usage of "omp declare target" + attribute with a cgraph_node flag offloadable. + (expand_omp_target): Set mark_force_output for offloadable functions. + (lower_omp_critical): Set offloadable flag for omp critical symbol. + * passes.c (ipa_write_summaries): New argument offload_lto_mode. Call + select_what_to_stream. Do not call lto_set_symtab_encoder_in_partition + if the node should not be streamed out. + * tree-pass.h (ipa_write_summaries): New bool argument. + * varpool.c: Include context.h. + (varpool_node::get_create): Set node->offloadable and g->have_offload if + decl have "omp declare target" attribute. + 2014-11-13 Bernd Schmidt Thomas Schwinge Ilya Verbin diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 7216b897184..8dcccbf19c6 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -81,6 +81,7 @@ along with GCC; see the file COPYING3. If not see #include "profile.h" #include "params.h" #include "tree-chkp.h" +#include "context.h" /* FIXME: Only for PROP_loops, but cgraph shouldn't have to know about this. */ #include "tree-pass.h" @@ -494,6 +495,14 @@ cgraph_node::create (tree decl) gcc_assert (TREE_CODE (decl) == FUNCTION_DECL); node->decl = decl; + + if (flag_openmp + && lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl))) + { + node->offloadable = 1; + g->have_offload = true; + } + node->register_symbol (); if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL) diff --git a/gcc/cgraph.h b/gcc/cgraph.h index e2becb96d56..1395bc1b4d9 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -450,6 +450,13 @@ public: /* Set when init priority is set. */ unsigned in_init_priority_hash : 1; + /* Set when symbol needs to be streamed into LTO bytecode for LTO, or in case + of offloading, for separate compilation for a different target. */ + unsigned need_lto_streaming : 1; + + /* Set when symbol can be streamed into bytecode for offloading. */ + unsigned offloadable : 1; + /* Ordering of all symtab entries. */ int order; diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 25af2347f42..9f49ed05f6e 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -224,6 +224,7 @@ along with GCC; see the file COPYING3. If not see #include "gimplify.h" #include "dbgcnt.h" #include "tree-chkp.h" +#include "lto-section-names.h" /* Queue of cgraph nodes scheduled to be added into cgraph. This is a secondary queue used during optimization to accommodate passes that @@ -2079,7 +2080,18 @@ ipa_passes (void) targetm.asm_out.lto_start (); if (!in_lto_p) - ipa_write_summaries (); + { + if (g->have_offload) + { + section_name_prefix = OFFLOAD_SECTION_NAME_PREFIX; + ipa_write_summaries (true); + } + if (flag_lto) + { + section_name_prefix = LTO_SECTION_NAME_PREFIX; + ipa_write_summaries (false); + } + } if (flag_generate_lto) targetm.asm_out.lto_end (); @@ -2163,8 +2175,12 @@ symbol_table::compile (void) fprintf (stderr, "Performing interprocedural optimizations\n"); state = IPA; + /* Offloading requires LTO infrastructure. */ + if (!in_lto_p && g->have_offload) + flag_generate_lto = 1; + /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */ - if (flag_lto) + if (flag_generate_lto) lto_streamer_hooks_init (); /* Don't run the IPA passes if there was any error or sorry messages. */ diff --git a/gcc/context.c b/gcc/context.c index 5339e28a98b..9279be40dd7 100644 --- a/gcc/context.c +++ b/gcc/context.c @@ -30,6 +30,8 @@ gcc::context *g; gcc::context::context () { + have_offload = false; + /* The pass manager's constructor uses the dump manager (to set up dumps for the various passes), so the dump manager must be set up before the pass manager. */ diff --git a/gcc/context.h b/gcc/context.h index b8fb439f1af..689ae5ad187 100644 --- a/gcc/context.h +++ b/gcc/context.h @@ -33,6 +33,9 @@ class context public: context (); + /* The flag shows if there are symbols to be streamed for offloading. */ + bool have_offload; + /* Pass-management. */ pass_manager *get_passes () { gcc_assert (m_passes); return m_passes; } diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c index eb1c6ec2d0d..0373b108699 100644 --- a/gcc/ipa-inline-analysis.c +++ b/gcc/ipa-inline-analysis.c @@ -4024,7 +4024,7 @@ inline_generate_summary (void) /* When not optimizing, do not bother to analyze. Inlining is still done because edge redirection needs to happen there. */ - if (!optimize && !flag_lto && !flag_wpa) + if (!optimize && !flag_generate_lto && !flag_wpa) return; function_insertion_hook_holder = @@ -4339,11 +4339,6 @@ void inline_free_summary (void) { struct cgraph_node *node; - if (!inline_edge_summary_vec.exists ()) - return; - FOR_EACH_DEFINED_FUNCTION (node) - if (!node->alias) - reset_inline_summary (node); if (function_insertion_hook_holder) symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder); function_insertion_hook_holder = NULL; @@ -4359,6 +4354,11 @@ inline_free_summary (void) if (edge_duplication_hook_holder) symtab->remove_edge_duplication_hook (edge_duplication_hook_holder); edge_duplication_hook_holder = NULL; + if (!inline_edge_summary_vec.exists ()) + return; + FOR_EACH_DEFINED_FUNCTION (node) + if (!node->alias) + reset_inline_summary (node); vec_free (inline_summary_vec); inline_edge_summary_vec.release (); if (edge_predicate_pool) diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c index da1f0e44682..fc8410c1c3e 100644 --- a/gcc/lto-cgraph.c +++ b/gcc/lto-cgraph.c @@ -330,6 +330,11 @@ referenced_from_other_partition_p (symtab_node *node, lto_symtab_encoder_t encod for (i = 0; node->iterate_referring (i, ref); i++) { + /* Ignore references from non-offloadable nodes while streaming NODE into + offload LTO section. */ + if (!ref->referring->need_lto_streaming) + continue; + if (ref->referring->in_other_partition || !lto_symtab_encoder_in_partition_p (encoder, ref->referring)) return true; @@ -348,9 +353,16 @@ reachable_from_other_partition_p (struct cgraph_node *node, lto_symtab_encoder_t if (node->global.inlined_to) return false; for (e = node->callers; e; e = e->next_caller) - if (e->caller->in_other_partition - || !lto_symtab_encoder_in_partition_p (encoder, e->caller)) - return true; + { + /* Ignore references from non-offloadable nodes while streaming NODE into + offload LTO section. */ + if (!e->caller->need_lto_streaming) + continue; + + if (e->caller->in_other_partition + || !lto_symtab_encoder_in_partition_p (encoder, e->caller)) + return true; + } return false; } @@ -818,6 +830,16 @@ create_references (lto_symtab_encoder_t encoder, symtab_node *node) lto_symtab_encoder_encode (encoder, ref->referred); } +/* Select what needs to be streamed out. In regular lto mode stream everything. + In offload lto mode stream only nodes marked as offloadable. */ +void +select_what_to_stream (bool offload_lto_mode) +{ + struct symtab_node *snode; + FOR_EACH_SYMBOL (snode) + snode->need_lto_streaming = !offload_lto_mode || snode->offloadable; +} + /* Find all symbols we want to stream into given partition and insert them to encoders. @@ -844,6 +866,8 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder) !lsei_end_p (lsei); lsei_next_function_in_partition (&lsei)) { struct cgraph_node *node = lsei_cgraph_node (lsei); + if (!node->need_lto_streaming) + continue; add_node_to (encoder, node, true); lto_set_symtab_encoder_in_partition (encoder, node); create_references (encoder, node); @@ -860,6 +884,8 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder) { varpool_node *vnode = lsei_varpool_node (lsei); + if (!vnode->need_lto_streaming) + continue; lto_set_symtab_encoder_in_partition (encoder, vnode); lto_set_symtab_encoder_encode_initializer (encoder, vnode); create_references (encoder, vnode); diff --git a/gcc/lto-section-names.h b/gcc/lto-section-names.h index cb752309872..f5dbed26bad 100644 --- a/gcc/lto-section-names.h +++ b/gcc/lto-section-names.h @@ -25,6 +25,11 @@ along with GCC; see the file COPYING3. If not see name for the functions and static_initializers. For other types of sections a '.' and the section type are appended. */ #define LTO_SECTION_NAME_PREFIX ".gnu.lto_" +#define OFFLOAD_SECTION_NAME_PREFIX ".gnu.offload_lto_" + +/* Can be either OFFLOAD_SECTION_NAME_PREFIX when we stream IR for offload + compiler, or LTO_SECTION_NAME_PREFIX for LTO case. */ +extern const char *section_name_prefix; /* Segment name for LTO sections. This is only used for Mach-O. */ diff --git a/gcc/lto-streamer.c b/gcc/lto-streamer.c index b6cac0b5e99..e8347dccd65 100644 --- a/gcc/lto-streamer.c +++ b/gcc/lto-streamer.c @@ -60,6 +60,7 @@ struct lto_stats_d lto_stats; static bitmap_obstack lto_obstack; static bool lto_obstack_initialized; +const char *section_name_prefix = LTO_SECTION_NAME_PREFIX; /* Return a string representing LTO tag TAG. */ @@ -189,7 +190,7 @@ lto_get_section_name (int section_type, const char *name, struct lto_file_decl_d sprintf (post, "." HOST_WIDE_INT_PRINT_HEX_PURE, f->id); else sprintf (post, "." HOST_WIDE_INT_PRINT_HEX_PURE, get_random_seed (false)); - return concat (LTO_SECTION_NAME_PREFIX, sep, add, post, NULL); + return concat (section_name_prefix, sep, add, post, NULL); } diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h index 4b875a2b8ba..cdbe507d718 100644 --- a/gcc/lto-streamer.h +++ b/gcc/lto-streamer.h @@ -831,6 +831,7 @@ bool referenced_from_this_partition_p (symtab_node *, bool reachable_from_this_partition_p (struct cgraph_node *, lto_symtab_encoder_t); lto_symtab_encoder_t compute_ltrans_boundary (lto_symtab_encoder_t encoder); +void select_what_to_stream (bool); /* In lto-symtab.c. */ diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index cbd1af51f14..1b2f1fe1514 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,17 @@ +2014-11-13 Ilya Verbin + Bernd Schmidt + Andrey Turetskiy + Michael Zolotukhin + + * lto-object.c (lto_obj_add_section): Use section_name_prefix instead of + LTO_SECTION_NAME_PREFIX. + * lto-partition.c (lto_promote_cross_file_statics): Call + select_what_to_stream. + * lto.c (lto_section_with_id): Use section_name_prefix instead of + LTO_SECTION_NAME_PREFIX. + (read_cgraph_and_symbols): Read OFFLOAD_SECTION_NAME_PREFIX sections, if + being built as an offload compiler. + 2014-10-29 Richard Sandiford * lto-lang.c: Remove redundant enum from machine_mode. diff --git a/gcc/lto/lto-object.c b/gcc/lto/lto-object.c index 1178326b991..b4124f65b97 100644 --- a/gcc/lto/lto-object.c +++ b/gcc/lto/lto-object.c @@ -242,8 +242,7 @@ lto_obj_add_section (void *data, const char *name, off_t offset, void **slot; struct lto_section_list *list = loasd->list; - if (strncmp (name, LTO_SECTION_NAME_PREFIX, - strlen (LTO_SECTION_NAME_PREFIX)) != 0) + if (strncmp (name, section_name_prefix, strlen (section_name_prefix))) return 1; new_name = xstrdup (name); diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c index 0e1a95bf918..65f0582cf6b 100644 --- a/gcc/lto/lto-partition.c +++ b/gcc/lto/lto-partition.c @@ -952,6 +952,8 @@ lto_promote_cross_file_statics (void) gcc_assert (flag_wpa); + select_what_to_stream (false); + /* First compute boundaries. */ n_sets = ltrans_partitions.length (); for (i = 0; i < n_sets; i++) diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index d8519d9426b..fbf4913875d 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -2137,7 +2137,7 @@ lto_section_with_id (const char *name, unsigned HOST_WIDE_INT *id) { const char *s; - if (strncmp (name, LTO_SECTION_NAME_PREFIX, strlen (LTO_SECTION_NAME_PREFIX))) + if (strncmp (name, section_name_prefix, strlen (section_name_prefix))) return 0; s = strrchr (name, '.'); return s && sscanf (s, "." HOST_WIDE_INT_PRINT_HEX_PURE, id) == 1; @@ -2912,6 +2912,10 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames) timevar_push (TV_IPA_LTO_DECL_IN); +#ifdef ACCEL_COMPILER + section_name_prefix = OFFLOAD_SECTION_NAME_PREFIX; +#endif + real_file_decl_data = decl_data = ggc_cleared_vec_alloc (nfiles + 1); real_file_count = nfiles; diff --git a/gcc/omp-low.c b/gcc/omp-low.c index e7d8a7e916e..8ac5d94bcd1 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, diff --git a/gcc/passes.c b/gcc/passes.c index 5e91a79414a..aa40fe5fa30 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -2416,7 +2416,7 @@ ipa_write_summaries_1 (lto_symtab_encoder_t encoder) /* Write out summaries for all the nodes in the callgraph. */ void -ipa_write_summaries (void) +ipa_write_summaries (bool offload_lto_mode) { lto_symtab_encoder_t encoder; int i, order_pos; @@ -2427,6 +2427,8 @@ ipa_write_summaries (void) if (!flag_generate_lto || seen_error ()) return; + select_what_to_stream (offload_lto_mode); + encoder = lto_symtab_encoder_new (false); /* Create the callgraph set in the same order used in @@ -2453,15 +2455,16 @@ ipa_write_summaries (void) renumber_gimple_stmt_uids (); pop_cfun (); } - if (node->definition) + if (node->definition && node->need_lto_streaming) lto_set_symtab_encoder_in_partition (encoder, node); } FOR_EACH_DEFINED_FUNCTION (node) - if (node->alias) + if (node->alias && node->need_lto_streaming) lto_set_symtab_encoder_in_partition (encoder, node); FOR_EACH_DEFINED_VARIABLE (vnode) - lto_set_symtab_encoder_in_partition (encoder, vnode); + if (vnode->need_lto_streaming) + lto_set_symtab_encoder_in_partition (encoder, vnode); ipa_write_summaries_1 (compute_ltrans_boundary (encoder)); diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h index 25ff364a1ad..b8f2801e198 100644 --- a/gcc/tree-pass.h +++ b/gcc/tree-pass.h @@ -602,7 +602,7 @@ extern void pass_fini_dump_file (opt_pass *); extern const char *get_current_pass_name (void); extern void print_current_pass (FILE *); extern void debug_pass (void); -extern void ipa_write_summaries (void); +extern void ipa_write_summaries (bool); extern void ipa_write_optimization_summaries (struct lto_symtab_encoder_d *); extern void ipa_read_summaries (void); extern void ipa_read_optimization_summaries (void); diff --git a/gcc/varpool.c b/gcc/varpool.c index ac7abc1be86..ee889f2db53 100644 --- a/gcc/varpool.c +++ b/gcc/varpool.c @@ -49,6 +49,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-ssa-alias.h" #include "gimple.h" #include "lto-streamer.h" +#include "context.h" const char * const tls_model_names[]={"none", "tls-emulated", "tls-real", "tls-global-dynamic", "tls-local-dynamic", @@ -164,6 +165,14 @@ varpool_node::get_create (tree decl) node = varpool_node::create_empty (); node->decl = decl; + + if (flag_openmp + && lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl))) + { + node->offloadable = 1; + g->have_offload = true; + } + node->register_symbol (); return node; } -- 2.11.4.GIT