[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