cgraph.c (symbol_table::create_edge): Set inline_failed.

* cgraph.c (symbol_table::create_edge): Set inline_failed.
	(cgraph_edge::make_direct): Likewise.
	(cgraph_edge::dump_edge_flags): Dump call_stmt_cannot_inline_p.
	* cgraphclones.c (duplicate_thunk_for_node): Set inline_failed.
	* cif-code.def (CIF_LTO_MISMATCHED_DECLARATIONS): New code
	(CIF_THUNK): New code.
	* ipa-inline-analysis.c (initialize_inline_failed): Preserve
	CIF_FINAL_ERROR codes; do not deal with call_stmt_cannot_inline_p.
	(compute_inline_parameters): Set inline_failed for thunks.
	(inline_analyze_function): Cleanup.
	* ipa-inline.c (can_inline_edge_p): Do not deal with
	call_stmt_cannot_inline_p.
	(can_early_inline_edge_p): Likewise.
	(early_inliner): Initialize inline_failed.
	* lto-cgraph.c (lto_output_edge): Sanity check inline_failed.

	* lto-symtab.c (lto_cgraph_replace_node): Initialize inline_failed.

From-SVN: r235839
This commit is contained in:
Jan Hubicka 2016-05-03 21:05:31 +02:00 committed by Jan Hubicka
parent 8b38916ad4
commit 1a0bf5e11b
9 changed files with 71 additions and 30 deletions

View File

@ -1,3 +1,21 @@
2016-05-03 Jan Hubicka <hubicka@ucw.cz>
* cgraph.c (symbol_table::create_edge): Set inline_failed.
(cgraph_edge::make_direct): Likewise.
(cgraph_edge::dump_edge_flags): Dump call_stmt_cannot_inline_p.
* cgraphclones.c (duplicate_thunk_for_node): Set inline_failed.
* cif-code.def (CIF_LTO_MISMATCHED_DECLARATIONS): New code
(CIF_THUNK): New code.
* ipa-inline-analysis.c (initialize_inline_failed): Preserve
CIF_FINAL_ERROR codes; do not deal with call_stmt_cannot_inline_p.
(compute_inline_parameters): Set inline_failed for thunks.
(inline_analyze_function): Cleanup.
* ipa-inline.c (can_inline_edge_p): Do not deal with
call_stmt_cannot_inline_p.
(can_early_inline_edge_p): Likewise.
(early_inliner): Initialize inline_failed.
* lto-cgraph.c (lto_output_edge): Sanity check inline_failed.
2016-05-03 Uros Bizjak <ubizjak@gmail.com> 2016-05-03 Uros Bizjak <ubizjak@gmail.com>
* config/i386/predicates.md (x87nonimm_ssenomem_operand): Rename * config/i386/predicates.md (x87nonimm_ssenomem_operand): Rename

View File

@ -859,9 +859,15 @@ symbol_table::create_edge (cgraph_node *caller, cgraph_node *callee,
&& callee && callee->decl && callee && callee->decl
&& !gimple_check_call_matching_types (call_stmt, callee->decl, && !gimple_check_call_matching_types (call_stmt, callee->decl,
false)) false))
{
edge->inline_failed = CIF_MISMATCHED_ARGUMENTS;
edge->call_stmt_cannot_inline_p = true; edge->call_stmt_cannot_inline_p = true;
}
else else
{
edge->inline_failed = CIF_FUNCTION_NOT_CONSIDERED;
edge->call_stmt_cannot_inline_p = false; edge->call_stmt_cannot_inline_p = false;
}
edge->indirect_info = NULL; edge->indirect_info = NULL;
edge->indirect_inlining_edge = 0; edge->indirect_inlining_edge = 0;
@ -1240,10 +1246,12 @@ cgraph_edge::make_direct (cgraph_node *callee)
/* Insert to callers list of the new callee. */ /* Insert to callers list of the new callee. */
edge->set_callee (callee); edge->set_callee (callee);
if (call_stmt) if (call_stmt
call_stmt_cannot_inline_p && !gimple_check_call_matching_types (call_stmt, callee->decl, false))
= !gimple_check_call_matching_types (call_stmt, callee->decl, {
false); call_stmt_cannot_inline_p = true;
inline_failed = CIF_MISMATCHED_ARGUMENTS;
}
/* We need to re-determine the inlining status of the edge. */ /* We need to re-determine the inlining status of the edge. */
initialize_inline_failed (edge); initialize_inline_failed (edge);
@ -1996,6 +2004,8 @@ cgraph_edge::dump_edge_flags (FILE *f)
fprintf (f, "(speculative) "); fprintf (f, "(speculative) ");
if (!inline_failed) if (!inline_failed)
fprintf (f, "(inlined) "); fprintf (f, "(inlined) ");
if (call_stmt_cannot_inline_p)
fprintf (f, "(call_stmt_cannot_inline_p) ");
if (indirect_inlining_edge) if (indirect_inlining_edge)
fprintf (f, "(indirect_inlining) "); fprintf (f, "(indirect_inlining) ");
if (count) if (count)

