diff options
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 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; } |