diff options
author | Richard Guenther <rguenther@suse.de> | 2010-11-30 14:33:00 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2010-11-30 14:33:00 +0000 |
commit | 20f455770b2c175d1867c02989a6bd4c411a4ee7 (patch) | |
tree | 16a1ccec49b0641047dbd3739de6833a0dffdf78 /gcc | |
parent | 3f1faac1daefa83b6588424873c01f7d1370277d (diff) | |
download | gcc-20f455770b2c175d1867c02989a6bd4c411a4ee7.zip gcc-20f455770b2c175d1867c02989a6bd4c411a4ee7.tar.gz gcc-20f455770b2c175d1867c02989a6bd4c411a4ee7.tar.bz2 |
re PR middle-end/46717 (Compiler segfault in profile-use mode)
2010-11-30 Richard Guenther <rguenther@suse.de>
PR tree-optimization/46717
* value-prof.c (gimple_ic): Preserve EH edges of the indirect
call. Manually create EH edges for the direct call and update
target PHI nodes.
From-SVN: r167298
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/value-prof.c | 34 |
2 files changed, 29 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0a325ce..ab808ce 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2010-11-30 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/46717 + * value-prof.c (gimple_ic): Preserve EH edges of the indirect + call. Manually create EH edges for the direct call and update + target PHI nodes. + 2010-11-30 Eric Botcazou <ebotcazou@adacore.com> * tree.c (build_range_type_1): Do not set TYPE_STRUCTURAL_EQUALITY_P diff --git a/gcc/value-prof.c b/gcc/value-prof.c index ea70e2a..9e27a96 100644 --- a/gcc/value-prof.c +++ b/gcc/value-prof.c @@ -1145,7 +1145,11 @@ gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call, icall_bb = e_di->dest; icall_bb->count = all - count; - e_ij = split_block (icall_bb, icall_stmt); + /* Do not disturb existing EH edges from the indirect call. */ + if (last_stmt (icall_bb) != icall_stmt) + e_ij = split_block (icall_bb, icall_stmt); + else + e_ij = find_fallthru_edge (icall_bb->succs); join_bb = e_ij->dest; join_bb->count = all; @@ -1181,21 +1185,27 @@ gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call, add_phi_arg (phi, gimple_call_lhs (dcall_stmt), e_dj, UNKNOWN_LOCATION); } - /* Fix eh edges */ + /* Build an EH edge for the direct call if necessary. */ lp_nr = lookup_stmt_eh_lp (icall_stmt); - if (lp_nr != 0) + if (lp_nr != 0 + && stmt_could_throw_p (dcall_stmt)) { - if (stmt_could_throw_p (dcall_stmt)) + edge e_eh, e; + edge_iterator ei; + gimple_stmt_iterator psi; + + add_stmt_to_eh_lp (dcall_stmt, lp_nr); + FOR_EACH_EDGE (e_eh, ei, icall_bb->succs) + if (e_eh->flags & EDGE_EH) + break; + e = make_edge (dcall_bb, e_eh->dest, EDGE_EH); + for (psi = gsi_start_phis (e_eh->dest); + !gsi_end_p (psi); gsi_next (&psi)) { - add_stmt_to_eh_lp (dcall_stmt, lp_nr); - make_eh_edges (dcall_stmt); + gimple phi = gsi_stmt (psi); + SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e), + PHI_ARG_DEF_FROM_EDGE (phi, e_eh)); } - - gcc_assert (stmt_could_throw_p (icall_stmt)); - make_eh_edges (icall_stmt); - - /* The old EH edges are sill on the join BB, purge them. */ - gimple_purge_dead_eh_edges (join_bb); } return dcall_stmt; |