View File

@ -338,6 +338,7 @@ duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node)
cgraph_edge *e = new_thunk->create_edge (node, NULL, 0, cgraph_edge *e = new_thunk->create_edge (node, NULL, 0,
CGRAPH_FREQ_BASE); CGRAPH_FREQ_BASE);
e->call_stmt_cannot_inline_p = true; e->call_stmt_cannot_inline_p = true;
e->inline_failed = CIF_THUNK;
symtab->call_edge_duplication_hooks (thunk->callees, e); symtab->call_edge_duplication_hooks (thunk->callees, e);
symtab->call_cgraph_duplication_hooks (thunk, new_thunk); symtab->call_cgraph_duplication_hooks (thunk, new_thunk);
return new_thunk; return new_thunk;

View File

@ -92,6 +92,10 @@ DEFCIFCODE(MISMATCHED_ARGUMENTS, CIF_FINAL_ERROR,
N_("mismatched arguments")) N_("mismatched arguments"))
/* Caller and callee disagree on the arguments. */ /* Caller and callee disagree on the arguments. */
DEFCIFCODE(LTO_MISMATCHED_DECLARATIONS, CIF_FINAL_ERROR,
N_("mismatched declarations during linktime optimization"))
/* Caller is thunk. */
DEFCIFCODE(THUNK, CIF_FINAL_ERROR, DEFCIFCODE(THUNK, CIF_FINAL_ERROR,
N_("thunk call")) N_("thunk call"))

View File

