Commit ec6a1e35 by Jan Hubicka Committed by Jan Hubicka

ipa-inline-transform.c (preserve_function_body_p): Look for first non-thunk clone.

	* ipa-inline-transform.c (preserve_function_body_p): Look for
	first non-thunk clone.
	(save_function_body): Save into first non-thunk.
	* lto-cgraph.c (lto_output_edge): When streaming thunk do not look
	up call stmt id.
	(lto_output_node): Inline thunks don't need body in every
	partition.
	* lto-streamer-in.c: Do not fixup thunk clones.
	* cgraphclones.c (cgraph_node::create_edge_including_clone): Skip
	thunks.
	* tree-inline.c (copy_bb): Be prepared for target node to be new after
	folding suceeds.

From-SVN: r236357
parent df8b0a11
2016-05-17 Jan Hubicka <hubicka@ucw.cz>
* ipa-inline-transform.c (preserve_function_body_p): Look for
first non-thunk clone.
(save_function_body): Save into first non-thunk.
* lto-cgraph.c (lto_output_edge): When streaming thunk do not look
up call stmt id.
(lto_output_node): Inline thunks don't need body in every
partition.
* lto-streamer-in.c: Do not fixup thunk clones.
* cgraphclones.c (cgraph_node::create_edge_including_clone): Skip
thunks.
* tree-inline.c (copy_bb): Be prepared for target node to be new after
folding suceeds.
2016-05-17 Kugan Vivekanandarajah <kuganv@linaro.org> 2016-05-17 Kugan Vivekanandarajah <kuganv@linaro.org>
PR middle-end/63586 PR middle-end/63586
......
...@@ -771,6 +771,8 @@ cgraph_node::create_edge_including_clones (cgraph_node *callee, ...@@ -771,6 +771,8 @@ cgraph_node::create_edge_including_clones (cgraph_node *callee,
node = clones; node = clones;
if (node) if (node)
while (node != this) while (node != this)
/* Thunk clones do not get updated while copying inline function body. */
if (!node->thunk.thunk_p)
{ {
cgraph_edge *edge = node->get_edge (old_stmt); cgraph_edge *edge = node->get_edge (old_stmt);
......
...@@ -506,6 +506,22 @@ save_inline_function_body (struct cgraph_node *node) ...@@ -506,6 +506,22 @@ save_inline_function_body (struct cgraph_node *node)
/* first_clone will be turned into real function. */ /* first_clone will be turned into real function. */
first_clone = node->clones; first_clone = node->clones;
/* Arrange first clone to not be thunk as those do not have bodies. */
if (first_clone->thunk.thunk_p)
{
while (first_clone->thunk.thunk_p)
first_clone = first_clone->next_sibling_clone;
first_clone->prev_sibling_clone->next_sibling_clone
= first_clone->next_sibling_clone;
if (first_clone->next_sibling_clone)
first_clone->next_sibling_clone->prev_sibling_clone
= first_clone->prev_sibling_clone;
first_clone->next_sibling_clone = node->clones;
first_clone->prev_sibling_clone = NULL;
node->clones->prev_sibling_clone = first_clone;
node->clones = first_clone;
}
first_clone->decl = copy_node (node->decl); first_clone->decl = copy_node (node->decl);
first_clone->decl->decl_with_vis.symtab_node = first_clone; first_clone->decl->decl_with_vis.symtab_node = first_clone;
gcc_assert (first_clone == cgraph_node::get (first_clone->decl)); gcc_assert (first_clone == cgraph_node::get (first_clone->decl));
...@@ -514,7 +530,8 @@ save_inline_function_body (struct cgraph_node *node) ...@@ -514,7 +530,8 @@ save_inline_function_body (struct cgraph_node *node)
first_clone. */ first_clone. */
if (first_clone->next_sibling_clone) if (first_clone->next_sibling_clone)
{ {
for (n = first_clone->next_sibling_clone; n->next_sibling_clone; n = n->next_sibling_clone) for (n = first_clone->next_sibling_clone; n->next_sibling_clone;
n = n->next_sibling_clone)
n->clone_of = first_clone; n->clone_of = first_clone;
n->clone_of = first_clone; n->clone_of = first_clone;
n->next_sibling_clone = first_clone->clones; n->next_sibling_clone = first_clone->clones;
...@@ -587,8 +604,9 @@ preserve_function_body_p (struct cgraph_node *node) ...@@ -587,8 +604,9 @@ preserve_function_body_p (struct cgraph_node *node)
gcc_assert (symtab->global_info_ready); gcc_assert (symtab->global_info_ready);
gcc_assert (!node->alias && !node->thunk.thunk_p); gcc_assert (!node->alias && !node->thunk.thunk_p);
/* Look if there is any clone around. */ /* Look if there is any non-thunk clone around. */
if (node->clones && !node->clones->thunk.thunk_p) for (node = node->clones; node; node = node->next_sibling_clone)
if (!node->thunk.thunk_p)
return true; return true;
return false; return false;
} }
......
...@@ -259,7 +259,7 @@ lto_output_edge (struct lto_simple_output_block *ob, struct cgraph_edge *edge, ...@@ -259,7 +259,7 @@ lto_output_edge (struct lto_simple_output_block *ob, struct cgraph_edge *edge,
streamer_write_gcov_count_stream (ob->main_stream, edge->count); streamer_write_gcov_count_stream (ob->main_stream, edge->count);
bp = bitpack_create (ob->main_stream); bp = bitpack_create (ob->main_stream);
uid = (!gimple_has_body_p (edge->caller->decl) uid = (!gimple_has_body_p (edge->caller->decl) || edge->caller->thunk.thunk_p
? edge->lto_stmt_uid : gimple_uid (edge->call_stmt) + 1); ? edge->lto_stmt_uid : gimple_uid (edge->call_stmt) + 1);
bp_pack_enum (&bp, cgraph_inline_failed_t, bp_pack_enum (&bp, cgraph_inline_failed_t,
CIF_N_REASONS, edge->inline_failed); CIF_N_REASONS, edge->inline_failed);
...@@ -398,7 +398,8 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, ...@@ -398,7 +398,8 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
boundary_p = !lto_symtab_encoder_in_partition_p (encoder, node); boundary_p = !lto_symtab_encoder_in_partition_p (encoder, node);
if (node->analyzed && (!boundary_p || node->alias || node->thunk.thunk_p)) if (node->analyzed && (!boundary_p || node->alias
|| (node->thunk.thunk_p && !node->global.inlined_to)))
tag = LTO_symtab_analyzed_node; tag = LTO_symtab_analyzed_node;
else else
tag = LTO_symtab_unavail_node; tag = LTO_symtab_unavail_node;
......
...@@ -953,6 +953,7 @@ fixup_call_stmt_edges (struct cgraph_node *orig, gimple **stmts) ...@@ -953,6 +953,7 @@ fixup_call_stmt_edges (struct cgraph_node *orig, gimple **stmts)
if (orig->clones) if (orig->clones)
for (node = orig->clones; node != orig;) for (node = orig->clones; node != orig;)
{ {
if (!node->thunk.thunk_p)
fixup_call_stmt_edges_1 (node, stmts, fn); fixup_call_stmt_edges_1 (node, stmts, fn);
if (node->clones) if (node->clones)
node = node->clones; node = node->clones;
......
...@@ -2063,7 +2063,7 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, ...@@ -2063,7 +2063,7 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
&& id->dst_node->definition && id->dst_node->definition
&& (fn = gimple_call_fndecl (stmt)) != NULL) && (fn = gimple_call_fndecl (stmt)) != NULL)
{ {
struct cgraph_node *dest = cgraph_node::get (fn); struct cgraph_node *dest = cgraph_node::get_create (fn);
/* We have missing edge in the callgraph. This can happen /* We have missing edge in the callgraph. This can happen
when previous inlining turned an indirect call into a when previous inlining turned an indirect call into a
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment