From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15645 invoked by alias); 27 Oct 2011 23:35:05 -0000 Received: (qmail 28115 invoked by uid 22791); 27 Oct 2011 23:32:49 -0000 X-SWARE-Spam-Status: No, hits=-1.5 required=5.0 tests=AWL,BAYES_00,RP_MATCHES_RCVD,TW_TM X-Spam-Check-By: sourceware.org Received: from smtp25.services.sfr.fr (HELO smtp25.services.sfr.fr) (93.17.128.120) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 27 Oct 2011 23:32:33 +0000 Received: from filter.sfr.fr (localhost [127.0.0.1]) by msfrf2512.sfr.fr (SMTP Server) with ESMTP id 0E005700004E; Fri, 28 Oct 2011 01:32:32 +0200 (CEST) Received: from gimli.local (145.15.72.86.rev.sfr.net [86.72.15.145]) by msfrf2512.sfr.fr (SMTP Server) with ESMTP id A4AAA700008E; Fri, 28 Oct 2011 01:32:31 +0200 (CEST) X-SFR-UUID: 20111027233231674.A4AAA700008E@msfrf2512.sfr.fr Content-Type: multipart/mixed; boundary="===============4963869586577794040==" MIME-Version: 1.0 From: Mikael Morin To: gfortran , GCC patches Message-ID: <20111027233231.18581.98482@gimli.local> In-Reply-To: <20111027233144.18581.30688@gimli.local> References: <20111027232818.18581.901@gimli.local> <20111027233144.18581.30688@gimli.local> Subject: [Patch, fortran] [45/66] inline sum and product: Update the scalarizer: Update dimension mapping inversion functions. Date: Thu, 27 Oct 2011 23:35:00 -0000 X-IsSubscribed: yes 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 X-SW-Source: 2011-10/txt/msg02550.txt.bz2 --===============4963869586577794040== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-length: 1873 gfc_trans_create_temp_arrays has been using loop bounds to set array temporary bounds; this is a sensible thing to do as gfc_conv_loop_setup tries to set loop bounds according to the most information (especially w.r.t. constantness) it can find. For plain arrays like `a(:,:)' or `b(:,1,:)', it's quite simple, as there is a direct maping between loop bounds and temporary bounds. Now, if we are creating a temporary for the argument of `transpose(a(:,1,1,:))' we have to be careful as the loop has a direct mapping to `transpose(a(:,1,1:))', while the temporary has a direct mapping to `a(:,1,1,:)'. It is currently done (in get_array_ref_dim) by looking at the dim array which is in the case above: {3,0}. If we want to know the bounds of the first dimension (or zero'th as it is zero-based) of the temporary, we see that dim[0] == 3, and that there is one element in dim that is below 3. Thus bounds are to be taken from dimension number one (the second as it is zero-based) of the loop. The same function is used to retrieve the shape dimension from the loop dimension in gfc_conv_loop_setup. Now, let's throw sum in the mix. Now we have to generate bounds properly when generating a temporary either for the inner or outer arrays in the following cases: sum(a(:,1,1,:), dim=1) transpose(sum(a(:,1,:,:), dim=1)) sum(transpose(a(:,1,1,:)), dim=1) For the outer array, in all cases, the current implementation can be kept as is, as the inner loop can be completely ignored. For the inner array, however, we have to take care of the current loop, and all the parents ones it is in, so this patch adds a walk towards the outer array. With this change, the function can't be used as is anymore in gfc_conv_loop_setup, as it is ignoring nested loops: we have to start from the most nested array slice before calling the function. This patch also does that. OK? --===============4963869586577794040== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="pr43829-45.CL" Content-length: 384 2011-10-19 Mikael Morin * trans-array.c (get_array_ref_dim, get_scalarizer_dim_for_array_dim): Rename the former to the latter and loop over the parents. (innermost_ss): New function. (get_array_ref_dim_for_loop_dim): New function. (gfc_trans_create_temp_array): Use get_scalarizer_dim_for_array_dim. (set_loop_bounds): Use get_array_dim_for_loop_dim). --===============4963869586577794040== Content-Type: text/x-diff; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="pr43829-45.patch" Content-length: 3723 diff --git a/trans-array.c b/trans-array.c index 25d9a37..d918fa8 100644 --- a/trans-array.c +++ b/trans-array.c @@ -868,28 +868,62 @@ gfc_trans_allocate_array_storage (stmtblock_t * pre, stmtblock_t * post, } -/* Get the array reference dimension corresponding to the given loop dimension. - It is different from the true array dimension given by the dim array in - the case of a partial array reference - It is different from the loop dimension in the case of a transposed array. - */ +/* Get the scalarizer array dimension corresponding to actual array dimension + given by ARRAY_DIM. + + For example, if SS represents the array ref a(1,:,:,1), it is a + bidimensional scalarizer array, and the result would be 0 for ARRAY_DIM=1, + and 1 for ARRAY_DIM=2. + If SS represents transpose(a(:,1,1,:)), it is again a bidimensional + scalarizer array, and the result would be 1 for ARRAY_DIM=0 and 0 for + ARRAY_DIM=3. + If SS represents sum(a(:,:,:,1), dim=1), it is a 2+1-dimensional scalarizer + array. If called on the inner ss, the result would be respectively 0,1,2 for + ARRAY_DIM=0,1,2. If called on the outer ss, the result would be 0,1 + for ARRAY_DIM=1,2. */ static int -get_array_ref_dim (gfc_ss *ss, int loop_dim) +get_scalarizer_dim_for_array_dim (gfc_ss *ss, int array_dim) { - int n, array_dim, array_ref_dim; + int array_ref_dim; + int n; array_ref_dim = 0; - array_dim = ss->dim[loop_dim]; - for (n = 0; n < ss->dimen; n++) - if (ss->dim[n] < array_dim) - array_ref_dim++; + for (; ss; ss = ss->parent) + for (n = 0; n < ss->dimen; n++) + if (ss->dim[n] < array_dim) + array_ref_dim++; return array_ref_dim; } +static gfc_ss * +innermost_ss (gfc_ss *ss) +{ + while (ss->nested_ss != NULL) + ss = ss->nested_ss; + + return ss; +} + + + +/* Get the array reference dimension corresponding to the given loop dimension. + It is different from the true array dimension given by the dim array in + the case of a partial array reference (i.e. a(:,:,1,:) for example) + It is different from the loop dimension in the case of a transposed array. + */ + +static int +get_array_ref_dim_for_loop_dim (gfc_ss *ss, int loop_dim) +{ + return get_scalarizer_dim_for_array_dim (innermost_ss (ss), + ss->dim[loop_dim]); +} + + /* Generate code to create and initialize the descriptor for a temporary array. This is used for both temporaries needed by the scalarizer, and functions returning arrays. Adjusts the loop variables to be @@ -959,7 +993,7 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, gfc_ss * ss, to the n'th dimension of the array. We need to reconstruct loop infos in the right order before using it to set the descriptor bounds. */ - tmp_dim = get_array_ref_dim (ss, n); + tmp_dim = get_scalarizer_dim_for_array_dim (ss, dim); from[tmp_dim] = loop->from[n]; to[tmp_dim] = loop->to[n]; @@ -1011,7 +1045,7 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, gfc_ss * ss, { for (n = 0; n < loop->dimen; n++) { - dim = ss->dim[n]; + dim = get_scalarizer_dim_for_array_dim (ss, ss->dim[n]); /* For a callee allocated array express the loop bounds in terms of the descriptor fields. */ @@ -4126,7 +4160,7 @@ set_loop_bounds (gfc_loopinfo *loop) && INTEGER_CST_P (info->stride[dim])) { loop->from[n] = info->start[dim]; - mpz_set (i, cshape[get_array_ref_dim (loopspec[n], n)]); + mpz_set (i, cshape[get_array_ref_dim_for_loop_dim (loopspec[n], n)]); mpz_sub_ui (i, i, 1); /* To = from + (size - 1) * stride. */ tmp = gfc_conv_mpz_to_tree (i, gfc_index_integer_kind); --===============4963869586577794040==--