aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2011-01-21 20:34:03 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2011-01-21 20:34:03 +0100
commit7360d2ac8dae5659de0adc18cd1d74b15a5971ed (patch)
tree5cf2b8119d9820d652ae6742a5b8b2fc1fb0887a /gcc
parent0eb35d462fca8490994778c4224676388c69828e (diff)
downloadgcc-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/ChangeLog10
-rw-r--r--gcc/fwprop.c47
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/opt/pr47366.C22
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 ();
+}