mirror of git://gcc.gnu.org/git/gcc.git
[PATCH 2/7] OpenMP 4.0 offloading infrastructure: LTO streaming.
gcc/ * cgraph.c: Include context.h. (cgraph_node::create): Set node->offloadable and g->have_offload if decl have "omp declare target" attribute. * cgraph.h (symtab_node): Add need_lto_streaming and offloadable flags. * cgraphunit.c: Include lto-section-names.h. (ipa_passes): Call ipa_write_summaries if there is something to write to OFFLOAD_SECTION_NAME_PREFIX sections. (symbol_table::compile): Set flag_generate_lto if there is something to offload. Replace flag_lto with flag_generate_lto before lto_streamer_hooks_init. * context.c (gcc::context::context): Initialize have_offload with false. * context.h (class context): Add have_offload flag. * ipa-inline-analysis.c (inline_generate_summary): Do not exit under flag_generate_lto. (inline_free_summary): Always remove hooks. * lto-cgraph.c (referenced_from_other_partition_p): Ignore references from non-offloadable nodes while streaming a node into offload section. (reachable_from_other_partition_p): Likewise. (select_what_to_stream): New function. (compute_ltrans_boundary): Do not call lto_set_symtab_encoder_in_partition if the node should not be streamed. * lto-section-names.h (OFFLOAD_SECTION_NAME_PREFIX): Define. (section_name_prefix): Declare. * lto-streamer.c (section_name_prefix): New variable. (lto_get_section_name): Use section_name_prefix instead of LTO_SECTION_NAME_PREFIX. * lto-streamer.h (select_what_to_stream): Declare. * omp-low.c: Include context.h. (is_targetreg_ctx): New function. (scan_sharing_clauses): Use offloadable flag, instead of an attribute. (create_omp_child_function, check_omp_nesting_restrictions): Use new is_targetreg_ctx function. Replace usage of "omp declare target" attribute with a cgraph_node flag offloadable. (expand_omp_target): Set mark_force_output for offloadable functions. (lower_omp_critical): Set offloadable flag for omp critical symbol. * passes.c (ipa_write_summaries): New argument offload_lto_mode. Call select_what_to_stream. Do not call lto_set_symtab_encoder_in_partition if the node should not be streamed out. * tree-pass.h (ipa_write_summaries): New bool argument. * varpool.c: Include context.h. (varpool_node::get_create): Set node->offloadable and g->have_offload if decl have "omp declare target" attribute. gcc/lto/ * lto-object.c (lto_obj_add_section): Use section_name_prefix instead of LTO_SECTION_NAME_PREFIX. * lto-partition.c (lto_promote_cross_file_statics): Call select_what_to_stream. * lto.c (lto_section_with_id): Use section_name_prefix instead of LTO_SECTION_NAME_PREFIX. (read_cgraph_and_symbols): Read OFFLOAD_SECTION_NAME_PREFIX sections, if being built as an offload compiler. Co-Authored-By: Andrey Turetskiy <andrey.turetskiy@intel.com> Co-Authored-By: Bernd Schmidt <bernds@codesourcery.com> Co-Authored-By: Michael Zolotukhin <michael.v.zolotukhin@intel.com> From-SVN: r217486
This commit is contained in:
parent
85c64bbee9
commit
1f6be68256
|
|
@ -1,3 +1,51 @@
|
||||||
|
2014-11-13 Ilya Verbin <ilya.verbin@intel.com>
|
||||||
|
Bernd Schmidt <bernds@codesourcery.com>
|
||||||
|
Andrey Turetskiy <andrey.turetskiy@intel.com>
|
||||||
|
Michael Zolotukhin <michael.v.zolotukhin@intel.com>
|
||||||
|
|
||||||
|
* cgraph.c: Include context.h.
|
||||||
|
(cgraph_node::create): Set node->offloadable and g->have_offload if
|
||||||
|
decl have "omp declare target" attribute.
|
||||||
|
* cgraph.h (symtab_node): Add need_lto_streaming and offloadable flags.
|
||||||
|
* cgraphunit.c: Include lto-section-names.h.
|
||||||
|
(ipa_passes): Call ipa_write_summaries if there is something to write to
|
||||||
|
OFFLOAD_SECTION_NAME_PREFIX sections.
|
||||||
|
(symbol_table::compile): Set flag_generate_lto if there is something to
|
||||||
|
offload.
|
||||||
|
Replace flag_lto with flag_generate_lto before lto_streamer_hooks_init.
|
||||||
|
* context.c (gcc::context::context): Initialize have_offload with false.
|
||||||
|
* context.h (class context): Add have_offload flag.
|
||||||
|
* ipa-inline-analysis.c (inline_generate_summary): Do not exit under
|
||||||
|
flag_generate_lto.
|
||||||
|
(inline_free_summary): Always remove hooks.
|
||||||
|
* lto-cgraph.c (referenced_from_other_partition_p): Ignore references
|
||||||
|
from non-offloadable nodes while streaming a node into offload section.
|
||||||
|
(reachable_from_other_partition_p): Likewise.
|
||||||
|
(select_what_to_stream): New function.
|
||||||
|
(compute_ltrans_boundary): Do not call
|
||||||
|
lto_set_symtab_encoder_in_partition if the node should not be streamed.
|
||||||
|
* lto-section-names.h (OFFLOAD_SECTION_NAME_PREFIX): Define.
|
||||||
|
(section_name_prefix): Declare.
|
||||||
|
* lto-streamer.c (section_name_prefix): New variable.
|
||||||
|
(lto_get_section_name): Use section_name_prefix instead of
|
||||||
|
LTO_SECTION_NAME_PREFIX.
|
||||||
|
* lto-streamer.h (select_what_to_stream): Declare.
|
||||||
|
* omp-low.c: Include context.h.
|
||||||
|
(is_targetreg_ctx): New function.
|
||||||
|
(scan_sharing_clauses): Use offloadable flag, instead of an attribute.
|
||||||
|
(create_omp_child_function, check_omp_nesting_restrictions): Use new
|
||||||
|
is_targetreg_ctx function. Replace usage of "omp declare target"
|
||||||
|
attribute with a cgraph_node flag offloadable.
|
||||||
|
(expand_omp_target): Set mark_force_output for offloadable functions.
|
||||||
|
(lower_omp_critical): Set offloadable flag for omp critical symbol.
|
||||||
|
* passes.c (ipa_write_summaries): New argument offload_lto_mode. Call
|
||||||
|
select_what_to_stream. Do not call lto_set_symtab_encoder_in_partition
|
||||||
|
if the node should not be streamed out.
|
||||||
|
* tree-pass.h (ipa_write_summaries): New bool argument.
|
||||||
|
* varpool.c: Include context.h.
|
||||||
|
(varpool_node::get_create): Set node->offloadable and g->have_offload if
|
||||||
|
decl have "omp declare target" attribute.
|
||||||
|
|
||||||
2014-11-13 Bernd Schmidt <bernds@codesourcery.com>
|
2014-11-13 Bernd Schmidt <bernds@codesourcery.com>
|
||||||
Thomas Schwinge <thomas@codesourcery.com>
|
Thomas Schwinge <thomas@codesourcery.com>
|
||||||
Ilya Verbin <ilya.verbin@intel.com>
|
Ilya Verbin <ilya.verbin@intel.com>
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,7 @@ along with GCC; see the file COPYING3. If not see
|
||||||
#include "profile.h"
|
#include "profile.h"
|
||||||
#include "params.h"
|
#include "params.h"
|
||||||
#include "tree-chkp.h"
|
#include "tree-chkp.h"
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
/* FIXME: Only for PROP_loops, but cgraph shouldn't have to know about this. */
|
/* FIXME: Only for PROP_loops, but cgraph shouldn't have to know about this. */
|
||||||
#include "tree-pass.h"
|
#include "tree-pass.h"
|
||||||
|
|
@ -494,6 +495,14 @@ cgraph_node::create (tree decl)
|
||||||
gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
|
gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
|
||||||
|
|
||||||
node->decl = decl;
|
node->decl = decl;
|
||||||
|
|
||||||
|
if (flag_openmp
|
||||||
|
&& lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl)))
|
||||||
|
{
|
||||||
|
node->offloadable = 1;
|
||||||
|
g->have_offload = true;
|
||||||
|
}
|
||||||
|
|
||||||
node->register_symbol ();
|
node->register_symbol ();
|
||||||
|
|
||||||
if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL)
|
if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL)
|
||||||
|
|
|
||||||
|
|
@ -450,6 +450,13 @@ public:
|
||||||
/* Set when init priority is set. */
|
/* Set when init priority is set. */
|
||||||
unsigned in_init_priority_hash : 1;
|
unsigned in_init_priority_hash : 1;
|
||||||
|
|
||||||
|
/* Set when symbol needs to be streamed into LTO bytecode for LTO, or in case
|
||||||
|
of offloading, for separate compilation for a different target. */
|
||||||
|
unsigned need_lto_streaming : 1;
|
||||||
|
|
||||||
|
/* Set when symbol can be streamed into bytecode for offloading. */
|
||||||
|
unsigned offloadable : 1;
|
||||||
|
|
||||||
|
|
||||||
/* Ordering of all symtab entries. */
|
/* Ordering of all symtab entries. */
|
||||||
int order;
|
int order;
|
||||||
|
|
|
||||||
|
|
@ -224,6 +224,7 @@ along with GCC; see the file COPYING3. If not see
|
||||||
#include "gimplify.h"
|
#include "gimplify.h"
|
||||||
#include "dbgcnt.h"
|
#include "dbgcnt.h"
|
||||||
#include "tree-chkp.h"
|
#include "tree-chkp.h"
|
||||||
|
#include "lto-section-names.h"
|
||||||
|
|
||||||
/* Queue of cgraph nodes scheduled to be added into cgraph. This is a
|
/* Queue of cgraph nodes scheduled to be added into cgraph. This is a
|
||||||
secondary queue used during optimization to accommodate passes that
|
secondary queue used during optimization to accommodate passes that
|
||||||
|
|
@ -2079,7 +2080,18 @@ ipa_passes (void)
|
||||||
targetm.asm_out.lto_start ();
|
targetm.asm_out.lto_start ();
|
||||||
|
|
||||||
if (!in_lto_p)
|
if (!in_lto_p)
|
||||||
ipa_write_summaries ();
|
{
|
||||||
|
if (g->have_offload)
|
||||||
|
{
|
||||||
|
section_name_prefix = OFFLOAD_SECTION_NAME_PREFIX;
|
||||||
|
ipa_write_summaries (true);
|
||||||
|
}
|
||||||
|
if (flag_lto)
|
||||||
|
{
|
||||||
|
section_name_prefix = LTO_SECTION_NAME_PREFIX;
|
||||||
|
ipa_write_summaries (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (flag_generate_lto)
|
if (flag_generate_lto)
|
||||||
targetm.asm_out.lto_end ();
|
targetm.asm_out.lto_end ();
|
||||||
|
|
@ -2163,8 +2175,12 @@ symbol_table::compile (void)
|
||||||
fprintf (stderr, "Performing interprocedural optimizations\n");
|
fprintf (stderr, "Performing interprocedural optimizations\n");
|
||||||
state = IPA;
|
state = IPA;
|
||||||
|
|
||||||
|
/* Offloading requires LTO infrastructure. */
|
||||||
|
if (!in_lto_p && g->have_offload)
|
||||||
|
flag_generate_lto = 1;
|
||||||
|
|
||||||
/* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
|
/* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
|
||||||
if (flag_lto)
|
if (flag_generate_lto)
|
||||||
lto_streamer_hooks_init ();
|
lto_streamer_hooks_init ();
|
||||||
|
|
||||||
/* Don't run the IPA passes if there was any error or sorry messages. */
|
/* Don't run the IPA passes if there was any error or sorry messages. */
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,8 @@ gcc::context *g;
|
||||||
|
|
||||||
gcc::context::context ()
|
gcc::context::context ()
|
||||||
{
|
{
|
||||||
|
have_offload = false;
|
||||||
|
|
||||||
/* The pass manager's constructor uses the dump manager (to set up
|
/* The pass manager's constructor uses the dump manager (to set up
|
||||||
dumps for the various passes), so the dump manager must be set up
|
dumps for the various passes), so the dump manager must be set up
|
||||||
before the pass manager. */
|
before the pass manager. */
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,9 @@ class context
|
||||||
public:
|
public:
|
||||||
context ();
|
context ();
|
||||||
|
|
||||||
|
/* The flag shows if there are symbols to be streamed for offloading. */
|
||||||
|
bool have_offload;
|
||||||
|
|
||||||
/* Pass-management. */
|
/* Pass-management. */
|
||||||
|
|
||||||
pass_manager *get_passes () { gcc_assert (m_passes); return m_passes; }
|
pass_manager *get_passes () { gcc_assert (m_passes); return m_passes; }
|
||||||
|
|
|
||||||
|
|
@ -4024,7 +4024,7 @@ inline_generate_summary (void)
|
||||||
|
|
||||||
/* When not optimizing, do not bother to analyze. Inlining is still done
|
/* When not optimizing, do not bother to analyze. Inlining is still done
|
||||||
because edge redirection needs to happen there. */
|
because edge redirection needs to happen there. */
|
||||||
if (!optimize && !flag_lto && !flag_wpa)
|
if (!optimize && !flag_generate_lto && !flag_wpa)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
function_insertion_hook_holder =
|
function_insertion_hook_holder =
|
||||||
|
|
@ -4339,11 +4339,6 @@ void
|
||||||
inline_free_summary (void)
|
inline_free_summary (void)
|
||||||
{
|
{
|
||||||
struct cgraph_node *node;
|
struct cgraph_node *node;
|
||||||
if (!inline_edge_summary_vec.exists ())
|
|
||||||
return;
|
|
||||||
FOR_EACH_DEFINED_FUNCTION (node)
|
|
||||||
if (!node->alias)
|
|
||||||
reset_inline_summary (node);
|
|
||||||
if (function_insertion_hook_holder)
|
if (function_insertion_hook_holder)
|
||||||
symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
|
symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
|
||||||
function_insertion_hook_holder = NULL;
|
function_insertion_hook_holder = NULL;
|
||||||
|
|
@ -4359,6 +4354,11 @@ inline_free_summary (void)
|
||||||
if (edge_duplication_hook_holder)
|
if (edge_duplication_hook_holder)
|
||||||
symtab->remove_edge_duplication_hook (edge_duplication_hook_holder);
|
symtab->remove_edge_duplication_hook (edge_duplication_hook_holder);
|
||||||
edge_duplication_hook_holder = NULL;
|
edge_duplication_hook_holder = NULL;
|
||||||
|
if (!inline_edge_summary_vec.exists ())
|
||||||
|
return;
|
||||||
|
FOR_EACH_DEFINED_FUNCTION (node)
|
||||||
|
if (!node->alias)
|
||||||
|
reset_inline_summary (node);
|
||||||
vec_free (inline_summary_vec);
|
vec_free (inline_summary_vec);
|
||||||
inline_edge_summary_vec.release ();
|
inline_edge_summary_vec.release ();
|
||||||
if (edge_predicate_pool)
|
if (edge_predicate_pool)
|
||||||
|
|
|
||||||
|
|
@ -330,6 +330,11 @@ referenced_from_other_partition_p (symtab_node *node, lto_symtab_encoder_t encod
|
||||||
|
|
||||||
for (i = 0; node->iterate_referring (i, ref); i++)
|
for (i = 0; node->iterate_referring (i, ref); i++)
|
||||||
{
|
{
|
||||||
|
/* Ignore references from non-offloadable nodes while streaming NODE into
|
||||||
|
offload LTO section. */
|
||||||
|
if (!ref->referring->need_lto_streaming)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (ref->referring->in_other_partition
|
if (ref->referring->in_other_partition
|
||||||
|| !lto_symtab_encoder_in_partition_p (encoder, ref->referring))
|
|| !lto_symtab_encoder_in_partition_p (encoder, ref->referring))
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -348,9 +353,16 @@ reachable_from_other_partition_p (struct cgraph_node *node, lto_symtab_encoder_t
|
||||||
if (node->global.inlined_to)
|
if (node->global.inlined_to)
|
||||||
return false;
|
return false;
|
||||||
for (e = node->callers; e; e = e->next_caller)
|
for (e = node->callers; e; e = e->next_caller)
|
||||||
|
{
|
||||||
|
/* Ignore references from non-offloadable nodes while streaming NODE into
|
||||||
|
offload LTO section. */
|
||||||
|
if (!e->caller->need_lto_streaming)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (e->caller->in_other_partition
|
if (e->caller->in_other_partition
|
||||||
|| !lto_symtab_encoder_in_partition_p (encoder, e->caller))
|
|| !lto_symtab_encoder_in_partition_p (encoder, e->caller))
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -818,6 +830,16 @@ create_references (lto_symtab_encoder_t encoder, symtab_node *node)
|
||||||
lto_symtab_encoder_encode (encoder, ref->referred);
|
lto_symtab_encoder_encode (encoder, ref->referred);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Select what needs to be streamed out. In regular lto mode stream everything.
|
||||||
|
In offload lto mode stream only nodes marked as offloadable. */
|
||||||
|
void
|
||||||
|
select_what_to_stream (bool offload_lto_mode)
|
||||||
|
{
|
||||||
|
struct symtab_node *snode;
|
||||||
|
FOR_EACH_SYMBOL (snode)
|
||||||
|
snode->need_lto_streaming = !offload_lto_mode || snode->offloadable;
|
||||||
|
}
|
||||||
|
|
||||||
/* Find all symbols we want to stream into given partition and insert them
|
/* Find all symbols we want to stream into given partition and insert them
|
||||||
to encoders.
|
to encoders.
|
||||||
|
|
||||||
|
|
@ -844,6 +866,8 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
|
||||||
!lsei_end_p (lsei); lsei_next_function_in_partition (&lsei))
|
!lsei_end_p (lsei); lsei_next_function_in_partition (&lsei))
|
||||||
{
|
{
|
||||||
struct cgraph_node *node = lsei_cgraph_node (lsei);
|
struct cgraph_node *node = lsei_cgraph_node (lsei);
|
||||||
|
if (!node->need_lto_streaming)
|
||||||
|
continue;
|
||||||
add_node_to (encoder, node, true);
|
add_node_to (encoder, node, true);
|
||||||
lto_set_symtab_encoder_in_partition (encoder, node);
|
lto_set_symtab_encoder_in_partition (encoder, node);
|
||||||
create_references (encoder, node);
|
create_references (encoder, node);
|
||||||
|
|
@ -860,6 +884,8 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
|
||||||
{
|
{
|
||||||
varpool_node *vnode = lsei_varpool_node (lsei);
|
varpool_node *vnode = lsei_varpool_node (lsei);
|
||||||
|
|
||||||
|
if (!vnode->need_lto_streaming)
|
||||||
|
continue;
|
||||||
lto_set_symtab_encoder_in_partition (encoder, vnode);
|
lto_set_symtab_encoder_in_partition (encoder, vnode);
|
||||||
lto_set_symtab_encoder_encode_initializer (encoder, vnode);
|
lto_set_symtab_encoder_encode_initializer (encoder, vnode);
|
||||||
create_references (encoder, vnode);
|
create_references (encoder, vnode);
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,11 @@ along with GCC; see the file COPYING3. If not see
|
||||||
name for the functions and static_initializers. For other types of
|
name for the functions and static_initializers. For other types of
|
||||||
sections a '.' and the section type are appended. */
|
sections a '.' and the section type are appended. */
|
||||||
#define LTO_SECTION_NAME_PREFIX ".gnu.lto_"
|
#define LTO_SECTION_NAME_PREFIX ".gnu.lto_"
|
||||||
|
#define OFFLOAD_SECTION_NAME_PREFIX ".gnu.offload_lto_"
|
||||||
|
|
||||||
|
/* Can be either OFFLOAD_SECTION_NAME_PREFIX when we stream IR for offload
|
||||||
|
compiler, or LTO_SECTION_NAME_PREFIX for LTO case. */
|
||||||
|
extern const char *section_name_prefix;
|
||||||
|
|
||||||
/* Segment name for LTO sections. This is only used for Mach-O. */
|
/* Segment name for LTO sections. This is only used for Mach-O. */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@ struct lto_stats_d lto_stats;
|
||||||
static bitmap_obstack lto_obstack;
|
static bitmap_obstack lto_obstack;
|
||||||
static bool lto_obstack_initialized;
|
static bool lto_obstack_initialized;
|
||||||
|
|
||||||
|
const char *section_name_prefix = LTO_SECTION_NAME_PREFIX;
|
||||||
|
|
||||||
/* Return a string representing LTO tag TAG. */
|
/* Return a string representing LTO tag TAG. */
|
||||||
|
|
||||||
|
|
@ -189,7 +190,7 @@ lto_get_section_name (int section_type, const char *name, struct lto_file_decl_d
|
||||||
sprintf (post, "." HOST_WIDE_INT_PRINT_HEX_PURE, f->id);
|
sprintf (post, "." HOST_WIDE_INT_PRINT_HEX_PURE, f->id);
|
||||||
else
|
else
|
||||||
sprintf (post, "." HOST_WIDE_INT_PRINT_HEX_PURE, get_random_seed (false));
|
sprintf (post, "." HOST_WIDE_INT_PRINT_HEX_PURE, get_random_seed (false));
|
||||||
return concat (LTO_SECTION_NAME_PREFIX, sep, add, post, NULL);
|
return concat (section_name_prefix, sep, add, post, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -831,6 +831,7 @@ bool referenced_from_this_partition_p (symtab_node *,
|
||||||
bool reachable_from_this_partition_p (struct cgraph_node *,
|
bool reachable_from_this_partition_p (struct cgraph_node *,
|
||||||
lto_symtab_encoder_t);
|
lto_symtab_encoder_t);
|
||||||
lto_symtab_encoder_t compute_ltrans_boundary (lto_symtab_encoder_t encoder);
|
lto_symtab_encoder_t compute_ltrans_boundary (lto_symtab_encoder_t encoder);
|
||||||
|
void select_what_to_stream (bool);
|
||||||
|
|
||||||
|
|
||||||
/* In lto-symtab.c. */
|
/* In lto-symtab.c. */
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,17 @@
|
||||||
|
2014-11-13 Ilya Verbin <ilya.verbin@intel.com>
|
||||||
|
Bernd Schmidt <bernds@codesourcery.com>
|
||||||
|
Andrey Turetskiy <andrey.turetskiy@intel.com>
|
||||||
|
Michael Zolotukhin <michael.v.zolotukhin@intel.com>
|
||||||
|
|
||||||
|
* lto-object.c (lto_obj_add_section): Use section_name_prefix instead of
|
||||||
|
LTO_SECTION_NAME_PREFIX.
|
||||||
|
* lto-partition.c (lto_promote_cross_file_statics): Call
|
||||||
|
select_what_to_stream.
|
||||||
|
* lto.c (lto_section_with_id): Use section_name_prefix instead of
|
||||||
|
LTO_SECTION_NAME_PREFIX.
|
||||||
|
(read_cgraph_and_symbols): Read OFFLOAD_SECTION_NAME_PREFIX sections, if
|
||||||
|
being built as an offload compiler.
|
||||||
|
|
||||||
2014-10-29 Richard Sandiford <richard.sandiford@arm.com>
|
2014-10-29 Richard Sandiford <richard.sandiford@arm.com>
|
||||||
|
|
||||||
* lto-lang.c: Remove redundant enum from machine_mode.
|
* lto-lang.c: Remove redundant enum from machine_mode.
|
||||||
|
|
|
||||||
|
|
@ -242,8 +242,7 @@ lto_obj_add_section (void *data, const char *name, off_t offset,
|
||||||
void **slot;
|
void **slot;
|
||||||
struct lto_section_list *list = loasd->list;
|
struct lto_section_list *list = loasd->list;
|
||||||
|
|
||||||
if (strncmp (name, LTO_SECTION_NAME_PREFIX,
|
if (strncmp (name, section_name_prefix, strlen (section_name_prefix)))
|
||||||
strlen (LTO_SECTION_NAME_PREFIX)) != 0)
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
new_name = xstrdup (name);
|
new_name = xstrdup (name);
|
||||||
|
|
|
||||||
|
|
@ -952,6 +952,8 @@ lto_promote_cross_file_statics (void)
|
||||||
|
|
||||||
gcc_assert (flag_wpa);
|
gcc_assert (flag_wpa);
|
||||||
|
|
||||||
|
select_what_to_stream (false);
|
||||||
|
|
||||||
/* First compute boundaries. */
|
/* First compute boundaries. */
|
||||||
n_sets = ltrans_partitions.length ();
|
n_sets = ltrans_partitions.length ();
|
||||||
for (i = 0; i < n_sets; i++)
|
for (i = 0; i < n_sets; i++)
|
||||||
|
|
|
||||||
|
|
@ -2137,7 +2137,7 @@ lto_section_with_id (const char *name, unsigned HOST_WIDE_INT *id)
|
||||||
{
|
{
|
||||||
const char *s;
|
const char *s;
|
||||||
|
|
||||||
if (strncmp (name, LTO_SECTION_NAME_PREFIX, strlen (LTO_SECTION_NAME_PREFIX)))
|
if (strncmp (name, section_name_prefix, strlen (section_name_prefix)))
|
||||||
return 0;
|
return 0;
|
||||||
s = strrchr (name, '.');
|
s = strrchr (name, '.');
|
||||||
return s && sscanf (s, "." HOST_WIDE_INT_PRINT_HEX_PURE, id) == 1;
|
return s && sscanf (s, "." HOST_WIDE_INT_PRINT_HEX_PURE, id) == 1;
|
||||||
|
|
@ -2912,6 +2912,10 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
|
||||||
|
|
||||||
timevar_push (TV_IPA_LTO_DECL_IN);
|
timevar_push (TV_IPA_LTO_DECL_IN);
|
||||||
|
|
||||||
|
#ifdef ACCEL_COMPILER
|
||||||
|
section_name_prefix = OFFLOAD_SECTION_NAME_PREFIX;
|
||||||
|
#endif
|
||||||
|
|
||||||
real_file_decl_data
|
real_file_decl_data
|
||||||
= decl_data = ggc_cleared_vec_alloc<lto_file_decl_data_ptr> (nfiles + 1);
|
= decl_data = ggc_cleared_vec_alloc<lto_file_decl_data_ptr> (nfiles + 1);
|
||||||
real_file_count = nfiles;
|
real_file_count = nfiles;
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,7 @@ along with GCC; see the file COPYING3. If not see
|
||||||
#include "tree-nested.h"
|
#include "tree-nested.h"
|
||||||
#include "tree-eh.h"
|
#include "tree-eh.h"
|
||||||
#include "cilk.h"
|
#include "cilk.h"
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
|
|
||||||
/* Lowering of OpenMP parallel and workshare constructs proceeds in two
|
/* Lowering of OpenMP parallel and workshare constructs proceeds in two
|
||||||
|
|
@ -273,6 +274,16 @@ is_parallel_ctx (omp_context *ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Return true if CTX is for an omp target region. */
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
is_targetreg_ctx (omp_context *ctx)
|
||||||
|
{
|
||||||
|
return gimple_code (ctx->stmt) == GIMPLE_OMP_TARGET
|
||||||
|
&& gimple_omp_target_kind (ctx->stmt) == GF_OMP_TARGET_KIND_REGION;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Return true if CTX is for an omp task. */
|
/* Return true if CTX is for an omp task. */
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
|
|
@ -1642,8 +1653,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
|
||||||
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
|
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
|
||||||
&& DECL_P (decl)
|
&& DECL_P (decl)
|
||||||
&& is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx))
|
&& is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx))
|
||||||
&& lookup_attribute ("omp declare target",
|
&& varpool_node::get_create (decl)->offloadable)
|
||||||
DECL_ATTRIBUTES (decl)))
|
|
||||||
break;
|
break;
|
||||||
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
|
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
|
||||||
&& OMP_CLAUSE_MAP_KIND (c) == OMP_CLAUSE_MAP_POINTER)
|
&& OMP_CLAUSE_MAP_KIND (c) == OMP_CLAUSE_MAP_POINTER)
|
||||||
|
|
@ -1783,8 +1793,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
|
||||||
decl = OMP_CLAUSE_DECL (c);
|
decl = OMP_CLAUSE_DECL (c);
|
||||||
if (DECL_P (decl)
|
if (DECL_P (decl)
|
||||||
&& is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx))
|
&& is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx))
|
||||||
&& lookup_attribute ("omp declare target",
|
&& varpool_node::get_create (decl)->offloadable)
|
||||||
DECL_ATTRIBUTES (decl)))
|
|
||||||
break;
|
break;
|
||||||
if (DECL_P (decl))
|
if (DECL_P (decl))
|
||||||
{
|
{
|
||||||
|
|
@ -1938,26 +1947,19 @@ create_omp_child_function (omp_context *ctx, bool task_copy)
|
||||||
DECL_EXTERNAL (decl) = 0;
|
DECL_EXTERNAL (decl) = 0;
|
||||||
DECL_CONTEXT (decl) = NULL_TREE;
|
DECL_CONTEXT (decl) = NULL_TREE;
|
||||||
DECL_INITIAL (decl) = make_node (BLOCK);
|
DECL_INITIAL (decl) = make_node (BLOCK);
|
||||||
bool target_p = false;
|
if (cgraph_node::get (current_function_decl)->offloadable)
|
||||||
if (lookup_attribute ("omp declare target",
|
cgraph_node::get_create (decl)->offloadable = 1;
|
||||||
DECL_ATTRIBUTES (current_function_decl)))
|
|
||||||
target_p = true;
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
omp_context *octx;
|
omp_context *octx;
|
||||||
for (octx = ctx; octx; octx = octx->outer)
|
for (octx = ctx; octx; octx = octx->outer)
|
||||||
if (gimple_code (octx->stmt) == GIMPLE_OMP_TARGET
|
if (is_targetreg_ctx (octx))
|
||||||
&& gimple_omp_target_kind (octx->stmt)
|
|
||||||
== GF_OMP_TARGET_KIND_REGION)
|
|
||||||
{
|
{
|
||||||
target_p = true;
|
cgraph_node::get_create (decl)->offloadable = 1;
|
||||||
|
g->have_offload = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (target_p)
|
|
||||||
DECL_ATTRIBUTES (decl)
|
|
||||||
= tree_cons (get_identifier ("omp declare target"),
|
|
||||||
NULL_TREE, DECL_ATTRIBUTES (decl));
|
|
||||||
|
|
||||||
t = build_decl (DECL_SOURCE_LOCATION (decl),
|
t = build_decl (DECL_SOURCE_LOCATION (decl),
|
||||||
RESULT_DECL, NULL_TREE, void_type_node);
|
RESULT_DECL, NULL_TREE, void_type_node);
|
||||||
|
|
@ -2663,8 +2665,7 @@ check_omp_nesting_restrictions (gimple stmt, omp_context *ctx)
|
||||||
break;
|
break;
|
||||||
case GIMPLE_OMP_TARGET:
|
case GIMPLE_OMP_TARGET:
|
||||||
for (; ctx != NULL; ctx = ctx->outer)
|
for (; ctx != NULL; ctx = ctx->outer)
|
||||||
if (gimple_code (ctx->stmt) == GIMPLE_OMP_TARGET
|
if (is_targetreg_ctx (ctx))
|
||||||
&& gimple_omp_target_kind (ctx->stmt) == GF_OMP_TARGET_KIND_REGION)
|
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
switch (gimple_omp_target_kind (stmt))
|
switch (gimple_omp_target_kind (stmt))
|
||||||
|
|
@ -8281,6 +8282,7 @@ expand_omp_target (struct omp_region *region)
|
||||||
if (kind == GF_OMP_TARGET_KIND_REGION)
|
if (kind == GF_OMP_TARGET_KIND_REGION)
|
||||||
{
|
{
|
||||||
unsigned srcidx, dstidx, num;
|
unsigned srcidx, dstidx, num;
|
||||||
|
struct cgraph_node *node;
|
||||||
|
|
||||||
/* If the target region needs data sent from the parent
|
/* If the target region needs data sent from the parent
|
||||||
function, then the very first statement (except possible
|
function, then the very first statement (except possible
|
||||||
|
|
@ -8412,6 +8414,11 @@ expand_omp_target (struct omp_region *region)
|
||||||
push_cfun (child_cfun);
|
push_cfun (child_cfun);
|
||||||
cgraph_edge::rebuild_edges ();
|
cgraph_edge::rebuild_edges ();
|
||||||
|
|
||||||
|
/* Prevent IPA from removing child_fn as unreachable, since there are no
|
||||||
|
refs from the parent function to child_fn in offload LTO mode. */
|
||||||
|
node = cgraph_node::get (child_fn);
|
||||||
|
node->mark_force_output ();
|
||||||
|
|
||||||
/* Some EH regions might become dead, see PR34608. If
|
/* Some EH regions might become dead, see PR34608. If
|
||||||
pass_cleanup_cfg isn't the first pass to happen with the
|
pass_cleanup_cfg isn't the first pass to happen with the
|
||||||
new child, these dead EH edges might cause problems.
|
new child, these dead EH edges might cause problems.
|
||||||
|
|
@ -9326,6 +9333,17 @@ lower_omp_critical (gimple_stmt_iterator *gsi_p, omp_context *ctx)
|
||||||
DECL_COMMON (decl) = 1;
|
DECL_COMMON (decl) = 1;
|
||||||
DECL_ARTIFICIAL (decl) = 1;
|
DECL_ARTIFICIAL (decl) = 1;
|
||||||
DECL_IGNORED_P (decl) = 1;
|
DECL_IGNORED_P (decl) = 1;
|
||||||
|
|
||||||
|
/* If '#pragma omp critical' is inside target region, the symbol must
|
||||||
|
be marked for offloading. */
|
||||||
|
omp_context *octx;
|
||||||
|
for (octx = ctx->outer; octx; octx = octx->outer)
|
||||||
|
if (is_targetreg_ctx (octx))
|
||||||
|
{
|
||||||
|
varpool_node::get_create (decl)->offloadable = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
varpool_node::finalize_decl (decl);
|
varpool_node::finalize_decl (decl);
|
||||||
|
|
||||||
splay_tree_insert (critical_name_mutexes, (splay_tree_key) name,
|
splay_tree_insert (critical_name_mutexes, (splay_tree_key) name,
|
||||||
|
|
|
||||||
|
|
@ -2416,7 +2416,7 @@ ipa_write_summaries_1 (lto_symtab_encoder_t encoder)
|
||||||
/* Write out summaries for all the nodes in the callgraph. */
|
/* Write out summaries for all the nodes in the callgraph. */
|
||||||
|
|
||||||
void
|
void
|
||||||
ipa_write_summaries (void)
|
ipa_write_summaries (bool offload_lto_mode)
|
||||||
{
|
{
|
||||||
lto_symtab_encoder_t encoder;
|
lto_symtab_encoder_t encoder;
|
||||||
int i, order_pos;
|
int i, order_pos;
|
||||||
|
|
@ -2427,6 +2427,8 @@ ipa_write_summaries (void)
|
||||||
if (!flag_generate_lto || seen_error ())
|
if (!flag_generate_lto || seen_error ())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
select_what_to_stream (offload_lto_mode);
|
||||||
|
|
||||||
encoder = lto_symtab_encoder_new (false);
|
encoder = lto_symtab_encoder_new (false);
|
||||||
|
|
||||||
/* Create the callgraph set in the same order used in
|
/* Create the callgraph set in the same order used in
|
||||||
|
|
@ -2453,14 +2455,15 @@ ipa_write_summaries (void)
|
||||||
renumber_gimple_stmt_uids ();
|
renumber_gimple_stmt_uids ();
|
||||||
pop_cfun ();
|
pop_cfun ();
|
||||||
}
|
}
|
||||||
if (node->definition)
|
if (node->definition && node->need_lto_streaming)
|
||||||
lto_set_symtab_encoder_in_partition (encoder, node);
|
lto_set_symtab_encoder_in_partition (encoder, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
FOR_EACH_DEFINED_FUNCTION (node)
|
FOR_EACH_DEFINED_FUNCTION (node)
|
||||||
if (node->alias)
|
if (node->alias && node->need_lto_streaming)
|
||||||
lto_set_symtab_encoder_in_partition (encoder, node);
|
lto_set_symtab_encoder_in_partition (encoder, node);
|
||||||
FOR_EACH_DEFINED_VARIABLE (vnode)
|
FOR_EACH_DEFINED_VARIABLE (vnode)
|
||||||
|
if (vnode->need_lto_streaming)
|
||||||
lto_set_symtab_encoder_in_partition (encoder, vnode);
|
lto_set_symtab_encoder_in_partition (encoder, vnode);
|
||||||
|
|
||||||
ipa_write_summaries_1 (compute_ltrans_boundary (encoder));
|
ipa_write_summaries_1 (compute_ltrans_boundary (encoder));
|
||||||
|
|
|
||||||
|
|
@ -602,7 +602,7 @@ extern void pass_fini_dump_file (opt_pass *);
|
||||||
extern const char *get_current_pass_name (void);
|
extern const char *get_current_pass_name (void);
|
||||||
extern void print_current_pass (FILE *);
|
extern void print_current_pass (FILE *);
|
||||||
extern void debug_pass (void);
|
extern void debug_pass (void);
|
||||||
extern void ipa_write_summaries (void);
|
extern void ipa_write_summaries (bool);
|
||||||
extern void ipa_write_optimization_summaries (struct lto_symtab_encoder_d *);
|
extern void ipa_write_optimization_summaries (struct lto_symtab_encoder_d *);
|
||||||
extern void ipa_read_summaries (void);
|
extern void ipa_read_summaries (void);
|
||||||
extern void ipa_read_optimization_summaries (void);
|
extern void ipa_read_optimization_summaries (void);
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ along with GCC; see the file COPYING3. If not see
|
||||||
#include "tree-ssa-alias.h"
|
#include "tree-ssa-alias.h"
|
||||||
#include "gimple.h"
|
#include "gimple.h"
|
||||||
#include "lto-streamer.h"
|
#include "lto-streamer.h"
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
const char * const tls_model_names[]={"none", "tls-emulated", "tls-real",
|
const char * const tls_model_names[]={"none", "tls-emulated", "tls-real",
|
||||||
"tls-global-dynamic", "tls-local-dynamic",
|
"tls-global-dynamic", "tls-local-dynamic",
|
||||||
|
|
@ -164,6 +165,14 @@ varpool_node::get_create (tree decl)
|
||||||
|
|
||||||
node = varpool_node::create_empty ();
|
node = varpool_node::create_empty ();
|
||||||
node->decl = decl;
|
node->decl = decl;
|
||||||
|
|
||||||
|
if (flag_openmp
|
||||||
|
&& lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl)))
|
||||||
|
{
|
||||||
|
node->offloadable = 1;
|
||||||
|
g->have_offload = true;
|
||||||
|
}
|
||||||
|
|
||||||
node->register_symbol ();
|
node->register_symbol ();
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue