aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2010-11-30 14:33:00 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2010-11-30 14:33:00 +0000
commit20f455770b2c175d1867c02989a6bd4c411a4ee7 (patch)
tree16a1ccec49b0641047dbd3739de6833a0dffdf78 /gcc
parent3f1faac1daefa83b6588424873c01f7d1370277d (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/value-prof.c34
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;