diff mbox

Call purge_dead_edges when needed in fwprop (PR rtl-optimization/47366)

Message ID 20110120163227.GZ2724@tyan-ft48-01.lab.bos.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Jan. 20, 2011, 4:32 p.m. UTC
Hi!

This testcase ICEs during checking, because fwprop turned
a MEM that was conservatively considered to potentially trap
(-fnon-call-exceptions) into one that clearly can't trap (frame based),
but doesn't clean up the EH edges for it, and then DSE removes
the dead stores and doesn't think about EH cleanup because
frame based stores (or any other that can be DSEd) really shouldn't
ever trap.

Fixed by calling purge_dead_edges in fwprop.  Bootstrapped/regtested on
x86_64-linux and i686-linux, ok for trunk?

2011-01-20  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.

	* g++.dg/opt/pr47366.C: New test.


	Jakub

Comments

Jeff Law Jan. 20, 2011, 4:36 p.m. UTC | #1
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 01/20/11 09:32, Jakub Jelinek wrote:
> Hi!
> 
> This testcase ICEs during checking, because fwprop turned
> a MEM that was conservatively considered to potentially trap
> (-fnon-call-exceptions) into one that clearly can't trap (frame based),
> but doesn't clean up the EH edges for it, and then DSE removes
> the dead stores and doesn't think about EH cleanup because
> frame based stores (or any other that can be DSEd) really shouldn't
> ever trap.
> 
> Fixed by calling purge_dead_edges in fwprop.  Bootstrapped/regtested on
> x86_64-linux and i686-linux, ok for trunk?
> 
> 2011-01-20  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.
> 
> 	* g++.dg/opt/pr47366.C: New test.
Any chance that fixes 47053 or 43695?

Jeff
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJNOGRxAAoJEBRtltQi2kC7ilAIAK31eNnw0tBuLmsLNDOn4lcP
cAHPv6zg/WztmiiSElXuXXezoLBmH1UQZ72fpmE6CdNRVRCC3tkp9eS/qAK46EoN
64S/guxxtv5gKos5Gs2LQYjj3pIo74AvJEfRXjO8OZk5rRRjjDGAXHdqwDfV5fTa
UxFLRGN0rDo7CrWE8zNUv3fDTnq1yahmZ4lNX1eo0Mpr4qeCv+onK06lV1PW/iKu
/XXWkyvuAZzmYD+hI3ef5uMf3gE0sgf25Czku6NN35BraIBD0gsOpqhUXknVf3r0
lk2X4f/Mq+LseqjliCzD+iIlAThAd4mHplJvaJJBz/a8zXzXFosFVtYexP/Fh6w=
=0HPv
-----END PGP SIGNATURE-----
Jakub Jelinek Jan. 20, 2011, 4:49 p.m. UTC | #2
On Thu, Jan 20, 2011 at 09:36:01AM -0700, Jeff Law wrote:
> On 01/20/11 09:32, Jakub Jelinek wrote:
> > 2011-01-20  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.
> > 
> > 	* g++.dg/opt/pr47366.C: New test.
> Any chance that fixes 47053 or 43695?

No, unfortunately.  PR47053 ICEs during reassoc verification
(i.e. GIMPLE passes), and PR43695 doesn't even use -fnon-call-exceptions.

	Jakub
Jeff Law Jan. 20, 2011, 4:51 p.m. UTC | #3
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 01/20/11 09:49, Jakub Jelinek wrote:
> On Thu, Jan 20, 2011 at 09:36:01AM -0700, Jeff Law wrote:
>> On 01/20/11 09:32, Jakub Jelinek wrote:
>>> 2011-01-20  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.
>>>
>>> 	* g++.dg/opt/pr47366.C: New test.
>> Any chance that fixes 47053 or 43695?
> 
> No, unfortunately.  PR47053 ICEs during reassoc verification
> (i.e. GIMPLE passes), and PR43695 doesn't even use -fnon-call-exceptions.
OK.  I just knew they had similar failure messages and were on the
regression list.  Thanks for checking.

jeff
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJNOGgdAAoJEBRtltQi2kC7C8MH/A+k3Txq5VjoLWMSCws+NTXr
01W8zu6q0Uac6NPLSkEs+Eskm6m4Bb4rF/WCD2+JTbMcmZKRIYkRaIrUgA4mBXcp
LzD93UcUsr9caOLtq7uAl4tKCkv1u/7A52DWOpUruhMGIme98Ig07yeJfaWPdIxw
cHSDKrpQJWAbUytphJE1+I2c5/qonVt9xdAesrCjSSafp4lW5IFCCQO3iOFhqR8p
3vp9GLr0757cJiWkByDBhYqLfQkeAMRCVS8xRuVqA6ryi6arRtEnm4Xj7oinOJvH
T2q4tmMnADIa72U22E/xV6qsfMHOyfIYvY2GxaCZezYV3rAXOicHw4nFUcyYKtM=
=FVaq
-----END PGP SIGNATURE-----
Jeff Law Jan. 21, 2011, 5:44 p.m. UTC | #4
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 01/20/11 09:32, Jakub Jelinek wrote:
> Hi!
> 
> This testcase ICEs during checking, because fwprop turned
> a MEM that was conservatively considered to potentially trap
> (-fnon-call-exceptions) into one that clearly can't trap (frame based),
> but doesn't clean up the EH edges for it, and then DSE removes
> the dead stores and doesn't think about EH cleanup because
> frame based stores (or any other that can be DSEd) really shouldn't
> ever trap.
> 
> Fixed by calling purge_dead_edges in fwprop.  Bootstrapped/regtested on
> x86_64-linux and i686-linux, ok for trunk?
> 
> 2011-01-20  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.
> 
> 	* g++.dg/opt/pr47366.C: New test.
OK.

jeff
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJNOcX+AAoJEBRtltQi2kC7mIAH/0z8R4g2tmerMb5KU5UOrBkr
c8WnubIR3l6NAI1BuwKFKo9Xtpf6f5SMhofs3NBl0aWbG7q/DyxIGPdeCWnrJRj+
HAIp+EzPW42KZ39BRg1wWTXGQnKdVfG5yIQTpCTdlmezqnkDqnPpT21vQj/Fa+3u
EI5BWKNb3+xbhU4RTYp0lvRthFRpZ7e1S3ZelW6Cl5f+FLK7FkLa805s5VwXIEZN
xFWcsRTKFTKjQJOOnKRgg7yCYBZ+h1Dis8LQu1lebdaJbxnJIPWIvnF9DawFjft9
B8jINd8jnY4Kx8BLwVhP+ojXP6ocOQW6krHuG3Zg0E77ouOoa6bMTZhUg+cjzP8=
=4sj/
-----END PGP SIGNATURE-----
diff mbox

Patch

--- gcc/fwprop.c.jj	2010-12-02 11:51:31.000000000 +0100
+++ gcc/fwprop.c	2011-01-20 13:48:25.000000000 +0100
@@ -1315,9 +1315,10 @@  forward_propagate_and_simplify (df_ref u
 
 
 /* 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;
 }
 
--- gcc/testsuite/g++.dg/opt/pr47366.C.jj	2011-01-20 13:51:25.000000000 +0100
+++ gcc/testsuite/g++.dg/opt/pr47366.C	2011-01-20 13:51:01.000000000 +0100
@@ -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 ();
+}