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 <[email protected]>
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 <[email protected]>
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