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

Reply via email to