Make cgraph_edge::resolve-speculation static
2020-01-09 Martin Jambor <mjambor@suse.cz> * cgraph.h (cgraph_edge): Make remove, set_call_stmt, make_direct, resolve_speculation and redirect_call_stmt_to_callee static. Change return type of set_call_stmt to cgraph_edge *. * auto-profile.c (afdo_indirect_call): Adjust call to redirect_call_stmt_to_callee. * cgraph.c (cgraph_edge::set_call_stmt): Make return cgraph-edge *, make the this pointer explicit, adjust self-recursive calls and the call top make_direct. Return the resulting edge. (cgraph_edge::remove): Make this pointer explicit. (cgraph_edge::resolve_speculation): Likewise, adjust call to remove. (cgraph_edge::make_direct): Likewise, adjust call to resolve_speculation. (cgraph_edge::redirect_call_stmt_to_callee): Likewise, also adjust call to set_call_stmt. (cgraph_update_edges_for_call_stmt_node): Update call to set_call_stmt and remove. * cgraphclones.c (cgraph_node::set_call_stmt_including_clones): Renamed edge to master_edge. Adjusted calls to set_call_stmt. (cgraph_node::create_edge_including_clones): Moved "first" definition of edge to the block where it was used. Adjusted calls to set_call_stmt. (cgraph_node::remove_symbol_and_inline_clones): Adjust call to cgraph_edge::remove. * cgraphunit.c (walk_polymorphic_call_targets): Adjusted calls to make_direct and redirect_call_stmt_to_callee. * ipa-fnsummary.c (redirect_to_unreachable): Adjust calls to resolve_speculation and make_direct. * ipa-inline-transform.c (inline_transform): Adjust call to redirect_call_stmt_to_callee. (check_speculations_1):: Adjust call to resolve_speculation. * ipa-inline.c (resolve_noninline_speculation): Adjust call to resolve-speculation. (inline_small_functions): Adjust call to resolve_speculation. (ipa_inline): Likewise. * ipa-prop.c (ipa_make_edge_direct_to_target): Adjust call to make_direct. * ipa-visibility.c (function_and_variable_visibility): Make iteration safe with regards to edge removal, adjust calls to redirect_call_stmt_to_callee. * ipa.c (walk_polymorphic_call_targets): Adjust calls to make_direct and redirect_call_stmt_to_callee. * multiple_target.c (create_dispatcher_calls): Adjust call to redirect_call_stmt_to_callee (redirect_to_specific_clone): Likewise. * tree-cfgcleanup.c (delete_unreachable_blocks_update_callgraph): Adjust calls to cgraph_edge::remove. * tree-inline.c (copy_bb): Adjust call to set_call_stmt. (redirect_all_calls): Adjust call to redirect_call_stmt_to_callee. (expand_call_inline): Adjust call to cgraph_edge::remove. From-SVN: r280043
This commit is contained in:
parent
87f9579a4f
commit
27c5a1779b
|
@ -1,3 +1,55 @@
|
||||||
|
2020-01-09 Martin Jambor <mjambor@suse.cz>
|
||||||
|
|
||||||
|
* cgraph.h (cgraph_edge): Make remove, set_call_stmt, make_direct,
|
||||||
|
resolve_speculation and redirect_call_stmt_to_callee static. Change
|
||||||
|
return type of set_call_stmt to cgraph_edge *.
|
||||||
|
* auto-profile.c (afdo_indirect_call): Adjust call to
|
||||||
|
redirect_call_stmt_to_callee.
|
||||||
|
* cgraph.c (cgraph_edge::set_call_stmt): Make return cgraph-edge *,
|
||||||
|
make the this pointer explicit, adjust self-recursive calls and the
|
||||||
|
call top make_direct. Return the resulting edge.
|
||||||
|
(cgraph_edge::remove): Make this pointer explicit.
|
||||||
|
(cgraph_edge::resolve_speculation): Likewise, adjust call to remove.
|
||||||
|
(cgraph_edge::make_direct): Likewise, adjust call to
|
||||||
|
resolve_speculation.
|
||||||
|
(cgraph_edge::redirect_call_stmt_to_callee): Likewise, also adjust
|
||||||
|
call to set_call_stmt.
|
||||||
|
(cgraph_update_edges_for_call_stmt_node): Update call to
|
||||||
|
set_call_stmt and remove.
|
||||||
|
* cgraphclones.c (cgraph_node::set_call_stmt_including_clones):
|
||||||
|
Renamed edge to master_edge. Adjusted calls to set_call_stmt.
|
||||||
|
(cgraph_node::create_edge_including_clones): Moved "first" definition
|
||||||
|
of edge to the block where it was used. Adjusted calls to
|
||||||
|
set_call_stmt.
|
||||||
|
(cgraph_node::remove_symbol_and_inline_clones): Adjust call to
|
||||||
|
cgraph_edge::remove.
|
||||||
|
* cgraphunit.c (walk_polymorphic_call_targets): Adjusted calls to
|
||||||
|
make_direct and redirect_call_stmt_to_callee.
|
||||||
|
* ipa-fnsummary.c (redirect_to_unreachable): Adjust calls to
|
||||||
|
resolve_speculation and make_direct.
|
||||||
|
* ipa-inline-transform.c (inline_transform): Adjust call to
|
||||||
|
redirect_call_stmt_to_callee.
|
||||||
|
(check_speculations_1):: Adjust call to resolve_speculation.
|
||||||
|
* ipa-inline.c (resolve_noninline_speculation): Adjust call to
|
||||||
|
resolve-speculation.
|
||||||
|
(inline_small_functions): Adjust call to resolve_speculation.
|
||||||
|
(ipa_inline): Likewise.
|
||||||
|
* ipa-prop.c (ipa_make_edge_direct_to_target): Adjust call to
|
||||||
|
make_direct.
|
||||||
|
* ipa-visibility.c (function_and_variable_visibility): Make iteration
|
||||||
|
safe with regards to edge removal, adjust calls to
|
||||||
|
redirect_call_stmt_to_callee.
|
||||||
|
* ipa.c (walk_polymorphic_call_targets): Adjust calls to make_direct
|
||||||
|
and redirect_call_stmt_to_callee.
|
||||||
|
* multiple_target.c (create_dispatcher_calls): Adjust call to
|
||||||
|
redirect_call_stmt_to_callee
|
||||||
|
(redirect_to_specific_clone): Likewise.
|
||||||
|
* tree-cfgcleanup.c (delete_unreachable_blocks_update_callgraph):
|
||||||
|
Adjust calls to cgraph_edge::remove.
|
||||||
|
* tree-inline.c (copy_bb): Adjust call to set_call_stmt.
|
||||||
|
(redirect_all_calls): Adjust call to redirect_call_stmt_to_callee.
|
||||||
|
(expand_call_inline): Adjust call to cgraph_edge::remove.
|
||||||
|
|
||||||
2020-01-09 Martin Liska <mliska@suse.cz>
|
2020-01-09 Martin Liska <mliska@suse.cz>
|
||||||
|
|
||||||
* params.opt: Set Optimization for
|
* params.opt: Set Optimization for
|
||||||
|
|
|
@ -1055,7 +1055,7 @@ afdo_indirect_call (gimple_stmt_iterator *gsi, const icall_target_map &map,
|
||||||
struct cgraph_edge *new_edge
|
struct cgraph_edge *new_edge
|
||||||
= indirect_edge->make_speculative (direct_call,
|
= indirect_edge->make_speculative (direct_call,
|
||||||
profile_count::uninitialized ());
|
profile_count::uninitialized ());
|
||||||
new_edge->redirect_call_stmt_to_callee ();
|
cgraph_edge::redirect_call_stmt_to_callee (new_edge);
|
||||||
gimple_remove_histogram_value (cfun, stmt, hist);
|
gimple_remove_histogram_value (cfun, stmt, hist);
|
||||||
inline_call (new_edge, true, NULL, NULL, false);
|
inline_call (new_edge, true, NULL, NULL, false);
|
||||||
}
|
}
|
||||||
|
|
129
gcc/cgraph.c
129
gcc/cgraph.c
|
@ -767,41 +767,41 @@ cgraph_node::get_edge (gimple *call_stmt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Change field call_stmt of edge to NEW_STMT.
|
/* Change field call_stmt of edge E to NEW_STMT. If UPDATE_SPECULATIVE and E
|
||||||
If UPDATE_SPECULATIVE and E is any component of speculative
|
is any component of speculative edge, then update all components.
|
||||||
edge, then update all components. */
|
Speculations can be resolved in the process and EDGE can be removed and
|
||||||
|
deallocated. Return the edge that now represents the call. */
|
||||||
|
|
||||||
void
|
cgraph_edge *
|
||||||
cgraph_edge::set_call_stmt (gcall *new_stmt, bool update_speculative)
|
cgraph_edge::set_call_stmt (cgraph_edge *e, gcall *new_stmt,
|
||||||
|
bool update_speculative)
|
||||||
{
|
{
|
||||||
tree decl;
|
tree decl;
|
||||||
|
|
||||||
/* Speculative edges has three component, update all of them
|
/* Speculative edges has three component, update all of them
|
||||||
when asked to. */
|
when asked to. */
|
||||||
if (update_speculative && speculative)
|
if (update_speculative && e->speculative)
|
||||||
{
|
{
|
||||||
cgraph_edge *direct, *indirect;
|
cgraph_edge *direct, *indirect;
|
||||||
ipa_ref *ref;
|
ipa_ref *ref;
|
||||||
|
bool e_indirect = e->indirect_unknown_callee;
|
||||||
|
|
||||||
speculative_call_info (direct, indirect, ref);
|
e->speculative_call_info (direct, indirect, ref);
|
||||||
direct->set_call_stmt (new_stmt, false);
|
|
||||||
indirect->set_call_stmt (new_stmt, false);
|
|
||||||
ref->stmt = new_stmt;
|
ref->stmt = new_stmt;
|
||||||
return;
|
cgraph_edge *d2 = set_call_stmt (direct, new_stmt, false);
|
||||||
|
gcc_assert (direct == d2);
|
||||||
|
indirect = set_call_stmt (indirect, new_stmt, false);
|
||||||
|
return e_indirect ? indirect : direct;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only direct speculative edges go to call_site_hash. */
|
/* Only direct speculative edges go to call_site_hash. */
|
||||||
if (caller->call_site_hash
|
if (e->caller->call_site_hash
|
||||||
&& (!speculative || !indirect_unknown_callee))
|
&& (!e->speculative || !e->indirect_unknown_callee))
|
||||||
{
|
e->caller->call_site_hash->remove_elt_with_hash
|
||||||
caller->call_site_hash->remove_elt_with_hash
|
(e->call_stmt, cgraph_edge_hasher::hash (e->call_stmt));
|
||||||
(call_stmt, cgraph_edge_hasher::hash (call_stmt));
|
|
||||||
}
|
|
||||||
|
|
||||||
cgraph_edge *e = this;
|
e->call_stmt = new_stmt;
|
||||||
|
if (e->indirect_unknown_callee
|
||||||
call_stmt = new_stmt;
|
|
||||||
if (indirect_unknown_callee
|
|
||||||
&& (decl = gimple_call_fndecl (new_stmt)))
|
&& (decl = gimple_call_fndecl (new_stmt)))
|
||||||
{
|
{
|
||||||
/* Constant propagation (and possibly also inlining?) can turn an
|
/* Constant propagation (and possibly also inlining?) can turn an
|
||||||
|
@ -809,13 +809,14 @@ cgraph_edge::set_call_stmt (gcall *new_stmt, bool update_speculative)
|
||||||
cgraph_node *new_callee = cgraph_node::get (decl);
|
cgraph_node *new_callee = cgraph_node::get (decl);
|
||||||
|
|
||||||
gcc_checking_assert (new_callee);
|
gcc_checking_assert (new_callee);
|
||||||
e = make_direct (new_callee);
|
e = make_direct (e, new_callee);
|
||||||
}
|
}
|
||||||
|
|
||||||
function *fun = DECL_STRUCT_FUNCTION (e->caller->decl);
|
function *fun = DECL_STRUCT_FUNCTION (e->caller->decl);
|
||||||
e->can_throw_external = stmt_can_throw_external (fun, new_stmt);
|
e->can_throw_external = stmt_can_throw_external (fun, new_stmt);
|
||||||
if (e->caller->call_site_hash)
|
if (e->caller->call_site_hash)
|
||||||
cgraph_add_edge_to_call_site_hash (e);
|
cgraph_add_edge_to_call_site_hash (e);
|
||||||
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate a cgraph_edge structure and fill it with data according to the
|
/* Allocate a cgraph_edge structure and fill it with data according to the
|
||||||
|
@ -1011,20 +1012,20 @@ symbol_table::free_edge (cgraph_edge *e)
|
||||||
/* Remove the edge in the cgraph. */
|
/* Remove the edge in the cgraph. */
|
||||||
|
|
||||||
void
|
void
|
||||||
cgraph_edge::remove (void)
|
cgraph_edge::remove (cgraph_edge *edge)
|
||||||
{
|
{
|
||||||
/* Call all edge removal hooks. */
|
/* Call all edge removal hooks. */
|
||||||
symtab->call_edge_removal_hooks (this);
|
symtab->call_edge_removal_hooks (edge);
|
||||||
|
|
||||||
if (!indirect_unknown_callee)
|
if (!edge->indirect_unknown_callee)
|
||||||
/* Remove from callers list of the callee. */
|
/* Remove from callers list of the callee. */
|
||||||
remove_callee ();
|
edge->remove_callee ();
|
||||||
|
|
||||||
/* Remove from callees list of the callers. */
|
/* Remove from callees list of the callers. */
|
||||||
remove_caller ();
|
edge->remove_caller ();
|
||||||
|
|
||||||
/* Put the edge onto the free list. */
|
/* Put the edge onto the free list. */
|
||||||
symtab->free_edge (this);
|
symtab->free_edge (edge);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Turn edge into speculative call calling N2. Update
|
/* Turn edge into speculative call calling N2. Update
|
||||||
|
@ -1135,14 +1136,15 @@ cgraph_edge::speculative_call_info (cgraph_edge *&direct,
|
||||||
gcc_assert (e && e2 && ref);
|
gcc_assert (e && e2 && ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Speculative call edge turned out to be direct call to CALLEE_DECL.
|
/* Speculative call EDGE turned out to be direct call to CALLEE_DECL. Remove
|
||||||
Remove the speculative call sequence and return edge representing the call.
|
the speculative call sequence and return edge representing the call, the
|
||||||
It is up to caller to redirect the call as appropriate. */
|
original EDGE can be removed and deallocated. It is up to caller to
|
||||||
|
redirect the call as appropriate. Return the edge that now represents the
|
||||||
|
call. */
|
||||||
|
|
||||||
cgraph_edge *
|
cgraph_edge *
|
||||||
cgraph_edge::resolve_speculation (tree callee_decl)
|
cgraph_edge::resolve_speculation (cgraph_edge *edge, tree callee_decl)
|
||||||
{
|
{
|
||||||
cgraph_edge *edge = this;
|
|
||||||
cgraph_edge *e2;
|
cgraph_edge *e2;
|
||||||
ipa_ref *ref;
|
ipa_ref *ref;
|
||||||
|
|
||||||
|
@ -1186,7 +1188,7 @@ cgraph_edge::resolve_speculation (tree callee_decl)
|
||||||
e2->speculative = false;
|
e2->speculative = false;
|
||||||
ref->remove_reference ();
|
ref->remove_reference ();
|
||||||
if (e2->indirect_unknown_callee || e2->inline_failed)
|
if (e2->indirect_unknown_callee || e2->inline_failed)
|
||||||
e2->remove ();
|
remove (e2);
|
||||||
else
|
else
|
||||||
e2->callee->remove_symbol_and_inline_clones ();
|
e2->callee->remove_symbol_and_inline_clones ();
|
||||||
if (edge->caller->call_site_hash)
|
if (edge->caller->call_site_hash)
|
||||||
|
@ -1195,43 +1197,42 @@ cgraph_edge::resolve_speculation (tree callee_decl)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make an indirect edge with an unknown callee an ordinary edge leading to
|
/* Make an indirect edge with an unknown callee an ordinary edge leading to
|
||||||
CALLEE. DELTA is an integer constant that is to be added to the this
|
CALLEE. Speculations can be resolved in the process and EDGE can be removed
|
||||||
pointer (first parameter) to compensate for skipping a thunk adjustment. */
|
and deallocated. Return the edge that now represents the call. */
|
||||||
|
|
||||||
cgraph_edge *
|
cgraph_edge *
|
||||||
cgraph_edge::make_direct (cgraph_node *callee)
|
cgraph_edge::make_direct (cgraph_edge *edge, cgraph_node *callee)
|
||||||
{
|
{
|
||||||
cgraph_edge *edge = this;
|
gcc_assert (edge->indirect_unknown_callee);
|
||||||
gcc_assert (indirect_unknown_callee);
|
|
||||||
|
|
||||||
/* If we are redirecting speculative call, make it non-speculative. */
|
/* If we are redirecting speculative call, make it non-speculative. */
|
||||||
if (indirect_unknown_callee && speculative)
|
if (edge->speculative)
|
||||||
{
|
{
|
||||||
edge = edge->resolve_speculation (callee->decl);
|
edge = resolve_speculation (edge, callee->decl);
|
||||||
|
|
||||||
/* On successful speculation just return the pre existing direct edge. */
|
/* On successful speculation just return the pre existing direct edge. */
|
||||||
if (!edge->indirect_unknown_callee)
|
if (!edge->indirect_unknown_callee)
|
||||||
return edge;
|
return edge;
|
||||||
}
|
}
|
||||||
|
|
||||||
indirect_unknown_callee = 0;
|
edge->indirect_unknown_callee = 0;
|
||||||
ggc_free (indirect_info);
|
ggc_free (edge->indirect_info);
|
||||||
indirect_info = NULL;
|
edge->indirect_info = NULL;
|
||||||
|
|
||||||
/* Get the edge out of the indirect edge list. */
|
/* Get the edge out of the indirect edge list. */
|
||||||
if (prev_callee)
|
if (edge->prev_callee)
|
||||||
prev_callee->next_callee = next_callee;
|
edge->prev_callee->next_callee = edge->next_callee;
|
||||||
if (next_callee)
|
if (edge->next_callee)
|
||||||
next_callee->prev_callee = prev_callee;
|
edge->next_callee->prev_callee = edge->prev_callee;
|
||||||
if (!prev_callee)
|
if (!edge->prev_callee)
|
||||||
caller->indirect_calls = next_callee;
|
edge->caller->indirect_calls = edge->next_callee;
|
||||||
|
|
||||||
/* Put it into the normal callee list */
|
/* Put it into the normal callee list */
|
||||||
prev_callee = NULL;
|
edge->prev_callee = NULL;
|
||||||
next_callee = caller->callees;
|
edge->next_callee = edge->caller->callees;
|
||||||
if (caller->callees)
|
if (edge->caller->callees)
|
||||||
caller->callees->prev_callee = edge;
|
edge->caller->callees->prev_callee = edge;
|
||||||
caller->callees = edge;
|
edge->caller->callees = edge;
|
||||||
|
|
||||||
/* Insert to callers list of the new callee. */
|
/* Insert to callers list of the new callee. */
|
||||||
edge->set_callee (callee);
|
edge->set_callee (callee);
|
||||||
|
@ -1242,13 +1243,12 @@ cgraph_edge::make_direct (cgraph_node *callee)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If necessary, change the function declaration in the call statement
|
/* If necessary, change the function declaration in the call statement
|
||||||
associated with E so that it corresponds to the edge callee. */
|
associated with E so that it corresponds to the edge callee. Speculations
|
||||||
|
can be resolved in the process and EDGE can be removed and deallocated. */
|
||||||
|
|
||||||
gimple *
|
gimple *
|
||||||
cgraph_edge::redirect_call_stmt_to_callee (void)
|
cgraph_edge::redirect_call_stmt_to_callee (cgraph_edge *e)
|
||||||
{
|
{
|
||||||
cgraph_edge *e = this;
|
|
||||||
|
|
||||||
tree decl = gimple_call_fndecl (e->call_stmt);
|
tree decl = gimple_call_fndecl (e->call_stmt);
|
||||||
gcall *new_stmt;
|
gcall *new_stmt;
|
||||||
gimple_stmt_iterator gsi;
|
gimple_stmt_iterator gsi;
|
||||||
|
@ -1263,7 +1263,7 @@ cgraph_edge::redirect_call_stmt_to_callee (void)
|
||||||
/* If there already is an direct call (i.e. as a result of inliner's
|
/* If there already is an direct call (i.e. as a result of inliner's
|
||||||
substitution), forget about speculating. */
|
substitution), forget about speculating. */
|
||||||
if (decl)
|
if (decl)
|
||||||
e = e->resolve_speculation (decl);
|
e = resolve_speculation (e, decl);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Expand speculation into GIMPLE code. */
|
/* Expand speculation into GIMPLE code. */
|
||||||
|
@ -1455,8 +1455,8 @@ cgraph_update_edges_for_call_stmt_node (cgraph_node *node,
|
||||||
if (new_stmt && is_gimple_call (new_stmt) && e->callee
|
if (new_stmt && is_gimple_call (new_stmt) && e->callee
|
||||||
&& fndecl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE))
|
&& fndecl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE))
|
||||||
{
|
{
|
||||||
node->get_edge (old_stmt)->set_call_stmt
|
cgraph_edge::set_call_stmt (node->get_edge (old_stmt),
|
||||||
(as_a <gcall *> (new_stmt));
|
as_a <gcall *> (new_stmt));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* See if the edge is already there and has the correct callee. It
|
/* See if the edge is already there and has the correct callee. It
|
||||||
|
@ -1470,7 +1470,7 @@ cgraph_update_edges_for_call_stmt_node (cgraph_node *node,
|
||||||
if (callee->decl == new_call
|
if (callee->decl == new_call
|
||||||
|| callee->former_clone_of == new_call)
|
|| callee->former_clone_of == new_call)
|
||||||
{
|
{
|
||||||
e->set_call_stmt (as_a <gcall *> (new_stmt));
|
cgraph_edge::set_call_stmt (e, as_a <gcall *> (new_stmt));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
callee = callee->clone_of;
|
callee = callee->clone_of;
|
||||||
|
@ -1482,7 +1482,7 @@ cgraph_update_edges_for_call_stmt_node (cgraph_node *node,
|
||||||
attached to edge is invalid. */
|
attached to edge is invalid. */
|
||||||
count = e->count;
|
count = e->count;
|
||||||
if (e->indirect_unknown_callee || e->inline_failed)
|
if (e->indirect_unknown_callee || e->inline_failed)
|
||||||
e->remove ();
|
cgraph_edge::remove (e);
|
||||||
else
|
else
|
||||||
e->callee->remove_symbol_and_inline_clones ();
|
e->callee->remove_symbol_and_inline_clones ();
|
||||||
}
|
}
|
||||||
|
@ -1502,7 +1502,8 @@ cgraph_update_edges_for_call_stmt_node (cgraph_node *node,
|
||||||
}
|
}
|
||||||
/* We only updated the call stmt; update pointer in cgraph edge.. */
|
/* We only updated the call stmt; update pointer in cgraph edge.. */
|
||||||
else if (old_stmt != new_stmt)
|
else if (old_stmt != new_stmt)
|
||||||
node->get_edge (old_stmt)->set_call_stmt (as_a <gcall *> (new_stmt));
|
cgraph_edge::set_call_stmt (node->get_edge (old_stmt),
|
||||||
|
as_a <gcall *> (new_stmt));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update or remove the corresponding cgraph edge if a GIMPLE_CALL
|
/* Update or remove the corresponding cgraph edge if a GIMPLE_CALL
|
||||||
|
|
39
gcc/cgraph.h
39
gcc/cgraph.h
|
@ -1736,13 +1736,15 @@ public:
|
||||||
friend struct cgraph_node;
|
friend struct cgraph_node;
|
||||||
friend class symbol_table;
|
friend class symbol_table;
|
||||||
|
|
||||||
/* Remove the edge in the cgraph. */
|
/* Remove EDGE from the cgraph. */
|
||||||
void remove (void);
|
static void remove (cgraph_edge *edge);
|
||||||
|
|
||||||
/* Change field call_stmt of edge to NEW_STMT.
|
/* Change field call_stmt of edge E to NEW_STMT. If UPDATE_SPECULATIVE and E
|
||||||
If UPDATE_SPECULATIVE and E is any component of speculative
|
is any component of speculative edge, then update all components.
|
||||||
edge, then update all components. */
|
Speculations can be resolved in the process and EDGE can be removed and
|
||||||
void set_call_stmt (gcall *new_stmt, bool update_speculative = true);
|
deallocated. Return the edge that now represents the call. */
|
||||||
|
static cgraph_edge *set_call_stmt (cgraph_edge *e, gcall *new_stmt,
|
||||||
|
bool update_speculative = true);
|
||||||
|
|
||||||
/* Redirect callee of the edge to N. The function does not update underlying
|
/* Redirect callee of the edge to N. The function does not update underlying
|
||||||
call expression. */
|
call expression. */
|
||||||
|
@ -1755,10 +1757,10 @@ public:
|
||||||
void redirect_callee_duplicating_thunks (cgraph_node *n);
|
void redirect_callee_duplicating_thunks (cgraph_node *n);
|
||||||
|
|
||||||
/* Make an indirect edge with an unknown callee an ordinary edge leading to
|
/* Make an indirect edge with an unknown callee an ordinary edge leading to
|
||||||
CALLEE. DELTA is an integer constant that is to be added to the this
|
CALLEE. Speculations can be resolved in the process and EDGE can be
|
||||||
pointer (first parameter) to compensate for skipping
|
removed and deallocated. Return the edge that now represents the
|
||||||
a thunk adjustment. */
|
call. */
|
||||||
cgraph_edge *make_direct (cgraph_node *callee);
|
static cgraph_edge *make_direct (cgraph_edge *edge, cgraph_node *callee);
|
||||||
|
|
||||||
/* Turn edge into speculative call calling N2. Update
|
/* Turn edge into speculative call calling N2. Update
|
||||||
the profile so the direct call is taken COUNT times
|
the profile so the direct call is taken COUNT times
|
||||||
|
@ -1769,14 +1771,19 @@ public:
|
||||||
void speculative_call_info (cgraph_edge *&direct, cgraph_edge *&indirect,
|
void speculative_call_info (cgraph_edge *&direct, cgraph_edge *&indirect,
|
||||||
ipa_ref *&reference);
|
ipa_ref *&reference);
|
||||||
|
|
||||||
/* Speculative call edge turned out to be direct call to CALLEE_DECL.
|
/* Speculative call edge turned out to be direct call to CALLEE_DECL. Remove
|
||||||
Remove the speculative call sequence and return edge representing the call.
|
the speculative call sequence and return edge representing the call, the
|
||||||
It is up to caller to redirect the call as appropriate. */
|
original EDGE can be removed and deallocated. It is up to caller to
|
||||||
cgraph_edge *resolve_speculation (tree callee_decl = NULL);
|
redirect the call as appropriate. Return the edge that now represents the
|
||||||
|
call. */
|
||||||
|
static cgraph_edge *resolve_speculation (cgraph_edge *edge,
|
||||||
|
tree callee_decl = NULL);
|
||||||
|
|
||||||
/* If necessary, change the function declaration in the call statement
|
/* If necessary, change the function declaration in the call statement
|
||||||
associated with the edge so that it corresponds to the edge callee. */
|
associated with edge E so that it corresponds to the edge callee.
|
||||||
gimple *redirect_call_stmt_to_callee (void);
|
Speculations can be resolved in the process and EDGE can be removed and
|
||||||
|
deallocated. */
|
||||||
|
static gimple *redirect_call_stmt_to_callee (cgraph_edge *e);
|
||||||
|
|
||||||
/* Create clone of edge in the node N represented
|
/* Create clone of edge in the node N represented
|
||||||
by CALL_EXPR the callgraph. */
|
by CALL_EXPR the callgraph. */
|
||||||
|
|
|
@ -744,10 +744,10 @@ cgraph_node::set_call_stmt_including_clones (gimple *old_stmt,
|
||||||
bool update_speculative)
|
bool update_speculative)
|
||||||
{
|
{
|
||||||
cgraph_node *node;
|
cgraph_node *node;
|
||||||
cgraph_edge *edge = get_edge (old_stmt);
|
cgraph_edge *master_edge = get_edge (old_stmt);
|
||||||
|
|
||||||
if (edge)
|
if (master_edge)
|
||||||
edge->set_call_stmt (new_stmt, update_speculative);
|
cgraph_edge::set_call_stmt (master_edge, new_stmt, update_speculative);
|
||||||
|
|
||||||
node = clones;
|
node = clones;
|
||||||
if (node)
|
if (node)
|
||||||
|
@ -756,7 +756,8 @@ cgraph_node::set_call_stmt_including_clones (gimple *old_stmt,
|
||||||
cgraph_edge *edge = node->get_edge (old_stmt);
|
cgraph_edge *edge = node->get_edge (old_stmt);
|
||||||
if (edge)
|
if (edge)
|
||||||
{
|
{
|
||||||
edge->set_call_stmt (new_stmt, update_speculative);
|
edge = cgraph_edge::set_call_stmt (edge, new_stmt,
|
||||||
|
update_speculative);
|
||||||
/* If UPDATE_SPECULATIVE is false, it means that we are turning
|
/* If UPDATE_SPECULATIVE is false, it means that we are turning
|
||||||
speculative call into a real code sequence. Update the
|
speculative call into a real code sequence. Update the
|
||||||
callgraph edges. */
|
callgraph edges. */
|
||||||
|
@ -800,11 +801,10 @@ cgraph_node::create_edge_including_clones (cgraph_node *callee,
|
||||||
cgraph_inline_failed_t reason)
|
cgraph_inline_failed_t reason)
|
||||||
{
|
{
|
||||||
cgraph_node *node;
|
cgraph_node *node;
|
||||||
cgraph_edge *edge;
|
|
||||||
|
|
||||||
if (!get_edge (stmt))
|
if (!get_edge (stmt))
|
||||||
{
|
{
|
||||||
edge = create_edge (callee, stmt, count);
|
cgraph_edge *edge = create_edge (callee, stmt, count);
|
||||||
edge->inline_failed = reason;
|
edge->inline_failed = reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -821,7 +821,7 @@ cgraph_node::create_edge_including_clones (cgraph_node *callee,
|
||||||
call in the clone or we are processing clones of unreachable
|
call in the clone or we are processing clones of unreachable
|
||||||
master where edges has been removed. */
|
master where edges has been removed. */
|
||||||
if (edge)
|
if (edge)
|
||||||
edge->set_call_stmt (stmt);
|
edge = cgraph_edge::set_call_stmt (edge, stmt);
|
||||||
else if (! node->get_edge (stmt))
|
else if (! node->get_edge (stmt))
|
||||||
{
|
{
|
||||||
edge = node->create_edge (callee, stmt, count);
|
edge = node->create_edge (callee, stmt, count);
|
||||||
|
@ -855,7 +855,7 @@ cgraph_node::remove_symbol_and_inline_clones (cgraph_node *forbidden_node)
|
||||||
|
|
||||||
if (this == forbidden_node)
|
if (this == forbidden_node)
|
||||||
{
|
{
|
||||||
callers->remove ();
|
cgraph_edge::remove (callers);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
for (e = callees; e; e = next)
|
for (e = callees; e; e = next)
|
||||||
|
|
|
@ -1024,16 +1024,13 @@ walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets,
|
||||||
target->dump_name ());
|
target->dump_name ());
|
||||||
}
|
}
|
||||||
|
|
||||||
edge->make_direct (target);
|
edge = cgraph_edge::make_direct (edge, target);
|
||||||
edge->redirect_call_stmt_to_callee ();
|
gimple *new_call = cgraph_edge::redirect_call_stmt_to_callee (edge);
|
||||||
|
|
||||||
if (symtab->dump_file)
|
if (symtab->dump_file)
|
||||||
{
|
{
|
||||||
fprintf (symtab->dump_file,
|
fprintf (symtab->dump_file, "Devirtualized as: ");
|
||||||
"Devirtualized as: ");
|
print_gimple_stmt (symtab->dump_file, new_call, 0, TDF_SLIM);
|
||||||
print_gimple_stmt (symtab->dump_file,
|
|
||||||
edge->call_stmt, 0,
|
|
||||||
TDF_SLIM);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -245,9 +245,9 @@ redirect_to_unreachable (struct cgraph_edge *e)
|
||||||
(builtin_decl_implicit (BUILT_IN_UNREACHABLE));
|
(builtin_decl_implicit (BUILT_IN_UNREACHABLE));
|
||||||
|
|
||||||
if (e->speculative)
|
if (e->speculative)
|
||||||
e = e->resolve_speculation (target->decl);
|
e = cgraph_edge::resolve_speculation (e, target->decl);
|
||||||
else if (!e->callee)
|
else if (!e->callee)
|
||||||
e->make_direct (target);
|
e = cgraph_edge::make_direct (e, target);
|
||||||
else
|
else
|
||||||
e->redirect_callee (target);
|
e->redirect_callee (target);
|
||||||
class ipa_call_summary *es = ipa_call_summaries->get (e);
|
class ipa_call_summary *es = ipa_call_summaries->get (e);
|
||||||
|
|
|
@ -258,7 +258,7 @@ check_speculations_1 (cgraph_node *n, vec<cgraph_edge *> *new_edges,
|
||||||
edge_set->add (new_edges->pop ());
|
edge_set->add (new_edges->pop ());
|
||||||
edge_set->remove (e);
|
edge_set->remove (e);
|
||||||
|
|
||||||
e->resolve_speculation (NULL);
|
cgraph_edge::resolve_speculation (e, NULL);
|
||||||
speculation_removed = true;
|
speculation_removed = true;
|
||||||
}
|
}
|
||||||
else if (!e->inline_failed)
|
else if (!e->inline_failed)
|
||||||
|
@ -712,7 +712,7 @@ inline_transform (struct cgraph_node *node)
|
||||||
if (!e->inline_failed)
|
if (!e->inline_failed)
|
||||||
has_inline = true;
|
has_inline = true;
|
||||||
next = e->next_callee;
|
next = e->next_callee;
|
||||||
e->redirect_call_stmt_to_callee ();
|
cgraph_edge::redirect_call_stmt_to_callee (e);
|
||||||
}
|
}
|
||||||
node->remove_all_references ();
|
node->remove_all_references ();
|
||||||
|
|
||||||
|
|
|
@ -1834,7 +1834,7 @@ resolve_noninline_speculation (edge_heap_t *edge_heap, struct cgraph_edge *edge)
|
||||||
|
|
||||||
if (edge->count.ipa ().initialized_p ())
|
if (edge->count.ipa ().initialized_p ())
|
||||||
spec_rem += edge->count.ipa ();
|
spec_rem += edge->count.ipa ();
|
||||||
edge->resolve_speculation ();
|
cgraph_edge::resolve_speculation (edge);
|
||||||
reset_edge_caches (where);
|
reset_edge_caches (where);
|
||||||
ipa_update_overall_fn_summary (where);
|
ipa_update_overall_fn_summary (where);
|
||||||
update_caller_keys (edge_heap, where,
|
update_caller_keys (edge_heap, where,
|
||||||
|
@ -1998,7 +1998,7 @@ inline_small_functions (void)
|
||||||
if (edge->speculative
|
if (edge->speculative
|
||||||
&& !speculation_useful_p (edge, edge->aux != NULL))
|
&& !speculation_useful_p (edge, edge->aux != NULL))
|
||||||
{
|
{
|
||||||
edge->resolve_speculation ();
|
cgraph_edge::resolve_speculation (edge);
|
||||||
update = true;
|
update = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2735,7 +2735,7 @@ ipa_inline (void)
|
||||||
{
|
{
|
||||||
if (edge->count.ipa ().initialized_p ())
|
if (edge->count.ipa ().initialized_p ())
|
||||||
spec_rem += edge->count.ipa ();
|
spec_rem += edge->count.ipa ();
|
||||||
edge->resolve_speculation ();
|
cgraph_edge::resolve_speculation (edge);
|
||||||
update = true;
|
update = true;
|
||||||
remove_functions = true;
|
remove_functions = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3299,7 +3299,7 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
|
||||||
if (!speculative)
|
if (!speculative)
|
||||||
{
|
{
|
||||||
struct cgraph_edge *orig = ie;
|
struct cgraph_edge *orig = ie;
|
||||||
ie = ie->make_direct (callee);
|
ie = cgraph_edge::make_direct (ie, callee);
|
||||||
/* If we resolved speculative edge the cost is already up to date
|
/* If we resolved speculative edge the cost is already up to date
|
||||||
for direct call (adjusted by inline_edge_duplication_hook). */
|
for direct call (adjusted by inline_edge_duplication_hook). */
|
||||||
if (ie == orig)
|
if (ie == orig)
|
||||||
|
|
|
@ -632,8 +632,10 @@ function_and_variable_visibility (bool whole_program)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
cgraph_node *alias = 0;
|
cgraph_node *alias = 0;
|
||||||
for (cgraph_edge *e = node->callees; e; e = e->next_callee)
|
cgraph_edge *next_edge;
|
||||||
|
for (cgraph_edge *e = node->callees; e; e = next_edge)
|
||||||
{
|
{
|
||||||
|
next_edge = e->next_callee;
|
||||||
/* Recursive function calls usually can't be interposed. */
|
/* Recursive function calls usually can't be interposed. */
|
||||||
|
|
||||||
if (!e->recursive_p ())
|
if (!e->recursive_p ())
|
||||||
|
@ -649,7 +651,7 @@ function_and_variable_visibility (bool whole_program)
|
||||||
if (gimple_has_body_p (e->caller->decl))
|
if (gimple_has_body_p (e->caller->decl))
|
||||||
{
|
{
|
||||||
push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl));
|
push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl));
|
||||||
e->redirect_call_stmt_to_callee ();
|
cgraph_edge::redirect_call_stmt_to_callee (e);
|
||||||
pop_cfun ();
|
pop_cfun ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -780,7 +782,7 @@ function_and_variable_visibility (bool whole_program)
|
||||||
if (gimple_has_body_p (e->caller->decl))
|
if (gimple_has_body_p (e->caller->decl))
|
||||||
{
|
{
|
||||||
push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl));
|
push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl));
|
||||||
e->redirect_call_stmt_to_callee ();
|
cgraph_edge::redirect_call_stmt_to_callee (e);
|
||||||
pop_cfun ();
|
pop_cfun ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -242,12 +242,12 @@ walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets,
|
||||||
edge->caller->dump_name (),
|
edge->caller->dump_name (),
|
||||||
target->dump_name ());
|
target->dump_name ());
|
||||||
}
|
}
|
||||||
edge = edge->make_direct (target);
|
edge = cgraph_edge::make_direct (edge, target);
|
||||||
if (ipa_fn_summaries)
|
if (ipa_fn_summaries)
|
||||||
ipa_update_overall_fn_summary (node->inlined_to
|
ipa_update_overall_fn_summary (node->inlined_to
|
||||||
? node->inlined_to : node);
|
? node->inlined_to : node);
|
||||||
else if (edge->call_stmt)
|
else if (edge->call_stmt)
|
||||||
edge->redirect_call_stmt_to_callee ();
|
cgraph_edge::redirect_call_stmt_to_callee (edge);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,7 +126,7 @@ create_dispatcher_calls (struct cgraph_node *node)
|
||||||
FOR_EACH_VEC_ELT (edges_to_redirect, i, e)
|
FOR_EACH_VEC_ELT (edges_to_redirect, i, e)
|
||||||
{
|
{
|
||||||
e->redirect_callee (inode);
|
e->redirect_callee (inode);
|
||||||
e->redirect_call_stmt_to_callee ();
|
cgraph_edge::redirect_call_stmt_to_callee (e);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Redirect references. */
|
/* Redirect references. */
|
||||||
|
@ -501,7 +501,7 @@ redirect_to_specific_clone (cgraph_node *node)
|
||||||
if (attribute_list_equal (attr_target, attr_target2))
|
if (attribute_list_equal (attr_target, attr_target2))
|
||||||
{
|
{
|
||||||
e->redirect_callee (callee);
|
e->redirect_callee (callee);
|
||||||
e->redirect_call_stmt_to_callee ();
|
cgraph_edge::redirect_call_stmt_to_callee (e);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1598,7 +1598,7 @@ delete_unreachable_blocks_update_callgraph (cgraph_node *dst_node,
|
||||||
if (!e->inline_failed)
|
if (!e->inline_failed)
|
||||||
e->callee->remove_symbol_and_inline_clones (dst_node);
|
e->callee->remove_symbol_and_inline_clones (dst_node);
|
||||||
else
|
else
|
||||||
e->remove ();
|
cgraph_edge::remove (e);
|
||||||
}
|
}
|
||||||
if (update_clones && dst_node->clones)
|
if (update_clones && dst_node->clones)
|
||||||
for (node = dst_node->clones; node != dst_node;)
|
for (node = dst_node->clones; node != dst_node;)
|
||||||
|
@ -1610,7 +1610,7 @@ delete_unreachable_blocks_update_callgraph (cgraph_node *dst_node,
|
||||||
if (!e->inline_failed)
|
if (!e->inline_failed)
|
||||||
e->callee->remove_symbol_and_inline_clones (dst_node);
|
e->callee->remove_symbol_and_inline_clones (dst_node);
|
||||||
else
|
else
|
||||||
e->remove ();
|
cgraph_edge::remove (e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->clones)
|
if (node->clones)
|
||||||
|
|
|
@ -2225,7 +2225,7 @@ copy_bb (copy_body_data *id, basic_block bb,
|
||||||
case CB_CGE_MOVE:
|
case CB_CGE_MOVE:
|
||||||
edge = id->dst_node->get_edge (orig_stmt);
|
edge = id->dst_node->get_edge (orig_stmt);
|
||||||
if (edge)
|
if (edge)
|
||||||
edge->set_call_stmt (call_stmt);
|
edge = cgraph_edge::set_call_stmt (edge, call_stmt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -2899,7 +2899,8 @@ redirect_all_calls (copy_body_data * id, basic_block bb)
|
||||||
struct cgraph_edge *edge = id->dst_node->get_edge (stmt);
|
struct cgraph_edge *edge = id->dst_node->get_edge (stmt);
|
||||||
if (edge)
|
if (edge)
|
||||||
{
|
{
|
||||||
gimple *new_stmt = edge->redirect_call_stmt_to_callee ();
|
gimple *new_stmt
|
||||||
|
= cgraph_edge::redirect_call_stmt_to_callee (edge);
|
||||||
/* If IPA-SRA transformation, run as part of edge redirection,
|
/* If IPA-SRA transformation, run as part of edge redirection,
|
||||||
removed the LHS because it is unused, save it to
|
removed the LHS because it is unused, save it to
|
||||||
killed_new_ssa_names so that we can prune it from debug
|
killed_new_ssa_names so that we can prune it from debug
|
||||||
|
@ -4750,7 +4751,7 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id,
|
||||||
tree op;
|
tree op;
|
||||||
gimple_stmt_iterator iter = gsi_for_stmt (stmt);
|
gimple_stmt_iterator iter = gsi_for_stmt (stmt);
|
||||||
|
|
||||||
cg_edge->remove ();
|
cgraph_edge::remove (cg_edge);
|
||||||
edge = id->src_node->callees->clone (id->dst_node, call_stmt,
|
edge = id->src_node->callees->clone (id->dst_node, call_stmt,
|
||||||
gimple_uid (stmt),
|
gimple_uid (stmt),
|
||||||
profile_count::one (),
|
profile_count::one (),
|
||||||
|
|
Loading…
Reference in New Issue