cgraph.h (cgraph_get_create_real_symbol_node): Declare.

* cgraph.h (cgraph_get_create_real_symbol_node): Declare.
	* cgraph.c (cgraph_get_create_real_symbol_node): New function.
	* cgrpahbuild.c: Use cgraph_get_create_real_symbol_node instead
	of cgraph_get_create_node.
	* ipa-prop.c (ipa_make_edge_direct_to_target): Likewise.

From-SVN: r196750
This commit is contained in:
Jan Hubicka 2013-03-17 16:43:13 +01:00 committed by Jan Hubicka
parent d1f45df55b
commit 48f4a6fa8a
5 changed files with 60 additions and 33 deletions

View File

@ -1,3 +1,11 @@
2013-03-16 Jan Hubicka <jh@suse.cz>
* cgraph.h (cgraph_get_create_real_symbol_node): Declare.
* cgraph.c (cgraph_get_create_real_symbol_node): New function.
* cgrpahbuild.c: Use cgraph_get_create_real_symbol_node instead
of cgraph_get_create_node.
* ipa-prop.c (ipa_make_edge_direct_to_target): Likewise.
2013-03-16 Jason Merrill <jason@redhat.com>
PR debug/49090

View File

@ -2595,4 +2595,47 @@ verify_cgraph (void)
FOR_EACH_FUNCTION (node)
verify_cgraph_node (node);
}
/* Create external decl node for DECL.
The difference i nbetween cgraph_get_create_node and
cgraph_get_create_real_symbol_node is that cgraph_get_create_node
may return inline clone, while cgraph_get_create_real_symbol_node
will create a new node in this case.
FIXME: This function should be removed once clones are put out of decl
hash. */
struct cgraph_node *
cgraph_get_create_real_symbol_node (tree decl)
{
struct cgraph_node *first_clone = cgraph_get_node (decl);
struct cgraph_node *node;
/* create symbol table node. even if inline clone exists, we can not take
it as a target of non-inlined call. */
node = cgraph_get_node (decl);
if (node && !node->global.inlined_to)
return node;
node = cgraph_create_node (decl);
/* ok, we previously inlined the function, then removed the offline copy and
now we want it back for external call. this can happen when devirtualizing
while inlining function called once that happens after extern inlined and
virtuals are already removed. in this case introduce the external node
and make it available for call. */
if (first_clone)
{
first_clone->clone_of = node;
node->clones = first_clone;
symtab_prevail_in_asm_name_hash ((symtab_node) node);
symtab_insert_node_to_hashtable ((symtab_node) node);
if (dump_file)
fprintf (dump_file, "Introduced new external node "
"(%s/%i) and turned into root of the clone tree.\n",
xstrdup (cgraph_node_name (node)), node->uid);
}
else if (dump_file)
fprintf (dump_file, "Introduced new external node "
"(%s/%i).\n", xstrdup (cgraph_node_name (node)), node->uid);
return node;
}
#include "gt-cgraph.h"

View File

@ -575,6 +575,7 @@ struct cgraph_indirect_call_info *cgraph_allocate_init_indirect_info (void);
struct cgraph_node * cgraph_create_node (tree);
struct cgraph_node * cgraph_create_empty_node (void);
struct cgraph_node * cgraph_get_create_node (tree);
struct cgraph_node * cgraph_get_create_real_symbol_node (tree);
struct cgraph_node * cgraph_same_body_alias (struct cgraph_node *, tree, tree);
struct cgraph_node * cgraph_add_thunk (struct cgraph_node *, tree, tree, bool, HOST_WIDE_INT,
HOST_WIDE_INT, tree, tree);

View File

