diff options
author | tkoenig <tkoenig@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-12-03 10:35:12 +0000 |
---|---|---|
committer | tkoenig <tkoenig@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-12-03 10:35:12 +0000 |
commit | 65a182bcf6e0fc890aebf2cd5522706ef482f8fb (patch) | |
tree | 9a5ce24417a6f1a45ba00b75518c778dfe427e49 /gcc/fortran/dependency.c | |
parent | fdcc25a6d6e003415dc121a7d12ccd78067a60af (diff) | |
download | gcc-65a182bcf6e0fc890aebf2cd5522706ef482f8fb.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@167413 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fortran/dependency.c')
-rw-r--r-- | gcc/fortran/dependency.c | 97 |
1 files changed, 50 insertions, 47 deletions
diff --git a/gcc/fortran/dependency.c b/gcc/fortran/dependency.c index 40969f6e2d4..77e8df72b68 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; } |