From 20f455770b2c175d1867c02989a6bd4c411a4ee7 Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Tue, 30 Nov 2010 14:33:00 +0000 Subject: [PATCH] re PR middle-end/46717 (Compiler segfault in profile-use mode) 2010-11-30 Richard Guenther 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 --- gcc/ChangeLog | 7 +++++++ gcc/value-prof.c | 34 ++++++++++++++++++++++------------ 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0a325cef219..ab808ce3992 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2010-11-30 Richard Guenther + + 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 * 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 ea70e2a15e7..9e27a9679fc 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; -- 2.30.2