[gomp4] Dumping gimple for offload.
Richard Biener
richard.guenther@gmail.com
Tue Sep 24 09:13:00 GMT 2013
On Mon, Sep 23, 2013 at 3:29 PM, Ilya Tocar <tocarip.intel@gmail.com> wrote:
> Hi,
>
> I've rebased my patch.
> Is it ok for gomp4
Passing through "is_omp" looks bad - please find a more suitable place
to attach this meta-information. From a quick look you only need it to
produce an alternate section name, thus consider assigning the section
name in a different place.
Richard.
>
> 2013/9/13 Ilya Tocar <tocarip.intel@gmail.com>:
>> Hi,
>>
>> I'm working on dumping gimple for "omp pragma target" stuff into
>> gnu.target_lto_ sections.
>> I've tried to reuse current lto infrastructure as much as possible.
>>
>> Could you please take a look at attached patch?
>
>
> ---
> gcc/ipa-inline-analysis.c | 2 +-
> gcc/ipa-profile.c | 2 +-
> gcc/ipa-prop.c | 4 +-
> gcc/ipa-pure-const.c | 2 +-
> gcc/ipa-reference.c | 2 +-
> gcc/lto-cgraph.c | 22 +++--
> gcc/lto-opts.c | 2 +-
> gcc/lto-section-out.c | 14 ++-
> gcc/lto-streamer-out.c | 215 +++++++++++++++++++++++++++++++++++++++-------
> gcc/lto-streamer.c | 6 +-
> gcc/lto-streamer.h | 13 +--
> gcc/lto/lto.c | 2 +-
> gcc/passes.c | 3 +-
> gcc/passes.def | 2 +
> gcc/timevar.def | 2 +
> gcc/tree-pass.h | 2 +
> 16 files changed, 237 insertions(+), 58 deletions(-)
>
> diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
> index ba6221e..ea3fc90 100644
> --- a/gcc/ipa-inline-analysis.c
> +++ b/gcc/ipa-inline-analysis.c
> @@ -4023,7 +4023,7 @@ inline_write_summary (void)
> }
> }
> streamer_write_char_stream (ob->main_stream, 0);
> - produce_asm (ob, NULL);
> + produce_asm (ob, NULL, false);
> destroy_output_block (ob);
>
> if (optimize && !flag_ipa_cp)
> diff --git a/gcc/ipa-profile.c b/gcc/ipa-profile.c
> index 424e4a6..b16ba6c 100644
> --- a/gcc/ipa-profile.c
> +++ b/gcc/ipa-profile.c
> @@ -247,7 +247,7 @@ ipa_profile_write_summary (void)
> streamer_write_uhwi_stream (ob->main_stream, histogram[i]->time);
> streamer_write_uhwi_stream (ob->main_stream, histogram[i]->size);
> }
> - lto_destroy_simple_output_block (ob);
> + lto_destroy_simple_output_block (ob, false);
> }
>
> /* Deserialize the ipa info for lto. */
> diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
> index c09ec2f..69603c9 100644
> --- a/gcc/ipa-prop.c
> +++ b/gcc/ipa-prop.c
> @@ -4234,7 +4234,7 @@ ipa_prop_write_jump_functions (void)
> ipa_write_node_info (ob, node);
> }
> streamer_write_char_stream (ob->main_stream, 0);
> - produce_asm (ob, NULL);
> + produce_asm (ob, NULL, false);
> destroy_output_block (ob);
> }
>
> @@ -4409,7 +4409,7 @@ ipa_prop_write_all_agg_replacement (void)
> write_agg_replacement_chain (ob, node);
> }
> streamer_write_char_stream (ob->main_stream, 0);
> - produce_asm (ob, NULL);
> + produce_asm (ob, NULL, false);
> destroy_output_block (ob);
> }
>
> diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
> index 55b679d..d6bbd52 100644
> --- a/gcc/ipa-pure-const.c
> +++ b/gcc/ipa-pure-const.c
> @@ -988,7 +988,7 @@ pure_const_write_summary (void)
> }
> }
>
> - lto_destroy_simple_output_block (ob);
> + lto_destroy_simple_output_block (ob, false);
> }
>
>
> diff --git a/gcc/ipa-reference.c b/gcc/ipa-reference.c
> index e6f19fd..0593c77 100644
> --- a/gcc/ipa-reference.c
> +++ b/gcc/ipa-reference.c
> @@ -1022,7 +1022,7 @@ ipa_reference_write_optimization_summary (void)
> }
> }
> BITMAP_FREE (ltrans_statics);
> - lto_destroy_simple_output_block (ob);
> + lto_destroy_simple_output_block (ob, false);
> splay_tree_delete (reference_vars_to_consider);
> }
>
> diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
> index 952588d..831e74d 100644
> --- a/gcc/lto-cgraph.c
> +++ b/gcc/lto-cgraph.c
> @@ -690,7 +690,7 @@ output_outgoing_cgraph_edges (struct cgraph_edge *edge,
> /* Output the part of the cgraph in SET. */
>
> static void
> -output_refs (lto_symtab_encoder_t encoder)
> +output_refs (lto_symtab_encoder_t encoder, bool is_omp)
> {
> lto_symtab_encoder_iterator lsei;
> struct lto_simple_output_block *ob;
> @@ -719,7 +719,7 @@ output_refs (lto_symtab_encoder_t encoder)
>
> streamer_write_uhwi_stream (ob->main_stream, 0);
>
> - lto_destroy_simple_output_block (ob);
> + lto_destroy_simple_output_block (ob, is_omp);
> }
>
> /* Add NODE into encoder as well as nodes it is cloned from.
> @@ -878,7 +878,7 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
> /* Output the part of the symtab in SET and VSET. */
>
> void
> -output_symtab (void)
> +output_symtab (bool is_omp)
> {
> struct cgraph_node *node;
> struct lto_simple_output_block *ob;
> @@ -907,9 +907,15 @@ output_symtab (void)
> {
> symtab_node node = lto_symtab_encoder_deref (encoder, i);
> if (cgraph_node *cnode = dyn_cast <cgraph_node> (node))
> - lto_output_node (ob, cnode, encoder);
> + {
> + if (!is_omp || lookup_attribute ("omp declare target",
> + DECL_ATTRIBUTES (node->symbol.decl)))
> + lto_output_node (ob, cnode, encoder);
> + }
> else
> - lto_output_varpool_node (ob, varpool (node), encoder);
> + if (!is_omp || lookup_attribute ("omp declare target",
> + DECL_ATTRIBUTES (node->symbol.decl)))
> + lto_output_varpool_node (ob, varpool (node), encoder);
>
> }
>
> @@ -924,7 +930,7 @@ output_symtab (void)
>
> streamer_write_uhwi_stream (ob->main_stream, 0);
>
> - lto_destroy_simple_output_block (ob);
> + lto_destroy_simple_output_block (ob, is_omp);
>
> /* Emit toplevel asms.
> When doing WPA we must output every asm just once. Since we do not partition asm
> @@ -936,7 +942,7 @@ output_symtab (void)
> lto_output_toplevel_asms ();
> }
>
> - output_refs (encoder);
> + output_refs (encoder, is_omp);
> }
>
> /* Overwrite the information in NODE based on FILE_DATA, TAG, FLAGS,
> @@ -1691,7 +1697,7 @@ output_cgraph_opt_summary (void)
> output_node_opt_summary (ob, cnode, encoder);
> }
> }
> - produce_asm (ob, NULL);
> + produce_asm (ob, NULL, false);
> destroy_output_block (ob);
> }
>
> diff --git a/gcc/lto-opts.c b/gcc/lto-opts.c
> index 4d9cdfd..b524b19 100644
> --- a/gcc/lto-opts.c
> +++ b/gcc/lto-opts.c
> @@ -70,7 +70,7 @@ lto_write_options (void)
> char *args;
> bool first_p = true;
>
> - section_name = lto_get_section_name (LTO_section_opts, NULL, NULL);
> + section_name = lto_get_section_name (LTO_section_opts, NULL, NULL, false);
> lto_begin_section (section_name, false);
> memset (&stream, 0, sizeof (stream));
>
> diff --git a/gcc/lto-section-out.c b/gcc/lto-section-out.c
> index 59eed71..ccf00e9 100644
> --- a/gcc/lto-section-out.c
> +++ b/gcc/lto-section-out.c
> @@ -49,6 +49,8 @@ static vec<lto_out_decl_state_ptr> decl_state_stack;
>
> vec<lto_out_decl_state_ptr> lto_function_decl_states;
>
> +vec<lto_out_decl_state_ptr> omp_function_decl_states;
> +
>
> /*****************************************************************************
> Output routines shared by all of the serialization passes.
> @@ -336,13 +338,13 @@ lto_create_simple_output_block (enum lto_section_type section_type)
> /* Produce a simple section for one of the ipa passes. */
>
> void
> -lto_destroy_simple_output_block (struct lto_simple_output_block *ob)
> +lto_destroy_simple_output_block (struct lto_simple_output_block *ob, bool is_omp)
> {
> char *section_name;
> struct lto_simple_header header;
> struct lto_output_stream *header_stream;
>
> - section_name = lto_get_section_name (ob->section_type, NULL, NULL);
> + section_name = lto_get_section_name (ob->section_type, NULL, NULL, is_omp);
> lto_begin_section (section_name, !flag_wpa);
> free (section_name);
>
> @@ -431,7 +433,8 @@ lto_pop_out_decl_state (void)
>
> void
> lto_record_function_out_decl_state (tree fn_decl,
> - struct lto_out_decl_state *state)
> + struct lto_out_decl_state *state,
> + bool is_omp)
> {
> int i;
>
> @@ -443,5 +446,8 @@ lto_record_function_out_decl_state (tree fn_decl,
> state->streams[i].tree_hash_table = NULL;
> }
> state->fn_decl = fn_decl;
> - lto_function_decl_states.safe_push (state);
> + if (is_omp)
> + omp_function_decl_states.safe_push (state);
> + else
> + lto_function_decl_states.safe_push (state);
> }
> diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
> index 8f823f2..fcc4682e 100644
> --- a/gcc/lto-streamer-out.c
> +++ b/gcc/lto-streamer-out.c
> @@ -1646,7 +1646,7 @@ output_cfg (struct output_block *ob, struct function *fn)
> a function, set FN to the decl for that function. */
>
> void
> -produce_asm (struct output_block *ob, tree fn)
> +produce_asm (struct output_block *ob, tree fn, bool is_omp)
> {
> enum lto_section_type section_type = ob->section_type;
> struct lto_function_header header;
> @@ -1656,10 +1656,10 @@ produce_asm (struct output_block *ob, tree fn)
> if (section_type == LTO_section_function_body)
> {
> const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fn));
> - section_name = lto_get_section_name (section_type, name, NULL);
> + section_name = lto_get_section_name (section_type, name, NULL, is_omp);
> }
> else
> - section_name = lto_get_section_name (section_type, NULL, NULL);
> + section_name = lto_get_section_name (section_type, NULL, NULL, false);
>
> lto_begin_section (section_name, !flag_wpa);
> free (section_name);
> @@ -1743,7 +1743,7 @@ output_struct_function_base (struct output_block *ob, struct function *fn)
> /* Output the body of function NODE->DECL. */
>
> static void
> -output_function (struct cgraph_node *node)
> +output_function (struct cgraph_node *node, bool is_omp)
> {
> tree function;
> struct function *fn;
> @@ -1841,7 +1841,7 @@ output_function (struct cgraph_node *node)
> streamer_write_uhwi (ob, 0);
>
> /* Create a section to hold the pickled output of this function. */
> - produce_asm (ob, function);
> + produce_asm (ob, function, is_omp);
>
> destroy_output_block (ob);
> }
> @@ -1874,7 +1874,7 @@ lto_output_toplevel_asms (void)
>
> streamer_write_string_cst (ob, ob->main_stream, NULL_TREE);
>
> - section_name = lto_get_section_name (LTO_section_asm, NULL, NULL);
> + section_name = lto_get_section_name (LTO_section_asm, NULL, NULL, false);
> lto_begin_section (section_name, !flag_wpa);
> free (section_name);
>
> @@ -1916,7 +1916,7 @@ copy_function (struct cgraph_node *node)
> size_t len;
> const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (function));
> char *section_name =
> - lto_get_section_name (LTO_section_function_body, name, NULL);
> + lto_get_section_name (LTO_section_function_body, name, NULL, false);
> size_t i, j;
> struct lto_in_decl_state *in_state;
> struct lto_out_decl_state *out_state = lto_get_out_decl_state ();
> @@ -1994,12 +1994,12 @@ lto_output (void)
> decl_state = lto_new_out_decl_state ();
> lto_push_out_decl_state (decl_state);
> if (gimple_has_body_p (node->symbol.decl) || !flag_wpa)
> - output_function (node);
> + output_function (node, false);
> else
> copy_function (node);
> gcc_assert (lto_get_out_decl_state () == decl_state);
> lto_pop_out_decl_state ();
> - lto_record_function_out_decl_state (node->symbol.decl, decl_state);
> + lto_record_function_out_decl_state (node->symbol.decl, decl_state, false);
> }
> }
>
> @@ -2007,13 +2007,98 @@ lto_output (void)
> be done now to make sure that all the statements in every function
> have been renumbered so that edges can be associated with call
> statements using the statement UIDs. */
> - output_symtab ();
> + output_symtab (false);
>
> #ifdef ENABLE_CHECKING
> lto_bitmap_free (output);
> #endif
> }
>
> +bool
> +gate_omp_out (void)
> +{
> + return flag_openmp;
> +}
> +
> +static void
> +omp_output (void)
> +{
> + lto_streamer_hooks_init();
> + struct lto_out_decl_state *decl_state;
> + int i, n_nodes;
> + lto_symtab_encoder_t encoder = lto_get_out_decl_state ()->symtab_node_encoder;
> +
> + /* Initialize the streamer. */
> + lto_streamer_init ();
> +
> + n_nodes = lto_symtab_encoder_size (encoder);
> + /* Process only the functions with bodies. */
> + for (i = 0; i < n_nodes; i++)
> + {
> + symtab_node snode = lto_symtab_encoder_deref (encoder, i);
> + cgraph_node *node = dyn_cast <cgraph_node> (snode);
> + if (node
> + && lto_symtab_encoder_encode_body_p (encoder, node)
> + && !node->symbol.alias
> + && !node->thunk.thunk_p
> + && gimple_has_body_p (node->symbol.decl)
> + && lookup_attribute ("omp declare target",
> + DECL_ATTRIBUTES (node->symbol.decl)))
> + {
> + decl_state = lto_new_out_decl_state ();
> + lto_push_out_decl_state (decl_state);
> + output_function (node, true);
> + lto_pop_out_decl_state ();
> + lto_record_function_out_decl_state (node->symbol.decl, decl_state, true);
> + }
> + }
> +
> + /* Emit the callgraph after emitting function bodies. This needs to
> + be done now to make sure that all the statements in every function
> + have been renumbered so that edges can be associated with call
> + statements using the statement UIDs. */
> + output_symtab (true);
> +}
> +
> +namespace {
> +
> +const pass_data pass_data_ipa_omp_gimple_out =
> +{
> + IPA_PASS, /* type */
> + "omp_gimple_out", /* name */
> + OPTGROUP_NONE, /* optinfo_flags */
> + true, /* has_gate */
> + false, /* has_execute */
> + TV_IPA_OMP_GIMPLE_OUT, /* tv_id */
> + 0, /* properties_required */
> + 0, /* properties_provided */
> + 0, /* properties_destroyed */
> + 0, /* todo_flags_start */
> + 0, /* todo_flags_finish */
> +};
> +
> +class pass_ipa_omp_gimple_out : public ipa_opt_pass_d
> +{
> +public:
> + pass_ipa_omp_gimple_out(gcc::context *ctxt)
> + : ipa_opt_pass_d(pass_data_ipa_omp_gimple_out, ctxt,
> + NULL, /* generate_summary */
> + omp_output, /* write_summary */
> + NULL, /* read_summary */
> + omp_output, /* write_optimization_summary */
> + NULL, /* read_optimization_summary */
> + NULL, /* stmt_fixup */
> + 0, /* function_transform_todo_flags_start */
> + NULL, /* function_transform */
> + NULL) /* variable_transform */
> + {}
> +
> + /* opt_pass methods: */
> + bool gate () { return gate_omp_out (); }
> +
> +}; // class pass_ipa_omp_gimple_out
> +
> +} // anon namespace
> namespace {
>
> const pass_data pass_data_ipa_lto_gimple_out =
> @@ -2055,6 +2140,12 @@ public:
> } // anon namespace
>
> ipa_opt_pass_d *
> +make_pass_ipa_omp_gimple_out (gcc::context *ctxt)
> +{
> + return new pass_ipa_omp_gimple_out (ctxt);
> +}
> +
> +ipa_opt_pass_d *
> make_pass_ipa_lto_gimple_out (gcc::context *ctxt)
> {
> return new pass_ipa_lto_gimple_out (ctxt);
> @@ -2330,10 +2421,10 @@ output_symbol_p (symtab_node node)
> SET and VSET are cgraph/varpool node sets we are outputting. */
>
> static void
> -produce_symtab (struct output_block *ob)
> +produce_symtab (struct output_block *ob, bool is_omp)
> {
> struct streamer_tree_cache_d *cache = ob->writer_cache;
> - char *section_name = lto_get_section_name (LTO_section_symtab, NULL, NULL);
> + char *section_name = lto_get_section_name (LTO_section_symtab, NULL, NULL, is_omp);
> struct pointer_set_t *seen;
> struct lto_output_stream stream;
> lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
> @@ -2353,7 +2444,9 @@ produce_symtab (struct output_block *ob)
> {
> symtab_node node = lsei_node (lsei);
>
> - if (!output_symbol_p (node) || DECL_EXTERNAL (node->symbol.decl))
> + if (!output_symbol_p (node) || DECL_EXTERNAL (node->symbol.decl)
> + || (is_omp && !lookup_attribute ("omp declare target",
> + DECL_ATTRIBUTES (node->symbol.decl))))
> continue;
> write_symbol (cache, &stream, node->symbol.decl, seen, false);
> }
> @@ -2362,7 +2455,9 @@ produce_symtab (struct output_block *ob)
> {
> symtab_node node = lsei_node (lsei);
>
> - if (!output_symbol_p (node) || !DECL_EXTERNAL (node->symbol.decl))
> + if (!output_symbol_p (node) || !DECL_EXTERNAL (node->symbol.decl)
> + || (is_omp && !lookup_attribute ("omp declare target",
> + DECL_ATTRIBUTES (node->symbol.decl))))
> continue;
> write_symbol (cache, &stream, node->symbol.decl, seen, false);
> }
> @@ -2381,7 +2476,7 @@ produce_symtab (struct output_block *ob)
> recover these on other side. */
>
> static void
> -produce_asm_for_decls (void)
> +produce_asm_for_decls (bool is_omp)
> {
> struct lto_out_decl_state *out_state;
> struct lto_out_decl_state *fn_out_state;
> @@ -2393,12 +2488,17 @@ produce_asm_for_decls (void)
> size_t decl_state_size;
> int32_t num_decl_states;
>
> + vec<lto_out_decl_state_ptr> decl_states = is_omp
> + ? omp_function_decl_states
> + : lto_function_decl_states;
> +
> +
> ob = create_output_block (LTO_section_decls);
> ob->global = true;
>
> memset (&header, 0, sizeof (struct lto_decl_header));
>
> - section_name = lto_get_section_name (LTO_section_decls, NULL, NULL);
> + section_name = lto_get_section_name (LTO_section_decls, NULL, NULL, is_omp);
> lto_begin_section (section_name, !flag_wpa);
> free (section_name);
>
> @@ -2409,12 +2509,12 @@ produce_asm_for_decls (void)
>
> /* Write the global symbols. */
> out_state = lto_get_out_decl_state ();
> - num_fns = lto_function_decl_states.length ();
> + num_fns = decl_states.length ();
> lto_output_decl_state_streams (ob, out_state);
> for (idx = 0; idx < num_fns; idx++)
> {
> fn_out_state =
> - lto_function_decl_states[idx];
> + decl_states[idx];
> lto_output_decl_state_streams (ob, fn_out_state);
> }
>
> @@ -2430,8 +2530,7 @@ produce_asm_for_decls (void)
> decl_state_size += lto_out_decl_state_written_size (out_state);
> for (idx = 0; idx < num_fns; idx++)
> {
> - fn_out_state =
> - lto_function_decl_states[idx];
> + fn_out_state = decl_states[idx];
> decl_state_size += lto_out_decl_state_written_size (fn_out_state);
> }
> header.decl_state_size = decl_state_size;
> @@ -2453,8 +2552,7 @@ produce_asm_for_decls (void)
> lto_output_decl_state_refs (ob, decl_state_stream, out_state);
> for (idx = 0; idx < num_fns; idx++)
> {
> - fn_out_state =
> - lto_function_decl_states[idx];
> + fn_out_state = decl_states[idx];
> lto_output_decl_state_refs (ob, decl_state_stream, fn_out_state);
> }
> lto_write_stream (decl_state_stream);
> @@ -2468,24 +2566,38 @@ produce_asm_for_decls (void)
> /* Write the symbol table. It is used by linker to determine dependencies
> and thus we can skip it for WPA. */
> if (!flag_wpa)
> - produce_symtab (ob);
> + produce_symtab (ob, is_omp);
>
> /* Write command line opts. */
> - lto_write_options ();
> + if (!is_omp)
> + lto_write_options ();
>
> /* Deallocate memory and clean up. */
> for (idx = 0; idx < num_fns; idx++)
> {
> - fn_out_state =
> - lto_function_decl_states[idx];
> + fn_out_state = decl_states[idx];
> lto_delete_out_decl_state (fn_out_state);
> }
> - lto_symtab_encoder_delete (ob->decl_state->symtab_node_encoder);
> + if (!is_omp || !flag_lto)
> + lto_symtab_encoder_delete (ob->decl_state->symtab_node_encoder);
> + omp_function_decl_states.release ();
> lto_function_decl_states.release ();
> destroy_output_block (ob);
> }
>
>
> +static void
> +produce_asm_for_decls_lto ()
> +{
> + produce_asm_for_decls (false);
> +}
> +
> +static void
> +produce_asm_for_decls_omp ()
> +{
> + produce_asm_for_decls (true);
> +}
> +
> namespace {
>
> const pass_data pass_data_ipa_lto_finish_out =
> @@ -2509,9 +2621,9 @@ public:
> pass_ipa_lto_finish_out(gcc::context *ctxt)
> : ipa_opt_pass_d(pass_data_ipa_lto_finish_out, ctxt,
> NULL, /* generate_summary */
> - produce_asm_for_decls, /* write_summary */
> + produce_asm_for_decls_lto, /* write_summary */
> NULL, /* read_summary */
> - produce_asm_for_decls, /* write_optimization_summary */
> + produce_asm_for_decls_lto, /* write_optimization_summary */
> NULL, /* read_optimization_summary */
> NULL, /* stmt_fixup */
> 0, /* function_transform_todo_flags_start */
> @@ -2531,3 +2643,48 @@ make_pass_ipa_lto_finish_out (gcc::context *ctxt)
> {
> return new pass_ipa_lto_finish_out (ctxt);
> }
> +namespace {
> +
> +const pass_data pass_data_ipa_omp_finish_out =
> +{
> + IPA_PASS, /* type */
> + "omp_decls_out", /* name */
> + OPTGROUP_NONE, /* optinfo_flags */
> + true, /* has_gate */
> + false, /* has_execute */
> + TV_IPA_OMP_DECL_OUT, /* tv_id */
> + 0, /* properties_required */
> + 0, /* properties_provided */
> + 0, /* properties_destroyed */
> + 0, /* todo_flags_start */
> + 0, /* todo_flags_finish */
> +};
> +
> +class pass_ipa_omp_finish_out : public ipa_opt_pass_d
> +{
> +public:
> + pass_ipa_omp_finish_out(gcc::context *ctxt)
> + : ipa_opt_pass_d(pass_data_ipa_omp_finish_out, ctxt,
> + NULL, /* generate_summary */
> + produce_asm_for_decls_omp, /* write_summary */
> + NULL, /* read_summary */
> + produce_asm_for_decls_omp, /* write_optimization_summary */
> + NULL, /* read_optimization_summary */
> + NULL, /* stmt_fixup */
> + 0, /* function_transform_todo_flags_start */
> + NULL, /* function_transform */
> + NULL) /* variable_transform */
> + {}
> +
> + /* opt_pass methods: */
> + bool gate () { return gate_omp_out (); }
> +
> +}; // class pass_ipa_lto_finish_out
> +
> +} // anon namespace
> +
> +ipa_opt_pass_d *
> +make_pass_ipa_omp_finish_out (gcc::context *ctxt)
> +{
> + return new pass_ipa_omp_finish_out (ctxt);
> +}
> diff --git a/gcc/lto-streamer.c b/gcc/lto-streamer.c
> index cdc75de..92af717 100644
> --- a/gcc/lto-streamer.c
> +++ b/gcc/lto-streamer.c
> @@ -140,7 +140,7 @@ lto_bitmap_free (bitmap b)
> to free the returned name. */
>
> char *
> -lto_get_section_name (int section_type, const char *name, struct lto_file_decl_data *f)
> +lto_get_section_name (int section_type, const char *name, struct lto_file_decl_data *f, bool is_omp)
> {
> const char *add;
> char post[32];
> @@ -173,7 +173,9 @@ 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 (is_omp ? OMP_SECTION_NAME_PREFIX
> + : LTO_SECTION_NAME_PREFIX,
> + sep, add, post, NULL);
> }
>
>
> diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h
> index 13a9593..65d5c2e 100644
> --- a/gcc/lto-streamer.h
> +++ b/gcc/lto-streamer.h
> @@ -141,6 +141,7 @@ 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 OMP_SECTION_NAME_PREFIX ".gnu.target_lto_"
>
> #define LTO_major_version 2
> #define LTO_minor_version 2
> @@ -804,14 +805,15 @@ extern void lto_output_type_ref_index (struct lto_out_decl_state *,
> struct lto_output_stream *, tree);
> extern struct lto_simple_output_block *lto_create_simple_output_block (
> enum lto_section_type);
> -extern void lto_destroy_simple_output_block (struct lto_simple_output_block *);
> +extern void lto_destroy_simple_output_block (struct lto_simple_output_block *, bool is_omp);
> extern struct lto_out_decl_state *lto_new_out_decl_state (void);
> extern void lto_delete_out_decl_state (struct lto_out_decl_state *);
> extern struct lto_out_decl_state *lto_get_out_decl_state (void);
> extern void lto_push_out_decl_state (struct lto_out_decl_state *);
> extern struct lto_out_decl_state *lto_pop_out_decl_state (void);
> extern void lto_record_function_out_decl_state (tree,
> - struct lto_out_decl_state *);
> + struct lto_out_decl_state *,
> + bool is_omp);
> extern void lto_append_block (struct lto_output_stream *);
>
>
> @@ -819,7 +821,7 @@ extern void lto_append_block (struct lto_output_stream *);
> extern const char *lto_tag_name (enum LTO_tags);
> extern bitmap lto_bitmap_alloc (void);
> extern void lto_bitmap_free (bitmap);
> -extern char *lto_get_section_name (int, const char *, struct lto_file_decl_data *);
> +extern char *lto_get_section_name (int, const char *, struct lto_file_decl_data *, bool is_omp);
> extern void print_lto_report (const char *);
> extern void lto_streamer_init (void);
> extern bool gate_lto_out (void);
> @@ -863,7 +865,7 @@ extern struct output_block *create_output_block (enum lto_section_type);
> extern void destroy_output_block (struct output_block *);
> extern void lto_output_tree (struct output_block *, tree, bool, bool);
> extern void lto_output_toplevel_asms (void);
> -extern void produce_asm (struct output_block *ob, tree fn);
> +extern void produce_asm (struct output_block *ob, tree fn, bool is_omp);
> void lto_output_decl_state_streams (struct output_block *,
> struct lto_out_decl_state *);
> void lto_output_decl_state_refs (struct output_block *,
> @@ -886,7 +888,7 @@ void lto_set_symtab_encoder_in_partition (lto_symtab_encoder_t,
>
> bool lto_symtab_encoder_encode_initializer_p (lto_symtab_encoder_t,
> struct varpool_node *);
> -void output_symtab (void);
> +void output_symtab (bool is_omp);
> void input_symtab (void);
> bool referenced_from_other_partition_p (struct ipa_ref_list *,
> lto_symtab_encoder_t);
> @@ -918,6 +920,7 @@ extern const char *lto_section_name[];
> /* Holds all the out decl states of functions output so far in the
> current output file. */
> extern vec<lto_out_decl_state_ptr> lto_function_decl_states;
> +extern vec<lto_out_decl_state_ptr> omp_function_decl_states;
>
> /* Return true if LTO tag TAG corresponds to a tree code. */
> static inline bool
> diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
> index 470f3c1..8ab1fae 100644
> --- a/gcc/lto/lto.c
> +++ b/gcc/lto/lto.c
> @@ -2946,7 +2946,7 @@ get_section_data (struct lto_file_decl_data *file_data,
> htab_t section_hash_table = file_data->section_hash_table;
> struct lto_section_slot *f_slot;
> struct lto_section_slot s_slot;
> - const char *section_name = lto_get_section_name (section_type, name, file_data);
> + const char *section_name = lto_get_section_name (section_type, name, file_data, false);
> char *data = NULL;
>
> *len = 0;
> diff --git a/gcc/passes.c b/gcc/passes.c
> index f3f85fd..5fc14f4 100644
> --- a/gcc/passes.c
> +++ b/gcc/passes.c
> @@ -2329,9 +2329,8 @@ ipa_write_summaries (void)
> struct cgraph_node *node;
> struct cgraph_node **order;
>
> - if (!flag_generate_lto || seen_error ())
> + if (!(flag_generate_lto || flag_openmp) || seen_error ())
> return;
> -
> encoder = lto_symtab_encoder_new (false);
>
> /* Create the callgraph set in the same order used in
> diff --git a/gcc/passes.def b/gcc/passes.def
> index 84eb3f3..774cab8 100644
> --- a/gcc/passes.def
> +++ b/gcc/passes.def
> @@ -102,6 +102,8 @@ along with GCC; see the file COPYING3. If not see
> TERMINATE_PASS_LIST ()
>
> INSERT_PASSES_AFTER (all_regular_ipa_passes)
> + NEXT_PASS (pass_ipa_omp_gimple_out);
> + NEXT_PASS (pass_ipa_omp_finish_out);
> NEXT_PASS (pass_ipa_whole_program_visibility);
> NEXT_PASS (pass_ipa_profile);
> NEXT_PASS (pass_ipa_devirt);
> diff --git a/gcc/timevar.def b/gcc/timevar.def
> index 5a880a8..d473083 100644
> --- a/gcc/timevar.def
> +++ b/gcc/timevar.def
> @@ -74,8 +74,10 @@ DEFTIMEVAR (TV_IPA_FNSPLIT , "ipa function splitting")
> DEFTIMEVAR (TV_IPA_OPT , "ipa various optimizations")
> DEFTIMEVAR (TV_IPA_LTO_GIMPLE_IN , "ipa lto gimple in")
> DEFTIMEVAR (TV_IPA_LTO_GIMPLE_OUT , "ipa lto gimple out")
> +DEFTIMEVAR (TV_IPA_OMP_GIMPLE_OUT , "ipa omp gimple out")
> DEFTIMEVAR (TV_IPA_LTO_DECL_IN , "ipa lto decl in")
> DEFTIMEVAR (TV_IPA_LTO_DECL_OUT , "ipa lto decl out")
> +DEFTIMEVAR (TV_IPA_OMP_DECL_OUT , "ipa omp decl out")
> DEFTIMEVAR (TV_IPA_LTO_DECL_INIT_IO , "ipa lto decl init I/O")
> DEFTIMEVAR (TV_IPA_LTO_CGRAPH_IO , "ipa lto cgraph I/O")
> DEFTIMEVAR (TV_IPA_LTO_DECL_MERGE , "ipa lto decl merge")
> diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
> index ea1a62f..1fb487c 100644
> --- a/gcc/tree-pass.h
> +++ b/gcc/tree-pass.h
> @@ -460,6 +460,7 @@ extern simple_ipa_opt_pass *make_pass_early_local_passes (gcc::context *ctxt);
>
> extern ipa_opt_pass_d *make_pass_ipa_whole_program_visibility (gcc::context
> *ctxt);
> +extern ipa_opt_pass_d *make_pass_ipa_omp_gimple_out (gcc::context *ctxt);
> extern ipa_opt_pass_d *make_pass_ipa_lto_gimple_out (gcc::context *ctxt);
> extern simple_ipa_opt_pass *make_pass_ipa_increase_alignment (gcc::context
> *ctxt);
> @@ -473,6 +474,7 @@ extern ipa_opt_pass_d *make_pass_ipa_reference (gcc::context *ctxt);
> extern ipa_opt_pass_d *make_pass_ipa_pure_const (gcc::context *ctxt);
> extern simple_ipa_opt_pass *make_pass_ipa_pta (gcc::context *ctxt);
> extern ipa_opt_pass_d *make_pass_ipa_lto_finish_out (gcc::context *ctxt);
> +extern ipa_opt_pass_d *make_pass_ipa_omp_finish_out (gcc::context *ctxt);
> extern simple_ipa_opt_pass *make_pass_ipa_tm (gcc::context *ctxt);
> extern ipa_opt_pass_d *make_pass_ipa_profile (gcc::context *ctxt);
> extern ipa_opt_pass_d *make_pass_ipa_cdtor_merge (gcc::context *ctxt);
> --
> 1.7.11.7
>
More information about the Gcc-patches
mailing list