From: rth Date: Thu, 30 Jul 2009 00:34:47 +0000 (+0000) Subject: * cgraph.c (cgraph_set_call_stmt_including_clones): Tidy. X-Git-Tag: upstream/4.9.2~34536 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=da50fe8f588a6dc5f7ebabd347d87741f06f7120;p=platform%2Fupstream%2Flinaro-gcc.git * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@150234 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 43e94c1..d61bf2d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2009-07-29 Richard Henderson + + * 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 * config/alpha/vms-cc.c: Deleted. diff --git a/gcc/cgraph.c b/gcc/cgraph.c index ea47aa3..ded99f9 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 605f91e..e62c5c1 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)