Currently we bail out early when the subscript dependence tester
runs into an unanalyzable dimension.  That's overly pessimistic
in case further dimensions reveal non-conflicting access functions
which now happens more times as we introduce artificial dimensions
for COMPONENT_REFs.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2012-03-15  Richard Guenther  <rguent...@suse.de>

        PR middle-end/52580
        * tree-data-ref.c (subscript_dependence_tester_1): Check
        all dimensions for non-conflicting access functions.

        * gfortran.dg/vect/pr52580.f: New testcase.

Index: gcc/tree-data-ref.c
===================================================================
*** gcc/tree-data-ref.c (revision 185384)
--- gcc/tree-data-ref.c (working copy)
*************** subscript_dependence_tester_1 (struct da
*** 3460,3465 ****
--- 3460,3466 ----
    unsigned int i;
    tree last_conflicts;
    struct subscript *subscript;
+   tree res = NULL_TREE;
  
    for (i = 0; VEC_iterate (subscript_p, DDR_SUBSCRIPTS (ddr), i, subscript);
         i++)
*************** subscript_dependence_tester_1 (struct da
*** 3471,3510 ****
                                      &overlaps_a, &overlaps_b,
                                      &last_conflicts, loop_nest);
  
        if (CF_NOT_KNOWN_P (overlaps_a)
          || CF_NOT_KNOWN_P (overlaps_b))
        {
!         finalize_ddr_dependent (ddr, chrec_dont_know);
!         dependence_stats.num_dependence_undetermined++;
!         free_conflict_function (overlaps_a);
!         free_conflict_function (overlaps_b);
!         return false;
        }
  
        else if (CF_NO_DEPENDENCE_P (overlaps_a)
               || CF_NO_DEPENDENCE_P (overlaps_b))
        {
!         finalize_ddr_dependent (ddr, chrec_known);
!         dependence_stats.num_dependence_independent++;
!         free_conflict_function (overlaps_a);
!         free_conflict_function (overlaps_b);
!         return false;
!       }
! 
!       else
!       {
!         if (SUB_CONFLICTS_IN_A (subscript))
!           free_conflict_function (SUB_CONFLICTS_IN_A (subscript));
!         if (SUB_CONFLICTS_IN_B (subscript))
!           free_conflict_function (SUB_CONFLICTS_IN_B (subscript));
! 
!         SUB_CONFLICTS_IN_A (subscript) = overlaps_a;
!         SUB_CONFLICTS_IN_B (subscript) = overlaps_b;
!         SUB_LAST_CONFLICT (subscript) = last_conflicts;
        }
      }
  
!   return true;
  }
  
  /* Computes the conflicting iterations in LOOP_NEST, and initialize DDR.  */
--- 3472,3514 ----
                                      &overlaps_a, &overlaps_b,
                                      &last_conflicts, loop_nest);
  
+       if (SUB_CONFLICTS_IN_A (subscript))
+       free_conflict_function (SUB_CONFLICTS_IN_A (subscript));
+       if (SUB_CONFLICTS_IN_B (subscript))
+       free_conflict_function (SUB_CONFLICTS_IN_B (subscript));
+ 
+       SUB_CONFLICTS_IN_A (subscript) = overlaps_a;
+       SUB_CONFLICTS_IN_B (subscript) = overlaps_b;
+       SUB_LAST_CONFLICT (subscript) = last_conflicts;
+ 
+       /* If there is any undetermined conflict function we have to
+          give a conservative answer in case we cannot prove that
+        no dependence exists when analyzing another subscript.  */
        if (CF_NOT_KNOWN_P (overlaps_a)
          || CF_NOT_KNOWN_P (overlaps_b))
        {
!         res = chrec_dont_know;
!         continue;
        }
  
+       /* When there is a subscript with no dependence we can stop.  */
        else if (CF_NO_DEPENDENCE_P (overlaps_a)
               || CF_NO_DEPENDENCE_P (overlaps_b))
        {
!         res = chrec_known;
!         break;
        }
      }
  
!   if (res == NULL_TREE)
!     return true;
! 
!   if (res == chrec_known)
!     dependence_stats.num_dependence_independent++;
!   else
!     dependence_stats.num_dependence_undetermined++;
!   finalize_ddr_dependent (ddr, res);
!   return false;
  }
  
  /* Computes the conflicting iterations in LOOP_NEST, and initialize DDR.  */
Index: gcc/testsuite/gfortran.dg/vect/pr52580.f
===================================================================
*** gcc/testsuite/gfortran.dg/vect/pr52580.f    (revision 0)
--- gcc/testsuite/gfortran.dg/vect/pr52580.f    (revision 0)
***************
*** 0 ****
--- 1,33 ----
+ ! { dg-do compile }
+ ! { dg-require-effective-target vect_double }
+       SUBROUTINE CALC2
+       IMPLICIT REAL*8 (A-H, O-Z)
+       PARAMETER (N1=1335, N2=1335)
+ 
+       COMMON  U(N1,N2), V(N1,N2), P(N1,N2),
+      *        UNEW(N1,N2), VNEW(N1,N2),
+      1        PNEW(N1,N2), UOLD(N1,N2),
+      *        VOLD(N1,N2), POLD(N1,N2),
+      2        CU(N1,N2), CV(N1,N2),
+      *        Z(N1,N2), H(N1,N2), PSI(N1,N2)
+       COMMON /CONS/ DT,TDT,DX,DY,A,ALPHA,ITMAX,MPRINT,M,N,MP1,
+      1              NP1,EL,PI,TPI,DI,DJ,PCF
+       TDTS8 = TDT/8.D0
+       TDTSDX = TDT/DX
+       TDTSDY = TDT/DY
+ 
+       DO 200 J=1,N
+       DO 200 I=1,M
+       UNEW(I+1,J) = UOLD(I+1,J)+
+      1    TDTS8*(Z(I+1,J+1)+Z(I+1,J))*(CV(I+1,J+1)+CV(I,J+1)+CV(I,J)
+      2       +CV(I+1,J))-TDTSDX*(H(I+1,J)-H(I,J))
+       VNEW(I,J+1) = VOLD(I,J+1)-TDTS8*(Z(I+1,J+1)+Z(I,J+1))
+      1       *(CU(I+1,J+1)+CU(I,J+1)+CU(I,J)+CU(I+1,J))
+      2       -TDTSDY*(H(I,J+1)-H(I,J))
+       PNEW(I,J) = POLD(I,J)-TDTSDX*(CU(I+1,J)-CU(I,J))
+      1       -TDTSDY*(CV(I,J+1)-CV(I,J))
+   200 CONTINUE
+       RETURN
+       END
+ ! { dg-final { scan-tree-dump-times "LOOP VECTORIZED" 1 "vect" } }
+ ! { dg-final { cleanup-tree-dump "vect" } }

Reply via email to