[gomp4] Dumping gimple for offload.

Ilya Tocar tocarip.intel@gmail.com
Wed Sep 25 14:50:00 GMT 2013


On 24 Sep 11:02, Richard Biener wrote:
> 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,

Mostly for name, but there are other uses
(e. g. choosing decl states vector).

>  thus consider assigning the section
> name in a different place.
> 
> Richard.

What do you mean  by different place?
I can add global dumping_omp_target variable to choose correct name,
depending on it's value (patch below). Is it better?


---
 gcc/lto-cgraph.c       |  10 ++-
 gcc/lto-section-out.c  |   6 +-
 gcc/lto-streamer-out.c | 182 +++++++++++++++++++++++++++++++++++++++++++++----
 gcc/lto-streamer.c     |   4 +-
 gcc/lto-streamer.h     |   6 ++
 gcc/passes.c           |   2 +-
 gcc/passes.def         |   2 +
 gcc/timevar.def        |   2 +
 gcc/tree-pass.h        |   2 +
 9 files changed, 198 insertions(+), 18 deletions(-)

diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
index 952588d..5187190 100644
--- a/gcc/lto-cgraph.c
+++ b/gcc/lto-cgraph.c
@@ -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 (!dumping_omp_target || 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 (!dumping_omp_target || lookup_attribute ("omp declare target",
+					  DECL_ATTRIBUTES (node->symbol.decl)))
+	    lto_output_varpool_node (ob, varpool (node), encoder);
 	
     }
 
diff --git a/gcc/lto-section-out.c b/gcc/lto-section-out.c
index 59eed71..ad247c1 100644
--- a/gcc/lto-section-out.c
+++ b/gcc/lto-section-out.c
@@ -49,6 +49,7 @@ 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.
@@ -443,5 +444,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 (dumping_omp_target)
+    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..66a0747 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -48,6 +48,9 @@ along with GCC; see the file COPYING3.  If not see
 #include "cfgloop.h"
 
 
+/* Off by default.  */
+bool dumping_omp_target = false;
+
 /* Clear the line info stored in DATA_IN.  */
 
 static void
@@ -2014,6 +2017,93 @@ lto_output (void)
 #endif
 }
 
+bool
+gate_omp_out (void)
+{
+  return flag_openmp;
+}
+
+static void
+omp_output (void)
+{
+  /* We need omp names for sections, turn this on.  */
+  dumping_omp_target = true;
+
+  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
+	  && 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);
+	  lto_pop_out_decl_state ();
+	  lto_record_function_out_decl_state (node->symbol.decl, decl_state);
+	}
+    }
+
+  /* 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 ();
+}
+
+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 +2145,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);
@@ -2353,7 +2449,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)
+	  || (dumping_omp_target && !lookup_attribute ("omp declare target",
+					   DECL_ATTRIBUTES (node->symbol.decl))))
 	continue;
       write_symbol (cache, &stream, node->symbol.decl, seen, false);
     }
@@ -2362,7 +2460,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)
+	  || (dumping_omp_target && !lookup_attribute ("omp declare target",
+					   DECL_ATTRIBUTES (node->symbol.decl))))
 	continue;
       write_symbol (cache, &stream, node->symbol.decl, seen, false);
     }
@@ -2393,6 +2493,11 @@ produce_asm_for_decls (void)
   size_t decl_state_size;
   int32_t num_decl_states;
 
+  vec<lto_out_decl_state_ptr> decl_states = dumping_omp_target
+    ? omp_function_decl_states
+    : lto_function_decl_states;
+
+
   ob = create_output_block (LTO_section_decls);
   ob->global = true;
 
@@ -2409,12 +2514,11 @@ 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];
+      fn_out_state = decl_states[idx];
       lto_output_decl_state_streams (ob, fn_out_state);
     }
 
@@ -2430,8 +2534,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 +2556,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);
@@ -2471,20 +2573,29 @@ produce_asm_for_decls (void)
     produce_symtab (ob);
 
   /* Write command line opts.  */
-  lto_write_options ();
+  if (!dumping_omp_target)
+    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 (!dumping_omp_target || !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_omp ()
+{
+  produce_asm_for_decls ();
+  /* Disable after everything is done.  */
+  dumping_omp_target = false;
+}
 
 namespace {
 
@@ -2531,3 +2642,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..5cc3f37 100644
--- a/gcc/lto-streamer.c
+++ b/gcc/lto-streamer.c
@@ -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 (dumping_omp_target ? 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..93106b3 100644
--- a/gcc/lto-streamer.h
+++ b/gcc/lto-streamer.h
@@ -141,12 +141,17 @@ 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
 
 typedef unsigned char	lto_decl_flags_t;
 
+/* When we dump gimple for omp target stuff we need to use
+   OMP_SECTION_NAME_PREFIX, for section names. We use this to
+   distinguish omp dumps by setting to true in them.  */
+extern bool dumping_omp_target;
 
 /* Tags representing the various IL objects written to the bytecode file
    (GIMPLE statements, basic blocks, EH regions, tree nodes, etc).
@@ -918,6 +923,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/passes.c b/gcc/passes.c
index f3f85fd..fda68cf 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -2329,7 +2329,7 @@ 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);
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

> 
> >
> > 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