aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrth <>2009-07-29 23:34:47 +0000
committerrth <>2009-07-29 23:34:47 +0000
commitc8481e7453c9e930226c8186a6ffb20ae158eccd (patch)
tree23026fcdcd9433b2a8685cc8e5e252e7bee82279
parent150e2cae45cc699e4ef4d35c255a9bf92e405a42 (diff)
* 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.
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/cgraph.c39
-rw-r--r--gcc/tree-inline.c108
3 files changed, 86 insertions, 68 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 43e94c13461..d61bf2d52b8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+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.
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index ea47aa32cdc..ded99f9cb81 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -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;
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 605f91ef1a9..e62c5c1e792 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -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)