aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/fortran/ChangeLog12
-rw-r--r--gcc/fortran/dependency.c97
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gfortran.dg/dependency_38.f9014
4 files changed, 81 insertions, 47 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index ae2f033..36b2ef2 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,5 +1,17 @@
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
as well as BT_DERIVED.
(gfc_array_allocate): Likewise.
diff --git a/gcc/fortran/dependency.c b/gcc/fortran/dependency.c
index 40969f6..77e8df7 100644
--- a/gcc/fortran/dependency.c
+++ b/gcc/fortran/dependency.c
@@ -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;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e0769f5..10295b2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..60cb2ad
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dependency_38.f90
@@ -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