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