From patchwork Mon Aug 9 18:22:50 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [pach,Fortran] Improve dependency checking Date: Mon, 09 Aug 2010 08:22:50 -0000 From: Thomas Koenig X-Patchwork-Id: 61297 Message-Id: <1281378170.3622.5.camel@linux-fd1f.site> To: fortran@gcc.gnu.org Cc: gcc-patches@gcc.gnu.org Hello world, here's another installment of dependency checking improvements. I debated a little with myself if extending gfc_ref_dimen_size really was the right approach, but I didn't want to duplicate its code. Regression-tested on trunk. OK? [If there isn't time to review this before tomorrow evening, I would ask somebody to commit this for me]. Thomas 2010-08-09 Thomas Koenig PR fortran/44235 * array.c (gfc_ref_dimen_size): Add end argument. If end is non-NULL, calculate it. (ref_size): Adjust call to gfc_ref_dimen_size. (gfc_array_dimen_size): Likewise. (gfc_array_res_shape): Likewise. * gfortran.h: Adjust prototype for gfc_ref_dimen_size. * resolve.c (resolve_array_ref): For stride not equal to -1, fill in the lowest possible end. 2010-08-09 Thomas Koenig PR fortran/44235 * dependency_32.f90: New test. Index: array.c =================================================================== --- array.c (Revision 162824) +++ array.c (Arbeitskopie) @@ -1940,10 +1940,11 @@ spec_size (gfc_array_spec *as, mpz_t *result) } -/* Get the number of elements in an array section. */ +/* Get the number of elements in an array section. Optionally, also supply + the end value. */ gfc_try -gfc_ref_dimen_size (gfc_array_ref *ar, int dimen, mpz_t *result) +gfc_ref_dimen_size (gfc_array_ref *ar, int dimen, mpz_t *result, mpz_t *end) { mpz_t upper, lower, stride; gfc_try t; @@ -2016,6 +2017,15 @@ gfc_try mpz_set_ui (*result, 0); t = SUCCESS; + if (end) + { + mpz_init (*end); + + mpz_sub_ui (*end, *result, 1UL); + mpz_mul (*end, *end, stride); + mpz_add (*end, *end, lower); + } + cleanup: mpz_clear (upper); mpz_clear (lower); @@ -2040,7 +2050,7 @@ ref_size (gfc_array_ref *ar, mpz_t *result) for (d = 0; d < ar->dimen; d++) { - if (gfc_ref_dimen_size (ar, d, &size) == FAILURE) + if (gfc_ref_dimen_size (ar, d, &size, NULL) == FAILURE) { mpz_clear (*result); return FAILURE; @@ -2086,7 +2096,7 @@ gfc_array_dimen_size (gfc_expr *array, int dimen, if (ref->u.ar.dimen_type[i] != DIMEN_ELEMENT) dimen--; - return gfc_ref_dimen_size (&ref->u.ar, i - 1, result); + return gfc_ref_dimen_size (&ref->u.ar, i - 1, result, NULL); } } @@ -2222,7 +2232,7 @@ gfc_array_ref_shape (gfc_array_ref *ar, mpz_t *sha { if (ar->dimen_type[i] != DIMEN_ELEMENT) { - if (gfc_ref_dimen_size (ar, i, &shape[d]) == FAILURE) + if (gfc_ref_dimen_size (ar, i, &shape[d], NULL) == FAILURE) goto cleanup; d++; } Index: gfortran.h =================================================================== --- gfortran.h (Revision 162824) +++ gfortran.h (Arbeitskopie) @@ -2753,7 +2753,7 @@ gfc_try spec_size (gfc_array_spec *, mpz_t *); gfc_try spec_dimen_size (gfc_array_spec *, int, mpz_t *); int gfc_is_compile_time_shape (gfc_array_spec *); -gfc_try gfc_ref_dimen_size (gfc_array_ref *, int dimen, mpz_t *); +gfc_try gfc_ref_dimen_size (gfc_array_ref *, int dimen, mpz_t *, mpz_t *); /* interface.c -- FIXME: some of these should be in symbol.c */ Index: resolve.c =================================================================== --- resolve.c (Revision 162824) +++ resolve.c (Arbeitskopie) @@ -4316,6 +4316,37 @@ resolve_array_ref (gfc_array_ref *ar) &ar->c_where[i], e->rank); return FAILURE; } + + /* Fill in the upper bound, which may be lower than the + specified one for something like a(2:10:5), which is + identical to a(2:7:5). Only relevant for non-zero strides. */ + if (ar->dimen_type[i] == DIMEN_RANGE + && ar->stride[i] != NULL && ar->stride[i]->expr_type == EXPR_CONSTANT + && mpz_cmp_si (ar->stride[i]->value.integer, 1L) != 0) + { + mpz_t size, end; + + if (gfc_ref_dimen_size (ar, i, &size, &end) == SUCCESS) + { + if (ar->end[i] == NULL) + { + ar->end[i] = + gfc_get_constant_expr (BT_INTEGER, gfc_index_integer_kind, + &ar->where); + mpz_set (ar->end[i]->value.integer, end); + } + else if (ar->end[i]->ts.type == BT_INTEGER + && ar->end[i]->expr_type == EXPR_CONSTANT) + { + mpz_set (ar->end[i]->value.integer, end); + } + else + gcc_unreachable (); + + mpz_clear (size); + mpz_clear (end); + } + } } if (ar->type == AR_FULL && ar->as->rank == 0) Index: simplify.c =================================================================== --- simplify.c (Revision 162824) +++ simplify.c (Arbeitskopie) @@ -2807,7 +2807,7 @@ simplify_bound_dim (gfc_expr *array, gfc_expr *kin { if (upper) { - if (gfc_ref_dimen_size (&ref->u.ar, d-1, &result->value.integer) + if (gfc_ref_dimen_size (&ref->u.ar, d-1, &result->value.integer, NULL) != SUCCESS) goto returnNull; }