From 758889e74df0f9a685cc69e1e40abada1776aacf Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Mon, 18 Apr 2011 15:25:17 +0000 Subject: [PATCH] backport: [multiple changes] 2011-04-18 Richard Guenther Backported from 4.6 branch 2011-01-19 Jakub Jelinek PR tree-optimization/47290 * tree-eh.c (infinite_empty_loop_p): New function. (cleanup_empty_eh): Use it. * g++.dg/torture/pr47290.C: New test. 2010-05-29 Jan Hubicka PR tree-optimization/46364 * cgraphunit.c (cgraph_materialize_clone): Only remove calles, refs and body; not the whole node for masters of materialized clones. * g++.dg/torture/pr46364.C: New testcase. From-SVN: r172653 --- gcc/ChangeLog | 16 +++++++++++ gcc/cgraphunit.c | 5 +++- gcc/testsuite/ChangeLog | 13 +++++++++ gcc/testsuite/g++.dg/torture/pr46364.C | 20 +++++++++++++ gcc/testsuite/g++.dg/torture/pr47290.C | 19 ++++++++++++ gcc/tree-eh.c | 40 ++++++++++++++++++++++++-- 6 files changed, 110 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/torture/pr46364.C create mode 100644 gcc/testsuite/g++.dg/torture/pr47290.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 84eb843a694b..19633f032c8b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2011-04-18 Richard Guenther + + Backported from 4.6 branch + 2011-01-19 Jakub Jelinek + + PR tree-optimization/47290 + * tree-eh.c (infinite_empty_loop_p): New function. + (cleanup_empty_eh): Use it. + + 2010-05-29 Jan Hubicka + + PR tree-optimization/46364 + * cgraphunit.c (cgraph_materialize_clone): Only remove calles, refs + and body; + not the whole node for masters of materialized clones. + 2011-04-18 Richard Guenther Backported from 4.6 branch diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 39839bfb9d94..0bea59b52214 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -2259,7 +2259,10 @@ cgraph_materialize_clone (struct cgraph_node *node) node->next_sibling_clone = NULL; node->prev_sibling_clone = NULL; if (!node->clone_of->analyzed && !node->clone_of->clones) - cgraph_remove_node (node->clone_of); + { + cgraph_release_function_body (node->clone_of); + cgraph_node_remove_callees (node->clone_of); + } node->clone_of = NULL; bitmap_obstack_release (NULL); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 36dd99a9c66d..97b381221eda 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,16 @@ +2011-04-18 Richard Guenther + + Backported from 4.6 branch + 2011-01-19 Jakub Jelinek + + PR tree-optimization/47290 + * g++.dg/torture/pr47290.C: New test. + + 2010-05-29 Jan Hubicka + + PR tree-optimization/46364 + * g++.dg/torture/pr46364.C: New testcase. + 2011-04-18 Richard Guenther Backported from 4.6 branch diff --git a/gcc/testsuite/g++.dg/torture/pr46364.C b/gcc/testsuite/g++.dg/torture/pr46364.C new file mode 100644 index 000000000000..8098991ace02 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr46364.C @@ -0,0 +1,20 @@ +// { dg-do compile } +#include + +void a() throw (int); +void b(std::string const &); + +void c(std::string *e) +{ + b(""); + + try { + a(); + } catch (...) { + *e = ""; + } +} + +void d() { + c(0); +} diff --git a/gcc/testsuite/g++.dg/torture/pr47290.C b/gcc/testsuite/g++.dg/torture/pr47290.C new file mode 100644 index 000000000000..b739de5b749a --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr47290.C @@ -0,0 +1,19 @@ +// PR tree-optimization/47290 +// { dg-do compile } + +struct V +{ + V (int = 0); + ~V () + { + for (;;) + ; + } + int size (); +}; + +struct S +{ + V a, b; + S () : b (a.size ()) {} +} s; diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index b5cf530adc7d..62884f3975d6 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -1,5 +1,5 @@ /* Exception handling semantics and decomposition for trees. - Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 + Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. This file is part of GCC. @@ -3688,6 +3688,42 @@ cleanup_empty_eh_unsplit (basic_block bb, edge e_out, eh_landing_pad lp) return false; } +/* Return true if edge E_FIRST is part of an empty infinite loop + or leads to such a loop through a series of single successor + empty bbs. */ + +static bool +infinite_empty_loop_p (edge e_first) +{ + bool inf_loop = false; + edge e; + + if (e_first->dest == e_first->src) + return true; + + e_first->src->aux = (void *) 1; + for (e = e_first; single_succ_p (e->dest); e = single_succ_edge (e->dest)) + { + gimple_stmt_iterator gsi; + if (e->dest->aux) + { + inf_loop = true; + break; + } + e->dest->aux = (void *) 1; + gsi = gsi_after_labels (e->dest); + if (!gsi_end_p (gsi) && is_gimple_debug (gsi_stmt (gsi))) + gsi_next_nondebug (&gsi); + if (!gsi_end_p (gsi)) + break; + } + e_first->src->aux = NULL; + for (e = e_first; e->dest->aux; e = single_succ_edge (e->dest)) + e->dest->aux = NULL; + + return inf_loop; +} + /* Examine the block associated with LP to determine if it's an empty handler for its EH region. If so, attempt to redirect EH edges to an outer region. Return true the CFG was updated in any way. This @@ -3727,7 +3763,7 @@ cleanup_empty_eh (eh_landing_pad lp) if (gsi_end_p (gsi)) { /* For the degenerate case of an infinite loop bail out. */ - if (e_out->dest == bb) + if (infinite_empty_loop_p (e_out)) return false; return cleanup_empty_eh_unsplit (bb, e_out, lp); -- 2.47.2