]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR fortran/45159 (Unnecessary temporaries)
authorThomas Koenig <tkoenig@gcc.gnu.org>
Fri, 3 Dec 2010 10:35:12 +0000 (10:35 +0000)
committerThomas Koenig <tkoenig@gcc.gnu.org>
Fri, 3 Dec 2010 10:35:12 +0000 (10:35 +0000)
2010-12-02  Thomas Koenig  <tkoenig@gcc.gnu.org>

PR fortran/45159
* dependency.c (check_section_vs_section):  Pre-calculate
the relationship between the strides and the relationship
between the start values.  Use an integer constant one for
that purpose.
Forward dependencies for positive strides apply for where
the lhs start <= rhs start and lhs stride <= rhs stride
and vice versa for negative stride.  No need to compare
end expressions in either case (assume no bounds violation).

2010-12-02  Thomas Koenig  <tkoenig@gcc.gnu.org>

PR fortran/45159
* gfortran.dg/dependency_38.f90:  New test.

From-SVN: r167413

gcc/fortran/ChangeLog
gcc/fortran/dependency.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/dependency_38.f90 [new file with mode: 0644]

index ae2f033ae6df7955027e1f251e8670ec9bc316f5..36b2ef26d1d800abdbd06a1d66efdf9a76d0ab44 100644 (file)
@@ -1,3 +1,15 @@
+2010-12-02  Thomas Koenig  <tkoenig@gcc.gnu.org>
+
+       PR fortran/45159
+       * dependency.c (check_section_vs_section):  Pre-calculate
+       the relationship between the strides and the relationship
+       between the start values.  Use an integer constant one for
+       that purpose.
+       Forward dependencies for positive strides apply for where
+       the lhs start <= rhs start and lhs stride <= rhs stride
+       and vice versa for negative stride.  No need to compare
+       end expressions in either case (assume no bounds violation).
+
 2010-12-02  Thomas Koenig  <tkoenig@gcc.gnu.org>
 
        * trans-array.c (gfc_could_be_alias):  Handle BT_CLASS
index 40969f6e2d403098a013e5e5d0d3a6aad9e5aa28..77e8df72b68d5a7717963412174e5efac6676388 100644 (file)
@@ -1071,8 +1071,10 @@ check_section_vs_section (gfc_array_ref *l_ar, gfc_array_ref *r_ar, int n)
   gfc_expr *r_stride;
   gfc_expr *r_lower;
   gfc_expr *r_upper;
+  gfc_expr *one_expr;
   int r_dir;
-  bool identical_strides;
+  int stride_comparison;
+  int start_comparison;
 
   /* If they are the same range, return without more ado.  */
   if (gfc_is_same_range (l_ar, r_ar, n, 0))
@@ -1126,22 +1128,24 @@ check_section_vs_section (gfc_array_ref *l_ar, gfc_array_ref *r_ar, int n)
   if (l_dir == 0 || r_dir == 0)
     return GFC_DEP_OVERLAP;
 
-  /* Determine if the strides are equal.  */
+  /* Determine the relationship between the strides.  Set stride_comparison to
+     -2 if the dependency cannot be determined
+     -1 if l_stride < r_stride
+      0 if l_stride == r_stride
+      1 if l_stride > r_stride
+     as determined by gfc_dep_compare_expr.  */
 
-  if (l_stride)
-    {
-      if (r_stride)
-       identical_strides = gfc_dep_compare_expr (l_stride, r_stride) == 0;
-      else
-       identical_strides = gfc_expr_is_one (l_stride, 0) == 1;
-    }
+  one_expr = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
+
+  stride_comparison = gfc_dep_compare_expr (l_stride ? l_stride : one_expr,
+                                           r_stride ? r_stride : one_expr);
+
+  if (l_start && r_start)
+    start_comparison = gfc_dep_compare_expr (l_start, r_start);
   else
-    {
-      if (r_stride)
-       identical_strides = gfc_expr_is_one (r_stride, 0) == 1;
-      else
-       identical_strides = true;
-    }
+    start_comparison = -2;
+      
+  gfc_free (one_expr);
 
   /* Determine LHS upper and lower bounds.  */
   if (l_dir == 1)
@@ -1237,61 +1241,60 @@ check_section_vs_section (gfc_array_ref *l_ar, gfc_array_ref *r_ar, int n)
 
 #undef IS_CONSTANT_INTEGER
 
-  /* Check for forward dependencies x:y vs. x+1:z.  */
-  if (l_dir == 1 && r_dir == 1
-      && l_start && r_start && gfc_dep_compare_expr (l_start, r_start) == -1
-      && l_end && r_end && gfc_dep_compare_expr (l_end, r_end) == -1)
-    {
-      if (identical_strides)
-       return GFC_DEP_FORWARD;
-    }
+  /* Check for forward dependencies x:y vs. x+1:z and x:y:z vs. x:y:z+1. */
 
