From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10394 invoked by alias); 27 Apr 2015 18:45:18 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 10375 invoked by uid 89); 27 Apr 2015 18:45:17 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.2 required=5.0 tests=AWL,BAYES_50,KAM_ASCII_DIVIDERS,KAM_LAZY_DOMAIN_SECURITY,RCVD_IN_DNSWL_LOW,T_RP_MATCHES_RCVD autolearn=no version=3.3.2 X-Spam-User: qpsmtpd, 2 recipients X-HELO: cc-smtpout2.netcologne.de Received: from cc-smtpout2.netcologne.de (HELO cc-smtpout2.netcologne.de) (89.1.8.212) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Mon, 27 Apr 2015 18:45:15 +0000 Received: from cc-smtpin3.netcologne.de (cc-smtpin3.netcologne.de [89.1.8.203]) by cc-smtpout2.netcologne.de (Postfix) with ESMTP id 01D5D1201B; Mon, 27 Apr 2015 20:45:12 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by cc-smtpin3.netcologne.de (Postfix) with ESMTP id E4AE611DFC; Mon, 27 Apr 2015 20:45:11 +0200 (CEST) Received: from [78.35.156.120] (helo=cc-smtpin3.netcologne.de) by localhost with ESMTP (eXpurgate 4.0.6) (envelope-from ) id 553e83b7-0b4b-7f0000012729-7f000001bf9d-1 for ; Mon, 27 Apr 2015 20:45:11 +0200 Received: from [192.168.178.20] (xdsl-78-35-156-120.netcologne.de [78.35.156.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by cc-smtpin3.netcologne.de (Postfix) with ESMTPSA; Mon, 27 Apr 2015 20:45:09 +0200 (CEST) Message-ID: <553E83B4.8020005@netcologne.de> Date: Mon, 27 Apr 2015 18:45:00 -0000 From: Thomas Koenig User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.6.0 MIME-Version: 1.0 To: Mikael Morin , "fortran@gcc.gnu.org" , gcc-patches Subject: Re: [Patch, Fortran] Simplify lbound References: <553B7BA4.6040103@netcologne.de> <553BD925.3050401@sfr.fr> In-Reply-To: <553BD925.3050401@sfr.fr> Content-Type: multipart/mixed; boundary="------------080906080500040701020507" X-SW-Source: 2015-04/txt/msg01669.txt.bz2 This is a multi-part message in MIME format. --------------080906080500040701020507 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit Content-length: 3120 Am 25.04.2015 um 20:12 schrieb Mikael Morin: > I've double-checked in the standard, and it seems it is not possible to > simplify after all: > > If ARRAY is a whole array and either ARRAY is an assumed-size > array of rank DIM or dimension DIM of ARRAY has nonzero extent, > LBOUND (ARRAY, DIM) has a value equal to the lower bound for > subscript DIM of ARRAY. Otherwise the result value is 1. > > We can't tell whether the array is zero-sized, so we can't tell the > lbound value. So it is only possible to simplify LBOUND if the lower bound is equal to one, both for assumed-shape and explicit-shape arrays... OK. The attached patch does that, including a test case which catches that particular case. > As you may want to simplify in the limited scope of the matmul inlining, > I'm giving comments about the patch (otherwise you can ignore them): > - No need to check for allocatable or pointer, it should be excluded by > as->type == AS_ASSUMED_SHAPE (but does no harm either). Actually, no. You can have assumed-shape allocatable or pointer dummy arguments which keep their original lbound; see the subroutine 'bar' in the test case. > - Please modify the early return condition: > if (as && (as->type == AS_DEFERRED || as->type == AS_ASSUMED_SHAPE > || as->type == AS_ASSUMED_RANK)) > return NULL; > and let the existing code do the simplification work. That is not part of my patch. > Or drop the lbound simplification idea, and fetch the lbound "by hand" > at matmul inline time. I will probably do so as a future optimization, but I think that most people will see no reason for using different lower bounds, so it is OK for the time being to (slightly) pessimize this case. So... here is the new patch. OK for trunk? Thomas 2015-04-25 Thomas Koenig PR fortran/37131 * simplify.c (simplify_bound): Get constant lower bounds of one from array spec for assumed and explicit shape shape arrays if the lower bounds are indeed one. 2015-04-25 Thomas Koenig PR fortran/37131 * gfortran.dg/coarray_lib_this_image_2.f90: Adjust scan pattern. * gfortran.dg/bound_9.f90: New test case. P.S: In an earlier version, I also added Index: trans-array.c =================================================================== --- trans-array.c (Revision 222431) +++ trans-array.c (Arbeitskopie) @@ -5693,6 +5693,7 @@ gfc_trans_array_bounds (tree type, gfc_symbol * sy to being zero size. */ tmp = fold_build2_loc (input_location, GE_EXPR, boolean_type_node, stride, gfc_index_zero_node); + tmp = gfc_likely (tmp, PRED_FORTRAN_SIZE_ZERO); tmp = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type, tmp, stride, gfc_index_zero_node); but that caused the condition to always return true. I haven't figured out why, but either I am misunderstanding something here, or gfc_likely is buggy, or both. --------------080906080500040701020507 Content-Type: text/x-patch; name="p4.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="p4.diff" Content-length: 1437 Index: simplify.c =================================================================== --- simplify.c (Revision 222431) +++ simplify.c (Arbeitskopie) @@ -3445,6 +3445,39 @@ simplify_bound (gfc_expr *array, gfc_expr *dim, gf done: + /* If the array shape is assumed shape or explicit, we can simplify lbound + to 1 if the given lower bound is one because this matches what lbound + should return for an empty array. */ + + if (!upper && as && dim && dim->expr_type == EXPR_CONSTANT + && (as->type == AS_ASSUMED_SHAPE || as->type == AS_EXPLICIT) + && ref->u.ar.type != AR_SECTION) + { + /* Watch out for allocatable or pointer dummy arrays, they can have + lower bounds that are not equal to one. */ + if (!(array->symtree && array->symtree->n.sym + && (array->symtree->n.sym->attr.allocatable + || array->symtree->n.sym->attr.pointer))) + { + unsigned long int ndim; + gfc_expr *lower, *res; + + ndim = mpz_get_si (dim->value.integer) - 1; + lower = as->lower[ndim]; + if (lower->expr_type == EXPR_CONSTANT + && mpz_cmp_si (lower->value.integer, 1) == 0) + { + res = gfc_copy_expr (lower); + if (kind) + { + int nkind = mpz_get_si (kind->value.integer); + res->ts.kind = nkind; + } + return res; + } + } + } + if (as && (as->type == AS_DEFERRED || as->type == AS_ASSUMED_SHAPE || as->type == AS_ASSUMED_RANK)) return NULL; --------------080906080500040701020507 Content-Type: text/x-fortran; name="bound_9.f90" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="bound_9.f90" Content-length: 1837 ! { dg-do run } ! { dg-options "-fdump-tree-original" } ! Check for different combinations of lbound for dummy arrays, ! stressing empty arrays. The assignments with "one =" should ! be simplified at compile time. module tst implicit none contains subroutine foo (a, b, one, m) integer, dimension(:), intent(in) :: a integer, dimension (-2:), intent(in) :: b integer, intent(out) :: one, m one = lbound(a,1) m = lbound(b,1) end subroutine foo subroutine bar (a, b, n, m) integer, dimension(:), allocatable, intent(inout) :: a integer, dimension(:), pointer, intent(inout) :: b integer, intent(out) :: n, m n = lbound(a,1) m = lbound(b,1) end subroutine bar subroutine baz (a, n, m, s) integer, intent(in) :: n,m integer, intent(out) :: s integer, dimension(n:m) :: a s = lbound(a,1) end subroutine baz subroutine qux (a, s, one) integer, intent(in) :: s integer, dimension(s) :: a integer, intent(out) :: one one = lbound(a,1) end subroutine qux end module tst program main use tst implicit none integer, dimension(3), target :: a, b integer, dimension(0) :: empty integer, dimension(:), allocatable :: x integer, dimension(:), pointer :: y integer :: n,m call foo(a,b,n,m) if (n .ne. 1 .or. m .ne. -2) call abort call foo(a(2:0), empty, n, m) if (n .ne. 1 .or. m .ne. 1) call abort call foo(empty, a(2:0), n, m) if (n .ne. 1 .or. m .ne. 1) call abort allocate (x(0)) call bar (x, y, n, m) if (n .ne. 1 .or. m .ne. 1) call abort call baz(a,3,2,n) if (n .ne. 1) call abort call baz(a,2,3,n) if (n .ne. 2) call abort call qux(a, -3, n) if (n .ne. 1) call abort end program main ! { dg-final { scan-tree-dump-times "\\*one = 1" 2 "original" } } ! { dg-final { cleanup-tree-dump "original" } } --------------080906080500040701020507--