From patchwork Tue Jan 31 23:07:35 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Thomas Koenig X-Patchwork-Id: 138875 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 58E09B6F98 for ; Wed, 1 Feb 2012 10:08:02 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1328656083; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject: References:In-Reply-To:Content-Type:Mailing-List:Precedence: List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender: Delivered-To; bh=DgHBNqninTJFPhEAPZWTbjOdCYs=; b=XC7DOKmWUXpHiJO JVKdHM5Se3L0cX9MDIAZtKZr6eUXr5yh/1LZl82fQwi+e3OBaP2ZHlFGJGOjw9JT hc684bEDHPNHtu1uLKQSfWqE46lUOIqzzp/vxRJh+d8Y/ruZaU2eTG7HlLoy0mUX C1sA1R97s/s/R2Da6mviIYJ+fP9o= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject:References:In-Reply-To:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=wO30mLMv4hIiQOmVQvB+je6+5TtuMA0PUjkOapxoMtIBCFHY179T0ABN1m20fs jQwzj8U3VFmeR1OYuvB56+4Rw56Op8hKPp8OEWh6MbNT8RzdVaMjfxoa+QGSA++Z vt7aGl0VPB8fEMQAkYZSB18a3OQk7U9TEMFY1+rYYo/50=; Received: (qmail 32561 invoked by alias); 31 Jan 2012 23:07:55 -0000 Received: (qmail 32530 invoked by uid 22791); 31 Jan 2012 23:07:54 -0000 X-SWARE-Spam-Status: No, hits=-1.5 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE, TW_TM, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from cc-smtpout2.netcologne.de (HELO cc-smtpout2.netcologne.de) (89.1.8.212) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 31 Jan 2012 23:07:40 +0000 Received: from cc-smtpin3.netcologne.de (cc-smtpin3.netcologne.de [89.1.8.203]) by cc-smtpout2.netcologne.de (Postfix) with ESMTP id B494C12714; Wed, 1 Feb 2012 00:07:38 +0100 (CET) Received: from [192.168.0.109] (xdsl-78-35-166-187.netcologne.de [78.35.166.187]) by cc-smtpin3.netcologne.de (Postfix) with ESMTPSA id 680E911D8A; Wed, 1 Feb 2012 00:07:35 +0100 (CET) Message-ID: <4F287437.2090902@netcologne.de> Date: Wed, 01 Feb 2012 00:07:35 +0100 From: Thomas Koenig User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; de; rv:1.9.2.17) Gecko/20110414 SUSE/3.1.10 Thunderbird/3.1.10 MIME-Version: 1.0 To: Tobias Burnus CC: fortran@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: Re: [patch, fortran] Fix PR 51958, wrong-code regression with function elimination References: <20120130084612.GA1146@physik.fu-berlin.de> In-Reply-To: <20120130084612.GA1146@physik.fu-berlin.de> 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 Tobias, here is an updated version of the patch, with a more extensive test case. Also regression-tested. OK for trunk? Thomas 2012-01-31 Thomas König PR fortran/51958 * frontend-passes.c (convert_elseif): New function. (optimize_namespace): Call it. 2012-01-31 Thomas König PR fortran/51958 * gfortran.dg/function_optimize_10.f90: New test. ! { do-do run } ! PR 51958 - this used to generate wrong code. ! Original test case by Don Simons. program main implicit none logical :: test1_ok logical :: test2_ok logical :: test3_ok character(len=1):: charq charq = 'c' test1_ok = .true. test2_ok = .false. if (charq .eq. ' ') then test1_ok = .false. else if ((my_ichar(charq).ge.97 .and. my_ichar(charq).le.103)) then test2_OK = .true. end if if ((.not. test1_ok) .or. (.not. test2_ok)) call abort test1_ok = .true. test2_ok = .true. test3_ok = .false. if (charq .eq. ' ') then test1_ok = .false. else if ((my_ichar(charq).lt.97 .or. my_ichar(charq).gt.103)) then test2_ok = .false. else if ((my_ichar(charq).ge.97 .and. my_ichar(charq).le.103)) then test3_ok = .true. end if if ((.not. test1_ok) .or. (.not. test2_ok) .or. (.not. test3_ok)) call abort test1_ok = .true. test2_ok = .true. test3_ok = .false. if (charq .eq. ' ') then test1_ok = .false. else if ((my_ichar(charq).lt.97 .or. my_ichar(charq).gt.103)) then test2_ok = .false. else test3_ok = .true. end if if ((.not. test1_ok) .or. (.not. test2_ok) .or. (.not. test3_ok)) call abort contains pure function my_ichar(c) integer :: my_ichar character(len=1), intent(in) :: c my_ichar = ichar(c) end function my_ichar end program main Index: frontend-passes.c =================================================================== --- frontend-passes.c (Revision 183449) +++ frontend-passes.c (Arbeitskopie) @@ -509,6 +509,70 @@ convert_do_while (gfc_code **c, int *walk_subtrees return 0; } +/* Code callback function for converting + if (a) then + ... + else if (b) then + end if + + into + if (a) then + else + if (b) then + end if + end if + + because otherwise common function elimination would place the BLOCKs + into the wrong place. */ + +static int +convert_elseif (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED, + void *data ATTRIBUTE_UNUSED) +{ + gfc_code *co = *c; + gfc_code *c_if1, *c_if2, *else_stmt; + + if (co->op != EXEC_IF) + return 0; + + /* This loop starts out with the first ELSE statement. */ + else_stmt = co->block->block; + + while (else_stmt != NULL) + { + gfc_code *next_else; + + /* If there is no condition, we're done. */ + if (else_stmt->expr1 == NULL) + break; + + next_else = else_stmt->block; + + /* Generate the new IF statement. */ + c_if2 = XCNEW (gfc_code); + c_if2->op = EXEC_IF; + c_if2->expr1 = else_stmt->expr1; + c_if2->next = else_stmt->next; + c_if2->loc = else_stmt->loc; + c_if2->block = next_else; + + /* ... plus the one to chain it to. */ + c_if1 = XCNEW (gfc_code); + c_if1->op = EXEC_IF; + c_if1->block = c_if2; + c_if1->loc = else_stmt->loc; + + /* Insert the new IF after the ELSE. */ + else_stmt->expr1 = NULL; + else_stmt->next = c_if1; + else_stmt->block = NULL; + else_stmt->next = c_if1; + + else_stmt = next_else; + } + /* Don't walk subtrees. */ + return 0; +} /* Optimize a namespace, including all contained namespaces. */ static void @@ -520,6 +584,7 @@ optimize_namespace (gfc_namespace *ns) in_omp_workshare = false; gfc_code_walker (&ns->code, convert_do_while, dummy_expr_callback, NULL); + gfc_code_walker (&ns->code, convert_elseif, dummy_expr_callback, NULL); gfc_code_walker (&ns->code, cfe_code, cfe_expr_0, NULL); gfc_code_walker (&ns->code, optimize_code, optimize_expr, NULL);