error ("caller edge frequency is too large");
error_found = true;
}
+ if (gimple_has_body_p (e->caller->decl)
+ && !e->caller->global.inlined_to
+ && (e->frequency
+ != compute_call_stmt_bb_frequency (e->caller->decl,
+ gimple_bb (e->call_stmt))))
+ {
+ error ("caller edge frequency %i does not match BB freqency %i",
+ e->frequency,
+ compute_call_stmt_bb_frequency (e->caller->decl,
+ gimple_bb (e->call_stmt)));
+ error_found = true;
+ }
if (!e->inline_failed)
{
if (node->global.inlined_to
if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
{
mark_decl_referenced (decl);
+ vnode->force_output = true;
if (vnode->finalized)
varpool_mark_needed_node (vnode);
}
static void
cgraph_emit_thunks (void)
{
- struct cgraph_node *n;
+ struct cgraph_node *n, *alias;
for (n = cgraph_nodes; n; n = n->next)
{
cgraph_mark_functions_to_output in cgraph_optimize). */
if (n->reachable
&& !DECL_EXTERNAL (n->decl))
- lang_hooks.callgraph.emit_associated_thunks (n->decl);
+ {
+ lang_hooks.callgraph.emit_associated_thunks (n->decl);
+ for (alias = n->same_body; alias; alias = alias->next)
+ if (!DECL_EXTERNAL (alias->decl))
+ lang_hooks.callgraph.emit_associated_thunks (alias->decl);
+ }
}
}
/* Make sure that BE didn't give up on compiling. */
gcc_assert (TREE_ASM_WRITTEN (decl));
current_function_decl = NULL;
+ if (node->same_body)
+ {
+ struct cgraph_node *alias;
+ bool saved_alias = node->alias;
+ for (alias = node->same_body; alias; alias = alias->next)
+ assemble_alias (alias->decl, DECL_ASSEMBLER_NAME (decl));
+ node->alias = saved_alias;
+ }
gcc_assert (!cgraph_preserve_function_body_p (decl));
cgraph_release_function_body (node);
/* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
/* 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. */
TREE_PUBLIC (first_clone->decl) = 0;
DECL_COMDAT (first_clone->decl) = 0;
VEC_free (ipa_opt_pass, heap,
- DECL_STRUCT_FUNCTION (first_clone->decl)->ipa_transforms_to_apply);
- DECL_STRUCT_FUNCTION (first_clone->decl)->ipa_transforms_to_apply = NULL;
+ first_clone->ipa_transforms_to_apply);
+ first_clone->ipa_transforms_to_apply = NULL;
#ifdef ENABLE_CHECKING
verify_cgraph_node (first_clone);
node->clone_of->clones = node->next_sibling_clone;
node->next_sibling_clone = NULL;
node->prev_sibling_clone = NULL;
+ if (!node->clone_of->analyzed && !node->clone_of->clones)
+ cgraph_remove_node (node->clone_of);
node->clone_of = NULL;
bitmap_obstack_release (NULL);
}
{
gimple new_stmt;
gimple_stmt_iterator gsi;
-
+
+ if (e->callee->same_body)
+ {
+ struct cgraph_node *alias;
+
+ for (alias = e->callee->same_body;
+ alias;
+ alias = alias->next)
+ if (decl == alias->decl)
+ break;
+ /* Don't update call from same body alias to the real
+ function. */
+ if (alias)
+ continue;
+ }
+
if (cgraph_dump_file)
{
fprintf (cgraph_dump_file, "updating call of %s in %s:",