summaryrefslogtreecommitdiff
path: root/gcc/cgraphunit.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cgraphunit.c')
-rw-r--r--gcc/cgraphunit.c102
1 files changed, 64 insertions, 38 deletions
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 2ad07187e04..7105e59c5ec 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -140,7 +140,6 @@ static void cgraph_expand_all_functions (void);
static void cgraph_mark_functions_to_output (void);
static void cgraph_expand_function (struct cgraph_node *);
static void cgraph_output_pending_asms (void);
-static void cgraph_optimize (void);
static void cgraph_analyze_function (struct cgraph_node *);
static FILE *cgraph_dump_file;
@@ -314,16 +313,9 @@ cgraph_build_cdtor_fns (void)
either outside this translation unit, something magic in the system
configury. */
-static bool
-decide_is_function_needed (struct cgraph_node *node, tree decl)
+bool
+cgraph_decide_is_function_needed (struct cgraph_node *node, tree decl)
{
- if (MAIN_NAME_P (DECL_NAME (decl))
- && TREE_PUBLIC (decl))
- {
- node->local.externally_visible = true;
- return true;
- }
-
/* If the user told us it is used, then it must be so. */
if (node->local.externally_visible)
return true;
@@ -361,7 +353,9 @@ decide_is_function_needed (struct cgraph_node *node, tree decl)
|| (!optimize && !node->local.disregard_inline_limits
&& !DECL_DECLARED_INLINE_P (decl)
&& !node->origin))
- && !flag_whole_program)
+ && !flag_whole_program
+ && !flag_lto
+ && !flag_whopr)
&& !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
return true;
@@ -522,7 +516,7 @@ cgraph_finalize_function (tree decl, bool nested)
node->finalized_by_frontend = true;
record_cdtor_fn (node->decl);
- if (decide_is_function_needed (node, decl))
+ if (cgraph_decide_is_function_needed (node, decl))
cgraph_mark_needed_node (node);
/* Since we reclaim unreachable nodes at the end of every language
@@ -551,7 +545,7 @@ void
cgraph_mark_if_needed (tree decl)
{
struct cgraph_node *node = cgraph_node (decl);
- if (node->local.finalized && decide_is_function_needed (node, decl))
+ if (node->local.finalized && cgraph_decide_is_function_needed (node, decl))
cgraph_mark_needed_node (node);
}
@@ -594,6 +588,21 @@ verify_cgraph_node (struct cgraph_node *node)
error ("Execution count is negative");
error_found = true;
}
+ if (node->global.inlined_to && node->local.externally_visible)
+ {
+ error ("Externally visible inline clone");
+ error_found = true;
+ }
+ if (node->global.inlined_to && node->address_taken)
+ {
+ error ("Inline clone with address taken");
+ error_found = true;
+ }
+ if (node->global.inlined_to && node->needed)
+ {
+ error ("Inline clone is needed");
+ error_found = true;
+ }
for (e = node->callers; e; e = e->next_caller)
{
if (e->count < 0)
@@ -692,7 +701,8 @@ verify_cgraph_node (struct cgraph_node *node)
if (node->analyzed && gimple_has_body_p (node->decl)
&& !TREE_ASM_WRITTEN (node->decl)
- && (!DECL_EXTERNAL (node->decl) || node->global.inlined_to))
+ && (!DECL_EXTERNAL (node->decl) || node->global.inlined_to)
+ && !flag_wpa)
{
if (this_cfun->cfg)
{
@@ -864,12 +874,8 @@ process_function_and_variable_attributes (struct cgraph_node *first,
warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wattributes,
"%<externally_visible%>"
" attribute have effect only on public objects");
- else
- {
- if (node->local.finalized)
- cgraph_mark_needed_node (node);
- node->local.externally_visible = true;
- }
+ else if (node->local.finalized)
+ cgraph_mark_needed_node (node);
}
}
for (vnode = varpool_nodes; vnode != first_var; vnode = vnode->next)
@@ -887,12 +893,8 @@ process_function_and_variable_attributes (struct cgraph_node *first,
warning_at (DECL_SOURCE_LOCATION (vnode->decl), OPT_Wattributes,
"%<externally_visible%>"
" attribute have effect only on public objects");
- else
- {
- if (vnode->finalized)
- varpool_mark_needed_node (vnode);
- vnode->externally_visible = true;
- }
+ else if (vnode->finalized)
+ varpool_mark_needed_node (vnode);
}
}
}
@@ -949,8 +951,8 @@ cgraph_analyze_functions (void)
continue;
}
- gcc_assert (!node->analyzed && node->reachable);
- cgraph_analyze_function (node);
+ if (!node->analyzed)
+ cgraph_analyze_function (node);
for (edge = node->callees; edge; edge = edge->next_callee)
if (!edge->callee->reachable)
@@ -1355,15 +1357,34 @@ ipa_passes (void)
current_function_decl = NULL;
gimple_register_cfg_hooks ();
bitmap_obstack_initialize (NULL);
- execute_ipa_pass_list (all_ipa_passes);
- /* Generate coverage variables and constructors. */
- coverage_finish ();
+ if (!in_lto_p)
+ execute_ipa_pass_list (all_small_ipa_passes);
- /* Process new functions added. */
- set_cfun (NULL);
- current_function_decl = NULL;
- cgraph_process_new_functions ();
+ /* If pass_all_early_optimizations was not scheduled, the state of
+ the cgraph will not be properly updated. Update it now. */
+ if (cgraph_state < CGRAPH_STATE_IPA_SSA)
+ cgraph_state = CGRAPH_STATE_IPA_SSA;
+
+ if (!in_lto_p)
+ {
+ /* Generate coverage variables and constructors. */
+ coverage_finish ();
+
+ /* Process new functions added. */
+ set_cfun (NULL);
+ current_function_decl = NULL;
+ cgraph_process_new_functions ();
+
+ execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_regular_ipa_passes);
+ }
+ execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_lto_gen_passes);
+
+ if (!in_lto_p)
+ ipa_write_summaries ();
+
+ if (!flag_ltrans)
+ execute_ipa_pass_list (all_regular_ipa_passes);
bitmap_obstack_release (NULL);
}
@@ -1371,7 +1392,7 @@ ipa_passes (void)
/* Perform simple optimizations based on callgraph. */
-static void
+void
cgraph_optimize (void)
{
if (errorcount || sorrycount)
@@ -1401,7 +1422,10 @@ cgraph_optimize (void)
/* Do nothing else if any IPA pass found errors. */
if (errorcount || sorrycount)
- return;
+ {
+ timevar_pop (TV_CGRAPHOPT);
+ return;
+ }
/* This pass remove bodies of extern inline functions we never inlined.
Do this later so other IPA passes see what is really going on. */
@@ -1421,6 +1445,7 @@ cgraph_optimize (void)
timevar_pop (TV_CGRAPHOPT);
/* Output everything. */
+ (*debug_hooks->assembly_start) ();
if (!quiet_flag)
fprintf (stderr, "Assembling functions:\n");
#ifdef ENABLE_CHECKING
@@ -1598,7 +1623,8 @@ cgraph_copy_node_for_versioning (struct cgraph_node *old_version,
also cloned. */
for (e = old_version->callees;e; e=e->next_callee)
{
- new_e = cgraph_clone_edge (e, new_version, e->call_stmt, 0, e->frequency,
+ new_e = cgraph_clone_edge (e, new_version, e->call_stmt,
+ e->lto_stmt_uid, 0, e->frequency,
e->loop_nest, true);
new_e->count = e->count;
}