Hello world, the attached patch fixes two cases of unnecessary array temporaries when vector indices were involved. When we saw something like that, we gave up even if
- The vector indices were equal - The vector indices didn't matter at all because, in a different dimension, things were known to be different. Regression-tested. OK for trunk? Thomas 2013-07-20 Thomas Koenig <tkoe...@gcc.gnu.org> PR fortran/56937 * dependency.c (gfc_dep_resolver): Treat identical array subscripts as identical; don't unconditionally return a dependency if an array subscript is found. 2013-07-20 Thomas Koenig <tkoe...@gcc.gnu.org> PR fortran/56937 * gfortran.dg/dependency_42.f90: New test. * gfortran.dg/dependency_43.f90: New test.
Index: dependency.c =================================================================== --- dependency.c (Revision 200743) +++ dependency.c (Arbeitskopie) @@ -2095,12 +2095,22 @@ gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gf for (n=0; n < lref->u.ar.dimen; n++) { - /* Assume dependency when either of array reference is vector - subscript. */ + /* Handle dependency when either of array reference is vector + subscript. Assume dependency unless they are identical. */ if (lref->u.ar.dimen_type[n] == DIMEN_VECTOR || rref->u.ar.dimen_type[n] == DIMEN_VECTOR) - return 1; + { + if (lref->u.ar.dimen_type[n] == DIMEN_VECTOR + && rref->u.ar.dimen_type[n] == DIMEN_VECTOR + && gfc_dep_compare_expr (lref->u.ar.start[n], + rref->u.ar.start[n]) == 0) + this_dep = GFC_DEP_EQUAL; + else + this_dep = GFC_DEP_OVERLAP; + goto update_fin_dep; + } + if (lref->u.ar.dimen_type[n] == DIMEN_RANGE && rref->u.ar.dimen_type[n] == DIMEN_RANGE) this_dep = check_section_vs_section (&lref->u.ar, &rref->u.ar, n); @@ -2164,6 +2174,8 @@ gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gf /* Overlap codes are in order of priority. We only need to know the worst one.*/ + + update_fin_dep: if (this_dep > fin_dep) fin_dep = this_dep; }
! { dg-do run } ! { dg-options "-Warray-temporaries" } ! PR fortran/56937 - unnecessary temporaries with vector indices program main real :: q(4), r(4), p(3) integer :: idx(3) p = [0.5, 1.0, 2.0] idx = [4,3,1] r = 1.0 r(idx) = r(idx) + p q = 1.0 q(4) = q(4) + p(1) q(3) = q(3) + p(2) q(1) = q(1) + p(3) if (any (q - r /= 0)) call abort end
! { dg-do run } ! { dg-options "-Warray-temporaries" } ! PR fortran/56937 - unnecessary temporaries with vector indices program main integer, dimension(3) :: i1, i2 real :: a(3,2) data a / 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 / i1 = [ 1, 2, 3 ] i2 = [ 3, 2, 1 ] a (i1,1) = a (i2,2) if (a(1,1) /= 6.0 .or. a(2,1) /= 5.0 .or. a(3,1) /= 4.0) call abort if (a(1,2) /= 4.0 .or. a(2,2) /= 5.0 .or. a(3,2) /= 6.0) call abort end program main