Commit c0c123ef by Jan Hubicka Committed by Jan Hubicka

cgraph.c (cgraph_release_function_body): Use used_as_abstract_origin.

	* cgraph.c (cgraph_release_function_body): Use used_as_abstract_origin.
	(cgraph_release_function_body): Likewise.
	(cgraph_can_remove_if_no_direct_calls_p): Likewise.
	* cgraph.h (cgrpah_node): Rename abstract_and_needed
	to used_as_abstract_origin.
	* tree-inline-transfrom.c (can_remove_node_now_p_1): Do not remove
	symbols used as abstract origins.
	* cgraphunit.c (analyze_functions): Update.
	* ipa.c (symtab_remove_unreachable_nodes): Recompute used_as_abstract_origin.
	* tree-inline.c (tree_function_versioning): Update
	used_as_abstract_origin; be ready for DECL_RESULT and DECL_ARGUMENTS to be
	NULL.

	* lto-symtab.c (lto_symtab_merge_symbols): Merge duplicated nodes for abstract functions.
	* cgraph.h (symtab_real_symbol_p): Abstract declarations are not real symbols.

From-SVN: r201408
parent 0cd1dd57
2013-08-01 Jan Hubicka <jh@suse.cz> 2013-08-01 Jan Hubicka <jh@suse.cz>
* cgraph.c (cgraph_release_function_body): Use used_as_abstract_origin.
(cgraph_release_function_body): Likewise.
(cgraph_can_remove_if_no_direct_calls_p): Likewise.
* cgraph.h (cgrpah_node): Rename abstract_and_needed
to used_as_abstract_origin.
* tree-inline-transfrom.c (can_remove_node_now_p_1): Do not remove
symbols used as abstract origins.
* cgraphunit.c (analyze_functions): Update.
* ipa.c (symtab_remove_unreachable_nodes): Recompute used_as_abstract_origin.
* tree-inline.c (tree_function_versioning): Update
used_as_abstract_origin; be ready for DECL_RESULT and DECL_ARGUMENTS to be
NULL.
* lto-symtab.c (lto_symtab_merge_symbols): Merge duplicated nodes for abstract functions.
* cgraph.h (symtab_real_symbol_p): Abstract declarations are not real symbols.
2013-08-01 Jan Hubicka <jh@suse.cz>
* profile.c (compute_value_histograms): Fix thinko. * profile.c (compute_value_histograms): Fix thinko.
2013-08-01 Sofiane Naci <sofiane.naci@arm.com> 2013-08-01 Sofiane Naci <sofiane.naci@arm.com>
......
...@@ -1316,7 +1316,7 @@ void ...@@ -1316,7 +1316,7 @@ void
cgraph_release_function_body (struct cgraph_node *node) cgraph_release_function_body (struct cgraph_node *node)
{ {
node->ipa_transforms_to_apply.release (); node->ipa_transforms_to_apply.release ();
if (!node->abstract_and_needed && cgraph_state != CGRAPH_STATE_PARSING) if (!node->used_as_abstract_origin && cgraph_state != CGRAPH_STATE_PARSING)
{ {
DECL_RESULT (node->symbol.decl) = NULL; DECL_RESULT (node->symbol.decl) = NULL;
DECL_ARGUMENTS (node->symbol.decl) = NULL; DECL_ARGUMENTS (node->symbol.decl) = NULL;
...@@ -1324,7 +1324,7 @@ cgraph_release_function_body (struct cgraph_node *node) ...@@ -1324,7 +1324,7 @@ cgraph_release_function_body (struct cgraph_node *node)
/* If the node is abstract and needed, then do not clear DECL_INITIAL /* If the node is abstract and needed, then do not clear DECL_INITIAL
of its associated function function declaration because it's of its associated function function declaration because it's
needed to emit debug info later. */ needed to emit debug info later. */
if (!node->abstract_and_needed && DECL_INITIAL (node->symbol.decl)) if (!node->used_as_abstract_origin && DECL_INITIAL (node->symbol.decl))
DECL_INITIAL (node->symbol.decl) = error_mark_node; DECL_INITIAL (node->symbol.decl) = error_mark_node;
release_function_body (node->symbol.decl); release_function_body (node->symbol.decl);
} }
......
...@@ -303,7 +303,7 @@ struct GTY(()) cgraph_node { ...@@ -303,7 +303,7 @@ struct GTY(()) cgraph_node {
/* Set when decl is an abstract function pointed to by the /* Set when decl is an abstract function pointed to by the
ABSTRACT_DECL_ORIGIN of a reachable function. */ ABSTRACT_DECL_ORIGIN of a reachable function. */
unsigned abstract_and_needed : 1; unsigned used_as_abstract_origin : 1;
/* Set once the function is lowered (i.e. its CFG is built). */ /* Set once the function is lowered (i.e. its CFG is built). */
unsigned lowered : 1; unsigned lowered : 1;
/* Set once the function has been instantiated and its callee /* Set once the function has been instantiated and its callee
...@@ -1347,13 +1347,13 @@ symtab_real_symbol_p (symtab_node node) ...@@ -1347,13 +1347,13 @@ symtab_real_symbol_p (symtab_node node)
{ {
struct cgraph_node *cnode; struct cgraph_node *cnode;
if (DECL_ABSTRACT (node->symbol.decl))
return false;
if (!is_a <cgraph_node> (node)) if (!is_a <cgraph_node> (node))
return true; return true;
cnode = cgraph (node); cnode = cgraph (node);
if (cnode->global.inlined_to) if (cnode->global.inlined_to)
return false; return false;
if (cnode->abstract_and_needed)
return false;
return true; return true;
} }
#endif /* GCC_CGRAPH_H */ #endif /* GCC_CGRAPH_H */
...@@ -928,7 +928,7 @@ analyze_functions (void) ...@@ -928,7 +928,7 @@ analyze_functions (void)
{ {
struct cgraph_node *origin_node struct cgraph_node *origin_node
= cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl)); = cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl));
origin_node->abstract_and_needed = true; origin_node->used_as_abstract_origin = true;
} }
} }
else else
......
...@@ -87,6 +87,7 @@ can_remove_node_now_p_1 (struct cgraph_node *node) ...@@ -87,6 +87,7 @@ can_remove_node_now_p_1 (struct cgraph_node *node)
the callgraph so references can point to it. */ the callgraph so references can point to it. */
return (!node->symbol.address_taken return (!node->symbol.address_taken
&& !ipa_ref_has_aliases_p (&node->symbol.ref_list) && !ipa_ref_has_aliases_p (&node->symbol.ref_list)
&& !node->used_as_abstract_origin
&& cgraph_can_remove_if_no_direct_calls_p (node) && cgraph_can_remove_if_no_direct_calls_p (node)
/* Inlining might enable more devirtualizing, so we want to remove /* Inlining might enable more devirtualizing, so we want to remove
those only after all devirtualizable virtual calls are processed. those only after all devirtualizable virtual calls are processed.
......
...@@ -234,9 +234,11 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file) ...@@ -234,9 +234,11 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
This is mostly when they can be referenced externally. Inline clones This is mostly when they can be referenced externally. Inline clones
are special since their declarations are shared with master clone and thus are special since their declarations are shared with master clone and thus
cgraph_can_remove_if_no_direct_calls_and_refs_p should not be called on them. */ cgraph_can_remove_if_no_direct_calls_and_refs_p should not be called on them. */
FOR_EACH_DEFINED_FUNCTION (node) FOR_EACH_FUNCTION (node)
if (!node->global.inlined_to {
&& !node->symbol.in_other_partition node->used_as_abstract_origin = false;
if (node->symbol.definition
&& !node->global.inlined_to
&& (!cgraph_can_remove_if_no_direct_calls_and_refs_p (node) && (!cgraph_can_remove_if_no_direct_calls_and_refs_p (node)
/* Keep around virtual functions for possible devirtualization. */ /* Keep around virtual functions for possible devirtualization. */
|| (before_inlining_p || (before_inlining_p
...@@ -248,6 +250,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file) ...@@ -248,6 +250,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
} }
else else
gcc_assert (!node->symbol.aux); gcc_assert (!node->symbol.aux);
}
/* Mark variables that are obviously needed. */ /* Mark variables that are obviously needed. */
FOR_EACH_DEFINED_VARIABLE (vnode) FOR_EACH_DEFINED_VARIABLE (vnode)
...@@ -272,6 +275,13 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file) ...@@ -272,6 +275,13 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
node->symbol.aux = (void *)2; node->symbol.aux = (void *)2;
else else
{ {
if (DECL_ABSTRACT_ORIGIN (node->symbol.decl))
{
struct cgraph_node *origin_node
= cgraph_get_create_real_symbol_node (DECL_ABSTRACT_ORIGIN (node->symbol.decl));
origin_node->used_as_abstract_origin = true;
enqueue_node ((symtab_node) origin_node, &first, reachable);
}
/* If any symbol in a comdat group is reachable, force /* If any symbol in a comdat group is reachable, force
all other in the same comdat group to be also reachable. */ all other in the same comdat group to be also reachable. */
if (node->symbol.same_comdat_group) if (node->symbol.same_comdat_group)
......
...@@ -474,7 +474,6 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, ...@@ -474,7 +474,6 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
bp_pack_value (&bp, node->symbol.forced_by_abi, 1); bp_pack_value (&bp, node->symbol.forced_by_abi, 1);
bp_pack_value (&bp, node->symbol.unique_name, 1); bp_pack_value (&bp, node->symbol.unique_name, 1);
bp_pack_value (&bp, node->symbol.address_taken, 1); bp_pack_value (&bp, node->symbol.address_taken, 1);
bp_pack_value (&bp, node->abstract_and_needed, 1);
bp_pack_value (&bp, tag == LTO_symtab_analyzed_node bp_pack_value (&bp, tag == LTO_symtab_analyzed_node
&& !DECL_EXTERNAL (node->symbol.decl) && !DECL_EXTERNAL (node->symbol.decl)
&& !DECL_COMDAT (node->symbol.decl) && !DECL_COMDAT (node->symbol.decl)
...@@ -889,7 +888,6 @@ input_overwrite_node (struct lto_file_decl_data *file_data, ...@@ -889,7 +888,6 @@ input_overwrite_node (struct lto_file_decl_data *file_data,
node->symbol.forced_by_abi = bp_unpack_value (bp, 1); node->symbol.forced_by_abi = bp_unpack_value (bp, 1);
node->symbol.unique_name = bp_unpack_value (bp, 1); node->symbol.unique_name = bp_unpack_value (bp, 1);
node->symbol.address_taken = bp_unpack_value (bp, 1); node->symbol.address_taken = bp_unpack_value (bp, 1);
node->abstract_and_needed = bp_unpack_value (bp, 1);
node->symbol.used_from_other_partition = bp_unpack_value (bp, 1); node->symbol.used_from_other_partition = bp_unpack_value (bp, 1);
node->lowered = bp_unpack_value (bp, 1); node->lowered = bp_unpack_value (bp, 1);
node->symbol.analyzed = tag == LTO_symtab_analyzed_node; node->symbol.analyzed = tag == LTO_symtab_analyzed_node;
......
...@@ -599,6 +599,13 @@ lto_symtab_merge_symbols (void) ...@@ -599,6 +599,13 @@ lto_symtab_merge_symbols (void)
&& (cnode2 = cgraph_get_node (node->symbol.decl)) && (cnode2 = cgraph_get_node (node->symbol.decl))
&& cnode2 != cnode) && cnode2 != cnode)
lto_cgraph_replace_node (cnode2, cnode); lto_cgraph_replace_node (cnode2, cnode);
/* Abstract functions may have duplicated cgraph nodes attached;
remove them. */
else if (cnode && DECL_ABSTRACT (cnode->symbol.decl)
&& (cnode2 = cgraph_get_node (node->symbol.decl))
&& cnode2 != cnode)
cgraph_remove_node (cnode2);
symtab_insert_node_to_hashtable ((symtab_node)node); symtab_insert_node_to_hashtable ((symtab_node)node);
} }
} }
......
...@@ -5085,6 +5085,8 @@ tree_function_versioning (tree old_decl, tree new_decl, ...@@ -5085,6 +5085,8 @@ tree_function_versioning (tree old_decl, tree new_decl,
DECL_ARTIFICIAL (new_decl) = 1; DECL_ARTIFICIAL (new_decl) = 1;
DECL_ABSTRACT_ORIGIN (new_decl) = DECL_ORIGIN (old_decl); DECL_ABSTRACT_ORIGIN (new_decl) = DECL_ORIGIN (old_decl);
if (DECL_ORIGIN (old_decl) == old_decl)
old_version_node->used_as_abstract_origin = true;
DECL_FUNCTION_PERSONALITY (new_decl) = DECL_FUNCTION_PERSONALITY (old_decl); DECL_FUNCTION_PERSONALITY (new_decl) = DECL_FUNCTION_PERSONALITY (old_decl);
/* Prepare the data structures for the tree copy. */ /* Prepare the data structures for the tree copy. */
...@@ -5122,6 +5124,8 @@ tree_function_versioning (tree old_decl, tree new_decl, ...@@ -5122,6 +5124,8 @@ tree_function_versioning (tree old_decl, tree new_decl,
old_entry_block = ENTRY_BLOCK_PTR_FOR_FUNCTION old_entry_block = ENTRY_BLOCK_PTR_FOR_FUNCTION
(DECL_STRUCT_FUNCTION (old_decl)); (DECL_STRUCT_FUNCTION (old_decl));
DECL_RESULT (new_decl) = DECL_RESULT (old_decl);
DECL_ARGUMENTS (new_decl) = DECL_ARGUMENTS (old_decl);
initialize_cfun (new_decl, old_decl, initialize_cfun (new_decl, old_decl,
old_entry_block->count); old_entry_block->count);
DECL_STRUCT_FUNCTION (new_decl)->gimple_df->ipa_pta DECL_STRUCT_FUNCTION (new_decl)->gimple_df->ipa_pta
......
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