Commit 9b2a5ef7 by Richard Henderson Committed by Richard Henderson

cgraph.c (cgraph_set_call_stmt_including_clones): Tidy.

        * cgraph.c (cgraph_set_call_stmt_including_clones): Tidy.
        (cgraph_create_edge_including_clones): Likewise.
        * tree-inline.c (copy_bb): Operate on the correct edges
        when updating the callgraph.

From-SVN: r150234
parent 2f5164ee
2009-07-29 Richard Henderson <rth@redhat.com>
* cgraph.c (cgraph_set_call_stmt_including_clones): Tidy.
(cgraph_create_edge_including_clones): Likewise.
* tree-inline.c (copy_bb): Operate on the correct edges
when updating the callgraph.
2009-07-29 Douglas B Rupp <rupp@gnat.com> 2009-07-29 Douglas B Rupp <rupp@gnat.com>
* config/alpha/vms-cc.c: Deleted. * config/alpha/vms-cc.c: Deleted.
......
...@@ -654,8 +654,8 @@ cgraph_set_call_stmt (struct cgraph_edge *e, gimple new_stmt) ...@@ -654,8 +654,8 @@ cgraph_set_call_stmt (struct cgraph_edge *e, gimple new_stmt)
} }
} }
/* Like cgraph_set_call_stmt but walk the clone tree and update all clones sharing /* Like cgraph_set_call_stmt but walk the clone tree and update all
same function body. */ clones sharing the same function body. */
void void
cgraph_set_call_stmt_including_clones (struct cgraph_node *orig, cgraph_set_call_stmt_including_clones (struct cgraph_node *orig,
...@@ -666,8 +666,10 @@ cgraph_set_call_stmt_including_clones (struct cgraph_node *orig, ...@@ -666,8 +666,10 @@ cgraph_set_call_stmt_including_clones (struct cgraph_node *orig,
if (edge) if (edge)
cgraph_set_call_stmt (edge, new_stmt); cgraph_set_call_stmt (edge, new_stmt);
if (orig->clones)
for (node = orig->clones; node != orig;) node = orig->clones;
if (node)
while (node != orig)
{ {
struct cgraph_edge *edge = cgraph_edge (node, old_stmt); struct cgraph_edge *edge = cgraph_edge (node, old_stmt);
if (edge) if (edge)
...@@ -690,29 +692,36 @@ cgraph_set_call_stmt_including_clones (struct cgraph_node *orig, ...@@ -690,29 +692,36 @@ cgraph_set_call_stmt_including_clones (struct cgraph_node *orig,
same function body. same function body.
TODO: COUNT and LOOP_DEPTH should be properly distributed based on relative TODO: COUNT and LOOP_DEPTH should be properly distributed based on relative
frequencies of the clones. frequencies of the clones. */
*/
void void
cgraph_create_edge_including_clones (struct cgraph_node *orig, struct cgraph_node *callee, cgraph_create_edge_including_clones (struct cgraph_node *orig,
gimple stmt, gcov_type count, int freq, struct cgraph_node *callee,
int loop_depth, gimple stmt, gcov_type count,
int freq, int loop_depth,
cgraph_inline_failed_t reason) cgraph_inline_failed_t reason)
{ {
struct cgraph_node *node; struct cgraph_node *node;
struct cgraph_edge *edge;
if (!cgraph_edge (orig, stmt)) if (!cgraph_edge (orig, stmt))
cgraph_create_edge (orig, callee, stmt, {
count, freq, loop_depth)->inline_failed = reason; edge = cgraph_create_edge (orig, callee, stmt, count, freq, loop_depth);
edge->inline_failed = reason;
}
if (orig->clones) node = orig->clones;
for (node = orig->clones; node != orig;) if (node)
while (node != orig)
{ {
/* It is possible that we already constant propagated into the clone /* It is possible that we already constant propagated into the clone
and turned indirect call into dirrect call. */ and turned indirect call into dirrect call. */
if (!cgraph_edge (node, stmt)) if (!cgraph_edge (node, stmt))
cgraph_create_edge (node, callee, stmt, count, freq, {
loop_depth)->inline_failed = reason; edge = cgraph_create_edge (node, callee, stmt, count,
freq, loop_depth);
edge->inline_failed = reason;
}
if (node->clones) if (node->clones)
node = node->clones; node = node->clones;
......
...@@ -1496,67 +1496,69 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, ...@@ -1496,67 +1496,69 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
callgraph edges and update or duplicate them. */ callgraph edges and update or duplicate them. */
if (is_gimple_call (stmt)) if (is_gimple_call (stmt))
{ {
struct cgraph_edge *edge = cgraph_edge (id->src_node, orig_stmt); struct cgraph_edge *edge;
int flags; int flags;
switch (id->transform_call_graph_edges) switch (id->transform_call_graph_edges)
{ {
case CB_CGE_DUPLICATE: case CB_CGE_DUPLICATE:
if (edge) edge = cgraph_edge (id->src_node, orig_stmt);
cgraph_clone_edge (edge, id->dst_node, stmt, if (edge)
REG_BR_PROB_BASE, 1, edge = cgraph_clone_edge (edge, id->dst_node, stmt,
edge->frequency, true); REG_BR_PROB_BASE, 1,
break; edge->frequency, true);
break;
case CB_CGE_MOVE_CLONES:
cgraph_set_call_stmt_including_clones (id->dst_node, orig_stmt, stmt); case CB_CGE_MOVE_CLONES:
break; cgraph_set_call_stmt_including_clones (id->dst_node,
orig_stmt, stmt);
case CB_CGE_MOVE: edge = cgraph_edge (id->dst_node, stmt);
if (edge) break;
cgraph_set_call_stmt (edge, stmt);
break; case CB_CGE_MOVE:
edge = cgraph_edge (id->dst_node, orig_stmt);
default: if (edge)
gcc_unreachable (); cgraph_set_call_stmt (edge, stmt);
break;
default:
gcc_unreachable ();
} }
edge = cgraph_edge (id->src_node, orig_stmt); /* Constant propagation on argument done during inlining
/* Constant propagation on argument done during inlining may create new direct call. Produce an edge for it. */
may create new direct call. Produce an edge for it. */ if ((!edge
if ((!edge || (edge->indirect_call
|| (edge->indirect_call && id->transform_call_graph_edges == CB_CGE_MOVE_CLONES))
&& id->transform_call_graph_edges == CB_CGE_MOVE_CLONES)) && is_gimple_call (stmt)
&& is_gimple_call (stmt) && (fn = gimple_call_fndecl (stmt)) != NULL)
&& (fn = gimple_call_fndecl (stmt)) != NULL) {
{ struct cgraph_node *dest = cgraph_node (fn);
struct cgraph_node *dest = cgraph_node (fn);
/* We have missing edge in the callgraph. This can happen
/* We have missing edge in the callgraph. This can happen in one case when previous inlining turned an indirect call into a
where previous inlining turned indirect call into direct call by direct call by constant propagating arguments. In all
constant propagating arguments. In all other cases we hit a bug other cases we hit a bug (incorrect node sharing is the
(incorrect node sharing is most common reason for missing edges. */ most common reason for missing edges). */
gcc_assert (dest->needed || !dest->analyzed); gcc_assert (dest->needed || !dest->analyzed);
if (id->transform_call_graph_edges == CB_CGE_MOVE_CLONES) if (id->transform_call_graph_edges == CB_CGE_MOVE_CLONES)
cgraph_create_edge_including_clones (id->dst_node, dest, stmt, cgraph_create_edge_including_clones
bb->count, (id->dst_node, dest, stmt, bb->count,
compute_call_stmt_bb_frequency (id->dst_node->decl, bb), compute_call_stmt_bb_frequency (id->dst_node->decl, bb),
bb->loop_depth, bb->loop_depth, CIF_ORIGINALLY_INDIRECT_CALL);
CIF_ORIGINALLY_INDIRECT_CALL); else
else cgraph_create_edge (id->dst_node, dest, stmt,
cgraph_create_edge (id->dst_node, dest, stmt, bb->count, CGRAPH_FREQ_BASE,
bb->count, CGRAPH_FREQ_BASE, bb->loop_depth)->inline_failed
bb->loop_depth)->inline_failed = CIF_ORIGINALLY_INDIRECT_CALL;
= CIF_ORIGINALLY_INDIRECT_CALL; if (dump_file)
if (dump_file) {
{ fprintf (dump_file, "Created new direct edge to %s",
fprintf (dump_file, "Created new direct edge to %s", cgraph_node_name (dest));
cgraph_node_name (dest)); }
} }
}
flags = gimple_call_flags (stmt); flags = gimple_call_flags (stmt);
if (flags & ECF_MAY_BE_ALLOCA) if (flags & ECF_MAY_BE_ALLOCA)
cfun->calls_alloca = true; cfun->calls_alloca = true;
if (flags & ECF_RETURNS_TWICE) if (flags & ECF_RETURNS_TWICE)
......
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