@ -1490,19 +1490,23 @@ initialize_inline_failed (struct cgraph_edge *e)
{ {
struct cgraph_node *callee = e->callee; struct cgraph_node *callee = e->callee;
if (e->indirect_unknown_callee) if (e->inline_failed && e->inline_failed != CIF_BODY_NOT_AVAILABLE
&& cgraph_inline_failed_type (e->inline_failed) == CIF_FINAL_ERROR)
;
else if (e->indirect_unknown_callee)
e->inline_failed = CIF_INDIRECT_UNKNOWN_CALL; e->inline_failed = CIF_INDIRECT_UNKNOWN_CALL;
else if (!callee->definition) else if (!callee->definition)
e->inline_failed = CIF_BODY_NOT_AVAILABLE; e->inline_failed = CIF_BODY_NOT_AVAILABLE;
else if (callee->local.redefined_extern_inline) else if (callee->local.redefined_extern_inline)
e->inline_failed = CIF_REDEFINED_EXTERN_INLINE; e->inline_failed = CIF_REDEFINED_EXTERN_INLINE;
else if (e->call_stmt_cannot_inline_p)
e->inline_failed = CIF_MISMATCHED_ARGUMENTS;
else if (cfun && fn_contains_cilk_spawn_p (cfun)) else if (cfun && fn_contains_cilk_spawn_p (cfun))
/* We can't inline if the function is spawing a function. */ /* We can't inline if the function is spawing a function. */
e->inline_failed = CIF_FUNCTION_NOT_INLINABLE; e->inline_failed = CIF_CILK_SPAWN;
else else
e->inline_failed = CIF_FUNCTION_NOT_CONSIDERED; e->inline_failed = CIF_FUNCTION_NOT_CONSIDERED;
gcc_checking_assert (!e->call_stmt_cannot_inline_p
|| cgraph_inline_failed_type (e->inline_failed)
== CIF_FINAL_ERROR);
} }
/* Callback of walk_aliased_vdefs. Flags that it has been invoked to the /* Callback of walk_aliased_vdefs. Flags that it has been invoked to the
@ -2925,7 +2929,7 @@ compute_inline_parameters (struct cgraph_node *node, bool early)
struct predicate t = true_predicate (); struct predicate t = true_predicate ();
info->inlinable = 0; info->inlinable = 0;
node->callees->call_stmt_cannot_inline_p = true; node->callees->inline_failed = CIF_THUNK;
node->local.can_change_signature = false; node->local.can_change_signature = false;
es->call_stmt_time = 1; es->call_stmt_time = 1;
es->call_stmt_size = 1; es->call_stmt_size = 1;
@ -4107,17 +4111,9 @@ inline_analyze_function (struct cgraph_node *node)
{ {
struct cgraph_edge *e; struct cgraph_edge *e;
for (e = node->callees; e; e = e->next_callee) for (e = node->callees; e; e = e->next_callee)
{
if (e->inline_failed == CIF_FUNCTION_NOT_CONSIDERED)
e->inline_failed = CIF_FUNCTION_NOT_OPTIMIZED; e->inline_failed = CIF_FUNCTION_NOT_OPTIMIZED;
e->call_stmt_cannot_inline_p = true;
}
for (e = node->indirect_calls; e; e = e->next_callee) for (e = node->indirect_calls; e; e = e->next_callee)
{
if (e->inline_failed == CIF_FUNCTION_NOT_CONSIDERED)
e->inline_failed = CIF_FUNCTION_NOT_OPTIMIZED; e->inline_failed = CIF_FUNCTION_NOT_OPTIMIZED;
e->call_stmt_cannot_inline_p = true;
}
} }
pop_cfun (); pop_cfun ();

View File

@ -335,12 +335,10 @@ can_inline_edge_p (struct cgraph_edge *e, bool report,
e->inline_failed = CIF_OVERWRITABLE; e->inline_failed = CIF_OVERWRITABLE;
inlinable = false; inlinable = false;
} }
/* All edges with call_stmt_cannot_inline_p should have inline_failed
initialized to one of FINAL_ERROR reasons. */
else if (e->call_stmt_cannot_inline_p) else if (e->call_stmt_cannot_inline_p)
{ gcc_unreachable ();
if (e->inline_failed != CIF_FUNCTION_NOT_OPTIMIZED)
e->inline_failed = e->caller->thunk.thunk_p ? CIF_THUNK : CIF_MISMATCHED_ARGUMENTS;
inlinable = false;
}
/* Don't inline if the functions have different EH personalities. */ /* Don't inline if the functions have different EH personalities. */
else if (DECL_FUNCTION_PERSONALITY (caller->decl) else if (DECL_FUNCTION_PERSONALITY (caller->decl)
&& DECL_FUNCTION_PERSONALITY (callee->decl) && DECL_FUNCTION_PERSONALITY (callee->decl)
@ -529,6 +527,8 @@ can_early_inline_edge_p (struct cgraph_edge *e)
/* Early inliner might get called at WPA stage when IPA pass adds new /* Early inliner might get called at WPA stage when IPA pass adds new
function. In this case we can not really do any of early inlining function. In this case we can not really do any of early inlining
because function bodies are missing. */ because function bodies are missing. */
if (cgraph_inline_failed_type (e->inline_failed) == CIF_FINAL_ERROR)
return false;
if (!gimple_has_body_p (callee->decl)) if (!gimple_has_body_p (callee->decl))
{ {
e->inline_failed = CIF_BODY_NOT_AVAILABLE; e->inline_failed = CIF_BODY_NOT_AVAILABLE;
@ -2741,8 +2741,11 @@ early_inliner (function *fun)
if (edge->callee->decl if (edge->callee->decl
&& !gimple_check_call_matching_types ( && !gimple_check_call_matching_types (
edge->call_stmt, edge->callee->decl, false)) edge->call_stmt, edge->callee->decl, false))
{
edge->inline_failed = CIF_MISMATCHED_ARGUMENTS;
edge->call_stmt_cannot_inline_p = true; edge->call_stmt_cannot_inline_p = true;
} }
}
if (iterations < PARAM_VALUE (PARAM_EARLY_INLINER_MAX_ITERATIONS) - 1) if (iterations < PARAM_VALUE (PARAM_EARLY_INLINER_MAX_ITERATIONS) - 1)
inline_update_overall_summary (node); inline_update_overall_summary (node);
timevar_pop (TV_INTEGRATION); timevar_pop (TV_INTEGRATION);

View File

@ -268,6 +268,8 @@ lto_output_edge (struct lto_simple_output_block *ob, struct cgraph_edge *edge,
bp_pack_value (&bp, edge->indirect_inlining_edge, 1); bp_pack_value (&bp, edge->indirect_inlining_edge, 1);
bp_pack_value (&bp, edge->speculative, 1); bp_pack_value (&bp, edge->speculative, 1);
bp_pack_value (&bp, edge->call_stmt_cannot_inline_p, 1); bp_pack_value (&bp, edge->call_stmt_cannot_inline_p, 1);
gcc_assert (!edge->call_stmt_cannot_inline_p
|| edge->inline_failed != CIF_BODY_NOT_AVAILABLE);
bp_pack_value (&bp, edge->can_throw_external, 1); bp_pack_value (&bp, edge->can_throw_external, 1);
bp_pack_value (&bp, edge->in_polymorphic_cdtor, 1); bp_pack_value (&bp, edge->in_polymorphic_cdtor, 1);
if (edge->indirect_unknown_callee) if (edge->indirect_unknown_callee)

View File

@ -1,3 +1,7 @@
2016-05-03 Jan Hubicka <hubicka@ucw.cz>
* lto-symtab.c (lto_cgraph_replace_node): Initialize inline_failed.
2016-04-27 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org> 2016-04-27 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
* lto-partition.h (lto_balanced_map): New parameter. * lto-partition.h (lto_balanced_map): New parameter.

View File

@ -81,8 +81,11 @@ lto_cgraph_replace_node (struct cgraph_node *node,
??? We really need a way to match function signatures for ABI ??? We really need a way to match function signatures for ABI
compatibility and perform related promotions at inlining time. */ compatibility and perform related promotions at inlining time. */
if (!compatible_p) if (!compatible_p)
{
e->inline_failed = CIF_LTO_MISMATCHED_DECLARATIONS;
e->call_stmt_cannot_inline_p = 1; e->call_stmt_cannot_inline_p = 1;
} }
}
/* Redirect incomming references. */ /* Redirect incomming references. */
prevailing_node->clone_referring (node); prevailing_node->clone_referring (node);