diff options
author | Jakub Jelinek <jakub@redhat.com> | 2011-01-21 20:34:03 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2011-01-21 20:34:03 +0100 |
commit | 7360d2ac8dae5659de0adc18cd1d74b15a5971ed (patch) | |
tree | 5cf2b8119d9820d652ae6742a5b8b2fc1fb0887a /gcc | |
parent | 0eb35d462fca8490994778c4224676388c69828e (diff) | |
download | gcc-7360d2ac8dae5659de0adc18cd1d74b15a5971ed.zip gcc-7360d2ac8dae5659de0adc18cd1d74b15a5971ed.tar.gz gcc-7360d2ac8dae5659de0adc18cd1d74b15a5971ed.tar.bz2 |
re PR rtl-optimization/47366 (ICE: verify_flow_info failed: missing REG_EH_REGION note in the end of bb 3 with -fnon-call-exceptions -fno-tree-ccp -fno-tree-forwprop)
PR rtl-optimization/47366
* fwprop.c (forward_propagate_into): Return bool. If
any changes are made, -fnon-call-exceptions is used and
REG_EH_REGION note is present, call purge_dead_edges
and return true if it purged anything.
(fwprop_addr): Adjust callers, call cleanup_cfg (0) if
any EH edges were purged.
* g++.dg/opt/pr47366.C: New test.
From-SVN: r169100
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/fwprop.c | 47 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/opt/pr47366.C | 22 |
4 files changed, 68 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 95481b1..ab3c70b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2011-01-21 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/47366 + * fwprop.c (forward_propagate_into): Return bool. If + any changes are made, -fnon-call-exceptions is used and + REG_EH_REGION note is present, call purge_dead_edges + and return true if it purged anything. + (fwprop_addr): Adjust callers, call cleanup_cfg (0) if + any EH edges were purged. + 2011-01-21 Jeff Law <law@redhat.com> PR rtl-optimization/41619 diff --git a/gcc/fwprop.c b/gcc/fwprop.c index 7ff5135..704e143 100644 --- a/gcc/fwprop.c +++ b/gcc/fwprop.c @@ -1,5 +1,5 @@ /* RTL-based forward propagation pass for GNU compiler. - Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 + Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. Contributed by Paolo Bonzini and Steven Bosscher. @@ -1315,9 +1315,10 @@ forward_propagate_and_simplify (df_ref use, rtx def_insn, rtx def_set) /* Given a use USE of an insn, if it has a single reaching - definition, try to forward propagate it into that insn. */ + definition, try to forward propagate it into that insn. + Return true if cfg cleanup will be needed. */ -static void +static bool forward_propagate_into (df_ref use) { df_ref def; @@ -1325,22 +1326,22 @@ forward_propagate_into (df_ref use) rtx parent; if (DF_REF_FLAGS (use) & DF_REF_READ_WRITE) - return; + return false; if (DF_REF_IS_ARTIFICIAL (use)) - return; + return false; /* Only consider uses that have a single definition. */ def = get_def_for_use (use); if (!def) - return; + return false; if (DF_REF_FLAGS (def) & DF_REF_READ_WRITE) - return; + return false; if (DF_REF_IS_ARTIFICIAL (def)) - return; + return false; /* Do not propagate loop invariant definitions inside the loop. */ if (DF_REF_BB (def)->loop_father != DF_REF_BB (use)->loop_father) - return; + return false; /* Check if the use is still present in the insn! */ use_insn = DF_REF_INSN (use); @@ -1350,19 +1351,26 @@ forward_propagate_into (df_ref use) parent = PATTERN (use_insn); if (!reg_mentioned_p (DF_REF_REG (use), parent)) - return; + return false; def_insn = DF_REF_INSN (def); if (multiple_sets (def_insn)) - return; + return false; def_set = single_set (def_insn); if (!def_set) - return; + return false; /* Only try one kind of propagation. If two are possible, we'll do it on the following iterations. */ - if (!forward_propagate_and_simplify (use, def_insn, def_set)) - forward_propagate_subreg (use, def_insn, def_set); + if (forward_propagate_and_simplify (use, def_insn, def_set) + || forward_propagate_subreg (use, def_insn, def_set)) + { + if (cfun->can_throw_non_call_exceptions + && find_reg_note (use_insn, REG_EH_REGION, NULL_RTX) + && purge_dead_edges (DF_REF_BB (use))) + return true; + } + return false; } @@ -1421,6 +1429,7 @@ static unsigned int fwprop (void) { unsigned i; + bool need_cleanup = false; fwprop_init (); @@ -1438,10 +1447,12 @@ fwprop (void) || DF_REF_BB (use)->loop_father == NULL /* The outer most loop is not really a loop. */ || loop_outer (DF_REF_BB (use)->loop_father) == NULL) - forward_propagate_into (use); + need_cleanup |= forward_propagate_into (use); } fwprop_done (); + if (need_cleanup) + cleanup_cfg (0); return 0; } @@ -1469,6 +1480,8 @@ static unsigned int fwprop_addr (void) { unsigned i; + bool need_cleanup = false; + fwprop_init (); /* Go through all the uses. df_uses_create will create new ones at the @@ -1481,11 +1494,13 @@ fwprop_addr (void) && DF_REF_BB (use)->loop_father != NULL /* The outer most loop is not really a loop. */ && loop_outer (DF_REF_BB (use)->loop_father) != NULL) - forward_propagate_into (use); + need_cleanup |= forward_propagate_into (use); } fwprop_done (); + if (need_cleanup) + cleanup_cfg (0); return 0; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 09b657a..2c1e8fb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-01-21 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/47366 + * g++.dg/opt/pr47366.C: New test. + 2011-01-21 Jason Merrill <jason@redhat.com> PR c++/46552 diff --git a/gcc/testsuite/g++.dg/opt/pr47366.C b/gcc/testsuite/g++.dg/opt/pr47366.C new file mode 100644 index 0000000..e133edf --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr47366.C @@ -0,0 +1,22 @@ +// PR rtl-optimization/47366 +// { dg-do compile } +// { dg-options "-O -fnon-call-exceptions -fno-tree-ccp -fno-tree-forwprop" } + +struct A +{ + int i; + virtual ~A (); +}; + +struct B : virtual A +{}; + +struct C : B +{ + void bar () {} +}; + +void foo () +{ + C ().bar (); +} |