aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorThomas Koenig <tkoenig@gcc.gnu.org>2010-12-03 10:35:12 +0000
committerThomas Koenig <tkoenig@gcc.gnu.org>2010-12-03 10:35:12 +0000
commit8976d513cc7e285ef043df4766efada449216eec (patch)
tree9a5ce24417a6f1a45ba00b75518c778dfe427e49 /gcc
parent272cec5de2c65fe12365a56080038a35ddc6c180 (diff)
downloadgcc-8976d513cc7e285ef043df4766efada449216eec.zip
gcc-8976d513cc7e285ef043df4766efada449216eec.tar.gz
gcc-8976d513cc7e285ef043df4766efada449216eec.tar.bz2
re PR fortran/45159 (Unnecessary temporaries)
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
Diffstat (limited to 'gcc')
-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