@ -73,7 +73,7 @@ record_reference (tree *tp, int *walk_subtrees, void *data)
decl = get_base_var (*tp);
if (TREE_CODE (decl) == FUNCTION_DECL)
{
struct cgraph_node *node = cgraph_get_create_node (decl);
struct cgraph_node *node = cgraph_get_create_real_symbol_node (decl);
if (!ctx->only_vars)
cgraph_mark_address_taken_node (node);
ipa_record_reference ((symtab_node)ctx->varpool_node,
@ -143,7 +143,7 @@ record_eh_tables (struct cgraph_node *node, struct function *fun)
{
struct cgraph_node *per_node;
per_node = cgraph_get_create_node (DECL_FUNCTION_PERSONALITY (node->symbol.decl));
per_node = cgraph_get_create_real_symbol_node (DECL_FUNCTION_PERSONALITY (node->symbol.decl));
ipa_record_reference ((symtab_node)node, (symtab_node)per_node, IPA_REF_ADDR, NULL);
cgraph_mark_address_taken_node (per_node);
}
@ -223,7 +223,7 @@ mark_address (gimple stmt, tree addr, void *data)
addr = get_base_address (addr);
if (TREE_CODE (addr) == FUNCTION_DECL)
{
struct cgraph_node *node = cgraph_get_create_node (addr);
struct cgraph_node *node = cgraph_get_create_real_symbol_node (addr);
cgraph_mark_address_taken_node (node);
ipa_record_reference ((symtab_node)data,
(symtab_node)node,
@ -252,7 +252,7 @@ mark_load (gimple stmt, tree t, void *data)
{
/* ??? This can happen on platforms with descriptors when these are
directly manipulated in the code. Pretend that it's an address. */
struct cgraph_node *node = cgraph_get_create_node (t);
struct cgraph_node *node = cgraph_get_create_real_symbol_node (t);
cgraph_mark_address_taken_node (node);
ipa_record_reference ((symtab_node)data,
(symtab_node)node,
@ -330,7 +330,7 @@ build_cgraph_edges (void)
{
tree fn = gimple_omp_parallel_child_fn (stmt);
ipa_record_reference ((symtab_node)node,
(symtab_node)cgraph_get_create_node (fn),
(symtab_node)cgraph_get_create_real_symbol_node (fn),
IPA_REF_ADDR, stmt);
}
if (gimple_code (stmt) == GIMPLE_OMP_TASK)
@ -338,12 +338,12 @@ build_cgraph_edges (void)
tree fn = gimple_omp_task_child_fn (stmt);
if (fn)
ipa_record_reference ((symtab_node)node,
(symtab_node) cgraph_get_create_node (fn),
(symtab_node) cgraph_get_create_real_symbol_node (fn),
IPA_REF_ADDR, stmt);
fn = gimple_omp_task_copy_fn (stmt);
if (fn)
ipa_record_reference ((symtab_node)node,
(symtab_node)cgraph_get_create_node (fn),
(symtab_node)cgraph_get_create_real_symbol_node (fn),
IPA_REF_ADDR, stmt);
}
}

View File

@ -2117,7 +2117,6 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target)
we may create the first reference to the object in the unit. */
if (!callee || callee->global.inlined_to)
{
struct cgraph_node *first_clone = callee;
/* We are better to ensure we can refer to it.
In the case of static functions we are out of luck, since we already
@ -2133,31 +2132,7 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target)
xstrdup (cgraph_node_name (ie->callee)), ie->callee->uid);
return NULL;
}
/* Create symbol table node. Even if inline clone exists, we can not take
it as a target of non-inlined call. */
callee = cgraph_create_node (target);
/* OK, we previously inlined the function, then removed the offline copy and
now we want it back for external call. This can happen when devirtualizing
while inlining function called once that happens after extern inlined and
virtuals are already removed. In this case introduce the external node
and make it available for call. */
if (first_clone)
{
first_clone->clone_of = callee;
callee->clones = first_clone;
symtab_prevail_in_asm_name_hash ((symtab_node)callee);
symtab_insert_node_to_hashtable ((symtab_node)callee);
if (dump_file)
fprintf (dump_file, "ipa-prop: Introduced new external node "
"(%s/%i) and turned into root of the clone tree.\n",
xstrdup (cgraph_node_name (callee)), callee->uid);
}
else if (dump_file)
fprintf (dump_file, "ipa-prop: Introduced new external node "
"(%s/%i).\n",
xstrdup (cgraph_node_name (callee)), callee->uid);
callee = cgraph_get_create_real_symbol_node (target);
}
ipa_check_create_node_params ();