From patchwork Thu Jan 20 16:32:27 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 79722 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 34341B7088 for ; Fri, 21 Jan 2011 03:32:42 +1100 (EST) Received: (qmail 28822 invoked by alias); 20 Jan 2011 16:32:39 -0000 Received: (qmail 28803 invoked by uid 22791); 20 Jan 2011 16:32:35 -0000 X-SWARE-Spam-Status: No, hits=-6.3 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, TW_CF, TW_FW, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 20 Jan 2011 16:32:30 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id p0KGWTD3002888 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 20 Jan 2011 11:32:29 -0500 Received: from tyan-ft48-01.lab.bos.redhat.com (tyan-ft48-01.lab.bos.redhat.com [10.16.42.4]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p0KGWSog015850 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Thu, 20 Jan 2011 11:32:28 -0500 Received: from tyan-ft48-01.lab.bos.redhat.com (localhost.localdomain [127.0.0.1]) by tyan-ft48-01.lab.bos.redhat.com (8.14.4/8.14.4) with ESMTP id p0KGWS9V005555 for ; Thu, 20 Jan 2011 17:32:28 +0100 Received: (from jakub@localhost) by tyan-ft48-01.lab.bos.redhat.com (8.14.4/8.14.4/Submit) id p0KGWRo3005554 for gcc-patches@gcc.gnu.org; Thu, 20 Jan 2011 17:32:27 +0100 Date: Thu, 20 Jan 2011 17:32:27 +0100 From: Jakub Jelinek To: gcc-patches@gcc.gnu.org Subject: [PATCH] Call purge_dead_edges when needed in fwprop (PR rtl-optimization/47366) Message-ID: <20110120163227.GZ2724@tyan-ft48-01.lab.bos.redhat.com> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org 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 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 --- 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 (); +}