@@ -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);
}
@@ -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);
}
@@ -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);
+}
@@ -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);
}
@@ -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
@@ -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);
@@ -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);
@@ -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")
@@ -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);