-  /* Check for forward dependencies x:y:-1 vs. x-1:z:-1.  */
-  if (l_dir == -1 && r_dir == -1
-      && l_start && r_start && gfc_dep_compare_expr (l_start, r_start) == 1
-      && l_end && r_end && gfc_dep_compare_expr (l_end, r_end) == 1)
-    {
-      if (identical_strides)
-       return GFC_DEP_FORWARD;
-    }
+  if (l_dir == 1 && r_dir == 1 &&
+      (start_comparison == 0 || start_comparison == -1)
+      && (stride_comparison == 0 || stride_comparison == -1))
+         return GFC_DEP_FORWARD;
 
+  /* Check for forward dependencies x:y:-1 vs. x-1:z:-1 and
+     x:y:-1 vs. x:y:-2.  */
+  if (l_dir == -1 && r_dir == -1 && 
+      (start_comparison == 0 || start_comparison == 1)
+      && (stride_comparison == 0 || stride_comparison == 1))
+    return GFC_DEP_FORWARD;
 
-  if (identical_strides)
+  if (stride_comparison == 0 || stride_comparison == -1)
     {
-
       if (l_start && IS_ARRAY_EXPLICIT (l_ar->as))
        {
 
-         /* Check for a(low:y:s) vs. a(z:a:s) where a has a lower bound
+         /* Check for a(low:y:s) vs. a(z:x:s) or
+            a(low:y:s) vs. a(z:x:s+1) where a has a lower bound
             of low, which is always at least a forward dependence.  */
 
          if (r_dir == 1
              && gfc_dep_compare_expr (l_start, l_ar->as->lower[n]) == 0)
            return GFC_DEP_FORWARD;
+       }
+    }
 
-         /* Check for a(high:y:-s) vs. a(z:a:-s) where a has a higher bound
+  if (stride_comparison == 0 || stride_comparison == 1)
+    {
+      if (l_start && IS_ARRAY_EXPLICIT (l_ar->as))
+       {
+      
+         /* Check for a(high:y:-s) vs. a(z:x:-s) or
+            a(high:y:-s vs. a(z:x:-s-1) where a has a higher bound
             of high, which is always at least a forward dependence.  */
 
          if (r_dir == -1
              && gfc_dep_compare_expr (l_start, l_ar->as->upper[n]) == 0)
            return GFC_DEP_FORWARD;
        }
+    }
 
+
+  if (stride_comparison == 0)
+    {
       /* From here, check for backwards dependencies.  */
-      /* x:y vs. x+1:z.  */
-      if (l_dir == 1 && r_dir == 1
-           && l_start && r_start
-           && gfc_dep_compare_expr (l_start, r_start) == 1
-           && l_end && r_end
-           && gfc_dep_compare_expr (l_end, r_end) == 1)
+      /* x+1:y vs. x:z.  */
+      if (l_dir == 1 && r_dir == 1  && start_comparison == 1)
        return GFC_DEP_BACKWARD;
 
-      /* x:y:-1 vs. x-1:z:-1.  */
-      if (l_dir == -1 && r_dir == -1
-           && l_start && r_start
-           && gfc_dep_compare_expr (l_start, r_start) == -1
-           && l_end && r_end
-           && gfc_dep_compare_expr (l_end, r_end) == -1)
+      /* x-1:y:-1 vs. x:z:-1.  */
+      if (l_dir == -1 && r_dir == -1 && start_comparison == -1)
        return GFC_DEP_BACKWARD;
     }
 
index e0769f5d8e2171af021ad46035d390d4fe94596a..10295b2cbd9029ce1b56bf1e8ce78b61ca92a59e 100644 (file)
@@ -1,3 +1,8 @@
+2010-12-02  Thomas Koenig  <tkoenig@gcc.gnu.org>
+
+       PR fortran/45159
+       * gfortran.dg/dependency_38.f90:  New test.
+
 2010-12-02  Ian Lance Taylor  <iant@google.com>
 
        * lib/go.exp: New file.
diff --git a/gcc/testsuite/gfortran.dg/dependency_38.f90 b/gcc/testsuite/gfortran.dg/dependency_38.f90
new file mode 100644 (file)
index 0000000..60cb2ad
--- /dev/null
@@ -0,0 +1,14 @@
+! { dg-do compile }
+! { dg-options "-Warray-temporaries" }
+! PR 45159 - No temporary should be created for this.
+program main
+  integer a(100)
+  a(10:16:2) = a(10:16:2)
+  a(10:16:2) = a(10:19:3)
+  a(10:18:2) = a(12:20:2)
+  a(1:10) = a(2:20:2)
+  a(16:10:-2) = a(16:10:-2)
+  a(19:10:-1) = a(19:1:-2)
+  a(19:10:-1) = a(18:9:-1)
+  a(19:11:-1) = a(18:2:-2)
+end program main